diff --git a/.gitignore b/.gitignore index 26813d864c87..70bc59603718 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ *.symtypes *.tar *.xz +*.zst Module.symvers modules.builtin diff --git a/Documentation/ABI/testing/sysfs-kernel-ion b/Documentation/ABI/testing/sysfs-kernel-ion deleted file mode 100644 index f57f970574ae..000000000000 --- a/Documentation/ABI/testing/sysfs-kernel-ion +++ /dev/null @@ -1,27 +0,0 @@ -What: /sys/kernel/ion -Date: Dec 2019 -KernelVersion: 4.14.158 -Contact: Suren Baghdasaryan , - Sandeep Patil -Description: - The /sys/kernel/ion directory contains a snapshot of the - internal state of ION memory heaps and pools. -Users: kernel memory tuning tools - -What: /sys/kernel/ion/total_heaps_kb -Date: Dec 2019 -KernelVersion: 4.14.158 -Contact: Suren Baghdasaryan , - Sandeep Patil -Description: - The total_heaps_kb file is read-only and specifies how much - memory in Kb is allocated to ION heaps. - -What: /sys/kernel/ion/total_pools_kb -Date: Dec 2019 -KernelVersion: 4.14.158 -Contact: Suren Baghdasaryan , - Sandeep Patil -Description: - The total_pools_kb file is read-only and specifies how much - memory in Kb is allocated to ION pools. diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt index 5b614f215d22..b58a1eb312ee 100644 --- a/Documentation/devicetree/bindings/arm/msm/msm.txt +++ b/Documentation/devicetree/bindings/arm/msm/msm.txt @@ -255,7 +255,6 @@ compatible = "qcom,sa8155p-adp-alcor" compatible = "qcom,sdxprairie-rumi" compatible = "qcom,sdxprairie-mtp" compatible = "qcom,sdxprairie-cdp" -compatible = "qcom,sdxprairie-ttp" compatible = "qcom,sa515m-ccard" compatible = "qcom,sa515m-ttp" compatible = "qcom,sdmmagpie-rumi" diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt index eec96f18ee31..d8dd4c2f128a 100644 --- a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt +++ b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt @@ -36,6 +36,13 @@ Properties: Definition: List of phandles to devices that the OPP tables with the L3 frequency and voltage mappings are loaded for. +- qcom,cpufreq-table-XX + Usage: optional + Value type: + Definition: List of frequencies (in kHz) to expose in CPU XX's cpufreq table. + All frequencies present in hardware will be exposed if this list + is not present. + Example: clock_cpucc: qcom,cpucc { compatible = "qcom,clk-cpu-osm"; @@ -49,4 +56,54 @@ Example: l3-devs = <&phandle0 &phandle1 &phandle2>; #clock-cells = <1>; + qcom,cpufreq-table-0 = + < 300000>, + < 403200>, + < 480000>, + < 576000>, + < 672000>, + < 768000>, + < 864000>, + < 979200>, + <1075200>, + <1171200>, + <1267200>; + + qcom,cpufreq-table-4 = + < 576000>, + < 672000>, + < 768000>, + < 864000>, + < 960000>, + <1056000>, + <1152000>, + <1248000>, + <1344000>, + <1420800>, + <1497600>, + <1593600>, + <1689600>, + <1785600>, + <1862400>, + <1939200>, + <2016000>; + + qcom,cpufreq-table-7 = + < 691200>, + < 768000>, + < 864000>, + < 940800>, + <1017600>, + <1113600>, + <1190400>, + <1286400>, + <1363200>, + <1459200>, + <1536000>, + <1632000>, + <1728000>, + <1824000>, + <1900800>, + <1977600>, + <2054400>; }; diff --git a/Documentation/devicetree/bindings/drm/msm/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/drm/msm/mdss-dsi-panel.txt index 8ee87ab2f31c..3b6e23b68e37 100644 --- a/Documentation/devicetree/bindings/drm/msm/mdss-dsi-panel.txt +++ b/Documentation/devicetree/bindings/drm/msm/mdss-dsi-panel.txt @@ -265,6 +265,8 @@ Optional properties: 0x00 = default value. - qcom,mdss-dsi-t-clk-pre: Specifies the byte clock cycles before mode switch. 0x00 = default value. +- qcom,mdss-dsi-t-clk-pre-extend: Boolean that specifies whether to enable t_clk_pre counter + increment by 2 byteclk. - qcom,mdss-dsi-stream: Specifies the packet stream to be used. 0 = stream 0 (default) 1 = stream 1 @@ -498,7 +500,6 @@ Optional properties: - qcom,panel-ack-disabled: A boolean property to indicate, whether we need to wait for any ACK from the panel for any commands that we send. - qcom,mdss-dsi-force-clock-lane-hs: Boolean to force dsi clock lanes to HS mode always. -- qcom,panel-cphy-mode: Boolean to specify whether panel is using cphy. - qcom,compression-mode: Select compression mode for panel. "fbc" - frame buffer compression @@ -660,6 +661,7 @@ Example: qcom,lanes-per-sublink = <2>; qcom,mdss-dsi-t-clk-post = <0x20>; qcom,mdss-dsi-t-clk-pre = <0x2c>; + qcom,mdss-dsi-t-clk-pre-extend; qcom,mdss-dsi-stream = <0>; qcom,mdss-dsi-mdp-trigger = <0>; qcom,mdss-dsi-dma-trigger = <0>; diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt index 2182ade92b46..0752f51238e1 100644 --- a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt +++ b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt @@ -510,6 +510,7 @@ the fps window. in floating state(not LP00 or LP11) to turn on this property. Software turns off PHY pmic power supply, phy ldo and DSI Lane ldo during idle screen (footswitch control off) when this property is enabled. +- qcom,skip-panel-reset: Boolean. when set, will skip panel reset during panel ON/OFF. [[Optional config sub-nodes]] These subnodes provide different configurations for a given same panel. Default configuration can be chosen by specifying phandle of the selected subnode in the qcom,config-select. diff --git a/Documentation/devicetree/bindings/gpu/adreno-iommu.txt b/Documentation/devicetree/bindings/gpu/adreno-iommu.txt index df29ef5d26a1..9ddca43a93d9 100644 --- a/Documentation/devicetree/bindings/gpu/adreno-iommu.txt +++ b/Documentation/devicetree/bindings/gpu/adreno-iommu.txt @@ -38,6 +38,8 @@ Optional properties: be aligned - qcom,unmap_fast : A boolean specifying if iommu unmap fast is supported on this target. +- qcom,secure-size : Specifies the size of gpu address region to be used for + secure memory mapping. - List of sub nodes, one for each of the translation context banks supported. The driver uses the names of these nodes to determine how they are used, diff --git a/Documentation/devicetree/bindings/input/qpnp-power-on.txt b/Documentation/devicetree/bindings/input/qpnp-power-on.txt index e13669a6acbd..e52ecc639bce 100644 --- a/Documentation/devicetree/bindings/input/qpnp-power-on.txt +++ b/Documentation/devicetree/bindings/input/qpnp-power-on.txt @@ -80,8 +80,14 @@ Optional properties: - qcom,shutdown-poweroff-type: Same description as qcom,warm-reset-poweroff- type but this applies for the system shutdown case. -- qcom,kpdpwr-sw-debounce: Boolean property to enable the debounce logic - on the KPDPWR_N rising edge. +- qcom,pon-sw-debounce Boolean property to enable software debouncing + logic for pon input keys. +- qcom,pon-sw-dbc-delay The debounce delay for the power-key interrupt + specified in us. This can be set to any value + as it is handled in software rather than by the + PMIC hardware. Only used if qcom,pon-sw-debounce + is enabled. Defaults to the value of + qcom,pon-dbc-delay if not specified. - qcom,resin-pon-reset: Boolean property which indicates that resin needs to be configured during reset in addition to the primary PON device that is configured diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-spmi-wled.txt b/Documentation/devicetree/bindings/leds/backlight/qcom-spmi-wled.txt index a0447c6d6469..81752a44865c 100644 --- a/Documentation/devicetree/bindings/leds/backlight/qcom-spmi-wled.txt +++ b/Documentation/devicetree/bindings/leds/backlight/qcom-spmi-wled.txt @@ -90,6 +90,14 @@ platforms. The PMIC is connected to the host processor via SPMI bus. 29600, 19600, 18100. Default: 29600 mV +- qcom,sync-dly + Usage: optional + Value type: + Definition: Delay for current sync in us. Values are + 0, 200, 400, 600, 800, 1000, 1200, 1400. + Default: 400 us. + This property is only applicable for WLED4. + - qcom,string-cfg Usage: optional Value type: diff --git a/Documentation/devicetree/bindings/net/qcom,stmmac-ethqos.txt b/Documentation/devicetree/bindings/net/qcom,stmmac-ethqos.txt index f910fb509396..7011dff0b7d9 100644 --- a/Documentation/devicetree/bindings/net/qcom,stmmac-ethqos.txt +++ b/Documentation/devicetree/bindings/net/qcom,stmmac-ethqos.txt @@ -114,6 +114,8 @@ Optional properties: - snps,high_credit: max write outstanding req. limit - snps,low_credit: max read outstanding req. limit - snps,priority: TX queue priority (Range: 0x0 to 0xF) +- rx-prog-swap: boolean value to enable RX_PROG_SWAP for 10/100M +- rx-dll-bypass: boolean value to indicate RX DLL in bypass mode. Examples: stmmac_axi_setup: stmmac-axi-config { diff --git a/Documentation/devicetree/bindings/thermal/qti-qmi-cdev.txt b/Documentation/devicetree/bindings/thermal/qti-qmi-cdev.txt index 15d0f4a607b1..0e136972f5f7 100644 --- a/Documentation/devicetree/bindings/thermal/qti-qmi-cdev.txt +++ b/Documentation/devicetree/bindings/thermal/qti-qmi-cdev.txt @@ -52,6 +52,7 @@ Subsystem properties: "mmw_skin1" -> MMW skin mitigation device1, "mmw_skin2" -> MMW skin mitigation device2, "mmw_skin3" -> MMW skin mitigation device3, + "modem_v2x" -> modem CV2X mitigation device, "cpr_cold" -> for cpr restriction, "cdsp_sw" -> for CDSP DCVS mitigation device, "cdsp_hw" -> for CDSP hardware mitigation device. @@ -95,6 +96,11 @@ Example: qcom,qmi-dev-name = "cpr_cold"; #cooling-cells = <2>; }; + + modem_v2x: modem_v2x { + qcom,qmi-dev-name = "modem_v2x"; + #cooling-cells = <2>; + }; }; adsp { diff --git a/Documentation/dontdiff b/Documentation/dontdiff index 2e2e52c267d5..844284713420 100644 --- a/Documentation/dontdiff +++ b/Documentation/dontdiff @@ -54,6 +54,7 @@ *.ver *.xml *.xz +*.zst *_MODULES *_vga16.c *~ diff --git a/Kconfig b/Kconfig index 8c4c1cb0f9cd..af31bb3d62da 100644 --- a/Kconfig +++ b/Kconfig @@ -3,7 +3,7 @@ # For a description of the syntax of this configuration file, # see Documentation/kbuild/kconfig-language.txt. # -mainmenu "Linux/$ARCH $KERNELVERSION Kernel Configuration" +mainmenu "Linux/$ARCH $VERSION.$PATCHLEVEL Kernel Configuration" config SRCARCH string diff --git a/Makefile b/Makefile index c1add4587a53..18bb45ffb8b8 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 4 PATCHLEVEL = 14 -SUBLEVEL = 190 +SUBLEVEL = 193 EXTRAVERSION = NAME = Petit Gorille @@ -737,17 +737,6 @@ endif ifeq ($(cc-name),clang) KBUILD_CFLAGS += -O3 KBUILD_CFLAGS += $(call cc-option, -mcpu=cortex-a55 -mtune=cortex-a55) - -ifdef CONFIG_LLVM_POLLY -KBUILD_CFLAGS += -mllvm -polly \ - -mllvm -polly-run-dce \ - -mllvm -polly-run-inliner \ - -mllvm -polly-opt-fusion=max \ - -mllvm -polly-ast-use-context \ - -mllvm -polly-detect-keep-going \ - -mllvm -polly-vectorizer=stripmine \ - -mllvm -polly-invariant-load-hoisting -endif endif endif diff --git a/README.md b/README.md index 5ef116b07359..d8ba802aed14 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@ -# iMMENSITY KERNAL for RedmiK20pro / Mi9Tpro +# IMMENSiTY KERNAL for Redmi K20pro / Mi9Tpro ![logo](https://github.com/UtsavBalar1231/xda-stuff/raw/master/immensity-new.png "logo here") -> Based on the Qualcomm AUTO tag **LE.UM.4.2.1.r1-02600-QCS404.0** -> Merged AOSP kernel_common/android-4.14-stable [4.14.185] -> Current CAF tag: **LE.UM.4.1.1.r1-00300-sa515m** +> Merged AOSP android-4.14-stable [4.14.192] +> Latest CAF tag: **LE.UM.3.2.3-45100-SA2150p** diff --git a/arch/arm/configs/vendor/sdm429-bg-perf_defconfig b/arch/arm/configs/vendor/sdm429-bg-perf_defconfig index fa92c8e76d54..a78dc6c5c287 100644 --- a/arch/arm/configs/vendor/sdm429-bg-perf_defconfig +++ b/arch/arm/configs/vendor/sdm429-bg-perf_defconfig @@ -76,8 +76,8 @@ CONFIG_CPU_FREQ_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y CONFIG_CPU_BOOST=y CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_MSM=y CONFIG_CPU_IDLE=y -CONFIG_ARM_CPUIDLE=y CONFIG_VFP=y CONFIG_NEON=y CONFIG_KERNEL_MODE_NEON=y @@ -626,6 +626,7 @@ CONFIG_PAGE_OWNER=y CONFIG_MAGIC_SYSRQ=y CONFIG_PANIC_TIMEOUT=5 CONFIG_SCHEDSTATS=y +CONFIG_SCHED_STACK_END_CHECK=y CONFIG_IPC_LOGGING=y CONFIG_CORESIGHT=y CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y diff --git a/arch/arm/configs/vendor/sdm429-bg_defconfig b/arch/arm/configs/vendor/sdm429-bg_defconfig index 167ce3b8f5d0..725b4396e640 100644 --- a/arch/arm/configs/vendor/sdm429-bg_defconfig +++ b/arch/arm/configs/vendor/sdm429-bg_defconfig @@ -78,8 +78,8 @@ CONFIG_CPU_FREQ_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y CONFIG_CPU_BOOST=y CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_MSM=y CONFIG_CPU_IDLE=y -CONFIG_ARM_CPUIDLE=y CONFIG_VFP=y CONFIG_NEON=y CONFIG_KERNEL_MODE_NEON=y diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h index a89b4076cde4..72821b4721ad 100644 --- a/arch/arm/include/asm/percpu.h +++ b/arch/arm/include/asm/percpu.h @@ -16,6 +16,8 @@ #ifndef _ASM_ARM_PERCPU_H_ #define _ASM_ARM_PERCPU_H_ +#include + /* * Same as asm-generic/percpu.h, except that we store the per cpu offset * in the TPIDRPRW. TPIDRPRW only exists on V6K and V7 diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index 7e662bdd5cb3..932b2244e709 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S @@ -101,6 +101,7 @@ __mmap_switched: str r2, [r6] @ Save atags pointer cmp r7, #0 strne r0, [r7] @ Save control register values + mov lr, #0 b start_kernel ENDPROC(__mmap_switched) diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index ed784fbafed9..6ffc8945adaf 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -700,6 +700,12 @@ static void disable_single_step(struct perf_event *bp) arch_install_hw_breakpoint(bp); } +static int watchpoint_fault_on_uaccess(struct pt_regs *regs, + struct arch_hw_breakpoint *info) +{ + return !user_mode(regs) && info->ctrl.privilege == ARM_BREAKPOINT_USER; +} + static void watchpoint_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { @@ -759,16 +765,27 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr, } pr_debug("watchpoint fired: address = 0x%x\n", info->trigger); + + /* + * If we triggered a user watchpoint from a uaccess routine, + * then handle the stepping ourselves since userspace really + * can't help us with this. + */ + if (watchpoint_fault_on_uaccess(regs, info)) + goto step; + perf_bp_event(wp, regs); /* - * If no overflow handler is present, insert a temporary - * mismatch breakpoint so we can single-step over the - * watchpoint trigger. + * Defer stepping to the overflow handler if one is installed. + * Otherwise, insert a temporary mismatch breakpoint so that + * we can single-step over the watchpoint trigger. */ - if (is_default_overflow_handler(wp)) - enable_single_step(wp, instruction_pointer(regs)); + if (!is_default_overflow_handler(wp)) + goto unlock; +step: + enable_single_step(wp, instruction_pointer(regs)); unlock: rcu_read_unlock(); } diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c index a87684532327..40da0872170f 100644 --- a/arch/arm/kernel/sys_oabi-compat.c +++ b/arch/arm/kernel/sys_oabi-compat.c @@ -287,7 +287,7 @@ asmlinkage long sys_oabi_epoll_wait(int epfd, return -EINVAL; if (!access_ok(VERIFY_WRITE, events, sizeof(*events) * maxevents)) return -EFAULT; - kbuf = kmalloc(sizeof(*kbuf) * maxevents, GFP_KERNEL); + kbuf = kmalloc_array(maxevents, sizeof(*kbuf), GFP_KERNEL); if (!kbuf) return -ENOMEM; fs = get_fs(); @@ -328,7 +328,7 @@ asmlinkage long sys_oabi_semtimedop(int semid, return -EINVAL; if (!access_ok(VERIFY_READ, tsops, sizeof(*tsops) * nsops)) return -EFAULT; - sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL); + sops = kmalloc_array(nsops, sizeof(*sops), GFP_KERNEL); if (!sops) return -ENOMEM; err = 0; diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c index 96a3d73ef4bf..7460f2b73d5e 100644 --- a/arch/arm/mach-footbridge/dc21285.c +++ b/arch/arm/mach-footbridge/dc21285.c @@ -257,7 +257,7 @@ int __init dc21285_setup(int nr, struct pci_sys_data *sys) if (nr || !footbridge_cfn_mode()) return 0; - res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); + res = kcalloc(2, sizeof(struct resource), GFP_KERNEL); if (!res) { printk("out of memory for root bus resources"); return 0; diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index bcf3df59f71b..6835b17113e5 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -421,7 +421,7 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys) if (nr >= 1) return 0; - res = kzalloc(sizeof(*res) * 2, GFP_KERNEL); + res = kcalloc(2, sizeof(*res), GFP_KERNEL); if (res == NULL) { /* * If we're out of memory this early, something is wrong, diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c index 8ed67f8d1762..27e22e702f96 100644 --- a/arch/arm/mach-omap1/mcbsp.c +++ b/arch/arm/mach-omap1/mcbsp.c @@ -389,7 +389,7 @@ static void omap_mcbsp_register_board_cfg(struct resource *res, int res_count, { int i; - omap_mcbsp_devices = kzalloc(size * sizeof(struct platform_device *), + omap_mcbsp_devices = kcalloc(size, sizeof(struct platform_device *), GFP_KERNEL); if (!omap_mcbsp_devices) { printk(KERN_ERR "Could not register McBSP devices\n"); diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 6d28aa20a7d3..c77efc90eaa1 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -37,7 +37,7 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, { char *hc_name; - hc_name = kzalloc(sizeof(char) * (HSMMC_NAME_LEN + 1), GFP_KERNEL); + hc_name = kzalloc(HSMMC_NAME_LEN + 1, GFP_KERNEL); if (!hc_name) { kfree(hc_name); return -ENOMEM; diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index acbede082b5b..7aee7443f01f 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -148,7 +148,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev) return -ENODEV; } - hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL); + hwmods = kcalloc(oh_cnt, sizeof(struct omap_hwmod *), GFP_KERNEL); if (!hwmods) { ret = -ENOMEM; goto odbfd_exit; @@ -468,7 +468,7 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev, } /* Allocate resources memory to account for new resources */ - res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL); + res = kcalloc(res_count, sizeof(struct resource), GFP_KERNEL); if (!res) goto oda_exit3; diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index 2f215facba10..8a24e36c3c05 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -288,10 +288,11 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) prcm_irq_setup = irq_setup; - prcm_irq_chips = kzalloc(sizeof(void *) * nr_regs, GFP_KERNEL); - prcm_irq_setup->saved_mask = kzalloc(sizeof(u32) * nr_regs, GFP_KERNEL); - prcm_irq_setup->priority_mask = kzalloc(sizeof(u32) * nr_regs, - GFP_KERNEL); + prcm_irq_chips = kcalloc(nr_regs, sizeof(void *), GFP_KERNEL); + prcm_irq_setup->saved_mask = kcalloc(nr_regs, sizeof(u32), + GFP_KERNEL); + prcm_irq_setup->priority_mask = kcalloc(nr_regs, sizeof(u32), + GFP_KERNEL); if (!prcm_irq_chips || !prcm_irq_setup->saved_mask || !prcm_irq_setup->priority_mask) diff --git a/arch/arm/mach-vexpress/spc.c b/arch/arm/mach-vexpress/spc.c index 635b0d549487..8e0a39689312 100644 --- a/arch/arm/mach-vexpress/spc.c +++ b/arch/arm/mach-vexpress/spc.c @@ -403,7 +403,7 @@ static int ve_spc_populate_opps(uint32_t cluster) uint32_t data = 0, off, ret, idx; struct ve_spc_opp *opps; - opps = kzalloc(sizeof(*opps) * MAX_OPPS, GFP_KERNEL); + opps = kcalloc(MAX_OPPS, sizeof(*opps), GFP_KERNEL); if (!opps) return -ENOMEM; diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 9498cdfdbfe6..37b558a93473 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -2398,8 +2398,8 @@ iommu_init_mapping(struct device *dev, struct dma_iommu_mapping *mapping) } mapping->bitmap_size = bitmap_size; - mapping->bitmaps = kzalloc(extensions * sizeof(unsigned long *), - GFP_KERNEL); + mapping->bitmaps = kcalloc(extensions, sizeof(unsigned long *), + GFP_KERNEL); if (!mapping->bitmaps) return -ENOMEM; diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c index 006421cc9257..10664bebd903 100644 --- a/arch/arm/mm/pgd.c +++ b/arch/arm/mm/pgd.c @@ -20,7 +20,7 @@ #include "mm.h" #ifdef CONFIG_ARM_LPAE -#define __pgd_alloc() kmalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL) +#define __pgd_alloc() kmalloc_array(PTRS_PER_PGD, sizeof(pgd_t), GFP_KERNEL) #define __pgd_free(pgd) kfree(pgd) #else #define __pgd_alloc() (pgd_t *)__get_free_pages(GFP_KERNEL, 2) diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 1e460b4ee3b9..094e33a5f9f2 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -1324,8 +1324,9 @@ static int omap_system_dma_probe(struct platform_device *pdev) if (dma_omap2plus()) { - dma_linked_lch = kzalloc(sizeof(struct dma_link_info) * - dma_lch_count, GFP_KERNEL); + dma_linked_lch = kcalloc(dma_lch_count, + sizeof(struct dma_link_info), + GFP_KERNEL); if (!dma_linked_lch) { ret = -ENOMEM; goto exit_dma_lch_fail; diff --git a/arch/arm/probes/kprobes/test-core.c b/arch/arm/probes/kprobes/test-core.c index a10d7187ad2c..a2bf5e1286b6 100644 --- a/arch/arm/probes/kprobes/test-core.c +++ b/arch/arm/probes/kprobes/test-core.c @@ -823,8 +823,9 @@ static int coverage_start_fn(const struct decode_header *h, void *args) static int coverage_start(const union decode_item *table) { - coverage.base = kmalloc(MAX_COVERAGE_ENTRIES * - sizeof(struct coverage_entry), GFP_KERNEL); + coverage.base = kmalloc_array(MAX_COVERAGE_ENTRIES, + sizeof(struct coverage_entry), + GFP_KERNEL); coverage.num_entries = 0; coverage.nesting = 0; return table_iter(table, coverage_start_fn, &coverage); diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index aec784b4d6c9..a73ab1a92bb4 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -461,7 +461,7 @@ dtb-$(CONFIG_ARCH_SDXPRAIRIE) += sdxprairie-rumi.dtb \ sdxprairie-v2-mtp-v1.1-cpe.dtb \ sdxprairie-v2-mtp-v1.1.dtb \ sdxprairie-v2-mtp-le-cpe.dtb \ - sdxprairie-v2-ttp-cpe.dtb \ + sdxprairie-v2-mtp-au-dsda.dtb \ sa515m-v2-ttp.dtb \ sa515m-v2-ttp-usb-ep.dtb \ sa515m-v2-ttp-pcie-ep.dtb \ diff --git a/arch/arm64/boot/dts/qcom/atoll-sde.dtsi b/arch/arm64/boot/dts/qcom/atoll-sde.dtsi index af9ccda50f6f..31c1f661bda6 100644 --- a/arch/arm64/boot/dts/qcom/atoll-sde.dtsi +++ b/arch/arm64/boot/dts/qcom/atoll-sde.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and diff --git a/arch/arm64/boot/dts/qcom/mdm9607.dtsi b/arch/arm64/boot/dts/qcom/mdm9607.dtsi index 23c160c7fa8c..a21deb71ecec 100644 --- a/arch/arm64/boot/dts/qcom/mdm9607.dtsi +++ b/arch/arm64/boot/dts/qcom/mdm9607.dtsi @@ -57,6 +57,12 @@ reg = <0x87c00000 0x400000>; }; + tz_apps_mem: tz_apps_region@0 { + compatible = "removed-dma-pool"; + no-map; + reg = <0x88000000 0x500000>; + }; + audio_mem: audio_region@0 { compatible = "shared-dma-pool"; reusable; @@ -69,7 +75,7 @@ reusable; alignment = <0x400000>; size = <0x0400000>; - status = "disabled"; + status = "ok"; }; }; @@ -1675,7 +1681,7 @@ qcom_seecom: qseecom@87a80000 { compatible = "qcom,qseecom"; - reg = <0x87a80000 0x100000>; + reg = <0x88000000 0x500000>; reg-names = "secapp-region"; memory-region = <&qseecom_mem>; qcom,hlos-num-ce-hw-instances = <1>; @@ -1697,7 +1703,7 @@ clock-names = "core_clk_src", "core_clk", "iface_clk", "bus_clk"; qcom,ce-opp-freq = <100000000>; - status = "disabled"; + status = "ok"; }; qcom_tzlog: tz-log@8600720 { diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index ee36196df1d1..4a8f48564538 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2015, 2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -84,18 +84,18 @@ }; wcnss_mem: wcnss@89300000 { - reg = <0x0 0x89300000 0x0 0x700000>; + reg = <0x0 0x89300000 0x0 0x600000>; no-map; }; venus_mem: venus@89900000 { - reg = <0x0 0x89A00000 0x0 0x600000>; + reg = <0x0 0x89900000 0x0 0x600000>; no-map; }; mba_mem: mba@8ea00000 { no-map; - reg = <0 0x8A000000 0 0x100000>; + reg = <0 0x8ea00000 0 0x100000>; }; }; diff --git a/arch/arm64/boot/dts/qcom/pm660.dtsi b/arch/arm64/boot/dts/qcom/pm660.dtsi index 7ebb230eb269..a26ed10d7dc5 100644 --- a/arch/arm64/boot/dts/qcom/pm660.dtsi +++ b/arch/arm64/boot/dts/qcom/pm660.dtsi @@ -551,6 +551,106 @@ }; &thermal_zones { + ibat-high { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&bcl_sensor 0>; + wake-capable-sensor; + + trips { + ibat-high { + temperature = <4200>; + hysteresis = <200>; + type = "passive"; + }; + }; + }; + + ibat-vhigh { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "step_wise"; + thermal-sensors = <&bcl_sensor 1>; + wake-capable-sensor; + + trips { + ibat-vhigh { + temperature = <4300>; + hysteresis = <100>; + type = "passive"; + }; + }; + }; + + vbat_adc { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_cap"; + thermal-sensors = <&bcl_sensor 2>; + wake-capable-sensor; + tracks-low; + + trips { + pm660_vbat_adc: vbat-adc { + temperature = <3200>; + hysteresis = <100>; + type = "passive"; + }; + }; + }; + + vbat_low { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_cap"; + thermal-sensors = <&bcl_sensor 3>; + wake-capable-sensor; + tracks-low; + + trips { + vbat-low { + temperature = <2800>; + hysteresis = <0>; + type = "passive"; + }; + }; + }; + + vbat_too_low { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_cap"; + thermal-sensors = <&bcl_sensor 4>; + wake-capable-sensor; + tracks-low; + + trips { + vbat-too-low { + temperature = <2600>; + hysteresis = <0>; + type = "passive"; + }; + }; + }; + + soc { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_cap"; + thermal-sensors = <&bcl_sensor 5>; + wake-capable-sensor; + tracks-low; + + trips { + pm660_low_soc: low-soc { + temperature = <10>; + hysteresis = <0>; + type = "passive"; + }; + }; + }; + pm660_temp_alarm: pm660-tz { polling-delay-passive = <0>; polling-delay = <0>; diff --git a/arch/arm64/boot/dts/qcom/pm660l.dtsi b/arch/arm64/boot/dts/qcom/pm660l.dtsi index cee370cb5a54..5640a5b9126e 100644 --- a/arch/arm64/boot/dts/qcom/pm660l.dtsi +++ b/arch/arm64/boot/dts/qcom/pm660l.dtsi @@ -163,6 +163,7 @@ label = "backlight"; qcom,pmic-revid = <&pm660l_revid>; qcom,auto-calibration; + qcom,sync-dly = <800>; status = "ok"; }; diff --git a/arch/arm64/boot/dts/qcom/pm8150.dtsi b/arch/arm64/boot/dts/qcom/pm8150.dtsi index d6b8eb94dd94..e6e5f4bacd44 100644 --- a/arch/arm64/boot/dts/qcom/pm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8150.dtsi @@ -47,8 +47,9 @@ <0x0 0x8 0x5 IRQ_TYPE_NONE>; interrupt-names = "kpdpwr", "resin", "resin-bark", "kpdpwr-resin-bark"; - qcom,pon-dbc-delay = <62500>; - qcom,kpdpwr-sw-debounce; + qcom,pon-dbc-delay = <62>; + qcom,pon-sw-dbc-delay = <15500>; + qcom,pon-sw-debounce; qcom,system-reset; qcom,store-hard-reset-reason; diff --git a/arch/arm64/boot/dts/qcom/qcs410-iot.dts b/arch/arm64/boot/dts/qcom/qcs410-iot.dts index 2fe709638dbc..3c640e55c721 100644 --- a/arch/arm64/boot/dts/qcom/qcs410-iot.dts +++ b/arch/arm64/boot/dts/qcom/qcs410-iot.dts @@ -14,7 +14,6 @@ #include "qcs410.dtsi" #include "qcs410-iot.dtsi" -#include "sm6150-audio-overlay.dtsi" / { model = "Qualcomm Technologies, Inc. QCS410 IOT"; @@ -22,6 +21,3 @@ qcom,board-id = <32 0>; }; -&sm6150_snd { - /delete-property/ fsa4480-i2c-handle; -}; diff --git a/arch/arm64/boot/dts/qcom/qcs410-iot.dtsi b/arch/arm64/boot/dts/qcom/qcs410-iot.dtsi index ae583f20ad78..3dc3f2141b17 100644 --- a/arch/arm64/boot/dts/qcom/qcs410-iot.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs410-iot.dtsi @@ -10,354 +10,10 @@ * GNU General Public License for more details. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "sm6150-sde-pll.dtsi" -#include "sm6150-sde-display.dtsi" -#include "qcs610-camera-sensor-idp.dtsi" +#include "qcs610-iot.dtsi" / { model = "Qualcomm Technologies, Inc. QCS410 IOT"; compatible = "qcom,qcs410-iot", "qcom,qcs410", "qcom,iot"; }; -&qupv3_se3_i2c { - status = "ok"; - #include "smb1390.dtsi" -}; - -&fsa4480 { - status = "disabled"; -}; - -&pm6150l_gpios { - key_vol_up { - key_vol_up_default: key_vol_up_default { - pins = "gpio2"; - function = "normal"; - input-enable; - bias-pull-up; - power-source = <0>; - }; - }; - - irled { - irled_pwm: irled_pwm_default { - pins = "gpio6"; - function = "func1"; - qcom,drive-strength = <2>; - power-source = <0>; - bias-disable; - output-low; - }; - }; -}; - -&soc { - gpio_keys { - compatible = "gpio-keys"; - label = "gpio-keys"; - - pinctrl-names = "default"; - pinctrl-0 = <&key_vol_up_default>; - - vol_up { - label = "volume_up"; - gpios = <&pm6150l_gpios 2 GPIO_ACTIVE_LOW>; - linux,input-type = <1>; - linux,code = ; - linux,can-disable; - debounce-interval = <15>; - gpio-key,wakeup; - }; - }; - - mtp_batterydata: qcom,battery-data { - qcom,batt-id-range-pct = <15>; - #include "qg-batterydata-alium-3600mah.dtsi" - #include "qg-batterydata-mlp356477-2800mah.dtsi" - }; -}; - -&pm6150l_wled { - qcom,string-cfg= <3>; - qcom,leds-per-string = <7>; - status = "ok"; -}; - -&pm6150l_lcdb { - status = "ok"; -}; - -&pm6150l_pwm_1 { - status = "okay"; -}; - -&pm6150_qg { - qcom,battery-data = <&mtp_batterydata>; - qcom,qg-iterm-ma = <100>; - qcom,hold-soc-while-full; - qcom,linearize-soc; - qcom,cl-feedback-on; -}; - -&pm6150_charger { - io-channels = <&pm6150_vadc ADC_USB_IN_V_16>, - <&pm6150_vadc ADC_USB_IN_I>, - <&pm6150_vadc ADC_CHG_TEMP>, - <&pm6150_vadc ADC_DIE_TEMP>, - <&pm6150_vadc ADC_AMUX_THM4_PU2>, - <&pm6150_vadc ADC_SBUx>, - <&pm6150_vadc ADC_VPH_PWR>; - io-channel-names = "usb_in_voltage", - "usb_in_current", - "chg_temp", - "die_temp", - "conn_temp", - "sbux_res", - "vph_voltage"; - qcom,battery-data = <&mtp_batterydata>; - qcom,auto-recharge-soc = <98>; - qcom,step-charging-enable; - qcom,sw-jeita-enable; - qcom,fcc-stepping-enable; - qcom,suspend-input-on-debug-batt; - qcom,sec-charger-config = <3>; - qcom,thermal-mitigation = <4200000 3500000 3000000 - 2500000 2000000 1500000 1000000 500000>; - dpdm-supply = <&qusb_phy0>; - qcom,charger-temp-max = <800>; - qcom,smb-temp-max = <800>; -}; - -&smb1390 { - /delete-property/ interrupts; - interrupts = <0x0 0xc2 0x0 IRQ_TYPE_LEVEL_LOW>; - pinctrl-names = "default"; - pinctrl-0 = <&smb_stat_default>; - status = "ok"; -}; - -&smb1390_charger { - /delete-property/ compatible; - compatible = "qcom,smb1390-charger-psy"; - io-channels = <&pm6150_vadc ADC_AMUX_THM3>; - io-channel-names = "cp_die_temp"; - status = "ok"; -}; - -&sdhc_1 { - vdd-supply = <&pm6150l_l11>; - qcom,vdd-voltage-level = <2950000 2950000>; - qcom,vdd-current-level = <0 570000>; - - vdd-io-supply = <&pm6150_l12>; - qcom,vdd-io-always-on; - qcom,vdd-io-lpm-sup; - qcom,vdd-io-voltage-level = <1800000 1800000>; - qcom,vdd-io-current-level = <0 325000>; - - pinctrl-names = "active", "sleep"; - pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>; - pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>; - - status = "ok"; -}; - -&sdhc_2 { - vdd-supply = <&pm6150l_l9>; - qcom,vdd-voltage-level = <2950000 2950000>; - qcom,vdd-current-level = <0 800000>; - - vdd-io-supply = <&pm6150l_l6>; - qcom,vdd-io-voltage-level = <1800000 3100000>; - qcom,vdd-io-current-level = <0 22000>; - - pinctrl-names = "active", "sleep"; - pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; - pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; - - cd-gpios = <&tlmm 99 GPIO_ACTIVE_LOW>; - - status = "ok"; -}; - -&pil_camera_mem { - reg = <0 0x8f800000 0 0x500000>; -}; - -&pil_modem_mem { - reg = <0 0x8fd00000 0 0x3100000>; -}; - -&pil_video_mem { - reg = <0 0x92e00000 0 0x500000>; -}; - -&wlan_msa_mem { - reg = <0 0x93300000 0 0x200000>; -}; - -&pil_cdsp_mem { - reg = <0 0x93500000 0 0x1e00000>; -}; - -&pil_adsp_mem { - reg = <0 0x95300000 0 0x1e00000>; -}; - -&pil_ipa_fw_mem { - reg = <0 0x97100000 0 0x10000>; -}; - -&pil_ipa_gsi_mem { - reg = <0 0x97110000 0 0x5000>; -}; - -&pil_gpu_mem { - reg = <0 0x97115000 0 0x2000>; -}; - -&L16A { - regulator-max-microvolt = <3304000>; -}; - -&L19A { - regulator-max-microvolt = <3304000>; -}; - -&L4C { - regulator-max-microvolt = <2912000>; -}; - -&L5C { - regulator-max-microvolt = <2912000>; -}; - -&sde_dp { - status="disabled"; -}; - -&mdss_dp_pll { - status="disabled"; -}; - -&mdss_mdp { - connectors = <&sde_rscc &sde_wb &sde_dsi>; -}; - -&qupv3_se1_i2c { - status = "ok"; - lt9611: lt,lt9611@3b { - compatible = "lt,lt9611"; - reg = <0x3b>; - interrupt-parent = <&tlmm>; - interrupts = <26 0>; - interrupt-names = "lt_irq"; - lt,irq-gpio = <&tlmm 26 0x0>; - lt,reset-gpio = <&tlmm 20 0x0>; - lt,hdmi-en-gpio = <&tlmm 79 0x0>; - instance_id = <0>; - lt,non-pluggable; - lt,preferred-mode = "1920x1080"; - - pinctrl-names = "default"; - pinctrl-0 = <<9611_pins>; - - vdd-supply = <&pm6150_l13>; - vcc-supply = <&pm6150_l16>; - - lt,supply-entries { - #address-cells = <1>; - #size-cells = <0>; - - lt,supply-entry@0 { - reg = <0>; - lt,supply-name = "vdd"; - lt,supply-min-voltage = <1800000>; - lt,supply-max-voltage = <1800000>; - lt,supply-enable-load = <200000>; - lt,supply-post-on-sleep = <50>; - }; - lt,supply-entry@1 { - reg = <1>; - lt,supply-name = "vcc"; - lt,supply-min-voltage = <3304000>; - lt,supply-max-voltage = <3304000>; - lt,supply-enable-load = <200000>; - lt,supply-post-on-sleep = <50>; - }; - - - }; - - lt,customize-modes { - lt,customize-mode-id@0 { - lt,mode-h-active = <1920>; - lt,mode-h-front-porch = <88>; - lt,mode-h-pulse-width = <44>; - lt,mode-h-back-porch = <148>; - lt,mode-h-active-high; - lt,mode-v-active = <1080>; - lt,mode-v-front-porch = <4>; - lt,mode-v-pulse-width = <5>; - lt,mode-v-back-porch = <36>; - lt,mode-v-active-high; - lt,mode-refresh-rate = <60>; - lt,mode-clock-in-khz = <148500>; - }; - }; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - lt9611_in: endpoint { - remote-endpoint = <&ext_dsi_out>; - }; - }; - }; - }; -}; - -&dsi_ext_bridge_hdmi_1080p { - qcom,mdss-dsi-ext-bridge = <0>; -}; - -&soc { - ext_dsi_bridge_display: qcom,dsi-display@50 { - label = "ext_dsi_bridge_display hdmi 1080p"; - qcom,dsi-display-active; - qcom,display-type = "primary"; - - qcom,dsi-ctrl-num = <0>; - qcom,dsi-phy-num = <0>; - qcom,dsi-select-clocks = "mux_byte_clk0", "mux_pixel_clk0"; - qcom,dsi-panel = <&dsi_ext_bridge_hdmi_1080p>; - }; -}; - -&sde_dsi { - qcom,dsi-display-list = <&ext_dsi_bridge_display>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - ext_dsi_out: endpoint { - remote-endpoint = <<9611_in>; - }; - }; - }; -}; diff --git a/arch/arm64/boot/dts/qcom/qcs610-iot.dts b/arch/arm64/boot/dts/qcom/qcs610-iot.dts index a0a6c723d172..9d79b8ceea0a 100644 --- a/arch/arm64/boot/dts/qcom/qcs610-iot.dts +++ b/arch/arm64/boot/dts/qcom/qcs610-iot.dts @@ -13,7 +13,6 @@ /dts-v1/; #include "qcs610.dtsi" #include "qcs610-iot.dtsi" -#include "sm6150-audio-overlay.dtsi" / { model = "Qualcomm Technologies, Inc. QCS610 IOT"; diff --git a/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi b/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi index 733d9335b4fd..6bf996060d60 100644 --- a/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs610-iot.dtsi @@ -25,6 +25,7 @@ #include "sm6150-sde-pll.dtsi" #include "sm6150-sde-display.dtsi" #include "qcs610-camera-sensor-idp.dtsi" +#include "sm6150-audio-overlay.dtsi" / { model = "Qualcomm Technologies, Inc. QCS610 IOT"; @@ -324,6 +325,10 @@ reg = <0 0x97115000 0 0x2000>; }; +&msm_gpu { + /delete-node/qcom,gpu-mempools; +}; + &sdhc_1 { vdd-supply = <&pm6150l_l11>; qcom,vdd-voltage-level = <2950000 2950000>; diff --git a/arch/arm64/boot/dts/qcom/qcs610-ipc.dts b/arch/arm64/boot/dts/qcom/qcs610-ipc.dts index aa9b6439e0b3..cb0b1a23bfa6 100644 --- a/arch/arm64/boot/dts/qcom/qcs610-ipc.dts +++ b/arch/arm64/boot/dts/qcom/qcs610-ipc.dts @@ -13,7 +13,6 @@ /dts-v1/; #include "qcs610.dtsi" -#include "qcs610-iot.dtsi" #include "qcs610-ipc.dtsi" / { @@ -21,7 +20,3 @@ compatible = "qcom,qcs610-iot", "qcom,qcs610", "qcom,iot"; qcom,board-id = <32 1>; }; - -&sm6150_snd { - /delete-property/ fsa4480-i2c-handle; -}; diff --git a/arch/arm64/boot/dts/qcom/qcs610-ipc.dtsi b/arch/arm64/boot/dts/qcom/qcs610-ipc.dtsi index 87c198d211ec..9340e5cb4d18 100644 --- a/arch/arm64/boot/dts/qcom/qcs610-ipc.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs610-ipc.dtsi @@ -10,8 +10,8 @@ * GNU General Public License for more details. */ -#include "sm6150-audio-overlay.dtsi" -#include "sm6150-camera-sensor-idp.dtsi" +#include "qcs610-iot.dtsi" + / { model = "Qualcomm Technologies, Inc. QCS610 IPC"; compatible = "qcom,qcs610-iot", "qcom,qcs610", "qcom,iot"; @@ -73,25 +73,6 @@ qcom,batteryless-platform; }; -&eeprom_rear { - cam_vana-supply = <&pm6150l_l4>; - rgltr-min-voltage = <1800000 2900000 1200000 0 2800000>; - rgltr-max-voltage = <1800000 2900000 1200000 0 2800000>; -}; - -&cam_cci { - qcom,cam-sensor@0 { - cam_vana-supply = <&pm6150l_l4>; - rgltr-min-voltage = <1800000 2900000 1200000 0>; - rgltr-max-voltage = <1800000 2900000 1200000 0>; - }; -}; - - -&led_flash_front { - status = "disabled"; -}; - &tlmm { led_red_default: led_red_default { mux { diff --git a/arch/arm64/boot/dts/qcom/quin-vm-common.dtsi b/arch/arm64/boot/dts/qcom/quin-vm-common.dtsi index 8c6dc3bebce6..90aa33ba6541 100644 --- a/arch/arm64/boot/dts/qcom/quin-vm-common.dtsi +++ b/arch/arm64/boot/dts/qcom/quin-vm-common.dtsi @@ -124,6 +124,11 @@ memory-region = <&qseecom_ta_mem>; qcom,ion-heap-type = "DMA"; }; + + qcom,ion-heap@9 { + reg = <9>; + qcom,ion-heap-type = "SYSTEM_SECURE"; + }; }; hab: qcom,hab { diff --git a/arch/arm64/boot/dts/qcom/sa2145p-ccard-nand-dc.dts b/arch/arm64/boot/dts/qcom/sa2145p-ccard-nand-dc.dts index 3ebad18c8340..3a5c5aef5c77 100644 --- a/arch/arm64/boot/dts/qcom/sa2145p-ccard-nand-dc.dts +++ b/arch/arm64/boot/dts/qcom/sa2145p-ccard-nand-dc.dts @@ -36,3 +36,21 @@ &blsp1_uart4_hs { status = "disabled"; }; + +&wlan_fw_mem { + reg = <0x0 0x86400000 0x0 0x100000>; +}; + +&qseecom_mem { + size = <0 0x400000>; +}; + +&soc { + /delete-node/ qcom,wlan_dsp@7000000; + /delete-node/ qcom,icnss@18800000; +}; + +&reserved_mem { + /delete-node/ wlan_msa_region@88E0000; + /delete-node/ wlan_fw_mem@86400000; +}; diff --git a/arch/arm64/boot/dts/qcom/sa2150p-ccard-nand-dc.dts b/arch/arm64/boot/dts/qcom/sa2150p-ccard-nand-dc.dts index a6183bd11c49..fb3ae4f7843d 100644 --- a/arch/arm64/boot/dts/qcom/sa2150p-ccard-nand-dc.dts +++ b/arch/arm64/boot/dts/qcom/sa2150p-ccard-nand-dc.dts @@ -104,3 +104,27 @@ &blsp1_uart4_hs { status = "disabled"; }; + +&wlan_fw_mem { + reg = <0x0 0x86400000 0x0 0x100000>; +}; + +&reserved_mem { + linux,cma { + size = <0 0x400000>; + }; +}; + +&qseecom_mem { + size = <0 0x400000>; +}; + +&soc { + /delete-node/ qcom,wlan_dsp@7000000; + /delete-node/ qcom,icnss@18800000; +}; + +&reserved_mem { + /delete-node/ wlan_msa_region@88E0000; + /delete-node/ wlan_fw_mem@86400000; +}; diff --git a/arch/arm64/boot/dts/qcom/sa2150p-ccard.dtsi b/arch/arm64/boot/dts/qcom/sa2150p-ccard.dtsi index c669832ac929..29e8955016f2 100644 --- a/arch/arm64/boot/dts/qcom/sa2150p-ccard.dtsi +++ b/arch/arm64/boot/dts/qcom/sa2150p-ccard.dtsi @@ -300,3 +300,21 @@ }; }; }; + +&pms405_vadc { + pa_therm1 { + /delete-property/ qcom,ratiometric; + /delete-property/ qcom,hw-settle-time; + label = "pa_therm1"; + reg = ; + qcom,pre-scaling = <1 1>; + }; + + pa_therm3 { + /delete-property/ qcom,ratiometric; + /delete-property/ qcom,hw-settle-time; + label = "pa_therm3"; + reg = ; + qcom,pre-scaling = <1 1>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sa515m-ccard-eth-ep.dts b/arch/arm64/boot/dts/qcom/sa515m-ccard-eth-ep.dts index 67e23a084989..7523ffe8312f 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-ccard-eth-ep.dts +++ b/arch/arm64/boot/dts/qcom/sa515m-ccard-eth-ep.dts @@ -41,3 +41,16 @@ &usb { qcom,smmu-s1-bypass; }; + +&sdx_ext_ipc { + compatible = "qcom,sa515m-ccard"; + qcom,status-in-gpio = <&tlmm 76 0x00>; + qcom,status-out-gpio = <&tlmm 33 0x00>; + qcom,status-out2-gpio = <&tlmm 31 0x00>; + qcom,wakeup-gpio-in = <&tlmm 77 0x00>; + qcom,wakeup-gpio-out = <&tlmm 96 0x00>; + pinctrl-names = "default"; + pinctrl-0 = <&wakeup_gpio_default>; + qcom,default-policy-nop; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/qcom/sa515m-ccard-pcie-ep.dts b/arch/arm64/boot/dts/qcom/sa515m-ccard-pcie-ep.dts index 81786435e82c..ff3f04b02f67 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-ccard-pcie-ep.dts +++ b/arch/arm64/boot/dts/qcom/sa515m-ccard-pcie-ep.dts @@ -73,6 +73,10 @@ }; &sdx_ext_ipc { + compatible = "qcom,sa515m-ccard"; + qcom,status-in-gpio = <&tlmm 76 0x00>; + qcom,status-out-gpio = <&tlmm 33 0x00>; + qcom,status-out2-gpio = <&tlmm 31 0x00>; qcom,default-policy-nop; status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/sa515m-ccard-usb-ep.dts b/arch/arm64/boot/dts/qcom/sa515m-ccard-usb-ep.dts index 1053f3273f31..7bd2e445adf7 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-ccard-usb-ep.dts +++ b/arch/arm64/boot/dts/qcom/sa515m-ccard-usb-ep.dts @@ -56,3 +56,16 @@ &usb { qcom,num-gsi-evt-buffs = <0x5>; }; + +&sdx_ext_ipc { + compatible = "qcom,sa515m-ccard"; + qcom,status-in-gpio = <&tlmm 76 0x00>; + qcom,status-out-gpio = <&tlmm 33 0x00>; + qcom,status-out2-gpio = <&tlmm 31 0x00>; + qcom,wakeup-gpio-in = <&tlmm 77 0x00>; + qcom,wakeup-gpio-out = <&tlmm 96 0x00>; + pinctrl-names = "default"; + pinctrl-0 = <&wakeup_gpio_default>; + qcom,default-policy-nop; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi index 2adf53c610e1..251b24cce5f1 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi +++ b/arch/arm64/boot/dts/qcom/sa515m-ccard.dtsi @@ -82,6 +82,15 @@ gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>; status = "okay"; }; + + qmi-tmd-devices { + modem { + modem_v2x: modem_v2x { + qcom,qmi-dev-name = "modem_v2x"; + #cooling-cells = <2>; + }; + }; + }; }; &mpss_adsp_mem { @@ -121,6 +130,51 @@ }; }; }; + + mdm-core-0-v2x-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 6>; + thermal-governor = "step_wise"; + wake-capable-sensor; + + trips { + tj_v2x_config0: active-config0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + + tj_v2x_config1: active-config1 { + temperature = <110000>; + hysteresis = <5000>; + type = "passive"; + }; + + tj_v2x_config2: active-config2 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + + cooling-maps { + modem_tj0_v2x_cdev { + trip = <&tj_v2x_config0>; + cooling-device = <&modem_v2x 1 1>; + }; + + modem_tj1_v2x_cdev { + trip = <&tj_v2x_config1>; + cooling-device = <&modem_v2x 2 2>; + }; + + modem_tj2_v2x_cdev { + trip = <&tj_v2x_config2>; + cooling-device = <&modem_v2x 3 3>; + }; + }; + }; }; &usb { @@ -589,3 +643,17 @@ }; }; }; + +&tlmm { + wakeup_gpio_default: wakeup_gpio_default { + mux { + pins = "gpio96"; + function = "gpio"; + }; + config { + pins = "gpio96"; + drive-strength = <2>; + bias-pull-down; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sa515m-flashless.dtsi b/arch/arm64/boot/dts/qcom/sa515m-flashless.dtsi index 1c1a676c0413..3445ca95d43a 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-flashless.dtsi +++ b/arch/arm64/boot/dts/qcom/sa515m-flashless.dtsi @@ -20,6 +20,17 @@ qcom,auto-boot; }; +&soc { + qmi-tmd-devices { + modem { + modem_v2x: modem_v2x { + qcom,qmi-dev-name = "modem_v2x"; + #cooling-cells = <2>; + }; + }; + }; +}; + &thermal_zones { /* update Tj thresholds */ mdm-core-0-step { @@ -40,4 +51,49 @@ }; }; }; + + mdm-core-0-v2x-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 6>; + thermal-governor = "step_wise"; + wake-capable-sensor; + + trips { + tj_v2x_config0: active-config0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + + tj_v2x_config1: active-config1 { + temperature = <110000>; + hysteresis = <5000>; + type = "passive"; + }; + + tj_v2x_config2: active-config2 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + + cooling-maps { + modem_tj0_v2x_cdev { + trip = <&tj_v2x_config0>; + cooling-device = <&modem_v2x 1 1>; + }; + + modem_tj1_v2x_cdev { + trip = <&tj_v2x_config1>; + cooling-device = <&modem_v2x 2 2>; + }; + + modem_tj2_v2x_cdev { + trip = <&tj_v2x_config2>; + cooling-device = <&modem_v2x 3 3>; + }; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/sa515m-v2-ccard-eth-ep.dts b/arch/arm64/boot/dts/qcom/sa515m-v2-ccard-eth-ep.dts index 9eeb1c42076f..e0a7d29a6b27 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-v2-ccard-eth-ep.dts +++ b/arch/arm64/boot/dts/qcom/sa515m-v2-ccard-eth-ep.dts @@ -41,3 +41,16 @@ &usb { qcom,smmu-s1-bypass; }; + +&sdx_ext_ipc { + compatible = "qcom,sa515m-ccard"; + qcom,status-in-gpio = <&tlmm 76 0x00>; + qcom,status-out-gpio = <&tlmm 33 0x00>; + qcom,status-out2-gpio = <&tlmm 31 0x00>; + qcom,wakeup-gpio-in = <&tlmm 77 0x00>; + qcom,wakeup-gpio-out = <&tlmm 96 0x00>; + pinctrl-names = "default"; + pinctrl-0 = <&wakeup_gpio_default>; + qcom,default-policy-nop; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/qcom/sa515m-v2-ccard-pcie-ep.dts b/arch/arm64/boot/dts/qcom/sa515m-v2-ccard-pcie-ep.dts index ebeac7624478..3b49920ff05c 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-v2-ccard-pcie-ep.dts +++ b/arch/arm64/boot/dts/qcom/sa515m-v2-ccard-pcie-ep.dts @@ -74,9 +74,10 @@ }; &sdx_ext_ipc { - compatible = "qcom,sa515m-ccard"; - qcom,status-in-gpio = <&tlmm 76 0x00>; - qcom,status-out-gpio = <&tlmm 33 0x00>; - qcom,status-out2-gpio = <&tlmm 31 0x00>; - status = "okay"; + compatible = "qcom,sa515m-ccard"; + qcom,status-in-gpio = <&tlmm 76 0x00>; + qcom,status-out-gpio = <&tlmm 33 0x00>; + qcom,status-out2-gpio = <&tlmm 31 0x00>; + qcom,default-policy-nop; + status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/sa515m-v2-ccard-usb-ep.dts b/arch/arm64/boot/dts/qcom/sa515m-v2-ccard-usb-ep.dts index 9734f0b88ab4..fe78525bc062 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-v2-ccard-usb-ep.dts +++ b/arch/arm64/boot/dts/qcom/sa515m-v2-ccard-usb-ep.dts @@ -56,3 +56,16 @@ &usb { qcom,num-gsi-evt-buffs = <0x5>; }; + +&sdx_ext_ipc { + compatible = "qcom,sa515m-ccard"; + qcom,status-in-gpio = <&tlmm 76 0x00>; + qcom,status-out-gpio = <&tlmm 33 0x00>; + qcom,status-out2-gpio = <&tlmm 31 0x00>; + qcom,wakeup-gpio-in = <&tlmm 77 0x00>; + qcom,wakeup-gpio-out = <&tlmm 96 0x00>; + pinctrl-names = "default"; + pinctrl-0 = <&wakeup_gpio_default>; + qcom,default-policy-nop; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/qcom/sa515m-v2-ttp.dtsi b/arch/arm64/boot/dts/qcom/sa515m-v2-ttp.dtsi index e35648a1520a..b8547fbf19c9 100644 --- a/arch/arm64/boot/dts/qcom/sa515m-v2-ttp.dtsi +++ b/arch/arm64/boot/dts/qcom/sa515m-v2-ttp.dtsi @@ -17,6 +17,17 @@ reg = <0x90800000 0xf800000>; }; +&soc { + qmi-tmd-devices { + modem { + modem_v2x: modem_v2x { + qcom,qmi-dev-name = "modem_v2x"; + #cooling-cells = <2>; + }; + }; + }; +}; + /* delete pm8150b nodes */ &thermal_zones { /delete-node/ pm8150b-wp-therm; @@ -50,6 +61,51 @@ }; }; }; + + mdm-core-0-v2x-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 6>; + thermal-governor = "step_wise"; + wake-capable-sensor; + + trips { + tj_v2x_config0: active-config0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + + tj_v2x_config1: active-config1 { + temperature = <110000>; + hysteresis = <5000>; + type = "passive"; + }; + + tj_v2x_config2: active-config2 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + + cooling-maps { + modem_tj0_v2x_cdev { + trip = <&tj_v2x_config0>; + cooling-device = <&modem_v2x 1 1>; + }; + + modem_tj1_v2x_cdev { + trip = <&tj_v2x_config1>; + cooling-device = <&modem_v2x 2 2>; + }; + + modem_tj2_v2x_cdev { + trip = <&tj_v2x_config2>; + cooling-device = <&modem_v2x 3 3>; + }; + }; + }; }; &usb { diff --git a/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi b/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi index 4b73b902333b..3f9013f63bd8 100644 --- a/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155-adp-air.dtsi @@ -13,6 +13,10 @@ #include #include "sa6155-cnss.dtsi" +&qupv3_2 { + status = "ok"; +}; + &bluetooth_ext { status = "ok"; }; diff --git a/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi b/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi index 1ecae102b065..ab3647ea3828 100644 --- a/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155-adp-star.dtsi @@ -13,6 +13,10 @@ #include #include "sa6155-cnss.dtsi" +&qupv3_2 { + status = "ok"; +}; + &bluetooth_ext { status = "ok"; }; diff --git a/arch/arm64/boot/dts/qcom/sa6155-display.dtsi b/arch/arm64/boot/dts/qcom/sa6155-display.dtsi index 27521931fb71..b0e59903b988 100644 --- a/arch/arm64/boot/dts/qcom/sa6155-display.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155-display.dtsi @@ -333,9 +333,11 @@ sde_card1: qcom,sde-kms-lease@0 { compatible = "qcom,sde-kms-lease"; qcom,dev-name = "msm_drm"; - qcom,lease-connectors = "shared-disp-0"; - qcom,lease-planes = "plane-0","plane-1","plane-9", - "plane-5"; + qcom,lease-connectors = "shared-disp-0","DP-1","DP-2","DP-3", + "Virtual-1"; + qcom,lease-planes = "plane-0","plane-1","plane-2","plane-3", + "plane-4", "plane-5", "plane-6", + "plane-7","plane-8","plane-9"; }; sde_card2: qcom,sde-kms-lease@1 { compatible = "qcom,sde-kms-lease"; diff --git a/arch/arm64/boot/dts/qcom/sa6155p-vm-usb.dtsi b/arch/arm64/boot/dts/qcom/sa6155p-vm-usb.dtsi index ef2dcb739f35..b74f80add290 100644 --- a/arch/arm64/boot/dts/qcom/sa6155p-vm-usb.dtsi +++ b/arch/arm64/boot/dts/qcom/sa6155p-vm-usb.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -58,6 +58,7 @@ 0x1a4>; /* GSI_IF_STS */ qcom,dwc-usb3-msm-tx-fifo-size = <21288>; qcom,pm-qos-latency = <61>; + qcom,ignore-wakeup-src-in-hostmode; status = "disabled"; dwc3@a600000 { compatible = "snps,dwc3"; diff --git a/arch/arm64/boot/dts/qcom/sa8155-adp-common.dtsi b/arch/arm64/boot/dts/qcom/sa8155-adp-common.dtsi index 9f47fd1779ee..a51e041d6ac6 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-adp-common.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-adp-common.dtsi @@ -16,6 +16,10 @@ #include "sa8155-pmic-overlay.dtsi" #include "sa8155-cnss.dtsi" +&qupv3_3 { + status = "ok"; +}; + &qupv3_se0_spi { status = "ok"; diff --git a/arch/arm64/boot/dts/qcom/sa8155-adp-star-display.dtsi b/arch/arm64/boot/dts/qcom/sa8155-adp-star-display.dtsi index f1333eaf11b0..4533d49ca22c 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-adp-star-display.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-adp-star-display.dtsi @@ -493,10 +493,15 @@ sde_card1: qcom,sde-kms-lease@0 { compatible = "qcom,sde-kms-lease"; qcom,dev-name = "msm_drm"; - qcom,lease-connectors = "shared-disp-1"; - qcom,lease-planes = "plane-0", "plane-1", "plane-12", "plane-13"; - }; - + qcom,lease-connectors = "DSI-2", "shared-disp-0", + "DP-1", "DP-2", "DP-3", "Virtual-1"; + qcom,lease-planes = "plane-0", "plane-1", "plane-2", + "plane-3","plane-4", "plane-5", + "plane-6","plane-7", "plane-8", + "plane-9","plane-10","plane-11", + "plane-12","plane-13","plane-14", + "plane-15"; + }; sde_card2: qcom,sde-kms-lease@1 { compatible = "qcom,sde-kms-lease"; qcom,dev-name = "msm_drm"; diff --git a/arch/arm64/boot/dts/qcom/sa8155-capture.dtsi b/arch/arm64/boot/dts/qcom/sa8155-capture.dtsi index 374be7156b3a..b876b34ae0c9 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-capture.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-capture.dtsi @@ -18,6 +18,10 @@ #include #include #include +#include +#include +#include + / { model = "Qualcomm Technologies, Inc. SM8150"; @@ -82,6 +86,8 @@ }; }; +#include "sm8150-gdsc.dtsi" + &soc { status = "ok"; #address-cells = <0x1>; @@ -148,13 +154,6 @@ 0x18100 0x18100 0x18100 0x18100>; }; - qcom,qupv3_1_geni_se@ac0000 { - compatible = "qcom,qupv3-geni-se"; - reg = <0xac0000 0x6000>; - qcom,bus-mas-id = <0x98>; - qcom,bus-slv-id = <0x200>; - }; - apps_rsc: mailbox@18220000 { compatible = "qcom,tcs-drv"; status="ok"; @@ -168,8 +167,377 @@ , ; }; + + clock_rpmh: qcom,rpmhclk { + compatible = "qcom,rpmh-clk-sm8150"; + mboxes = <&apps_rsc 0>; + mbox-names = "apps"; + #clock-cells = <1>; + }; + + disp_rsc: mailbox@af20000 { + compatible = "qcom,tcs-drv"; + label = "display_rsc"; + reg = <0xaf20000 0x100>, <0xaf21c00 0x3000>; + interrupts = <0 129 0>; + #mbox-cells = <1>; + qcom,drv-id = <0>; + qcom,tcs-config = , + , + , + ; + }; + + qmp_aop: qcom,qmp-aop@c300000 { + compatible = "qcom,qmp-mbox"; + reg = <0xc300000 0x1000>, <0x17c0000C 0x4>; + reg-names = "msgram", "irq-reg-base"; + qcom,irq-mask = <0x1>; + interrupts = ; + + label = "aop"; + qcom,early-boot; + priority = <0>; + mbox-desc-offset = <0x0>; + #mbox-cells = <1>; + }; + + cmd_db: qcom,cmd-db@c3f000c { + compatible = "qcom,cmd-db"; + reg = <0xc3f000c 8>; + }; + + qupv3_1: qcom,qupv3_1_geni_se@ac0000 { + compatible = "qcom,qupv3-geni-se"; + reg = <0xac0000 0x6000>; + qcom,bus-mas-id = ; + qcom,bus-slv-id = ; + qcom,iommu-s1-bypass; + + iommu_qupv3_1_geni_se_cb: qcom,iommu_qupv3_1_geni_se_cb { + compatible = "qcom,qupv3-geni-se-cb"; + iommus = <&apps_smmu 0x603 0x0>; + }; + + }; + /* 2-wire UART */ + + /* Debug UART Instance for CDP/MTP platform */ + qupv3_se12_2uart: qcom,qup_uart@0xa90000 { + compatible = "qcom,msm-geni-console"; + reg = <0xa90000 0x4000>; + reg-names = "se_phys"; + clock-names = "se-clk", "m-ahb", "s-ahb"; + clocks = <&clock_gcc GCC_QUPV3_WRAP1_S4_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>, + <&clock_gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&qupv3_se12_2uart_active>; + pinctrl-1 = <&qupv3_se12_2uart_sleep>; + interrupts = ; + qcom,wrapper-core = <&qupv3_1>; + status = "ok"; + }; + + apps_smmu: apps-smmu@0x15000000 { + compatible = "qcom,qsmmu-v500"; + reg = <0x15000000 0x100000>, + <0x15182000 0x20>; + reg-names = "base", "tcu-base"; + #iommu-cells = <2>; + qcom,skip-init; + qcom,use-3-lvl-tables; + qcom,disable-atos; + #global-interrupts = <1>; + #size-cells = <1>; + #address-cells = <1>; + ranges; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + qcom,msm-bus,name = "apps_smmu"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,active-only; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + , + , + <0 0>, + , + , + <0 1000>; + }; + + ufs_ice: ufsice@1d90000 { + compatible = "qcom,ice"; + reg = <0x1d90000 0x8000>; + qcom,enable-ice-clk; + clock-names = "ufs_core_clk", "bus_clk", + "iface_clk", "ice_core_clk"; + clocks = <&clock_gcc GCC_UFS_PHY_AXI_CLK>, + <&clock_gcc GCC_UFS_MEM_CLKREF_CLK>, + <&clock_gcc GCC_UFS_PHY_AHB_CLK>, + <&clock_gcc GCC_UFS_PHY_ICE_CORE_CLK>; + qcom,op-freq-hz = <0>, <0>, <0>, <300000000>; + vdd-hba-supply = <&ufs_phy_gdsc>; + qcom,msm-bus,name = "ufs_ice_noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <1 650 0 0>, /* No vote */ + <1 650 1000 0>; /* Max. bandwidth */ + qcom,bus-vector-names = "MIN", + "MAX"; + qcom,instance-type = "ufs"; + }; + + ufsphy_mem: ufsphy_mem@1d87000 { + compatible = "qcom,ufs-phy-qmp-v4"; + reg = <0x1d87000 0xda8>; /* PHY regs */ + reg-names = "phy_mem"; + #phy-cells = <0>; + ufs-qcom-crypto = <&ufs_ice>; + + lanes-per-direction = <2>; + + clock-names = "ref_clk_src", + "ref_clk", + "ref_aux_clk"; + clocks = <&clock_rpmh RPMH_CXO_CLK>, + <&clock_gcc GCC_UFS_MEM_CLKREF_CLK>, + <&clock_gcc GCC_UFS_PHY_PHY_AUX_CLK>; + + vdda-pll-supply = <&pm8150_2_l8>; + vdda-phy-max-microamp = <87100>; + vdda-pll-max-microamp = <18300>; + vdda-phy-supply = <&pm8150_1_l5>; + + status = "ok"; + }; + + ufshc_mem: ufshc@1d84000 { + compatible = "qcom,ufshc"; + reg = <0x1d84000 0x2500>; + interrupts = <0 265 0>; + phys = <&ufsphy_mem>; + phy-names = "ufsphy"; + ufs-qcom-crypto = <&ufs_ice>; + + lanes-per-direction = <2>; + dev-ref-clk-freq = <0>; /* 19.2 MHz */ + + clock-names = + "core_clk", + "bus_aggr_clk", + "iface_clk", + "core_clk_unipro", + "core_clk_ice", + "ref_clk", + "tx_lane0_sync_clk", + "rx_lane0_sync_clk", + "rx_lane1_sync_clk"; + clocks = + <&clock_gcc GCC_UFS_PHY_AXI_CLK>, + <&clock_gcc GCC_AGGRE_UFS_PHY_AXI_CLK>, + <&clock_gcc GCC_UFS_PHY_AHB_CLK>, + <&clock_gcc GCC_UFS_PHY_UNIPRO_CORE_CLK>, + <&clock_gcc GCC_UFS_PHY_ICE_CORE_CLK>, + <&clock_rpmh RPMH_CXO_CLK>, + <&clock_gcc GCC_UFS_PHY_TX_SYMBOL_0_CLK>, + <&clock_gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>, + <&clock_gcc GCC_UFS_PHY_RX_SYMBOL_1_CLK>; + freq-table-hz = + <37500000 300000000>, + <0 0>, + <0 0>, + <37500000 300000000>, + <37500000 300000000>, + <0 0>, + <0 0>, + <0 0>, + <0 0>; + + qcom,msm-bus,name = "ufshc_mem"; + qcom,msm-bus,num-cases = <26>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + /* + * During HS G3 UFS runs at nominal voltage corner, vote + * higher bandwidth to push other buses in the data path + * to run at nominal to achieve max throughput. + * 4GBps pushes BIMC to run at nominal. + * 200MBps pushes CNOC to run at nominal. + * Vote for half of this bandwidth for HS G3 1-lane. + * For max bandwidth, vote high enough to push the buses + * to run in turbo voltage corner. + */ + <123 512 0 0>, <1 757 0 0>, /* No vote */ + <123 512 922 0>, <1 757 1000 0>, /* PWM G1 */ + <123 512 1844 0>, <1 757 1000 0>, /* PWM G2 */ + <123 512 3688 0>, <1 757 1000 0>, /* PWM G3 */ + <123 512 7376 0>, <1 757 1000 0>, /* PWM G4 */ + <123 512 1844 0>, <1 757 1000 0>, /* PWM G1 L2 */ + <123 512 3688 0>, <1 757 1000 0>, /* PWM G2 L2 */ + <123 512 7376 0>, <1 757 1000 0>, /* PWM G3 L2 */ + <123 512 14752 0>, <1 757 1000 0>, /* PWM G4 L2 */ + <123 512 127796 0>, <1 757 1000 0>, /* HS G1 RA */ + <123 512 255591 0>, <1 757 1000 0>, /* HS G2 RA */ + <123 512 2097152 0>, <1 757 102400 0>, /* HS G3 RA */ + <123 512 4194304 0>, <1 757 204800 0>, /* HS G4 RA */ + <123 512 255591 0>, <1 757 1000 0>, /* HS G1 RA L2 */ + <123 512 511181 0>, <1 757 1000 0>, /* HS G2 RA L2 */ + <123 512 4194304 0>, <1 757 204800 0>, /* HS G3 RA L2 */ + <123 512 8388608 0>, <1 757 409600 0>, /* HS G4 RA L2 */ + <123 512 149422 0>, <1 757 1000 0>, /* HS G1 RB */ + <123 512 298189 0>, <1 757 1000 0>, /* HS G2 RB */ + <123 512 2097152 0>, <1 757 102400 0>, /* HS G3 RB */ + <123 512 4194304 0>, <1 757 204800 0>, /* HS G4 RB */ + <123 512 298189 0>, <1 757 1000 0>, /* HS G1 RB L2 */ + <123 512 596378 0>, <1 757 1000 0>, /* HS G2 RB L2 */ + /* As UFS working in HS G3 RB L2 mode, aggregated + * bandwidth (AB) should take care of providing + * optimum throughput requested. However, as tested, + * in order to scale up CNOC clock, instantaneous + * bindwidth (IB) needs to be given a proper value too. + */ + <123 512 4194304 0>, <1 757 204800 409600>, /* HS G3 RB L2 */ + <123 512 8388608 0>, <1 757 409600 409600>, /* HS G4 RB L2 */ + <123 512 7643136 0>, <1 757 307200 0>; /* Max. bandwidth */ + + qcom,bus-vector-names = "MIN", + "PWM_G1_L1", "PWM_G2_L1", "PWM_G3_L1", "PWM_G4_L1", + "PWM_G1_L2", "PWM_G2_L2", "PWM_G3_L2", "PWM_G4_L2", + "HS_RA_G1_L1", "HS_RA_G2_L1", "HS_RA_G3_L1", "HS_RA_G4_L1", + "HS_RA_G1_L2", "HS_RA_G2_L2", "HS_RA_G3_L2", "HS_RA_G4_L2", + "HS_RB_G1_L1", "HS_RB_G2_L1", "HS_RB_G3_L1", "HS_RB_G4_L1", + "HS_RB_G1_L2", "HS_RB_G2_L2", "HS_RB_G3_L2", "HS_RB_G4_L2", + "MAX"; + + /* PM QoS */ + qcom,pm-qos-cpu-groups = <0x0f 0xf0>; + qcom,pm-qos-cpu-group-latency-us = <44 44>; + qcom,pm-qos-default-cpu = <0>; + + pinctrl-names = "dev-reset-assert", "dev-reset-deassert"; + pinctrl-0 = <&ufs_dev_reset_assert>; + pinctrl-1 = <&ufs_dev_reset_deassert>; + + resets = <&clock_gcc GCC_UFS_PHY_BCR>; + reset-names = "core_reset"; + + vdd-hba-supply = <&ufs_phy_gdsc>; + vdd-hba-fixed-regulator; + vcc-supply = <&pm8150_1_l10>; + vcc-voltage-level = <2950000 2960000>; + vccq2-supply = <&pm8150_1_s4>; + vcc-max-microamp = <750000>; + vccq2-max-microamp = <750000>; + + qcom,vddp-ref-clk-supply = <&pm8150_2_l5>; + qcom,vddp-ref-clk-max-microamp = <100>; + + status = "ok"; + }; + +}; + +&apps_smmu { + qcom,actlr = + /* HF0 and HF1 TBUs: +3 deep PF */ + <0x800 0x7ff 0x103>, + + /* SF TBU: +3 deep PF */ + <0x2000 0x3ff 0x103>, + + /* NPU SIDs: +15 deep PF */ + <0x1480 0x3 0x303>, + <0x1484 0x1 0x303>, + <0x1080 0x3 0x303>, + <0x1084 0x1 0x303>; +}; + +&ufs_phy_gdsc { + status = "ok"; }; #include "sa8155-regulator.dtsi" #include "sm8150-pinctrl.dtsi" - +#include "sm8150-bus.dtsi" diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm-usb.dtsi b/arch/arm64/boot/dts/qcom/sa8155-vm-usb.dtsi index 90366d5cb5db..80c4744e12e1 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm-usb.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-vm-usb.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -58,7 +58,7 @@ 0x144 /* GSI_RING_BASE_ADDR_H */ 0x1a4>; /* GSI_IF_STS */ qcom,dwc-usb3-msm-tx-fifo-size = <27696>; - + qcom,ignore-wakeup-src-in-hostmode; status = "disabled"; dwc3@a600000 { diff --git a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi index d472b2de0bc8..6982f506569d 100644 --- a/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8155-vm.dtsi @@ -998,7 +998,7 @@ compatible = "qcom,smem"; memory-region = <&smem_region>; hwlocks = <&tcsr_mutex 3>; - smem-host-id = <10>; + smem-host-id = <12>; }; gvm_intr: mailbox@17c00000 { diff --git a/arch/arm64/boot/dts/qcom/sa8195-vm-usb.dtsi b/arch/arm64/boot/dts/qcom/sa8195-vm-usb.dtsi index 1035d25de40b..01e507a282e6 100644 --- a/arch/arm64/boot/dts/qcom/sa8195-vm-usb.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195-vm-usb.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -56,7 +56,7 @@ 0x144 /* GSI_RING_BASE_ADDR_H */ 0x1a4>; /* GSI_IF_STS */ qcom,dwc-usb3-msm-tx-fifo-size = <27696>; - + qcom,ignore-wakeup-src-in-hostmode; status = "disabled"; dwc3@a600000 { diff --git a/arch/arm64/boot/dts/qcom/sa8195p-adp-common.dtsi b/arch/arm64/boot/dts/qcom/sa8195p-adp-common.dtsi index f4cb5d816cef..4ded57fd707b 100644 --- a/arch/arm64/boot/dts/qcom/sa8195p-adp-common.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p-adp-common.dtsi @@ -14,6 +14,10 @@ #include #include "sa8195p-cnss.dtsi" +&qupv3_3 { + status = "ok"; +}; + &qupv3_se0_spi { status = "ok"; diff --git a/arch/arm64/boot/dts/qcom/sa8195p-adp-star-display.dtsi b/arch/arm64/boot/dts/qcom/sa8195p-adp-star-display.dtsi index 3f8bb0d0213d..cc9c64a84ac8 100755 --- a/arch/arm64/boot/dts/qcom/sa8195p-adp-star-display.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8195p-adp-star-display.dtsi @@ -484,9 +484,15 @@ sde_card1: qcom,sde-kms-lease@0 { compatible = "qcom,sde-kms-lease"; qcom,dev-name = "msm_drm"; - qcom,lease-connectors = "shared-disp-0"; - qcom,lease-planes = "plane-0", "plane-1", - "plane-12","plane-13"; + qcom,lease-connectors = "DSI-2", "shared-disp-0", + "DP-1", "DP-2", "DP-3", "DP-4", "DP-5", + "Virtual-1"; + qcom,lease-planes = "plane-0", "plane-1", "plane-2", + "plane-3","plane-4", "plane-5", + "plane-6","plane-7", "plane-8", + "plane-9","plane-10","plane-11", + "plane-12","plane-13","plane-14", + "plane-15"; }; sde_card2: qcom,sde-kms-lease@1 { diff --git a/arch/arm64/boot/dts/qcom/sda429-bg-dvt2-wtp-overlay.dts b/arch/arm64/boot/dts/qcom/sda429-bg-dvt2-wtp-overlay.dts index 03c3a00fa5ad..04d3b38f2d42 100644 --- a/arch/arm64/boot/dts/qcom/sda429-bg-dvt2-wtp-overlay.dts +++ b/arch/arm64/boot/dts/qcom/sda429-bg-dvt2-wtp-overlay.dts @@ -16,15 +16,68 @@ #include #include "sda429-bg-dvt2-wtp.dtsi" +#include "sdm429-mdss-panels.dtsi" / { model = "Qualcomm Technologies, Inc. SDA429 QRD BG WTP Overlay"; compatible = "qcom,sdm429w-qrd", "qcom,sdm429w", "qcom,qrd"; qcom,msm-id = <437 0x0>; - qcom,board-id = <0x00010b 8>; + qcom,board-id = <0x00010b 0xA>; qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>; }; +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&mdss_dsi { + /delete-property/ vdda-supply; + /delete-property/ vddio-supply; + vdda-supply = <&L6A>; /* 0.8v */ + vddio-supply = <&L13A>; /* 1.8v */ + + qcom,ctrl-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,ctrl-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda"; + qcom,supply-min-voltage = <800000>; + qcom,supply-max-voltage = <800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <20>; + }; + }; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_auo_416p_amoled_cmd>; + /delete-property/ vdd-supply; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_te_active>; + pinctrl-1 = <&mdss_te_suspend>; + vddio-supply = <&L11A>; + qcom,platform-te-gpio = <&tlmm 24 0>; + qcom,platform-reset-gpio = <&tlmm 60 0>; + qcom,platform-enable-gpio = <&pm660_gpios 12 0>; + +}; + +&mdss_dsi0_pll { + /delete-property/ vddio-supply; + vddio-supply = <&L13A>; +}; + +&mdss_dsi1 { + status = "disabled"; +}; + +&mdss_dsi1_pll { + status = "disabled"; +}; + &i2c_4 { status = "ok"; diff --git a/arch/arm64/boot/dts/qcom/sda429-wtp-overlay.dts b/arch/arm64/boot/dts/qcom/sda429-wtp-overlay.dts index 7bbdfa9ae059..aa6d7612dd96 100644 --- a/arch/arm64/boot/dts/qcom/sda429-wtp-overlay.dts +++ b/arch/arm64/boot/dts/qcom/sda429-wtp-overlay.dts @@ -16,6 +16,7 @@ #include #include "sda429-wtp.dtsi" +#include "sdm429-mdss-panels.dtsi" / { model = "Qualcomm Technologies, Inc. SDA429 QRD BG WTP Overlay"; @@ -25,6 +26,58 @@ qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>; }; +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&mdss_dsi { + /delete-property/ vdda-supply; + /delete-property/ vddio-supply; + vdda-supply = <&L6A>; /* 0.8v */ + vddio-supply = <&L13A>; /* 1.8v */ + + qcom,ctrl-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,ctrl-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda"; + qcom,supply-min-voltage = <800000>; + qcom,supply-max-voltage = <800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <20>; + }; + }; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_auo_416p_amoled_cmd>; + /delete-property/ vdd-supply; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_te_active>; + pinctrl-1 = <&mdss_te_suspend>; + vddio-supply = <&L11A>; + qcom,platform-te-gpio = <&tlmm 24 0>; + qcom,platform-reset-gpio = <&tlmm 60 0>; + qcom,platform-enable-gpio = <&pm660_gpios 12 0>; + +}; + +&mdss_dsi0_pll { + /delete-property/ vddio-supply; + vddio-supply = <&L13A>; +}; + +&mdss_dsi1 { + status = "disabled"; +}; + +&mdss_dsi1_pll { + status = "disabled"; +}; + &i2c_4 { status = "ok"; diff --git a/arch/arm64/boot/dts/qcom/sdm429-bg-soc.dtsi b/arch/arm64/boot/dts/qcom/sdm429-bg-soc.dtsi index 6ac3d71f82f5..d35f17738438 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-bg-soc.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-bg-soc.dtsi @@ -26,6 +26,7 @@ spi_3: spi@78b7000 { /* BLSP1 QUP3*/ status = "ok"; + qcom,shared_ee; qcom,bg-spi { compatible = "qcom,bg-spi"; reg = <0>; diff --git a/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi b/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi index e5c016ee8f0e..8632471a74cd 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi @@ -43,7 +43,7 @@ reg = <0x100>; enable-method = "psci"; cpu-release-addr = <0x0 0x90000000>; - efficiency = <1024>; + capacity-dmips-mhz = <1024>; sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>; next-level-cache = <&L2_1>; #cooling-cells = <2>; @@ -69,7 +69,7 @@ reg = <0x101>; enable-method = "psci"; cpu-release-addr = <0x0 0x90000000>; - efficiency = <1024>; + capacity-dmips-mhz = <1024>; sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>; next-level-cache = <&L2_1>; #cooling-cells = <2>; @@ -89,7 +89,7 @@ reg = <0x102>; enable-method = "psci"; cpu-release-addr = <0x0 0x90000000>; - efficiency = <1024>; + capacity-dmips-mhz = <1024>; sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>; next-level-cache = <&L2_1>; #cooling-cells = <2>; @@ -109,7 +109,7 @@ reg = <0x103>; enable-method = "psci"; cpu-release-addr = <0x0 0x90000000>; - efficiency = <1024>; + capacity-dmips-mhz = <1024>; sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>; next-level-cache = <&L2_1>; #cooling-cells = <2>; @@ -134,9 +134,6 @@ 1305600 207 1497600 256 1708800 327 - 1804800 343 - 1958400 445 - 2016000 470 >; idle-cost-data = < 100 80 60 40 @@ -148,9 +145,6 @@ 1305600 61 1497600 71 1708800 85 - 1804800 88 - 1958400 110 - 2016000 120 >; idle-cost-data = < 4 3 2 1 diff --git a/arch/arm64/boot/dts/qcom/sdm429-mdss-panels.dtsi b/arch/arm64/boot/dts/qcom/sdm429-mdss-panels.dtsi index c564239c6988..fe112f060f7d 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-mdss-panels.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-mdss-panels.dtsi @@ -45,6 +45,7 @@ qcom,mdss-dsi-panel-status-check-mode = "te_signal_check"; qcom,mdss-dsi-power-off-disable; qcom,mdss-dsi-tear-disable; + qcom,mdss-skip-panel-reset; }; diff --git a/arch/arm64/boot/dts/qcom/sdm429-thermal.dtsi b/arch/arm64/boot/dts/qcom/sdm429-thermal.dtsi new file mode 100644 index 000000000000..a7d1b7635fc8 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdm429-thermal.dtsi @@ -0,0 +1,706 @@ +/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +&soc { + qmi-tmd-devices { + compatible = "qcom,qmi-cooling-devices"; + + modem { + qcom,instance-id = <0x0>; + + modem_pa: modem_pa { + qcom,qmi-dev-name = "pa"; + #cooling-cells = <2>; + }; + + modem_proc: modem_proc { + qcom,qmi-dev-name = "modem"; + #cooling-cells = <2>; + }; + + modem_current: modem_current { + qcom,qmi-dev-name = "modem_current"; + #cooling-cells = <2>; + }; + + modem_vdd: modem_vdd { + qcom,qmi-dev-name = "cpuv_restriction_cold"; + #cooling-cells = <2>; + }; + }; + }; +}; + +&thermal_zones { + aoss0-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&tsens0 0>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + mdm-core-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&tsens0 1>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + lpass-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&tsens0 2>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + camera-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "user_space"; + thermal-sensors = <&tsens0 3>; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + cpuss1-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 4>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + apc1-cpu0-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 5>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + apc1-cpu1-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 6>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + apc1-cpu2-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 7>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + apc1-cpu3-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 8>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + cpuss0-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 9>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + gpu-usr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 10>; + thermal-governor = "user_space"; + wake-capable-sensor; + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + gpu-step { + polling-delay-passive = <250>; + polling-delay = <0>; + thermal-sensors = <&tsens0 10>; + thermal-governor = "step_wise"; + wake-capable-sensor; + trips { + gpu_step_trip: gpu-step-trip { + temperature = <95000>; + hysteresis = <0>; + type = "passive"; + }; + }; + cooling-maps { + gpu_cdev0 { + trip = <&gpu_step_trip>; + cooling-device = + <&msm_gpu THERMAL_NO_LIMIT + THERMAL_NO_LIMIT>; + }; + }; + }; + + hexa-cpu-max-step { + polling-delay-passive = <50>; + polling-delay = <100>; + thermal-governor = "step_wise"; + wake-capable-sensor; + trips { + cpu_trip:cpu-trip { + temperature = <85000>; + hysteresis = <0>; + type = "passive"; + }; + }; + cooling-maps { + cpu0_cdev { + trip = <&cpu_trip>; + cooling-device = + <&CPU0 THERMAL_NO_LIMIT + (THERMAL_MAX_LIMIT-1)>; + }; + cpu1_cdev { + trip = <&cpu_trip>; + cooling-device = + <&CPU1 THERMAL_NO_LIMIT + (THERMAL_MAX_LIMIT-1)>; + }; + cpu2_cdev { + trip = <&cpu_trip>; + cooling-device = + <&CPU2 THERMAL_NO_LIMIT + (THERMAL_MAX_LIMIT-1)>; + }; + cpu3_cdev { + trip = <&cpu_trip>; + cooling-device = + <&CPU3 THERMAL_NO_LIMIT + (THERMAL_MAX_LIMIT-1)>; + }; + }; + }; + + apc1-cpu0-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 5>; + thermal-governor = "step_wise"; + wake-capable-sensor; + trips { + apc1_cpu0_trip: apc1-cpu0-trip { + temperature = <105000>; + hysteresis = <15000>; + type = "passive"; + }; + }; + cooling-maps { + cpu0_cdev { + trip = <&apc1_cpu0_trip>; + cooling-device = + <&CPU0 THERMAL_MAX_LIMIT + THERMAL_MAX_LIMIT>; + }; + }; + }; + + apc1-cpu1-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 6>; + thermal-governor = "step_wise"; + wake-capable-sensor; + trips { + apc1_cpu1_trip: apc1-cpu1-trip { + temperature = <105000>; + hysteresis = <15000>; + type = "passive"; + }; + }; + cooling-maps { + cpu1_cdev { + trip = <&apc1_cpu1_trip>; + cooling-device = + <&CPU1 THERMAL_MAX_LIMIT + THERMAL_MAX_LIMIT>; + }; + }; + }; + + apc1-cpu2-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 7>; + thermal-governor = "step_wise"; + wake-capable-sensor; + trips { + apc1_cpu2_trip: apc1-cpu2-trip { + temperature = <105000>; + hysteresis = <15000>; + type = "passive"; + }; + }; + cooling-maps { + cpu2_cdev { + trip = <&apc1_cpu2_trip>; + cooling-device = + <&CPU2 THERMAL_MAX_LIMIT + THERMAL_MAX_LIMIT>; + }; + }; + }; + + apc1-cpu3-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 8>; + thermal-governor = "step_wise"; + wake-capable-sensor; + trips { + apc1_cpu3_trip: apc1-cpu3-trip { + temperature = <105000>; + hysteresis = <15000>; + type = "passive"; + }; + }; + cooling-maps { + cpu3_cdev { + trip = <&apc1_cpu3_trip>; + cooling-device = + <&CPU3 THERMAL_MAX_LIMIT + THERMAL_MAX_LIMIT>; + }; + }; + }; + + aoss0-lowf { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 0>; + wake-capable-sensor; + tracks-low; + trips { + aoss0_trip: aoss-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + cooling-maps { + cpu0_vdd_cdev { + trip = <&aoss0_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + cx_vdd_cdev { + trip = <&aoss0_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + modem_vdd_cdev { + trip = <&aoss0_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + mdm-core-lowf { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 1>; + wake-capable-sensor; + tracks-low; + trips { + mdm_core_trip: mdm-core-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + cooling-maps { + cpu0_vdd_cdev { + trip = <&mdm_core_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + cx_vdd_cdev { + trip = <&mdm_core_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + modem_vdd_cdev { + trip = <&mdm_core_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + lpass-lowf { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 2>; + wake-capable-sensor; + tracks-low; + trips { + qdsp_trip: qdsp-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + cooling-maps { + cpu0_vdd_cdev { + trip = <&qdsp_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + cx_vdd_cdev { + trip = <&qdsp_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + modem_vdd_cdev { + trip = <&qdsp_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + camera-lowf { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 3>; + wake-capable-sensor; + tracks-low; + trips { + camera_trip: camera-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + cooling-maps { + cpu0_vdd_cdev { + trip = <&camera_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + cx_vdd_cdev { + trip = <&camera_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + modem_vdd_cdev { + trip = <&camera_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + cpuss1-lowf { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 4>; + wake-capable-sensor; + tracks-low; + trips { + cpuss1_trip: cpuss1-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + cooling-maps { + cpu0_vdd_cdev { + trip = <&cpuss1_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + cx_vdd_cdev { + trip = <&cpuss1_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + modem_vdd_cdev { + trip = <&cpuss1_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + apc1-cpu0-lowf { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 5>; + wake-capable-sensor; + tracks-low; + trips { + cpu0_trip: apc1-cpu0-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + cooling-maps { + cpu0_vdd_cdev { + trip = <&cpu0_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + cx_vdd_cdev { + trip = <&cpu0_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + modem_vdd_cdev { + trip = <&cpu0_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + apc1-cpu1-lowf { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 6>; + wake-capable-sensor; + tracks-low; + trips { + cpu1_trip: apc1-cpu1-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + cooling-maps { + cpu0_vdd_cdev { + trip = <&cpu1_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + cx_vdd_cdev { + trip = <&cpu1_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + modem_vdd_cdev { + trip = <&cpu1_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + apc1-cpu2-lowf { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 7>; + wake-capable-sensor; + tracks-low; + trips { + cpu2_trip: apc1-cpu2-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + cooling-maps { + cpu0_vdd_cdev { + trip = <&cpu2_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + cx_vdd_cdev { + trip = <&cpu2_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + modem_vdd_cdev { + trip = <&cpu2_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + apc1-cpu3-lowf { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 8>; + wake-capable-sensor; + tracks-low; + trips { + cpu3_trip: apc1-cpu3-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + cooling-maps { + cpu0_vdd_cdev { + trip = <&cpu3_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + cx_vdd_cdev { + trip = <&cpu3_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + modem_vdd_cdev { + trip = <&cpu3_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + cpuss0-lowf { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 9>; + wake-capable-sensor; + tracks-low; + trips { + cpuss0_lowf_trip: cpuss0-lowf-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + cooling-maps { + cpu0_vdd_cdev { + trip = <&cpuss0_lowf_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + cx_vdd_cdev { + trip = <&cpuss0_lowf_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + modem_vdd_cdev { + trip = <&cpuss0_lowf_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + gpu-lowf { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 10>; + wake-capable-sensor; + tracks-low; + trips { + gpu_lowf_trip: gpu-lowf-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + cooling-maps { + cpu0_vdd_cdev { + trip = <&gpu_lowf_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + cx_vdd_cdev { + trip = <&gpu_lowf_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + modem_vdd_cdev { + trip = <&gpu_lowf_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm429.dtsi b/arch/arm64/boot/dts/qcom/sdm429.dtsi index 31218880dc07..22955a639d93 100644 --- a/arch/arm64/boot/dts/qcom/sdm429.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429.dtsi @@ -19,6 +19,9 @@ #include #include +#define MHZ_TO_MBPS(mhz, w) ((mhz * 1000000 * w) / (1024 * 1024)) +#define BW_OPP_ENTRY(mhz, w) opp-mhz {opp-hz = /bits/ 64 ;} + / { model = "Qualcomm Technologies, Inc. SDM429"; compatible = "qcom,sdm429"; @@ -423,7 +426,33 @@ cpu-pmu { compatible = "arm,armv8-pmuv3"; interrupts = <1 7 0xff00>; - status = "disabled"; + }; + + qcom,memshare { + compatible = "qcom,memshare"; + + qcom,client_1 { + compatible = "qcom,memshare-peripheral"; + qcom,peripheral-size = <0x200000>; + qcom,client-id = <0>; + qcom,allocate-boot-time; + label = "modem"; + }; + + qcom,client_2 { + compatible = "qcom,memshare-peripheral"; + qcom,peripheral-size = <0x0>; + qcom,client-id = <2>; + label = "modem"; + }; + + mem_client_3_size: qcom,client_3 { + compatible = "qcom,memshare-peripheral"; + qcom,peripheral-size = <0x0>; + qcom,client-id = <1>; + qcom,allocate-on-request; + label = "modem"; + }; }; qcom,sps { @@ -471,7 +500,6 @@ qcom,msm-rtb { compatible = "qcom,msm-rtb"; qcom,rtb-size = <0x100000>; /* 1M EBI1 buffer */ - status = "disabled"; }; qcom,rmtfs_sharedmem@00000000 { @@ -613,6 +641,46 @@ }; }; + mem_dump { + compatible = "qcom,mem-dump"; + memory-region = <0x85>; + + rpm_sw_dump { + qcom,dump-size = <0x28000>; + qcom,dump-id = <0xea>; + }; + + pmic_dump { + qcom,dump-size = <0x10000>; + qcom,dump-id = <0xe4>; + }; + + vsense_dump { + qcom,dump-size = <0x1000>; + qcom,dump-id = <0xe9>; + }; + + tmc_etf_dump { + qcom,dump-size = <0x10000>; + qcom,dump-id = <0xf0>; + }; + + tmc_etr_reg_dump { + qcom,dump-size = <0x1000>; + qcom,dump-id = <0x100>; + }; + + tmc_etf_reg_dump { + qcom,dump-size = <0x1000>; + qcom,dump-id = <0x101>; + }; + + misc_data_dump { + qcom,dump-size = <0x1000>; + qcom,dump-id = <0xe8>; + }; + }; + qcom,lpass@c000000 { compatible = "qcom,pil-tz-generic"; reg = <0xc000000 0x00100>; @@ -705,7 +773,44 @@ qcom,smem-state-names = "qcom,force-stop"; memory-region = <&wcnss_fw_mem>; }; + qcom,venus@1de0000 { + compatible = "qcom,pil-tz-generic"; + reg = <0x1de0000 0x4000>; + vdd-supply = <&venus_gdsc>; + qcom,proxy-reg-names = "vdd"; + + clocks = <&gcc GCC_VENUS0_VCODEC0_CLK>, + <&gcc GCC_VENUS0_AHB_CLK>, + <&gcc GCC_VENUS0_AXI_CLK>, + <&gcc GCC_CRYPTO_CLK>, + <&gcc GCC_CRYPTO_AHB_CLK>, + <&gcc GCC_CRYPTO_AXI_CLK>, + <&gcc CRYPTO_CLK_SRC>; + + clock-names = "core_clk", "iface_clk", "bus_clk", + "scm_core_clk", "scm_iface_clk", + "scm_bus_clk", "scm_core_clk_src"; + + qcom,proxy-clock-names = "core_clk", "iface_clk", + "bus_clk", "scm_core_clk", + "scm_iface_clk", "scm_bus_clk", + "scm_core_clk_src"; + qcom,scm_core_clk_src-freq = <80000000>; + + qcom,msm-bus,name = "pil-venus"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 0 304000>; + + qcom,mas-crypto = <&mas_crypto>; + qcom,pas-id = <9>; + qcom,proxy-timeout-ms = <100>; + qcom,firmware-name = "venus"; + memory-region = <&venus_mem>; + }; pil_modem: qcom,mss@4080000 { compatible = "qcom,pil-q6v55-mss"; reg = <0x4080000 0x100>, @@ -1315,7 +1420,88 @@ interrupt-names = "slimbus_irq", "slimbus_bam_irq"; qcom,apps-ch-pipes = <0x600000>; qcom,ea-pc = <0x230>; - status = "disabled"; + status = "okay"; + + /* Slimbus Slave DT for WCN3980 */ + btfmslim_codec: wcn3990 { + compatible = "qcom,btfmslim_slave"; + elemental-addr = [00 01 20 02 17 02]; + qcom,btfm-slim-ifd = "btfmslim_slave_ifd"; + qcom,btfm-slim-ifd-elemental-addr = [00 00 20 02 17 02]; + }; + }; + + qcom,msm-adsp-loader { + status = "ok"; + compatible = "qcom,adsp-loader"; + qcom,adsp-state = <0>; + }; + + msm_cpufreq: qcom,msm-cpufreq { + compatible = "qcom,msm-cpufreq"; + clock-names = "cpu0_clk"; + clocks = <&cpu APCS_MUX_C1_CLK>; + + qcom,cpufreq-table = + < 960000 >, + < 1305600 >, + < 1497600 >, + < 1708800 >; + }; + ddr_bw_opp_table: ddr-bw-opp-table { + compatible = "operating-points-v2"; + BW_OPP_ENTRY( 211,8); /* 2265 MB/s */ + BW_OPP_ENTRY( 384, 8); /* 4539 MB/s */ + BW_OPP_ENTRY( 662, 8); /* 5416 MB/s */ + BW_OPP_ENTRY( 749, 8); + }; + + cpubw: qcom,cpubw { + compatible = "qcom,devbw"; + governor = "performance"; + qcom,src-dst-ports = <1 512>; + qcom,active-only; + operating-points-v2 = <&ddr_bw_opp_table>; + }; + + com,cpu-bwmon { + compatible = "qcom,bimc-bwmon2"; + reg = <0x408000 0x300>, <0x401000 0x200>; + reg-names = "base", "global_base"; + interrupts = <0 183 4>; + qcom,mport = <0>; + qcom,target-dev = <&cpubw>; + }; + + cpu0_cpu_ddr_latfloor: qcom,cpu0-cpu-ddr-latfloor { + compatible = "qcom,devbw"; + governor = "performance"; + qcom,src-dst-ports = <1 512>; + qcom,active-only; + operating-points-v2 = <&ddr_bw_opp_table>; + }; + + cpu0_computemon: qcom,cpu0-computemon { + compatible = "qcom,arm-cpu-mon"; + qcom,cpulist = <&CPU0 &CPU1 &CPU2 &CPU3>; + qcom,target-dev = <&cpu0_cpu_ddr_latfloor>; + qcom,core-dev-table = + < 960000 MHZ_TO_MBPS( 211, 8) >, + < 1305600 MHZ_TO_MBPS( 384, 8) >, + < 1497600 MHZ_TO_MBPS( 662, 8) >, + < 1708800 MHZ_TO_MBPS( 749, 8) >; + }; + + tsens0: tsens@4a8000 { + compatible = "qcom,msm8937-tsens"; + reg = <0x4a8000 0x1000>, + <0x4a9000 0x1000>, + <0xa4000 0x1000>; + reg-names = "tsens_srot_physical", + "tsens_tm_physical", "tsens_eeprom_physical"; + interrupts = <0 184 0>; + interrupt-names = "tsens-upper-lower"; + #thermal-sensor-cells = <1>; }; }; @@ -1325,6 +1511,7 @@ #include "sdm429-mdss.dtsi" #include "sdm429-mdss-pll.dtsi" #include "sdm429-audio.dtsi" +#include "sdm429-thermal.dtsi" &venus_gdsc { clock-names = "bus_clk", "core_clk"; diff --git a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi index 1cf4c8ad62a0..c670547294ba 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi @@ -122,7 +122,7 @@ qcom,fg-bmd-en-delay-ms = <300>; qcom,fg-force-load-profile; qcom,fg-jeita-thresholds = <0 20 45 60>; - status = "disabled"; + status = "ok"; }; &pm660_haptics { @@ -165,6 +165,8 @@ }; }; +#include + &thermal_zones { xo-therm-adc { polling-delay-passive = <0>; @@ -245,6 +247,164 @@ }; }; }; + + quiet-therm-step { + polling-delay-passive = <1000>; + polling-delay = <0>; + thermal-sensors = <&pm660_adc_tm 0x51>; + thermal-governor = "step_wise"; + wake-capable-sensor; + + trips { + quiet_batt_439_trip1: quiet-batt-trip1 { + temperature = <38000>; + hysteresis = <2000>; + type = "passive"; + }; + + quiet_batt_439_trip2: quiet-batt-trip2 { + temperature = <40000>; + hysteresis = <2000>; + type = "passive"; + }; + + quiet_batt_439_trip3: quiet-batt-trip3 { + temperature = <42000>; + hysteresis = <2000>; + type = "passive"; + }; + + quiet_batt_439_trip4: quiet-batt-trip4 { + temperature = <44000>; + hysteresis = <2000>; + type = "passive"; + }; + + quiet_modem_439_trip1: quiet-modem-trip0 { + temperature = <44000>; + hysteresis = <4000>; + type = "passive"; + }; + + quiet_modem_439_trip2: quiet-modem-trip1 { + temperature = <46000>; + hysteresis = <4000>; + type = "passive"; + }; + + quiet_batt_439_trip5: quiet-batt-trip5 { + temperature = <46000>; + hysteresis = <2000>; + type = "passive"; + }; + + quiet_modem_439_trip3: quiet-modem-trp3 { + temperature = <48000>; + hysteresis = <2000>; + type = "passive"; + }; + + quiet_cpus_439_trip: quiet-cpus-trip { + temperature = <48000>; + hysteresis = <0>; + type = "passive"; + }; + + quiet_batt_439_trip6: quiet-batt-trip6 { + temperature = <55000>; + hysteresis = <2000>; + type = "passive"; + }; + + quiet_modem_439_trip4: quiet-modem-trip3 { + temperature = <55000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + + cooling-maps { + skin_cpu0 { + trip = <&quiet_cpus_439_trip>; + /* throttle from fmax to 1497600KHz */ + cooling-device = <&CPU0 THERMAL_NO_LIMIT + (THERMAL_MAX_LIMIT-3)>; + }; + + skin_cpu1 { + trip = <&quiet_cpus_439_trip>; + cooling-device = <&CPU1 THERMAL_NO_LIMIT + (THERMAL_MAX_LIMIT-3)>; + }; + + skin_cpu2 { + trip = <&quiet_cpus_439_trip>; + cooling-device = <&CPU2 THERMAL_NO_LIMIT + (THERMAL_MAX_LIMIT-3)>; + }; + + skin_cpu3 { + trip = <&quiet_cpus_439_trip>; + cooling-device = <&CPU3 THERMAL_NO_LIMIT + (THERMAL_MAX_LIMIT-3)>; + }; + + modem_proc_lvl1 { + trip = <&quiet_modem_439_trip1>; + cooling-device = <&modem_proc 1 1>; + }; + + modem_proc_lvl2 { + trip = <&quiet_modem_439_trip4>; + cooling-device = <&modem_proc 3 3>; + }; + + modem_lvl1 { + trip = <&quiet_modem_439_trip2>; + cooling-device = <&modem_pa 1 1>; + }; + + modem_lvl2 { + trip = <&quiet_modem_439_trip3>; + cooling-device = <&modem_pa 2 2>; + }; + + modem_lvl3 { + trip = <&quiet_modem_439_trip4>; + cooling-device = <&modem_pa 3 3>; + }; + + battery_lvl1 { + trip = <&quiet_batt_439_trip1>; + cooling-device = <&pm660_charger 1 1>; + }; + + battery_lvl2 { + trip = <&quiet_batt_439_trip2>; + cooling-device = <&pm660_charger 2 2>; + }; + + battery_lvl3 { + trip = <&quiet_batt_439_trip3>; + cooling-device = <&pm660_charger 3 3>; + }; + + battery_lvl4 { + trip = <&quiet_batt_439_trip4>; + cooling-device = <&pm660_charger 4 4>; + }; + + battery_lvl5 { + trip = <&quiet_batt_439_trip5>; + cooling-device = <&pm660_charger 5 5>; + }; + + battery_lvl6 { + trip = <&quiet_batt_439_trip6>; + cooling-device = <&pm660_charger 6 6>; + }; + }; + }; }; &usb_otg { diff --git a/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi index e3c95e217f21..8d154467c1ec 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi @@ -56,7 +56,7 @@ qcom,use-voltage-level; }; - pm660_cx_cdev: regulator-cx-cdev { + pm660_cx_cdev: cx { compatible = "qcom,regulator-cooling-device"; regulator-cdev-supply = <&pm660_s1_floor_level>; regulator-levels = ; qcom,bus-slv-id = ; qcom,iommu-s1-bypass; + status = "ok"; iommu_qupv3_0_geni_se_cb: qcom,iommu_qupv3_0_geni_se_cb { compatible = "qcom,qupv3-geni-se-cb"; @@ -348,6 +349,7 @@ qcom,bus-mas-id = ; qcom,bus-slv-id = ; qcom,iommu-s1-bypass; + status = "ok"; iommu_qupv3_1_geni_se_cb: qcom,iommu_qupv3_1_geni_se_cb { compatible = "qcom,qupv3-geni-se-cb"; @@ -616,6 +618,7 @@ qcom,bus-mas-id = ; qcom,bus-slv-id = ; qcom,iommu-s1-bypass; + status = "ok"; iommu_qupv3_2_geni_se_cb: qcom,iommu_qupv3_2_geni_se_cb { compatible = "qcom,qupv3-geni-se-cb"; @@ -871,6 +874,11 @@ qcom,bus-mas-id = ; qcom,bus-slv-id = ; qcom,iommu-s1-bypass; + qcom,subsys-name = "slpi"; + clock-names = "corex", "core2x"; + clocks = <&clock_scc SCC_QUPV3_CORE_CLK>, + <&clock_scc SCC_QUPV3_2XCORE_CLK>; + status = "disabled"; iommu_qupv3_3_geni_se_cb: qcom,iommu_qupv3_3_geni_se_cb { compatible = "qcom,qupv3-geni-se-cb"; diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie-pinctrl.dtsi index aaf72774fa18..edba1fd6cdbb 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie-pinctrl.dtsi @@ -1685,18 +1685,5 @@ bias-pull-down; }; }; - - wakeup_gpio_default: wakeup_gpio_default { - mux { - pins = "gpio22"; - function = "gpio"; - }; - - config { - pins = "gpio22"; - drive-strength = <2>; - bias-pull-down; - }; - }; }; }; diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-smp2p.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie-smp2p.dtsi new file mode 100644 index 000000000000..f31c53b3506e --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdxprairie-smp2p.dtsi @@ -0,0 +1,132 @@ +/* Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +&soc { + qcom,smp2p-modem@17811008 { + compatible = "qcom,smp2p"; + reg = <0x17811008 0x4>; + qcom,remote-pid = <1>; + qcom,irq-bitmask = <0x4000>; + interrupts = ; + }; + + smp2pgpio_smp2p_15_in: qcom,smp2pgpio-smp2p-15-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <15>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_15_in { + compatible = "qcom,smp2pgpio_test_smp2p_15_in"; + gpios = <&smp2pgpio_smp2p_15_in 0 0>; + }; + + smp2pgpio_smp2p_15_out: qcom,smp2pgpio-smp2p-15-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <15>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_15_out { + compatible = "qcom,smp2pgpio_test_smp2p_15_out"; + gpios = <&smp2pgpio_smp2p_15_out 0 0>; + }; + + smp2pgpio_smp2p_1_in: qcom,smp2pgpio-smp2p-1-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <1>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_1_in { + compatible = "qcom,smp2pgpio_test_smp2p_1_in"; + gpios = <&smp2pgpio_smp2p_1_in 0 0>; + }; + + smp2pgpio_smp2p_1_out: qcom,smp2pgpio-smp2p-1-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <1>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_1_out { + compatible = "qcom,smp2pgpio_test_smp2p_1_out"; + gpios = <&smp2pgpio_smp2p_1_out 0 0>; + }; + + /* ssr - inbound entry from mss */ + smp2pgpio_ssr_smp2p_1_in: qcom,smp2pgpio-ssr-smp2p-1-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "slave-kernel"; + qcom,remote-pid = <1>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + /* ssr - outbound entry to mss */ + smp2pgpio_ssr_smp2p_1_out: qcom,smp2pgpio-ssr-smp2p-1-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "master-kernel"; + qcom,remote-pid = <1>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + /* ipa - outbound entry to mss */ + smp2pgpio_ipa_1_out: qcom,smp2pgpio-ipa-1-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "ipa"; + qcom,remote-pid = <1>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + /* ipa - inbound entry from mss */ + smp2pgpio_ipa_1_in: qcom,smp2pgpio-ipa-1-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "ipa"; + qcom,remote-pid = <1>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; +}; + diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-v2-dsda-cdp.dts b/arch/arm64/boot/dts/qcom/sdxprairie-v2-dsda-cdp.dts index 99e9f86f5f14..271348b2067a 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie-v2-dsda-cdp.dts +++ b/arch/arm64/boot/dts/qcom/sdxprairie-v2-dsda-cdp.dts @@ -22,6 +22,17 @@ qcom,board-id = <0x6010001 0x0>; }; +&soc { + qmi-tmd-devices { + modem { + modem_v2x: modem_v2x { + qcom,qmi-dev-name = "modem_v2x"; + #cooling-cells = <2>; + }; + }; + }; +}; + /* delete pm8150b nodes */ &thermal_zones { /delete-node/ pm8150b-wp-therm; @@ -55,6 +66,51 @@ }; }; }; + + mdm-core-0-v2x-step { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 6>; + thermal-governor = "step_wise"; + wake-capable-sensor; + + trips { + tj_v2x_config0: active-config0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + + tj_v2x_config1: active-config1 { + temperature = <110000>; + hysteresis = <5000>; + type = "passive"; + }; + + tj_v2x_config2: active-config2 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + + cooling-maps { + modem_tj0_v2x_cdev { + trip = <&tj_v2x_config0>; + cooling-device = <&modem_v2x 1 1>; + }; + + modem_tj1_v2x_cdev { + trip = <&tj_v2x_config1>; + cooling-device = <&modem_v2x 2 2>; + }; + + modem_tj2_v2x_cdev { + trip = <&tj_v2x_config2>; + cooling-device = <&modem_v2x 3 3>; + }; + }; + }; }; &usb { @@ -99,3 +155,7 @@ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; + +&mpss_adsp_mem { + reg = <0x90800000 0xf800000>; +}; diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-v2-ttp-cpe.dts b/arch/arm64/boot/dts/qcom/sdxprairie-v2-mtp-au-dsda.dts similarity index 82% rename from arch/arm64/boot/dts/qcom/sdxprairie-v2-ttp-cpe.dts rename to arch/arm64/boot/dts/qcom/sdxprairie-v2-mtp-au-dsda.dts index e8c478d1593b..b81e0dd144ed 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie-v2-ttp-cpe.dts +++ b/arch/arm64/boot/dts/qcom/sdxprairie-v2-mtp-au-dsda.dts @@ -15,9 +15,9 @@ #include "sdxprairie-v2-mtp-cpe.dtsi" / { - model = "Qualcomm Technologies, Inc. SDXPRAIRIE V2 TTP (CPE)"; - compatible = "qcom,sdxprairie-ttp", - "qcom,sdxprairie", "qcom,ttp"; + model = "Qualcomm Technologies, Inc. SDXPRAIRIE V2 AU DSDA"; + compatible = "qcom,sdxprairie-mtp", + "qcom,sdxprairie", "qcom,mtp"; qcom,board-id = <0x08010008 0x0>; }; diff --git a/arch/arm64/boot/dts/qcom/sdxprairie-v2-mtp-le-cpe.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie-v2-mtp-le-cpe.dtsi index 0150fb2eef74..b078b9d38ef0 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie-v2-mtp-le-cpe.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie-v2-mtp-le-cpe.dtsi @@ -37,3 +37,27 @@ status = "disabled"; }; }; + +&cnss_qca6390 { + status = "disabled"; +}; + +&ipa_hw { + qcom,use-ipa-in-mhi-mode; +}; + +&pcie0 { + status = "disabled"; +}; + +&pcie_ep { + status = "ok"; +}; + +&mhi_device { + status = "ok"; +}; + +&mhi_net_device { + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi index 1213da795253..ae83aacc0450 100644 --- a/arch/arm64/boot/dts/qcom/sdxprairie.dtsi +++ b/arch/arm64/boot/dts/qcom/sdxprairie.dtsi @@ -480,6 +480,16 @@ qcom,smem-states = <&modem_smp2p_out 0>; qcom,smem-state-names = "qcom,force-stop"; + /* GPIO intput to mss */ + qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>; + qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_1_in 1 0>; + qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_1_in 2 0>; + qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_1_in 3 0>; + qcom,gpio-shutdown-ack = <&smp2pgpio_ssr_smp2p_1_in 7 0>; + + /* GPIO output to mss */ + qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>; + status = "ok"; }; @@ -1597,10 +1607,6 @@ qcom,status-in-gpio = <&tlmm 64 0x00>; qcom,status-out-gpio = <&tlmm 63 0x00>; qcom,status-out2-gpio = <&tlmm 66 0x00>; - qcom,wakeup-gpio-in = <&tlmm 87 0x00>; - qcom,wakeup-gpio-out = <&tlmm 22 0x00>; - pinctrl-names = "default"; - pinctrl-0 = <&wakeup_gpio_default>; status = "disabled"; }; }; @@ -1619,6 +1625,7 @@ #include "sdxprairie-aqc.dtsi" #include "sdxprairie-thermal.dtsi" #include "sdxprairie-qcom-smmu.dtsi" +#include "sdxprairie-smp2p.dtsi" &gdsc_usb30 { status = "ok"; diff --git a/arch/arm64/boot/dts/qcom/sm6150-qupv3.dtsi b/arch/arm64/boot/dts/qcom/sm6150-qupv3.dtsi index cc6dd19ab227..4a013abe62e3 100644 --- a/arch/arm64/boot/dts/qcom/sm6150-qupv3.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6150-qupv3.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -32,6 +32,7 @@ qcom,bus-mas-id = ; qcom,bus-slv-id = ; qcom,iommu-s1-bypass; + status = "ok"; iommu_qupv3_0_geni_se_cb: qcom,iommu_qupv3_0_geni_se_cb { compatible = "qcom,qupv3-geni-se-cb"; @@ -147,6 +148,7 @@ qcom,bus-mas-id = ; qcom,bus-slv-id = ; qcom,iommu-s1-bypass; + status = "ok"; iommu_qupv3_1_geni_se_cb: qcom,iommu_qupv3_1_geni_se_cb { compatible = "qcom,qupv3-geni-se-cb"; @@ -350,6 +352,11 @@ qcom,bus-mas-id = ; qcom,bus-slv-id = ; qcom,iommu-s1-bypass; + qcom,subsys-name = "adsp"; + clock-names = "corex", "core2x"; + clocks = <&clock_scc SCC_QUPV3_CORE_CLK>, + <&clock_scc SCC_QUPV3_2XCORE_CLK>; + status = "disabled"; iommu_qupv3_2_geni_se_cb: qcom,iommu_qupv3_2_geni_se_cb { compatible = "qcom,qupv3-geni-se-cb"; diff --git a/arch/arm64/boot/dts/qcom/sm8150-qupv3.dtsi b/arch/arm64/boot/dts/qcom/sm8150-qupv3.dtsi index 90d7d8d911ec..99045e871fd0 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-qupv3.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-qupv3.dtsi @@ -20,6 +20,7 @@ qcom,bus-mas-id = ; qcom,bus-slv-id = ; qcom,iommu-s1-bypass; + status = "ok"; iommu_qupv3_0_geni_se_cb: qcom,iommu_qupv3_0_geni_se_cb { compatible = "qcom,qupv3-geni-se-cb"; @@ -385,6 +386,7 @@ qcom,bus-mas-id = ; qcom,bus-slv-id = ; qcom,iommu-s1-bypass; + status = "ok"; iommu_qupv3_1_geni_se_cb: qcom,iommu_qupv3_1_geni_se_cb { compatible = "qcom,qupv3-geni-se-cb"; @@ -713,6 +715,7 @@ qcom,bus-mas-id = ; qcom,bus-slv-id = ; qcom,iommu-s1-bypass; + status = "ok"; iommu_qupv3_2_geni_se_cb: qcom,iommu_qupv3_2_geni_se_cb { compatible = "qcom,qupv3-geni-se-cb"; @@ -981,6 +984,11 @@ qcom,bus-mas-id = ; qcom,bus-slv-id = ; qcom,iommu-s1-bypass; + qcom,subsys-name = "slpi"; + clock-names = "corex", "core2x"; + clocks = <&clock_scc SCC_QUPV3_CORE_CLK>, + <&clock_scc SCC_QUPV3_2XCORE_CLK>; + status = "disabled"; iommu_qupv3_3_geni_se_cb: qcom,iommu_qupv3_3_geni_se_cb { compatible = "qcom,qupv3-geni-se-cb"; diff --git a/arch/arm64/boot/dts/qcom/sm8150-v2.dtsi b/arch/arm64/boot/dts/qcom/sm8150-v2.dtsi index d9da79994ba1..60b5b968a509 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-v2.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150-v2.dtsi @@ -29,6 +29,70 @@ /delete-node/ suspendable-ddr-bw-opp-table; }; +&clock_cpucc { + qcom,cpufreq-table-0 = + < 300000>, + < 403200>, + < 499200>, + < 576000>, + < 672000>, + < 768000>, + < 844800>, + < 940800>, + <1036800>, + <1113600>, + <1209600>, + <1305600>, + <1382400>, + <1478400>, + <1555200>, + <1632000>, + <1708800>, + <1785600>; + + qcom,cpufreq-table-4 = + < 710400>, + < 825600>, + < 940800>, + <1056000>, + <1171200>, + <1286400>, + <1401600>, + <1497600>, + <1612800>, + <1708800>, + <1804800>, + <1920000>, + <2016000>, + <2131200>, + <2227200>, + <2323200>, + <2419200>; + + qcom,cpufreq-table-7 = + < 825600>, + < 940800>, + <1056000>, + <1171200>, + <1286400>, + <1401600>, + <1497600>, + <1612800>, + <1708800>, + <1804800>, + <1920000>, + <2016000>, + <2131200>, + <2227200>, + <2323200>, + <2419200>, + <2534400>, + <2649600>, + <2745600>, + <2841600>, + <2956800>; +}; + &mdss_mdp { qcom,fullsize-va-map; qcom,sde-min-core-ib-kbps = <0>; diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi index e1b09781d813..0ca17d3a3af9 100644 --- a/arch/arm64/boot/dts/qcom/sm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi @@ -550,7 +550,7 @@ }; chosen { - bootargs = "rcu_nocbs=0-7 cgroup.memory=nokmem,nosocket noirqdebug"; + bootargs = "rcu_nocbs=0-7 cgroup.memory=nokmem,nosocket noirqdebug printk.devkmsg=on"; }; soc: soc { }; @@ -1544,6 +1544,56 @@ &cpu7_cpu_l3_lat>; #clock-cells = <1>; + qcom,cpufreq-table-0 = + < 300000>, + < 403200>, + < 480000>, + < 576000>, + < 672000>, + < 768000>, + < 864000>, + < 979200>, + <1075200>, + <1171200>, + <1267200>; + + qcom,cpufreq-table-4 = + < 576000>, + < 672000>, + < 768000>, + < 864000>, + < 960000>, + <1056000>, + <1152000>, + <1248000>, + <1344000>, + <1420800>, + <1497600>, + <1593600>, + <1689600>, + <1785600>, + <1862400>, + <1939200>, + <2016000>; + + qcom,cpufreq-table-7 = + < 691200>, + < 768000>, + < 864000>, + < 940800>, + <1017600>, + <1113600>, + <1190400>, + <1286400>, + <1363200>, + <1459200>, + <1536000>, + <1632000>, + <1728000>, + <1824000>, + <1900800>, + <1977600>, + <2054400>; }; clock_debugcc: qcom,cc-debug { diff --git a/arch/arm64/boot/dts/qcom/trinket-coresight.dtsi b/arch/arm64/boot/dts/qcom/trinket-coresight.dtsi index e991d4159b1a..3c46db0a9c7b 100644 --- a/arch/arm64/boot/dts/qcom/trinket-coresight.dtsi +++ b/arch/arm64/boot/dts/qcom/trinket-coresight.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2219,6 +2219,7 @@ coresight-name = "coresight-cti-gpu_isdb_cti"; + status = "disabled"; clocks = <&clock_rpmcc RPM_SMD_QDSS_CLK>, <&clock_gpucc GPU_CC_CX_APB_CLK>; clock-names = "apb_pclk", "gpu_apb_clk"; diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig index 06859cdcef13..89b667856914 100644 --- a/arch/arm64/configs/cuttlefish_defconfig +++ b/arch/arm64/configs/cuttlefish_defconfig @@ -18,7 +18,6 @@ CONFIG_CPUSETS=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_BPF=y CONFIG_NAMESPACES=y -# CONFIG_PID_NS is not set CONFIG_SCHED_AUTOGROUP=y CONFIG_SCHED_TUNE=y CONFIG_DEFAULT_USE_ENERGY_AWARE=y @@ -62,7 +61,6 @@ CONFIG_SETEND_EMULATION=y CONFIG_ARM64_SW_TTBR0_PAN=y CONFIG_ARM64_LSE_ATOMICS=y CONFIG_RANDOMIZE_BASE=y -# CONFIG_EFI is not set # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_MISC=y CONFIG_COMPAT=y @@ -214,6 +212,7 @@ CONFIG_GNSS_CMDLINE_SERIAL=m CONFIG_OF_UNITTEST=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_VIRTIO_BLK=y @@ -445,6 +444,7 @@ CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y +# CONFIG_EFIVAR_FS is not set CONFIG_SDCARD_FS=y CONFIG_PSTORE=y CONFIG_PSTORE_CONSOLE=y @@ -465,6 +465,8 @@ CONFIG_DEBUG_LIST=y CONFIG_RCU_CPU_STALL_TIMEOUT=60 CONFIG_ENABLE_DEFAULT_TRACERS=y CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y +CONFIG_TEST_MEMINIT=y +CONFIG_TEST_STACKINIT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=65536 diff --git a/arch/arm64/configs/raphael_defconfig b/arch/arm64/configs/raphael_defconfig index 8de98f710767..d304c046bf27 100644 --- a/arch/arm64/configs/raphael_defconfig +++ b/arch/arm64/configs/raphael_defconfig @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 4.14.190 Kernel Configuration +# Linux/arm64 4.14 Kernel Configuration # CONFIG_ARM64=y CONFIG_64BIT=y @@ -48,7 +48,7 @@ CONFIG_THREAD_INFO_IN_TASK=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_CROSS_COMPILE="" # CONFIG_COMPILE_TEST is not set -CONFIG_LOCALVERSION="-iMMENSITY-Mi9FOD" +CONFIG_LOCALVERSION="-IMMENSiTY-MI9FOD" CONFIG_LOCALVERSION_AUTO=y CONFIG_LOCALVERSION_COMMIT_SHA=y CONFIG_DEFAULT_HOSTNAME="(none)" @@ -167,8 +167,14 @@ CONFIG_PID_NS=y CONFIG_NET_NS=y # CONFIG_SCHED_AUTOGROUP is not set CONFIG_SCHED_TUNE=y -# CONFIG_CPUSETS_ASSIST is not set -CONFIG_DYNAMIC_STUNE_BOOST=y +CONFIG_CPUSETS_ASSIST=y +CONFIG_CPUSET_AUDIO_APP="0-3,5-6" +CONFIG_CPUSET_BG="0-1" +CONFIG_CPUSET_CAMERA="0-7" +CONFIG_CPUSET_FG="0-3,5-6" +CONFIG_CPUSET_RESTRICTED="0-3" +CONFIG_CPUSET_SYSTEM_BG="0-3,5-6" +CONFIG_CPUSET_TOP_APP="0-7" CONFIG_DEFAULT_USE_ENERGY_AWARE=y # CONFIG_SYSFS_DEPRECATED is not set # CONFIG_RELAY is not set @@ -179,7 +185,7 @@ CONFIG_RD_GZIP=y # CONFIG_RD_LZMA is not set # CONFIG_RD_XZ is not set # CONFIG_RD_LZO is not set -# CONFIG_RD_LZ4 is not set +CONFIG_RD_LZ4=y CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # CONFIG_GCC_LTO is not set @@ -277,9 +283,10 @@ CONFIG_ARCH_SUPPORTS_THINLTO=y CONFIG_LTO_NONE=y # CONFIG_LTO_CLANG is not set CONFIG_ARCH_SUPPORTS_SHADOW_CALL_STACK=y -CONFIG_ROP_PROTECTION_NONE=y -# CONFIG_SHADOW_CALL_STACK is not set +# CONFIG_ROP_PROTECTION_NONE is not set +CONFIG_SHADOW_CALL_STACK=y # CONFIG_LLVM_POLLY is not set +CONFIG_SHADOW_CALL_STACK_VMAP=y CONFIG_HAVE_CONTEXT_TRACKING=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y @@ -364,8 +371,8 @@ CONFIG_CFQ_GROUP_IOSCHED=y CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_MQ_IOSCHED_DEADLINE=y -CONFIG_MQ_IOSCHED_KYBER=y +# CONFIG_MQ_IOSCHED_DEADLINE is not set +# CONFIG_MQ_IOSCHED_KYBER is not set # CONFIG_IOSCHED_BFQ is not set CONFIG_ASN1=y CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y @@ -543,11 +550,11 @@ CONFIG_HOLES_IN_ZONE=y # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_PREEMPT_COUNT=y -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set -CONFIG_HZ=250 +CONFIG_HZ=100 CONFIG_SCHED_HRTICK=y CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y @@ -582,7 +589,7 @@ CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y # CONFIG_MEMORY_FAILURE is not set # CONFIG_TRANSPARENT_HUGEPAGE is not set # CONFIG_ARCH_WANTS_THP_SWAP is not set -CONFIG_CLEANCACHE=y +# CONFIG_CLEANCACHE is not set # CONFIG_FRONTSWAP is not set CONFIG_CMA=y CONFIG_CMA_AREAS=7 @@ -598,7 +605,7 @@ CONFIG_BALANCE_ANON_FILE_RECLAIM=y CONFIG_ARCH_SUPPORTS_SPECULATIVE_PAGE_FAULT=y CONFIG_SPECULATIVE_PAGE_FAULT=y # CONFIG_HAVE_LOW_MEMORY_KILLER is not set -CONFIG_PROCESS_RECLAIM=y +# CONFIG_PROCESS_RECLAIM is not set # CONFIG_FORCE_ALLOC_FROM_DMA_ZONE is not set CONFIG_ARM64_DMA_USE_IOMMU=y CONFIG_ARM64_DMA_IOMMU_ALIGNMENT=9 @@ -614,13 +621,13 @@ CONFIG_FORCE_MAX_ZONEORDER=11 # CONFIG_HARDEN_BRANCH_PREDICTOR is not set # CONFIG_PRINT_VMEMLAYOUT is not set # CONFIG_ARM64_SSBD is not set -CONFIG_ARM64_TAGGED_ADDR_ABI=y +# CONFIG_ARM64_TAGGED_ADDR_ABI is not set # CONFIG_RODATA_FULL_DEFAULT_ENABLED is not set CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y CONFIG_CP15_BARRIER_EMULATION=y CONFIG_SETEND_EMULATION=y -# CONFIG_ARM64_SW_TTBR0_PAN is not set +CONFIG_ARM64_SW_TTBR0_PAN=y # # ARMv8.1 architectural features @@ -688,7 +695,7 @@ CONFIG_PM=y CONFIG_PM_OPP=y CONFIG_PM_CLK=y CONFIG_PM_GENERIC_DOMAINS=y -CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set CONFIG_PM_GENERIC_DOMAINS_SLEEP=y CONFIG_PM_GENERIC_DOMAINS_OF=y CONFIG_CPU_PM=y @@ -706,12 +713,11 @@ CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y # CONFIG_CPU_IDLE_GOV_LADDER is not set # CONFIG_CPU_IDLE_GOV_MENU is not set -CONFIG_DT_IDLE_STATES=y # # ARM CPU Idle Drivers # -CONFIG_ARM_CPUIDLE=y +# CONFIG_ARM_CPUIDLE is not set # CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set # @@ -733,10 +739,19 @@ CONFIG_CPU_FREQ_GOV_POWERSAVE=y # CONFIG_CPU_FREQ_GOV_USERSPACE is not set # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set # CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set -CONFIG_CPU_BOOST=y +# CONFIG_CPU_BOOST is not set CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_SCHEDUTIL_UP_RATE_LIMIT=5000 +CONFIG_SCHEDUTIL_DOWN_RATE_LIMIT=10000 # CONFIG_CPU_FREQ_GOV_INTERACTIVE is not set -# CONFIG_CPU_INPUT_BOOST is not set +CONFIG_CPU_FREQ_DEFAULT_LITTLE_MIN=1036800 +CONFIG_CPU_FREQ_DEFAULT_BIG_MIN=1056000 +CONFIG_CPU_FREQ_DEFAULT_PRIME_MIN=1171200 +CONFIG_CPU_INPUT_BOOST=y +CONFIG_WAKE_BOOST_DURATION_MS=1000 +CONFIG_MAX_BOOST_FREQ_LP=1785600 +CONFIG_MAX_BOOST_FREQ_PERF=2323200 +CONFIG_MAX_BOOST_FREQ_PERFP=2649600 # # CPU frequency scaling drivers @@ -929,7 +944,7 @@ CONFIG_NETFILTER_XT_TARGET_CONNMARK=y CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y CONFIG_NETFILTER_XT_TARGET_CT=y CONFIG_NETFILTER_XT_TARGET_DSCP=y -# CONFIG_NETFILTER_XT_TARGET_HL is not set +CONFIG_NETFILTER_XT_TARGET_HL=y # CONFIG_NETFILTER_XT_TARGET_HMARK is not set CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y @@ -1055,7 +1070,7 @@ CONFIG_IP6_NF_IPTABLES=y # CONFIG_IP6_NF_MATCH_EUI64 is not set # CONFIG_IP6_NF_MATCH_FRAG is not set # CONFIG_IP6_NF_MATCH_OPTS is not set -# CONFIG_IP6_NF_MATCH_HL is not set +CONFIG_IP6_NF_MATCH_HL=y # CONFIG_IP6_NF_MATCH_IPV6HEADER is not set # CONFIG_IP6_NF_MATCH_MH is not set CONFIG_IP6_NF_MATCH_RPFILTER=y @@ -1147,7 +1162,7 @@ CONFIG_NET_SCH_NETEM=y CONFIG_NET_SCH_FQ_CODEL=y # CONFIG_NET_SCH_FQ is not set # CONFIG_NET_SCH_HHF is not set -CONFIG_NET_SCH_PIE=y +# CONFIG_NET_SCH_PIE is not set CONFIG_NET_SCH_INGRESS=y # CONFIG_NET_SCH_PLUG is not set CONFIG_NET_SCH_DEFAULT=y @@ -1215,7 +1230,7 @@ CONFIG_QRTR=y CONFIG_QRTR_NODE_ID=1 CONFIG_QRTR_SMD=y # CONFIG_QRTR_USB is not set -# CONFIG_QRTR_FIFO is not set +CONFIG_QRTR_FIFO=y # CONFIG_NET_NCSI is not set # CONFIG_RMNET_DATA is not set # CONFIG_RMNET_USB is not set @@ -1393,7 +1408,7 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_NULL_BLK is not set CONFIG_ZRAM=y CONFIG_ZRAM_WRITEBACK=y -CONFIG_ZRAM_DEFAULT_COMP_ALGORITHM="lz4" +CONFIG_ZRAM_DEFAULT_COMP_ALGORITHM="zstd" CONFIG_ZRAM_SIZE_OVERRIDE=2 # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y @@ -1516,7 +1531,7 @@ CONFIG_SCSI=y CONFIG_SCSI_DMA=y # CONFIG_SCSI_NETLINK is not set # CONFIG_SCSI_MQ_DEFAULT is not set -CONFIG_SCSI_PROC_FS=y +# CONFIG_SCSI_PROC_FS is not set # # SCSI support type (disk, tape, CD-ROM) @@ -1583,13 +1598,13 @@ CONFIG_DM_VERITY_FEC=y # CONFIG_DM_LOG_WRITES is not set # CONFIG_DM_INTEGRITY is not set # CONFIG_DM_VERITY_AVB is not set -# CONFIG_DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED is not set -CONFIG_DM_BOW=y +CONFIG_DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED=y +# CONFIG_DM_BOW is not set # CONFIG_TARGET_CORE is not set CONFIG_NETDEVICES=y CONFIG_MII=y CONFIG_NET_CORE=y -CONFIG_BONDING=y +# CONFIG_BONDING is not set CONFIG_DUMMY=y # CONFIG_EQUALIZER is not set # CONFIG_IFB is not set @@ -1702,14 +1717,14 @@ CONFIG_PPP_BSDCOMP=y CONFIG_PPP_DEFLATE=y CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=y -CONFIG_PPP_MULTILINK=y -CONFIG_PPPOE=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPPOE is not set CONFIG_PPTP=y CONFIG_PPPOL2TP=y CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y -CONFIG_PPP_ASYNC=y -CONFIG_PPP_SYNC_TTY=y +# CONFIG_PPP_ASYNC is not set +# CONFIG_PPP_SYNC_TTY is not set # CONFIG_SLIP is not set CONFIG_SLHC=y CONFIG_USB_NET_DRIVERS=y @@ -1751,10 +1766,7 @@ CONFIG_USB_NET_CDC_NCM=y CONFIG_WLAN=y # CONFIG_WIRELESS_WDS is not set # CONFIG_WLAN_VENDOR_ADMTEK is not set -CONFIG_WLAN_VENDOR_ATH=y -# CONFIG_ATH_DEBUG is not set -# CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS is not set -# CONFIG_ATH6KL is not set +# CONFIG_WLAN_VENDOR_ATH is not set # CONFIG_WLAN_VENDOR_ATMEL is not set # CONFIG_WLAN_VENDOR_BROADCOM is not set # CONFIG_WLAN_VENDOR_CISCO is not set @@ -1806,7 +1818,7 @@ CONFIG_INPUT_POLLDEV=y # Userland interfaces # # CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_JOYDEV=y CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_EVBUG is not set # CONFIG_INPUT_KEYRESET is not set @@ -2009,7 +2021,7 @@ CONFIG_UNIX98_PTYS=y # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_N_GSM is not set # CONFIG_TRACE_SINK is not set -CONFIG_LDISC_AUTOLOAD=y +# CONFIG_LDISC_AUTOLOAD is not set # CONFIG_DEVMEM is not set # @@ -2060,8 +2072,6 @@ CONFIG_HW_RANDOM_MSM_LEGACY=y # # Diag Support # -CONFIG_DIAG_CHAR=y -CONFIG_DIAG_OVER_USB=y CONFIG_MSM_FASTCVPD=y CONFIG_MSM_ADSPRPC=y # CONFIG_MSM_RDBG is not set @@ -2280,8 +2290,8 @@ CONFIG_POWER_RESET=y CONFIG_POWER_RESET_QCOM=y # CONFIG_QCOM_DLOAD_MODE is not set # CONFIG_POWER_RESET_RESTART is not set -CONFIG_POWER_RESET_XGENE=y -CONFIG_POWER_RESET_SYSCON=y +# CONFIG_POWER_RESET_XGENE is not set +# CONFIG_POWER_RESET_SYSCON is not set # CONFIG_POWER_RESET_SYSCON_POWEROFF is not set # CONFIG_SYSCON_REBOOT_MODE is not set CONFIG_POWER_SUPPLY=y @@ -2643,7 +2653,7 @@ CONFIG_REGULATOR_PROXY_CONSUMER=y # CONFIG_REGULATOR_PV88090 is not set # CONFIG_REGULATOR_PWM is not set # CONFIG_REGULATOR_QCOM_SPMI is not set -CONFIG_REGULATOR_QPNP_AMOLED=y +# CONFIG_REGULATOR_QPNP_AMOLED is not set # CONFIG_REGULATOR_QPNP_LABIBB is not set CONFIG_REGULATOR_QPNP_LCDB=y # CONFIG_REGULATOR_QPNP_OLEDB is not set @@ -2745,43 +2755,132 @@ CONFIG_MSM_NPU=y # # Media ancillary drivers (tuners, sensors, i2c, spi, frontends) # -CONFIG_MEDIA_SUBDRV_AUTOSELECT=y +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set + +# +# I2C Encoders, decoders, sensors and other helper chips +# # # Audio decoders, processors and mixers # +# CONFIG_VIDEO_TVAUDIO is not set +# CONFIG_VIDEO_TDA7432 is not set +# CONFIG_VIDEO_TDA9840 is not set +# CONFIG_VIDEO_TEA6415C is not set +# CONFIG_VIDEO_TEA6420 is not set +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_CS3308 is not set +# CONFIG_VIDEO_CS5345 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_UDA1342 is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_VP27SMPX is not set +# CONFIG_VIDEO_SONY_BTF_MPX is not set # # RDS decoders # +# CONFIG_VIDEO_SAA6588 is not set # # Video decoders # +# CONFIG_VIDEO_ADV7180 is not set +# CONFIG_VIDEO_ADV7183 is not set +# CONFIG_VIDEO_ADV748X is not set +# CONFIG_VIDEO_ADV7604 is not set +# CONFIG_VIDEO_ADV7842 is not set +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_ML86V7667 is not set +# CONFIG_VIDEO_AD5820 is not set +# CONFIG_VIDEO_DW9714 is not set +# CONFIG_VIDEO_SAA7110 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_TC358743 is not set +# CONFIG_VIDEO_TVP514X is not set +# CONFIG_VIDEO_TVP5150 is not set +# CONFIG_VIDEO_TVP7002 is not set +# CONFIG_VIDEO_TW2804 is not set +# CONFIG_VIDEO_TW9903 is not set +# CONFIG_VIDEO_TW9906 is not set +# CONFIG_VIDEO_VPX3220 is not set # # Video and audio decoders # +# CONFIG_VIDEO_SAA717X is not set +# CONFIG_VIDEO_CX25840 is not set # # Video encoders # +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set +# CONFIG_VIDEO_ADV7343 is not set +# CONFIG_VIDEO_ADV7393 is not set +# CONFIG_VIDEO_ADV7511 is not set +# CONFIG_VIDEO_AD9389B is not set +# CONFIG_VIDEO_AK881X is not set +# CONFIG_VIDEO_THS8200 is not set # # Camera sensor devices # +# CONFIG_VIDEO_OV2640 is not set +# CONFIG_VIDEO_OV2659 is not set +# CONFIG_VIDEO_OV5640 is not set +# CONFIG_VIDEO_OV5645 is not set +# CONFIG_VIDEO_OV5647 is not set +# CONFIG_VIDEO_OV6650 is not set +# CONFIG_VIDEO_OV5670 is not set +# CONFIG_VIDEO_OV7640 is not set +# CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_OV9650 is not set +# CONFIG_VIDEO_OV13858 is not set +# CONFIG_VIDEO_VS6624 is not set +# CONFIG_VIDEO_MT9M032 is not set +# CONFIG_VIDEO_MT9M111 is not set +# CONFIG_VIDEO_MT9P031 is not set +# CONFIG_VIDEO_MT9T001 is not set +# CONFIG_VIDEO_MT9V011 is not set +# CONFIG_VIDEO_MT9V032 is not set +# CONFIG_VIDEO_SR030PC30 is not set +# CONFIG_VIDEO_NOON010PC30 is not set +# CONFIG_VIDEO_M5MOLS is not set +# CONFIG_VIDEO_S5K6AA is not set +# CONFIG_VIDEO_S5K6A3 is not set +# CONFIG_VIDEO_S5K4ECGX is not set +# CONFIG_VIDEO_S5K5BAF is not set +# CONFIG_VIDEO_SMIAPP is not set +# CONFIG_VIDEO_ET8EK8 is not set +# CONFIG_VIDEO_S5C73M3 is not set # # Flash devices # +# CONFIG_VIDEO_ADP1653 is not set +# CONFIG_VIDEO_AS3645A is not set +# CONFIG_VIDEO_LM3560 is not set +# CONFIG_VIDEO_LM3646 is not set # # Video improvement chips # +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set # # Audio/Video compression chips # +# CONFIG_VIDEO_SAA6752HS is not set # # SDR tuner chips @@ -2790,11 +2889,22 @@ CONFIG_MEDIA_SUBDRV_AUTOSELECT=y # # Miscellaneous helper chips # +# CONFIG_VIDEO_THS7303 is not set +# CONFIG_VIDEO_M52790 is not set # # Sensors used on soc_camera driver # +# +# SPI helper chips +# +# CONFIG_VIDEO_GS1662 is not set + +# +# Customise DVB Frontends +# + # # Tools to develop new frontends # @@ -2831,7 +2941,7 @@ CONFIG_DRM_MSM=y # CONFIG_DRM_MSM_HDMI is not set # CONFIG_DRM_MSM_DSI is not set CONFIG_DRM_MSM_DSI_STAGING=y -# CONFIG_DSI_PARSER is not set +CONFIG_DSI_PARSER=y # CONFIG_DRM_MSM_MDP5 is not set # CONFIG_DRM_MSM_MDP4 is not set # CONFIG_DRM_MSM_HDCP is not set @@ -2933,7 +3043,7 @@ CONFIG_FB_NOTIFY=y CONFIG_BACKLIGHT_LCD_SUPPORT=y # CONFIG_LCD_CLASS_DEVICE is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_BACKLIGHT_GENERIC=y +# CONFIG_BACKLIGHT_GENERIC is not set # CONFIG_BACKLIGHT_PWM is not set # CONFIG_BACKLIGHT_PM8941_WLED is not set CONFIG_BACKLIGHT_QCOM_SPMI_WLED=y @@ -2966,9 +3076,9 @@ CONFIG_SND_PCM_TIMER=y # CONFIG_SND_HRTIMER is not set CONFIG_SND_DYNAMIC_MINORS=y CONFIG_SND_MAX_CARDS=32 -CONFIG_SND_SUPPORT_OLD_API=y +# CONFIG_SND_SUPPORT_OLD_API is not set CONFIG_SND_PROC_FS=y -CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PROCFS is not set # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set # CONFIG_SND_SEQUENCER is not set @@ -3144,7 +3254,7 @@ CONFIG_HID_GENERIC=y # CONFIG_HID_A4TECH is not set # CONFIG_HID_ACCUTOUCH is not set # CONFIG_HID_ACRUX is not set -CONFIG_HID_APPLE=y +# CONFIG_HID_APPLE is not set # CONFIG_HID_APPLEIR is not set # CONFIG_HID_ASUS is not set # CONFIG_HID_AUREAL is not set @@ -3156,10 +3266,9 @@ CONFIG_HID_APPLE=y # CONFIG_HID_PRODIKEYS is not set # CONFIG_HID_CMEDIA is not set # CONFIG_HID_CYPRESS is not set -CONFIG_HID_DRAGONRISE=y -# CONFIG_DRAGONRISE_FF is not set +# CONFIG_HID_DRAGONRISE is not set # CONFIG_HID_EMS_FF is not set -CONFIG_HID_ELECOM=y +# CONFIG_HID_ELECOM is not set # CONFIG_HID_ELO is not set # CONFIG_HID_EZKEY is not set # CONFIG_HID_GEMBIRD is not set @@ -3179,21 +3288,20 @@ CONFIG_HID_ELECOM=y # CONFIG_HID_LED is not set # CONFIG_HID_LENOVO is not set # CONFIG_HID_LOGITECH is not set -CONFIG_HID_MAGICMOUSE=y +# CONFIG_HID_MAGICMOUSE is not set # CONFIG_HID_MAYFLASH is not set -CONFIG_HID_MICROSOFT=y +# CONFIG_HID_MICROSOFT is not set # CONFIG_HID_MONTEREY is not set -CONFIG_HID_MULTITOUCH=y +# CONFIG_HID_MULTITOUCH is not set # CONFIG_HID_NINTENDO is not set # CONFIG_HID_NTI is not set # CONFIG_HID_NTRIG is not set # CONFIG_HID_ORTEK is not set -CONFIG_HID_PANTHERLORD=y -# CONFIG_PANTHERLORD_FF is not set +# CONFIG_HID_PANTHERLORD is not set # CONFIG_HID_PENMOUNT is not set # CONFIG_HID_PETALYNX is not set # CONFIG_HID_PICOLCD is not set -CONFIG_HID_PLANTRONICS=y +# CONFIG_HID_PLANTRONICS is not set # CONFIG_HID_PRIMAX is not set # CONFIG_HID_RETRODE is not set # CONFIG_HID_ROCCAT is not set @@ -3220,7 +3328,7 @@ CONFIG_HID_STEAM=y # CONFIG_HID_ZYDACRON is not set # CONFIG_HID_SENSOR_HUB is not set # CONFIG_HID_ALPS is not set -CONFIG_HID_QVR=y +# CONFIG_HID_QVR is not set # # USB HID support @@ -3345,14 +3453,14 @@ CONFIG_USB_DWC3_MSM=y # CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set -CONFIG_USB_EHSET_TEST_FIXTURE=y +# CONFIG_USB_EHSET_TEST_FIXTURE is not set # CONFIG_USB_ISIGHTFW is not set # CONFIG_USB_YUREX is not set # CONFIG_USB_EZUSB_FX2 is not set # CONFIG_USB_HUB_USB251XB is not set # CONFIG_USB_HSIC_USB3503 is not set # CONFIG_USB_HSIC_USB4604 is not set -CONFIG_USB_LINK_LAYER_TEST=y +# CONFIG_USB_LINK_LAYER_TEST is not set # CONFIG_USB_CHAOSKEY is not set # CONFIG_USB_REDRIVER_NB7VPQ904M is not set # CONFIG_USB_TYPEC_MUX_NXP5150A is not set @@ -3372,7 +3480,7 @@ CONFIG_NOP_USB_XCEIV=y # CONFIG_USB_MSM_OTG is not set # CONFIG_USB_MSM_SSPHY is not set # CONFIG_USB_QCOM_8X16_PHY is not set -CONFIG_USB_QCOM_EMU_PHY=y +# CONFIG_USB_QCOM_EMU_PHY is not set CONFIG_USB_MSM_SSPHY_QMP=y # CONFIG_MSM_QUSB_PHY is not set CONFIG_MSM_HSUSB_PHY=y @@ -3405,16 +3513,15 @@ CONFIG_USB_U_ETHER=y CONFIG_USB_U_AUDIO=y CONFIG_USB_F_NCM=y CONFIG_USB_RNDIS=y +CONFIG_USB_F_RNDIS=y CONFIG_USB_F_MASS_STORAGE=y CONFIG_USB_F_FS=y CONFIG_USB_F_UAC2=y CONFIG_USB_F_MIDI=y -CONFIG_USB_F_HID=y CONFIG_USB_F_MTP=y CONFIG_USB_F_PTP=y CONFIG_USB_F_AUDIO_SRC=y CONFIG_USB_F_ACC=y -CONFIG_USB_F_DIAG=y CONFIG_USB_F_CDEV=y CONFIG_USB_F_CCID=y CONFIG_USB_F_GSI=y @@ -3427,7 +3534,7 @@ CONFIG_USB_CONFIGFS_NCM=y # CONFIG_USB_CONFIGFS_ECM is not set # CONFIG_USB_CONFIGFS_ECM_SUBSET is not set # CONFIG_USB_CONFIGFS_QCRNDIS is not set -# CONFIG_USB_CONFIGFS_RNDIS is not set +CONFIG_USB_CONFIGFS_RNDIS=y # CONFIG_USB_CONFIGFS_RMNET_BAM is not set # CONFIG_USB_CONFIGFS_MBIM_BAM is not set # CONFIG_USB_CONFIGFS_EEM is not set @@ -3443,10 +3550,10 @@ CONFIG_USB_CONFIGFS_UEVENT=y # CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set CONFIG_USB_CONFIGFS_F_UAC2=y CONFIG_USB_CONFIGFS_F_MIDI=y -CONFIG_USB_CONFIGFS_F_HID=y +# CONFIG_USB_CONFIGFS_F_HID is not set # CONFIG_USB_CONFIGFS_F_UVC is not set # CONFIG_USB_CONFIGFS_F_PRINTER is not set -CONFIG_USB_CONFIGFS_F_DIAG=y +# CONFIG_USB_CONFIGFS_F_DIAG is not set CONFIG_USB_CONFIGFS_F_CDEV=y CONFIG_USB_CONFIGFS_F_CCID=y CONFIG_USB_CONFIGFS_F_GSI=y @@ -3789,11 +3896,10 @@ CONFIG_STAGING=y CONFIG_ASHMEM=y # CONFIG_ANDROID_LOW_MEMORY_KILLER is not set CONFIG_ION=y -CONFIG_ION_SYSTEM_HEAP=y +# CONFIG_ION_SYSTEM_HEAP is not set # CONFIG_ION_CARVEOUT_HEAP is not set # CONFIG_ION_CHUNK_HEAP is not set # CONFIG_ION_CMA_HEAP is not set -# CONFIG_ION_FORCE_DMA_SYNC is not set # CONFIG_ION_DEFER_FREE_NO_SCHED_IDLE is not set CONFIG_ALLOC_BUFFERS_IN_4K_CHUNKS=y # CONFIG_STAGING_BOARD is not set @@ -3816,13 +3922,6 @@ CONFIG_ALLOC_BUFFERS_IN_4K_CHUNKS=y # CONFIG_QCA_CLD_WLAN=y CONFIG_QCA_CLD_WLAN_PROFILE="default" -CONFIG_STAGING_EXFAT_FS=y -CONFIG_STAGING_EXFAT_DISCARD=y -# CONFIG_STAGING_EXFAT_DELAYED_SYNC is not set -# CONFIG_STAGING_EXFAT_KERNEL_DEBUG is not set -# CONFIG_STAGING_EXFAT_DEBUG_MSG is not set -CONFIG_STAGING_EXFAT_DEFAULT_CODEPAGE=437 -CONFIG_STAGING_EXFAT_DEFAULT_IOCHARSET="utf8" # CONFIG_GOLDFISH is not set # CONFIG_CHROME_PLATFORMS is not set @@ -3840,6 +3939,7 @@ CONFIG_USB_BAM=y # CONFIG_VETH_IPA is not set CONFIG_GSI=y # CONFIG_GSI_REGISTER_VERSION_2 is not set +# CONFIG_GSI_DEBUG is not set CONFIG_IPA3=y # CONFIG_IPA is not set # CONFIG_IPA_DEBUG is not set @@ -3868,7 +3968,7 @@ CONFIG_COMMON_CLK=y # CONFIG_COMMON_CLK_CDCE925 is not set # CONFIG_COMMON_CLK_CS2000_CP is not set # CONFIG_CLK_QORIQ is not set -CONFIG_COMMON_CLK_XGENE=y +# CONFIG_COMMON_CLK_XGENE is not set # CONFIG_COMMON_CLK_NXP is not set # CONFIG_COMMON_CLK_PWM is not set # CONFIG_COMMON_CLK_PXA is not set @@ -4085,10 +4185,7 @@ CONFIG_MSM_PIL=y CONFIG_MSM_SYSMON_QMI_COMM=y CONFIG_MSM_PIL_SSR_GENERIC=y # CONFIG_MSM_PIL_MSS_QDSP6V5 is not set -CONFIG_SETUP_SSR_NOTIF_TIMEOUTS=y -CONFIG_SSR_SYSMON_NOTIF_TIMEOUT=20000 -CONFIG_SSR_SUBSYS_NOTIF_TIMEOUT=20000 -CONFIG_PANIC_ON_SSR_NOTIF_TIMEOUT=y +# CONFIG_SETUP_SSR_NOTIF_TIMEOUTS is not set CONFIG_MSM_BOOT_STATS=y # CONFIG_MSM_BOOT_TIME_MARKER is not set # CONFIG_MSM_CORE_HANG_DETECT is not set @@ -4117,9 +4214,9 @@ CONFIG_QSEE_IPC_IRQ_BRIDGE=y CONFIG_QCOM_GLINK=y CONFIG_QCOM_GLINK_PKT=y # CONFIG_MSM_JTAGV8 is not set -CONFIG_QTI_RPM_STATS_LOG=y +# CONFIG_QTI_RPM_STATS_LOG is not set CONFIG_MSM_CDSP_LOADER=y -CONFIG_QCOM_SMCINVOKE=y +# CONFIG_QCOM_SMCINVOKE is not set CONFIG_MSM_EVENT_TIMER=y # CONFIG_MSM_AVTIMER is not set CONFIG_MSM_PM=y @@ -4136,8 +4233,8 @@ CONFIG_MEM_SHARE_QMI_SERVICE=y # CONFIG_MSM_HAB is not set # CONFIG_MSM_AGL is not set # CONFIG_QCOM_HGSL_TCSR_SIGNAL is not set -CONFIG_MSM_PERFORMANCE=y -CONFIG_QCOM_QHEE_ENABLE_MEM_PROTECTION=y +# CONFIG_MSM_PERFORMANCE is not set +# CONFIG_QCOM_QHEE_ENABLE_MEM_PROTECTION is not set CONFIG_QCOM_SMP2P_SLEEPSTATE=y CONFIG_QCOM_CDSP_RM=y # CONFIG_QCOM_CX_IPEAK is not set @@ -4148,6 +4245,7 @@ CONFIG_QCOM_AOP_DDRSS_COMMANDS=y # CONFIG_MSM_BGCOM is not set # CONFIG_MSM_PIL_SSR_BG is not set CONFIG_QCOM_SOC_INFO=y +# CONFIG_RENAME_BLOCK_DEVICE is not set # CONFIG_WCNSS_CORE is not set # CONFIG_SUNXI_SRAM is not set # CONFIG_SOC_TI is not set @@ -4646,7 +4744,7 @@ CONFIG_DCACHE_WORD_ACCESS=y # CONFIG_EXT3_FS is not set CONFIG_EXT4_FS=y CONFIG_EXT4_USE_FOR_EXT2=y -# CONFIG_EXT4_FS_POSIX_ACL is not set +CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y CONFIG_EXT4_ENCRYPTION=y CONFIG_EXT4_FS_ENCRYPTION=y @@ -4671,6 +4769,9 @@ CONFIG_F2FS_FS_SECURITY=y CONFIG_F2FS_FS_ENCRYPTION=y # CONFIG_F2FS_FAULT_INJECTION is not set # CONFIG_F2FS_FS_COMPRESSION is not set +CONFIG_F2FS_REPORT_FAKE_KERNEL_VERSION=y +CONFIG_F2FS_FAKE_KERNEL_RELEASE="4.14.117-perf-g2146d60" +CONFIG_F2FS_FAKE_KERNEL_VERSION="#1 SMP PREEMPT Mon Apr 27 03:21:17 CST 2020" # CONFIG_FS_DAX is not set CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y @@ -4828,9 +4929,12 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_MAC_TURKISH is not set CONFIG_NLS_UTF8=y # CONFIG_DLM is not set -CONFIG_UNICODE=y -# CONFIG_UNICODE_NORMALIZATION_SELFTEST is not set +# CONFIG_UNICODE is not set # CONFIG_FILE_TABLE_DEBUG is not set +CONFIG_EXFAT_FS=y +CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" +CONFIG_EXFAT_VIRTUAL_XATTR=y +CONFIG_EXFAT_VIRTUAL_XATTR_SELINUX_LABEL="u:object_r:exfat:s0" # CONFIG_VIRTUALIZATION is not set # @@ -4893,7 +4997,7 @@ CONFIG_CC_HAS_SANCOV_TRACE_PC=y # CONFIG_PANIC_ON_OOPS is not set CONFIG_PANIC_ON_OOPS_VALUE=0 CONFIG_PANIC_TIMEOUT=-1 -CONFIG_SCHED_DEBUG=y +# CONFIG_SCHED_DEBUG is not set # CONFIG_SCHED_INFO is not set # CONFIG_PANIC_ON_SCHED_BUG is not set # CONFIG_PANIC_ON_RT_THROTTLING is not set @@ -4918,7 +5022,6 @@ CONFIG_DEBUG_BUGVERBOSE=y CONFIG_RCU_CPU_STALL_TIMEOUT=21 CONFIG_RCU_PANIC_ON_STALL=0 CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y @@ -4978,7 +5081,7 @@ CONFIG_KEYS_COMPAT=y # CONFIG_PFT is not set CONFIG_PFK=y CONFIG_PFK_WRAPPED_KEY_SUPPORTED=y -# CONFIG_SECURITY_DMESG_RESTRICT is not set +CONFIG_SECURITY_DMESG_RESTRICT=y CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y # CONFIG_SECURITY_WRITABLE_HOOKS is not set @@ -4996,9 +5099,10 @@ CONFIG_SECURITY_SELINUX=y # CONFIG_SECURITY_SELINUX_BOOTPARAM is not set # CONFIG_SECURITY_SELINUX_DISABLE is not set CONFIG_SECURITY_SELINUX_DEVELOP=y -CONFIG_SECURITY_SELINUX_AVC_STATS=y +# CONFIG_SECURITY_SELINUX_AVC_STATS is not set CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=0 CONFIG_SECURITY_SELINUX_SIDTAB_HASH_BITS=9 +CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE=256 # CONFIG_SECURITY_SMACK is not set # CONFIG_SECURITY_TOMOYO is not set # CONFIG_SECURITY_APPARMOR is not set @@ -5148,8 +5252,8 @@ CONFIG_CRYPTO_ZSTD=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_CRYPTO_DRBG_MENU=y CONFIG_CRYPTO_DRBG_HMAC=y -CONFIG_CRYPTO_DRBG_HASH=y -CONFIG_CRYPTO_DRBG_CTR=y +# CONFIG_CRYPTO_DRBG_HASH is not set +# CONFIG_CRYPTO_DRBG_CTR is not set CONFIG_CRYPTO_DRBG=y CONFIG_CRYPTO_JITTERENTROPY=y # CONFIG_CRYPTO_USER_API_HASH is not set @@ -5227,6 +5331,7 @@ CONFIG_ZSTD_DECOMPRESS=y # CONFIG_XZ_DEC is not set # CONFIG_XZ_DEC_BCJ is not set CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_LZ4=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_REED_SOLOMON=y CONFIG_REED_SOLOMON_ENC8=y diff --git a/arch/arm64/configs/vendor/atoll-perf_defconfig b/arch/arm64/configs/vendor/atoll-perf_defconfig index fec102ee0204..7268935d0211 100644 --- a/arch/arm64/configs/vendor/atoll-perf_defconfig +++ b/arch/arm64/configs/vendor/atoll-perf_defconfig @@ -292,6 +292,7 @@ CONFIG_NETDEVICES=y CONFIG_BONDING=y CONFIG_DUMMY=y CONFIG_TUN=y +CONFIG_VETH=y CONFIG_SKY2=y CONFIG_RMNET=y CONFIG_SMSC911X=y @@ -670,6 +671,7 @@ CONFIG_ESOC_MDM_DRV=y CONFIG_ESOC_MDM_DBG_ENG=y CONFIG_MSM_TZ_LOG=y CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y CONFIG_EXT4_ENCRYPTION=y CONFIG_EXT4_FS_ENCRYPTION=y @@ -677,11 +679,14 @@ CONFIG_EXT4_FS_ICE_ENCRYPTION=y CONFIG_F2FS_FS=y CONFIG_F2FS_FS_SECURITY=y CONFIG_F2FS_FS_ENCRYPTION=y +CONFIG_FS_VERITY=y +CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_OVERLAY_FS=y +CONFIG_INCREMENTAL_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS_POSIX_ACL=y @@ -720,7 +725,6 @@ CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SMACK=y CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_XCBC=y -CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_TWOFISH=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y diff --git a/arch/arm64/configs/vendor/atoll_defconfig b/arch/arm64/configs/vendor/atoll_defconfig index b9f29521b8f3..571da08e467a 100644 --- a/arch/arm64/configs/vendor/atoll_defconfig +++ b/arch/arm64/configs/vendor/atoll_defconfig @@ -303,6 +303,7 @@ CONFIG_NETDEVICES=y CONFIG_BONDING=y CONFIG_DUMMY=y CONFIG_TUN=y +CONFIG_VETH=y CONFIG_RMNET=y CONFIG_AT803X_PHY=y CONFIG_MICREL_PHY=y @@ -701,6 +702,7 @@ CONFIG_ESOC_MDM_DRV=y CONFIG_ESOC_MDM_DBG_ENG=y CONFIG_MSM_TZ_LOG=y CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y CONFIG_EXT4_ENCRYPTION=y CONFIG_EXT4_FS_ENCRYPTION=y @@ -708,11 +710,14 @@ CONFIG_EXT4_FS_ICE_ENCRYPTION=y CONFIG_F2FS_FS=y CONFIG_F2FS_FS_SECURITY=y CONFIG_F2FS_FS_ENCRYPTION=y +CONFIG_FS_VERITY=y +CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_OVERLAY_FS=y +CONFIG_INCREMENTAL_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS_POSIX_ACL=y @@ -808,7 +813,6 @@ CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SMACK=y CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_XCBC=y -CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_TWOFISH=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y diff --git a/arch/arm64/configs/vendor/debugfs.config b/arch/arm64/configs/vendor/debugfs.config new file mode 100644 index 000000000000..059013b6a88a --- /dev/null +++ b/arch/arm64/configs/vendor/debugfs.config @@ -0,0 +1,2 @@ +CONFIG_PAGE_OWNER=n +CONFIG_DEBUG_FS=n diff --git a/arch/arm64/configs/vendor/sa2150p-nand_defconfig b/arch/arm64/configs/vendor/sa2150p-nand_defconfig index 1f8ddc2423f6..e35d9fe9cf9c 100644 --- a/arch/arm64/configs/vendor/sa2150p-nand_defconfig +++ b/arch/arm64/configs/vendor/sa2150p-nand_defconfig @@ -6,7 +6,6 @@ CONFIG_HIGH_RES_TIMERS=y CONFIG_IRQ_TIME_ACCOUNTING=y CONFIG_SCHED_WALT=y CONFIG_TASKSTATS=y -CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y CONFIG_RCU_EXPERT=y @@ -20,7 +19,6 @@ CONFIG_RT_GROUP_SCHED=y CONFIG_CGROUP_FREEZER=y CONFIG_CPUSETS=y CONFIG_CGROUP_CPUACCT=y -CONFIG_CGROUP_DEBUG=y CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set # CONFIG_PID_NS is not set @@ -47,9 +45,7 @@ CONFIG_PCI_MSM=y CONFIG_PCI_MSM_MSI=y CONFIG_NR_CPUS=4 CONFIG_PREEMPT=y -CONFIG_CLEANCACHE=y CONFIG_CMA=y -CONFIG_CMA_DEBUGFS=y CONFIG_ZSMALLOC=y CONFIG_SECCOMP=y # CONFIG_HARDEN_BRANCH_PREDICTOR is not set @@ -66,7 +62,6 @@ CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set -CONFIG_PM_DEBUG=y CONFIG_CPU_IDLE=y CONFIG_ARM_CPUIDLE=y CONFIG_CPU_FREQ=y @@ -187,7 +182,6 @@ CONFIG_BRIDGE_EBT_ARPREPLY=y CONFIG_BRIDGE_EBT_DNAT=y CONFIG_BRIDGE_EBT_SNAT=y CONFIG_L2TP=y -CONFIG_L2TP_DEBUGFS=y CONFIG_L2TP_V3=y CONFIG_L2TP_IP=y CONFIG_L2TP_ETH=y @@ -282,11 +276,9 @@ CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=y CONFIG_I2C_MSM_V2=y CONFIG_SPI=y -CONFIG_SPI_DEBUG=y CONFIG_SPI_QUP=y CONFIG_SPI_SPIDEV=y CONFIG_SPMI=y -CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y CONFIG_SLIMBUS=y CONFIG_SLIMBUS_MSM_NGD=y CONFIG_PPS_CLIENT_GPIO=y @@ -321,7 +313,6 @@ CONFIG_REGULATOR_SPM=y CONFIG_REGULATOR_STUB=y # CONFIG_RC_CORE is not set # CONFIG_VGA_ARB is not set -# CONFIG_DSI_PARSER is not set CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_DYNAMIC_MINORS=y @@ -347,8 +338,6 @@ CONFIG_USB_MSM_SSPHY=y CONFIG_USB_QCOM_EMU_PHY=y CONFIG_DUAL_ROLE_USB_INTF=y CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_DEBUG_FILES=y -CONFIG_USB_GADGET_DEBUG_FS=y CONFIG_USB_GADGET_VBUS_DRAW=900 CONFIG_USB_CONFIGFS=y CONFIG_USB_CONFIGFS_F_FS=y @@ -358,7 +347,6 @@ CONFIG_MMC_PERF_PROFILING=y CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_BLOCK_DEFERRED_RESUME=y CONFIG_MMC_TEST=m -CONFIG_MMC_RING_BUFFER=y CONFIG_MMC_PARANOID_SD_INIT=y CONFIG_MMC_CLKGATE=y CONFIG_MMC_SDHCI=y @@ -395,12 +383,10 @@ CONFIG_ARM_SMMU=y CONFIG_QCOM_LAZY_MAPPING=y CONFIG_IOMMU_DEBUG=y CONFIG_IOMMU_DEBUG_TRACKING=y -CONFIG_IOMMU_TESTS=y CONFIG_RPMSG_CHAR=y CONFIG_RPMSG_QCOM_GLINK_RPM=y CONFIG_RPMSG_QCOM_GLINK_SMEM=y CONFIG_MSM_RPM_SMD=y -CONFIG_QCOM_CPUSS_DUMP=y CONFIG_QCOM_QMI_HELPERS=y CONFIG_QCOM_SMEM=y CONFIG_QCOM_SMD_RPM=y @@ -408,7 +394,6 @@ CONFIG_MSM_SPM=y CONFIG_MSM_L2_SPM=y CONFIG_QCOM_SCM=y CONFIG_QCOM_MEMORY_DUMP_V2=y -CONFIG_MSM_DEBUG_LAR_UNLOCK=y CONFIG_QCOM_WATCHDOG_V2=y CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y CONFIG_QCOM_WDOG_IPI_ENABLE=y @@ -421,7 +406,6 @@ CONFIG_MSM_SYSMON_QMI_COMM=y CONFIG_MSM_PIL_SSR_GENERIC=y CONFIG_MSM_BOOT_STATS=y CONFIG_MSM_BOOT_TIME_MARKER=y -CONFIG_MSM_CORE_HANG_DETECT=y CONFIG_QCOM_DCC_V2=y CONFIG_SDX_EXT_IPC=y CONFIG_QTI_NOTIFY_SIDEBAND=y @@ -429,6 +413,7 @@ CONFIG_QCOM_BUS_SCALING=y CONFIG_MSM_TZ_SMMU=y CONFIG_QCOM_GLINK=y CONFIG_QCOM_GLINK_PKT=y +CONFIG_MSM_JTAGV8=y CONFIG_QTI_RPM_STATS_LOG=y CONFIG_MSM_CDSP_LOADER=y CONFIG_QCOM_SMCINVOKE=y @@ -458,7 +443,6 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y -CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y @@ -474,49 +458,19 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ASCII=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y -CONFIG_DYNAMIC_DEBUG=y CONFIG_DEBUG_INFO=y CONFIG_PAGE_OWNER=y CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_PAGEALLOC=y -CONFIG_SLUB_DEBUG_PANIC_ON=y -CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y CONFIG_PAGE_POISONING=y CONFIG_PAGE_POISONING_ENABLE_DEFAULT=y -CONFIG_DEBUG_OBJECTS=y -CONFIG_DEBUG_OBJECTS_FREE=y -CONFIG_DEBUG_OBJECTS_TIMERS=y -CONFIG_DEBUG_OBJECTS_WORK=y -CONFIG_DEBUG_OBJECTS_RCU_HEAD=y -CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y -CONFIG_SLUB_DEBUG_ON=y -CONFIG_DEBUG_KMEMLEAK=y -CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=4000 -CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y -CONFIG_DEBUG_STACK_USAGE=y -CONFIG_DEBUG_MEMORY_INIT=y CONFIG_PANIC_ON_RECURSIVE_FAULT=y CONFIG_PANIC_ON_OOPS=y CONFIG_PANIC_TIMEOUT=5 CONFIG_SCHEDSTATS=y -CONFIG_SCHED_STACK_END_CHECK=y -CONFIG_DEBUG_SPINLOCK=y -CONFIG_DEBUG_MUTEXES=y -CONFIG_DEBUG_ATOMIC_SLEEP=y -CONFIG_FAULT_INJECTION=y -CONFIG_FAIL_PAGE_ALLOC=y -CONFIG_UFS_FAULT_INJECTION=y -CONFIG_FAULT_INJECTION_DEBUG_FS=y -CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y CONFIG_IPC_LOGGING=y -CONFIG_QCOM_RTB=y -CONFIG_QCOM_RTB_SEPARATE_CPUS=y -CONFIG_BLK_DEV_IO_TRACE=y -CONFIG_LKDTM=y CONFIG_BUG_ON_DATA_CORRUPTION=y CONFIG_CORESIGHT=y CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y -CONFIG_CORESIGHT_SOURCE_ETM4X=y CONFIG_CORESIGHT_DYNAMIC_REPLICATOR=y CONFIG_CORESIGHT_STM=y CONFIG_CORESIGHT_CTI=y @@ -524,8 +478,6 @@ CONFIG_CORESIGHT_TPDA=y CONFIG_CORESIGHT_TPDM=y CONFIG_CORESIGHT_HWEVENT=y CONFIG_CORESIGHT_DUMMY=y -CONFIG_CORESIGHT_REMOTE_ETM=y -CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_EVENT=y CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y @@ -543,3 +495,4 @@ CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y CONFIG_CRYPTO_DEV_QCRYPTO=y CONFIG_CRYPTO_DEV_QCEDEV=y CONFIG_CRYPTO_DEV_QCOM_ICE=y +CONFIG_STACK_HASH_ORDER_SHIFT=12 diff --git a/arch/arm64/configs/vendor/sa2150p_defconfig b/arch/arm64/configs/vendor/sa2150p_defconfig index 43100c444244..5a7550fc9fdf 100644 --- a/arch/arm64/configs/vendor/sa2150p_defconfig +++ b/arch/arm64/configs/vendor/sa2150p_defconfig @@ -6,7 +6,6 @@ CONFIG_HIGH_RES_TIMERS=y CONFIG_IRQ_TIME_ACCOUNTING=y CONFIG_SCHED_WALT=y CONFIG_TASKSTATS=y -CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y CONFIG_RCU_EXPERT=y @@ -20,7 +19,6 @@ CONFIG_RT_GROUP_SCHED=y CONFIG_CGROUP_FREEZER=y CONFIG_CPUSETS=y CONFIG_CGROUP_CPUACCT=y -CONFIG_CGROUP_DEBUG=y CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set # CONFIG_PID_NS is not set @@ -47,9 +45,7 @@ CONFIG_PCI_MSM=y CONFIG_PCI_MSM_MSI=y CONFIG_NR_CPUS=4 CONFIG_PREEMPT=y -CONFIG_CLEANCACHE=y CONFIG_CMA=y -CONFIG_CMA_DEBUGFS=y CONFIG_ZSMALLOC=y CONFIG_SECCOMP=y # CONFIG_HARDEN_BRANCH_PREDICTOR is not set @@ -66,7 +62,6 @@ CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set -CONFIG_PM_DEBUG=y CONFIG_CPU_IDLE=y CONFIG_ARM_CPUIDLE=y CONFIG_CPU_FREQ=y @@ -187,7 +182,6 @@ CONFIG_BRIDGE_EBT_ARPREPLY=y CONFIG_BRIDGE_EBT_DNAT=y CONFIG_BRIDGE_EBT_SNAT=y CONFIG_L2TP=y -CONFIG_L2TP_DEBUGFS=y CONFIG_L2TP_V3=y CONFIG_L2TP_IP=y CONFIG_L2TP_ETH=y @@ -296,11 +290,9 @@ CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=y CONFIG_I2C_MSM_V2=y CONFIG_SPI=y -CONFIG_SPI_DEBUG=y CONFIG_SPI_QUP=y CONFIG_SPI_SPIDEV=y CONFIG_SPMI=y -CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y CONFIG_SLIMBUS_MSM_NGD=y CONFIG_PPS_CLIENT_GPIO=y CONFIG_PINCTRL_QCS405=y @@ -333,7 +325,6 @@ CONFIG_REGULATOR_SPM=y CONFIG_REGULATOR_STUB=y # CONFIG_RC_CORE is not set # CONFIG_VGA_ARB is not set -# CONFIG_DSI_PARSER is not set CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_DYNAMIC_MINORS=y @@ -359,8 +350,6 @@ CONFIG_USB_MSM_SSPHY=y CONFIG_USB_QCOM_EMU_PHY=y CONFIG_DUAL_ROLE_USB_INTF=y CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_DEBUG_FILES=y -CONFIG_USB_GADGET_DEBUG_FS=y CONFIG_USB_GADGET_VBUS_DRAW=900 CONFIG_USB_CONFIGFS=y CONFIG_USB_CONFIGFS_F_FS=y @@ -370,7 +359,6 @@ CONFIG_MMC_PERF_PROFILING=y CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_BLOCK_DEFERRED_RESUME=y CONFIG_MMC_TEST=m -CONFIG_MMC_RING_BUFFER=y CONFIG_MMC_PARANOID_SD_INIT=y CONFIG_MMC_CLKGATE=y CONFIG_MMC_SDHCI=y @@ -407,12 +395,10 @@ CONFIG_ARM_SMMU=y CONFIG_QCOM_LAZY_MAPPING=y CONFIG_IOMMU_DEBUG=y CONFIG_IOMMU_DEBUG_TRACKING=y -CONFIG_IOMMU_TESTS=y CONFIG_RPMSG_CHAR=y CONFIG_RPMSG_QCOM_GLINK_RPM=y CONFIG_RPMSG_QCOM_GLINK_SMEM=y CONFIG_MSM_RPM_SMD=y -CONFIG_QCOM_CPUSS_DUMP=y CONFIG_QCOM_QMI_HELPERS=y CONFIG_QCOM_SMEM=y CONFIG_QCOM_SMD_RPM=y @@ -420,7 +406,6 @@ CONFIG_MSM_SPM=y CONFIG_MSM_L2_SPM=y CONFIG_QCOM_SCM=y CONFIG_QCOM_MEMORY_DUMP_V2=y -CONFIG_MSM_DEBUG_LAR_UNLOCK=y CONFIG_QCOM_WATCHDOG_V2=y CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y CONFIG_QCOM_WDOG_IPI_ENABLE=y @@ -433,7 +418,6 @@ CONFIG_MSM_SYSMON_QMI_COMM=y CONFIG_MSM_PIL_SSR_GENERIC=y CONFIG_MSM_BOOT_STATS=y CONFIG_MSM_BOOT_TIME_MARKER=y -CONFIG_MSM_CORE_HANG_DETECT=y CONFIG_QCOM_DCC_V2=y CONFIG_SDX_EXT_IPC=y CONFIG_QTI_NOTIFY_SIDEBAND=y @@ -441,6 +425,7 @@ CONFIG_QCOM_BUS_SCALING=y CONFIG_MSM_TZ_SMMU=y CONFIG_QCOM_GLINK=y CONFIG_QCOM_GLINK_PKT=y +CONFIG_MSM_JTAGV8=y CONFIG_QTI_RPM_STATS_LOG=y CONFIG_MSM_CDSP_LOADER=y CONFIG_QCOM_SMCINVOKE=y @@ -470,7 +455,6 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y -CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y @@ -486,49 +470,19 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ASCII=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y -CONFIG_DYNAMIC_DEBUG=y CONFIG_DEBUG_INFO=y CONFIG_PAGE_OWNER=y CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_PAGEALLOC=y -CONFIG_SLUB_DEBUG_PANIC_ON=y -CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y CONFIG_PAGE_POISONING=y CONFIG_PAGE_POISONING_ENABLE_DEFAULT=y -CONFIG_DEBUG_OBJECTS=y -CONFIG_DEBUG_OBJECTS_FREE=y -CONFIG_DEBUG_OBJECTS_TIMERS=y -CONFIG_DEBUG_OBJECTS_WORK=y -CONFIG_DEBUG_OBJECTS_RCU_HEAD=y -CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y -CONFIG_SLUB_DEBUG_ON=y -CONFIG_DEBUG_KMEMLEAK=y -CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=4000 -CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y -CONFIG_DEBUG_STACK_USAGE=y -CONFIG_DEBUG_MEMORY_INIT=y CONFIG_PANIC_ON_RECURSIVE_FAULT=y CONFIG_PANIC_ON_OOPS=y CONFIG_PANIC_TIMEOUT=5 CONFIG_SCHEDSTATS=y -CONFIG_SCHED_STACK_END_CHECK=y -CONFIG_DEBUG_SPINLOCK=y -CONFIG_DEBUG_MUTEXES=y -CONFIG_DEBUG_ATOMIC_SLEEP=y -CONFIG_FAULT_INJECTION=y -CONFIG_FAIL_PAGE_ALLOC=y -CONFIG_UFS_FAULT_INJECTION=y -CONFIG_FAULT_INJECTION_DEBUG_FS=y -CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y CONFIG_IPC_LOGGING=y -CONFIG_QCOM_RTB=y -CONFIG_QCOM_RTB_SEPARATE_CPUS=y -CONFIG_BLK_DEV_IO_TRACE=y -CONFIG_LKDTM=y CONFIG_BUG_ON_DATA_CORRUPTION=y CONFIG_CORESIGHT=y CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y -CONFIG_CORESIGHT_SOURCE_ETM4X=y CONFIG_CORESIGHT_DYNAMIC_REPLICATOR=y CONFIG_CORESIGHT_STM=y CONFIG_CORESIGHT_CTI=y @@ -536,8 +490,6 @@ CONFIG_CORESIGHT_TPDA=y CONFIG_CORESIGHT_TPDM=y CONFIG_CORESIGHT_HWEVENT=y CONFIG_CORESIGHT_DUMMY=y -CONFIG_CORESIGHT_REMOTE_ETM=y -CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_EVENT=y CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y @@ -554,3 +506,4 @@ CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y CONFIG_CRYPTO_DEV_QCRYPTO=y CONFIG_CRYPTO_DEV_QCEDEV=y CONFIG_CRYPTO_DEV_QCOM_ICE=y +CONFIG_STACK_HASH_ORDER_SHIFT=12 diff --git a/arch/arm64/configs/vendor/sdmshrike-perf_defconfig b/arch/arm64/configs/vendor/sdmshrike-perf_defconfig index 1d6ef880eaa8..98a1c46dea3a 100644 --- a/arch/arm64/configs/vendor/sdmshrike-perf_defconfig +++ b/arch/arm64/configs/vendor/sdmshrike-perf_defconfig @@ -76,6 +76,7 @@ CONFIG_SETEND_EMULATION=y CONFIG_RANDOMIZE_BASE=y # CONFIG_EFI is not set CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y +CONFIG_BUILD_ARM64_UNCOMPRESSED_KERNEL=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y CONFIG_PM_WAKELOCKS=y diff --git a/arch/arm64/configs/vendor/sdmshrike_defconfig b/arch/arm64/configs/vendor/sdmshrike_defconfig index cb315f41648e..84bd6089822f 100644 --- a/arch/arm64/configs/vendor/sdmshrike_defconfig +++ b/arch/arm64/configs/vendor/sdmshrike_defconfig @@ -82,6 +82,7 @@ CONFIG_SETEND_EMULATION=y # CONFIG_ARM64_VHE is not set CONFIG_RANDOMIZE_BASE=y CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y +CONFIG_BUILD_ARM64_UNCOMPRESSED_KERNEL=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y CONFIG_PM_WAKELOCKS=y diff --git a/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig b/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig index 1f0d081ed1e4..572272b6ad84 100644 --- a/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig @@ -655,6 +655,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_OVERLAY_FS=y +CONFIG_INCREMENTAL_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS_POSIX_ACL=y diff --git a/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig b/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig index cfb1b76eedd7..712b4ac30eb6 100644 --- a/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig @@ -694,6 +694,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_OVERLAY_FS=y +CONFIG_INCREMENTAL_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS_POSIX_ACL=y diff --git a/arch/arm64/configs/vendor/sdmsteppe-perf_defconfig b/arch/arm64/configs/vendor/sdmsteppe-perf_defconfig index d51203f36562..6069cb150ce2 100644 --- a/arch/arm64/configs/vendor/sdmsteppe-perf_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe-perf_defconfig @@ -288,6 +288,7 @@ CONFIG_NETDEVICES=y CONFIG_BONDING=y CONFIG_DUMMY=y CONFIG_TUN=y +CONFIG_VETH=y CONFIG_SKY2=y CONFIG_RMNET=y CONFIG_SMSC911X=y @@ -649,6 +650,7 @@ CONFIG_ESOC_MDM_DRV=y CONFIG_ESOC_MDM_DBG_ENG=y CONFIG_MSM_TZ_LOG=y CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y CONFIG_EXT4_ENCRYPTION=y CONFIG_EXT4_FS_ENCRYPTION=y @@ -656,11 +658,14 @@ CONFIG_EXT4_FS_ICE_ENCRYPTION=y CONFIG_F2FS_FS=y CONFIG_F2FS_FS_SECURITY=y CONFIG_F2FS_FS_ENCRYPTION=y +CONFIG_FS_VERITY=y +CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_OVERLAY_FS=y +CONFIG_INCREMENTAL_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS_POSIX_ACL=y @@ -699,7 +704,6 @@ CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SMACK=y CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_XCBC=y -CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_TWOFISH=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y diff --git a/arch/arm64/configs/vendor/sdmsteppe_defconfig b/arch/arm64/configs/vendor/sdmsteppe_defconfig index bc8dddb15d11..2d93f5047063 100644 --- a/arch/arm64/configs/vendor/sdmsteppe_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe_defconfig @@ -299,6 +299,7 @@ CONFIG_NETDEVICES=y CONFIG_BONDING=y CONFIG_DUMMY=y CONFIG_TUN=y +CONFIG_VETH=y CONFIG_RMNET=y CONFIG_AT803X_PHY=y CONFIG_MICREL_PHY=y @@ -687,6 +688,7 @@ CONFIG_ESOC_MDM_DRV=y CONFIG_ESOC_MDM_DBG_ENG=y CONFIG_MSM_TZ_LOG=y CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y CONFIG_EXT4_ENCRYPTION=y CONFIG_EXT4_FS_ENCRYPTION=y @@ -694,11 +696,14 @@ CONFIG_EXT4_FS_ICE_ENCRYPTION=y CONFIG_F2FS_FS=y CONFIG_F2FS_FS_SECURITY=y CONFIG_F2FS_FS_ENCRYPTION=y +CONFIG_FS_VERITY=y +CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_OVERLAY_FS=y +CONFIG_INCREMENTAL_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS_POSIX_ACL=y @@ -794,7 +799,6 @@ CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SMACK=y CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_XCBC=y -CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_TWOFISH=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y diff --git a/arch/arm64/configs/vendor/sm8150-perf_defconfig b/arch/arm64/configs/vendor/sm8150-perf_defconfig index ae6e24be182f..084e44000588 100644 --- a/arch/arm64/configs/vendor/sm8150-perf_defconfig +++ b/arch/arm64/configs/vendor/sm8150-perf_defconfig @@ -298,6 +298,7 @@ CONFIG_NETDEVICES=y CONFIG_BONDING=y CONFIG_DUMMY=y CONFIG_TUN=y +CONFIG_VETH=y CONFIG_SKY2=y CONFIG_RMNET=y CONFIG_SMSC911X=y @@ -656,6 +657,7 @@ CONFIG_ESOC_MDM_DRV=y CONFIG_ESOC_MDM_DBG_ENG=y CONFIG_MSM_TZ_LOG=y CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y CONFIG_EXT4_ENCRYPTION=y CONFIG_EXT4_FS_ENCRYPTION=y @@ -663,11 +665,14 @@ CONFIG_EXT4_FS_ICE_ENCRYPTION=y CONFIG_F2FS_FS=y CONFIG_F2FS_FS_SECURITY=y CONFIG_F2FS_FS_ENCRYPTION=y +CONFIG_FS_VERITY=y +CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_OVERLAY_FS=y +CONFIG_INCREMENTAL_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS_POSIX_ACL=y @@ -708,7 +713,6 @@ CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SMACK=y CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_XCBC=y -CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_TWOFISH=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y diff --git a/arch/arm64/configs/vendor/sm8150_defconfig b/arch/arm64/configs/vendor/sm8150_defconfig index 00883b59ca12..e21d100fa8ad 100644 --- a/arch/arm64/configs/vendor/sm8150_defconfig +++ b/arch/arm64/configs/vendor/sm8150_defconfig @@ -311,6 +311,7 @@ CONFIG_NETDEVICES=y CONFIG_BONDING=y CONFIG_DUMMY=y CONFIG_TUN=y +CONFIG_VETH=y CONFIG_RMNET=y CONFIG_PPP=y CONFIG_PPP_BSDCOMP=y @@ -687,6 +688,7 @@ CONFIG_ESOC_MDM_DRV=y CONFIG_ESOC_MDM_DBG_ENG=y CONFIG_MSM_TZ_LOG=y CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y CONFIG_EXT4_ENCRYPTION=y CONFIG_EXT4_FS_ENCRYPTION=y @@ -694,11 +696,14 @@ CONFIG_EXT4_FS_ICE_ENCRYPTION=y CONFIG_F2FS_FS=y CONFIG_F2FS_FS_SECURITY=y CONFIG_F2FS_FS_ENCRYPTION=y +CONFIG_FS_VERITY=y +CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_OVERLAY_FS=y +CONFIG_INCREMENTAL_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS_POSIX_ACL=y @@ -795,7 +800,6 @@ CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SMACK=y CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_XCBC=y -CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_TWOFISH=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y diff --git a/arch/arm64/configs/vendor/trinket-perf_defconfig b/arch/arm64/configs/vendor/trinket-perf_defconfig index 1af661907f0e..d6b5f618497e 100644 --- a/arch/arm64/configs/vendor/trinket-perf_defconfig +++ b/arch/arm64/configs/vendor/trinket-perf_defconfig @@ -292,6 +292,7 @@ CONFIG_NETDEVICES=y CONFIG_BONDING=y CONFIG_DUMMY=y CONFIG_TUN=y +CONFIG_VETH=y CONFIG_RMNET=y CONFIG_PPP=y CONFIG_PPP_BSDCOMP=y @@ -635,10 +636,13 @@ CONFIG_NVMEM_SPMI_SDAM=y CONFIG_SENSORS_SSC=y CONFIG_MSM_TZ_LOG=y CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y CONFIG_F2FS_FS=y CONFIG_F2FS_FS_SECURITY=y CONFIG_F2FS_FS_ENCRYPTION=y +CONFIG_FS_VERITY=y +CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_QFMT_V2=y @@ -684,7 +688,6 @@ CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SMACK=y CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_XCBC=y -CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_TWOFISH=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y diff --git a/arch/arm64/configs/vendor/trinket_defconfig b/arch/arm64/configs/vendor/trinket_defconfig index 26e416621815..5132a6da3b89 100644 --- a/arch/arm64/configs/vendor/trinket_defconfig +++ b/arch/arm64/configs/vendor/trinket_defconfig @@ -303,6 +303,7 @@ CONFIG_NETDEVICES=y CONFIG_BONDING=y CONFIG_DUMMY=y CONFIG_TUN=y +CONFIG_VETH=y CONFIG_RMNET=y CONFIG_PPP=y CONFIG_PPP_BSDCOMP=y @@ -667,10 +668,13 @@ CONFIG_NVMEM_SPMI_SDAM=y CONFIG_SENSORS_SSC=y CONFIG_MSM_TZ_LOG=y CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y CONFIG_F2FS_FS=y CONFIG_F2FS_FS_SECURITY=y CONFIG_F2FS_FS_ENCRYPTION=y +CONFIG_FS_VERITY=y +CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_QFMT_V2=y @@ -772,7 +776,6 @@ CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SMACK=y CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_XCBC=y -CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_TWOFISH=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y diff --git a/arch/arm64/include/asm/alternative.h b/arch/arm64/include/asm/alternative.h index 4ed869845a23..3abb2dacb43f 100644 --- a/arch/arm64/include/asm/alternative.h +++ b/arch/arm64/include/asm/alternative.h @@ -68,13 +68,13 @@ void apply_alternatives(void *start, size_t length); ".pushsection .altinstructions,\"a\"\n" \ ALTINSTR_ENTRY(feature) \ ".popsection\n" \ - ".pushsection .altinstr_replacement, \"a\"\n" \ + ".subsection 1\n" \ "663:\n\t" \ newinstr "\n" \ "664:\n\t" \ - ".popsection\n\t" \ ".org . - (664b-663b) + (662b-661b)\n\t" \ - ".org . - (662b-661b) + (664b-663b)\n" \ + ".org . - (662b-661b) + (664b-663b)\n\t" \ + ".previous\n" \ ".endif\n" #define __ALTERNATIVE_CFG_CB(oldinstr, feature, cfg_enabled, cb) \ @@ -112,9 +112,9 @@ void apply_alternatives(void *start, size_t length); 662: .pushsection .altinstructions, "a" altinstruction_entry 661b, 663f, \cap, 662b-661b, 664f-663f .popsection - .pushsection .altinstr_replacement, "ax" + .subsection 1 663: \insn2 -664: .popsection +664: .previous .org . - (664b-663b) + (662b-661b) .org . - (662b-661b) + (664b-663b) .endif @@ -155,7 +155,7 @@ void apply_alternatives(void *start, size_t length); .pushsection .altinstructions, "a" altinstruction_entry 663f, 661f, \cap, 664f-663f, 662f-661f .popsection - .pushsection .altinstr_replacement, "ax" + .subsection 1 .align 2 /* So GAS knows label 661 is suitably aligned */ 661: .endm @@ -174,9 +174,9 @@ void apply_alternatives(void *start, size_t length); .macro alternative_else 662: .if .Lasm_alt_mode==0 - .pushsection .altinstr_replacement, "ax" + .subsection 1 .else - .popsection + .previous .endif 663: .endm @@ -187,7 +187,7 @@ void apply_alternatives(void *start, size_t length); .macro alternative_endif 664: .if .Lasm_alt_mode==0 - .popsection + .previous .endif .org . - (664b-663b) + (662b-661b) .org . - (662b-661b) + (664b-663b) diff --git a/arch/arm64/include/asm/checksum.h b/arch/arm64/include/asm/checksum.h index 11d95683928d..bb7b748e8067 100644 --- a/arch/arm64/include/asm/checksum.h +++ b/arch/arm64/include/asm/checksum.h @@ -35,16 +35,17 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) { __uint128_t tmp; u64 sum; + int n = ihl; /* we want it signed */ tmp = *(const __uint128_t *)iph; iph += 16; - ihl -= 4; + n -= 4; tmp += ((tmp >> 64) | (tmp << 64)); sum = tmp >> 64; do { sum += *(const u32 *)iph; iph += 4; - } while (--ihl); + } while (--n > 0); sum += ((sum >> 32) | (sum << 32)); return csum_fold((__force u32)(sum >> 32)); diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c index 092046704cbc..20cf50f0dac3 100644 --- a/arch/arm64/kernel/armv8_deprecated.c +++ b/arch/arm64/kernel/armv8_deprecated.c @@ -243,8 +243,8 @@ static void __init register_insn_emulation_sysctl(struct ctl_table *table) struct insn_emulation *insn; struct ctl_table *insns_sysctl, *sysctl; - insns_sysctl = kzalloc(sizeof(*sysctl) * (nr_insn_emulated + 1), - GFP_KERNEL); + insns_sysctl = kcalloc(nr_insn_emulated + 1, sizeof(*sysctl), + GFP_KERNEL); raw_spin_lock_irqsave(&insn_emulation_lock, flags); list_for_each_entry(insn, &insn_emulation, node) { diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c index 95b5f7679e39..90f980bedb20 100644 --- a/arch/arm64/kernel/hibernate.c +++ b/arch/arm64/kernel/hibernate.c @@ -303,7 +303,6 @@ int swsusp_arch_suspend(void) sleep_cpu = smp_processor_id(); ret = swsusp_save(); } else { - place_marker("M - Image Kernel Start"); /* Clean kernel core startup/idle code to PoC*/ dcache_clean_range(__mmuoff_data_start, __mmuoff_data_end); dcache_clean_range(__idmap_text_start, __idmap_text_end); @@ -339,7 +338,6 @@ int swsusp_arch_suspend(void) } local_dbg_restore(flags); - place_marker("PM: Kernel restore start!"); return ret; } diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index 0da789ac6880..6def300a2b69 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -156,9 +156,6 @@ SECTIONS KEEP(*(.altinstructions)) __alt_instructions_end = .; } - .altinstr_replacement : { - *(.altinstr_replacement) - } . = ALIGN(PAGE_SIZE); __inittext_end = .; diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c index 9284788733d6..c5af439c172d 100644 --- a/arch/arm64/mm/context.c +++ b/arch/arm64/mm/context.c @@ -256,7 +256,7 @@ static int asids_init(void) */ WARN_ON(NUM_USER_ASIDS - 1 <= num_possible_cpus()); atomic64_set(&asid_generation, ASID_FIRST_VERSION); - asid_map = kzalloc(BITS_TO_LONGS(NUM_USER_ASIDS) * sizeof(*asid_map), + asid_map = kcalloc(BITS_TO_LONGS(NUM_USER_ASIDS), sizeof(*asid_map), GFP_KERNEL); if (!asid_map) panic("Failed to allocate bitmap for %lu ASIDs\n", diff --git a/arch/blackfin/mm/isram-driver.c b/arch/blackfin/mm/isram-driver.c index aaa1e64b753b..3aa8545f0351 100644 --- a/arch/blackfin/mm/isram-driver.c +++ b/arch/blackfin/mm/isram-driver.c @@ -370,7 +370,7 @@ static __init int isram_test_init(void) pr_info("INFO: testing %#x bytes (%p - %p)\n", test_len, l1inst, l1inst + test_len); - sdram = kmalloc(test_len * 2, GFP_KERNEL); + sdram = kmalloc_array(test_len, 2, GFP_KERNEL); if (!sdram) { sram_free(l1inst); pr_warning("SKIP: could not allocate sdram\n"); diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c index d688fe117dca..fbe4dc49aabb 100644 --- a/arch/cris/arch-v32/drivers/cryptocop.c +++ b/arch/cris/arch-v32/drivers/cryptocop.c @@ -1533,7 +1533,9 @@ int cryptocop_new_session(cryptocop_session_id *sid, struct cryptocop_transform_ return -ENOMEM; } - sess->tfrm_ctx = kmalloc(no_tfrms * sizeof(struct cryptocop_transform_ctx), alloc_flag); + sess->tfrm_ctx = kmalloc_array(no_tfrms, + sizeof(struct cryptocop_transform_ctx), + alloc_flag); if (!sess->tfrm_ctx) { DEBUG_API(printk("cryptocop_new_session, kmalloc cryptocop_transform_ctx\n")); kfree(sess); @@ -2698,7 +2700,7 @@ static int cryptocop_ioctl_process(struct inode *inode, struct file *filp, unsig /* Map user pages for in and out data of the operation. */ noinpages = (((unsigned long int)(oper.indata + prev_ix) & ~PAGE_MASK) + oper.inlen - 1 - prev_ix + ~PAGE_MASK) >> PAGE_SHIFT; DEBUG(printk("cryptocop_ioctl_process: noinpages=%d\n", noinpages)); - inpages = kmalloc(noinpages * sizeof(struct page*), GFP_KERNEL); + inpages = kmalloc_array(noinpages, sizeof(struct page *), GFP_KERNEL); if (!inpages){ DEBUG_API(printk("cryptocop_ioctl_process: kmalloc inpages\n")); nooutpages = noinpages = 0; @@ -2708,7 +2710,8 @@ static int cryptocop_ioctl_process(struct inode *inode, struct file *filp, unsig if (oper.do_cipher){ nooutpages = (((unsigned long int)oper.cipher_outdata & ~PAGE_MASK) + oper.cipher_outlen - 1 + ~PAGE_MASK) >> PAGE_SHIFT; DEBUG(printk("cryptocop_ioctl_process: nooutpages=%d\n", nooutpages)); - outpages = kmalloc(nooutpages * sizeof(struct page*), GFP_KERNEL); + outpages = kmalloc_array(nooutpages, sizeof(struct page *), + GFP_KERNEL); if (!outpages){ DEBUG_API(printk("cryptocop_ioctl_process: kmalloc outpages\n")); nooutpages = noinpages = 0; @@ -2752,8 +2755,11 @@ static int cryptocop_ioctl_process(struct inode *inode, struct file *filp, unsig /* Add 6 to nooutpages to make room for possibly inserted buffers for storing digest and * csum output and splits when units are (dis-)connected. */ - cop->tfrm_op.indata = kmalloc((noinpages) * sizeof(struct iovec), GFP_KERNEL); - cop->tfrm_op.outdata = kmalloc((6 + nooutpages) * sizeof(struct iovec), GFP_KERNEL); + cop->tfrm_op.indata = kmalloc_array(noinpages, sizeof(struct iovec), + GFP_KERNEL); + cop->tfrm_op.outdata = kmalloc_array(6 + nooutpages, + sizeof(struct iovec), + GFP_KERNEL); if (!cop->tfrm_op.indata || !cop->tfrm_op.outdata) { DEBUG_API(printk("cryptocop_ioctl_process: kmalloc iovecs\n")); err = -ENOMEM; diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index 94f8bf777afa..dfe40cbdf3b3 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c @@ -350,7 +350,8 @@ init_record_index_pools(void) /* - 3 - */ slidx_pool.max_idx = (rec_max_size/sect_min_size) * 2 + 1; slidx_pool.buffer = - kmalloc(slidx_pool.max_idx * sizeof(slidx_list_t), GFP_KERNEL); + kmalloc_array(slidx_pool.max_idx, sizeof(slidx_list_t), + GFP_KERNEL); return slidx_pool.buffer ? 0 : -ENOMEM; } diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index d76529cbff20..9b820f7a6a98 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c @@ -85,7 +85,7 @@ static int __init topology_init(void) } #endif - sysfs_cpus = kzalloc(sizeof(struct ia64_cpu) * NR_CPUS, GFP_KERNEL); + sysfs_cpus = kcalloc(NR_CPUS, sizeof(struct ia64_cpu), GFP_KERNEL); if (!sysfs_cpus) panic("kzalloc in topology_init failed - NR_CPUS too big?"); @@ -319,8 +319,8 @@ static int cpu_cache_sysfs_init(unsigned int cpu) return -1; } - this_cache=kzalloc(sizeof(struct cache_info)*unique_caches, - GFP_KERNEL); + this_cache=kcalloc(unique_caches, sizeof(struct cache_info), + GFP_KERNEL); if (this_cache == NULL) return -ENOMEM; diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index 46ecc5d948aa..acf10eb9da15 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c @@ -430,8 +430,9 @@ int ia64_itr_entry(u64 target_mask, u64 va, u64 pte, u64 log_size) int cpu = smp_processor_id(); if (!ia64_idtrs[cpu]) { - ia64_idtrs[cpu] = kmalloc(2 * IA64_TR_ALLOC_MAX * - sizeof (struct ia64_tr_entry), GFP_KERNEL); + ia64_idtrs[cpu] = kmalloc_array(2 * IA64_TR_ALLOC_MAX, + sizeof(struct ia64_tr_entry), + GFP_KERNEL); if (!ia64_idtrs[cpu]) return -ENOMEM; } diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c index 11f2275570fb..5b009d54d3df 100644 --- a/arch/ia64/sn/kernel/io_common.c +++ b/arch/ia64/sn/kernel/io_common.c @@ -132,7 +132,7 @@ static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device, printk_once(KERN_WARNING "PROM version < 4.50 -- implementing old PROM flush WAR\n"); - war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL); + war_list = kcalloc(DEV_PER_WIDGET, sizeof(*war_list), GFP_KERNEL); BUG_ON(!war_list); SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST, diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index 85d095154902..d9b576df4f82 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c @@ -474,7 +474,8 @@ void __init sn_irq_lh_init(void) { int i; - sn_irq_lh = kmalloc(sizeof(struct list_head *) * NR_IRQS, GFP_KERNEL); + sn_irq_lh = kmalloc_array(NR_IRQS, sizeof(struct list_head *), + GFP_KERNEL); if (!sn_irq_lh) panic("SN PCI INIT: Failed to allocate memory for PCI init\n"); diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c index 8dbbef4a4f47..7195df1da121 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c @@ -184,7 +184,7 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont /* Setup the PMU ATE map */ soft->pbi_int_ate_resource.lowest_free_index = 0; soft->pbi_int_ate_resource.ate = - kzalloc(soft->pbi_int_ate_size * sizeof(u64), GFP_KERNEL); + kcalloc(soft->pbi_int_ate_size, sizeof(u64), GFP_KERNEL); if (!soft->pbi_int_ate_resource.ate) { kfree(soft); diff --git a/arch/mips/alchemy/common/clock.c b/arch/mips/alchemy/common/clock.c index a83c7b7e2eb1..afebd7b99299 100644 --- a/arch/mips/alchemy/common/clock.c +++ b/arch/mips/alchemy/common/clock.c @@ -985,7 +985,7 @@ static int __init alchemy_clk_setup_imux(int ctype) return -ENODEV; } - a = kzalloc((sizeof(*a)) * 6, GFP_KERNEL); + a = kcalloc(6, sizeof(*a), GFP_KERNEL); if (!a) return -ENOMEM; diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c index fc482d900ddd..c55a02422b38 100644 --- a/arch/mips/alchemy/common/dbdma.c +++ b/arch/mips/alchemy/common/dbdma.c @@ -411,8 +411,8 @@ u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries) * and if we try that first we are likely to not waste larger * slabs of memory. */ - desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t), - GFP_KERNEL|GFP_DMA); + desc_base = (u32) kmalloc_array(entries, sizeof(au1x_ddma_desc_t), + GFP_KERNEL|GFP_DMA); if (desc_base == 0) return 0; @@ -1050,7 +1050,7 @@ static int __init dbdma_setup(unsigned int irq, dbdev_tab_t *idtable) { int ret; - dbdev_tab = kzalloc(sizeof(dbdev_tab_t) * DBDEV_TAB_SIZE, GFP_KERNEL); + dbdev_tab = kcalloc(DBDEV_TAB_SIZE, sizeof(dbdev_tab_t), GFP_KERNEL); if (!dbdev_tab) return -ENOMEM; diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c index d77a64f4c78b..1454d9f6ab2d 100644 --- a/arch/mips/alchemy/common/platform.c +++ b/arch/mips/alchemy/common/platform.c @@ -115,7 +115,7 @@ static void __init alchemy_setup_uarts(int ctype) uartclk = clk_get_rate(clk); clk_put(clk); - ports = kzalloc(s * (c + 1), GFP_KERNEL); + ports = kcalloc(s, (c + 1), GFP_KERNEL); if (!ports) { printk(KERN_INFO "Alchemy: no memory for UART data\n"); return; @@ -198,7 +198,7 @@ static unsigned long alchemy_ehci_data[][2] __initdata = { static int __init _new_usbres(struct resource **r, struct platform_device **d) { - *r = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); + *r = kcalloc(2, sizeof(struct resource), GFP_KERNEL); if (!*r) return -ENOMEM; *d = kzalloc(sizeof(struct platform_device), GFP_KERNEL); diff --git a/arch/mips/alchemy/devboards/platform.c b/arch/mips/alchemy/devboards/platform.c index 4640edab207c..203854ddd1bb 100644 --- a/arch/mips/alchemy/devboards/platform.c +++ b/arch/mips/alchemy/devboards/platform.c @@ -103,7 +103,7 @@ int __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start, if (stschg_irq) cnt++; - sr = kzalloc(sizeof(struct resource) * cnt, GFP_KERNEL); + sr = kcalloc(cnt, sizeof(struct resource), GFP_KERNEL); if (!sr) return -ENOMEM; @@ -178,7 +178,7 @@ int __init db1x_register_norflash(unsigned long size, int width, return -EINVAL; ret = -ENOMEM; - parts = kzalloc(sizeof(struct mtd_partition) * 5, GFP_KERNEL); + parts = kcalloc(5, sizeof(struct mtd_partition), GFP_KERNEL); if (!parts) goto out; diff --git a/arch/mips/bmips/dma.c b/arch/mips/bmips/dma.c index 04790f4e1805..6dec30842b2f 100644 --- a/arch/mips/bmips/dma.c +++ b/arch/mips/bmips/dma.c @@ -94,7 +94,7 @@ static int __init bmips_init_dma_ranges(void) goto out_bad; /* add a dummy (zero) entry at the end as a sentinel */ - bmips_dma_ranges = kzalloc(sizeof(struct bmips_dma_range) * (len + 1), + bmips_dma_ranges = kcalloc(len + 1, sizeof(struct bmips_dma_range), GFP_KERNEL); if (!bmips_dma_ranges) goto out_bad; diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c index fd26fadc8617..ef29a9c2ffd6 100644 --- a/arch/mips/txx9/rbtx4939/setup.c +++ b/arch/mips/txx9/rbtx4939/setup.c @@ -219,7 +219,7 @@ static int __init rbtx4939_led_probe(struct platform_device *pdev) "nand-disk", }; - leds_data = kzalloc(sizeof(*leds_data) * RBTX4939_MAX_7SEGLEDS, + leds_data = kcalloc(RBTX4939_MAX_7SEGLEDS, sizeof(*leds_data), GFP_KERNEL); if (!leds_data) return -ENOMEM; diff --git a/arch/parisc/include/asm/cmpxchg.h b/arch/parisc/include/asm/cmpxchg.h index ab5c215cf46c..068958575871 100644 --- a/arch/parisc/include/asm/cmpxchg.h +++ b/arch/parisc/include/asm/cmpxchg.h @@ -60,6 +60,7 @@ extern void __cmpxchg_called_with_bad_pointer(void); extern unsigned long __cmpxchg_u32(volatile unsigned int *m, unsigned int old, unsigned int new_); extern u64 __cmpxchg_u64(volatile u64 *ptr, u64 old, u64 new_); +extern u8 __cmpxchg_u8(volatile u8 *ptr, u8 old, u8 new_); /* don't worry...optimizer will get rid of most of this */ static inline unsigned long @@ -71,6 +72,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size) #endif case 4: return __cmpxchg_u32((unsigned int *)ptr, (unsigned int)old, (unsigned int)new_); + case 1: return __cmpxchg_u8((u8 *)ptr, (u8)old, (u8)new_); } __cmpxchg_called_with_bad_pointer(); return old; diff --git a/arch/parisc/lib/bitops.c b/arch/parisc/lib/bitops.c index 70ffbcf889b8..2e4d1f05a926 100644 --- a/arch/parisc/lib/bitops.c +++ b/arch/parisc/lib/bitops.c @@ -79,3 +79,15 @@ unsigned long __cmpxchg_u32(volatile unsigned int *ptr, unsigned int old, unsign _atomic_spin_unlock_irqrestore(ptr, flags); return (unsigned long)prev; } + +u8 __cmpxchg_u8(volatile u8 *ptr, u8 old, u8 new) +{ + unsigned long flags; + u8 prev; + + _atomic_spin_lock_irqsave(ptr, flags); + if ((prev = *ptr) == old) + *ptr = new; + _atomic_spin_unlock_irqrestore(ptr, flags); + return prev; +} diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c index 7caeae73348d..777566fcb5d9 100644 --- a/arch/powerpc/kernel/rtasd.c +++ b/arch/powerpc/kernel/rtasd.c @@ -548,7 +548,7 @@ static int __init rtas_event_scan_init(void) rtas_error_log_max = rtas_get_error_log_max(); rtas_error_log_buffer_max = rtas_error_log_max + sizeof(int); - rtas_log_buf = vmalloc(rtas_error_log_buffer_max*LOG_NUMBER); + rtas_log_buf = vmalloc(array_size(LOG_NUMBER, rtas_error_log_buffer_max)); if (!rtas_log_buf) { printk(KERN_ERR "rtasd: no memory\n"); return -ENOMEM; diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index 22b01a3962f0..c4f59971e515 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -789,7 +789,7 @@ static int __init vdso_init(void) #ifdef CONFIG_VDSO32 /* Make sure pages are in the correct state */ - vdso32_pagelist = kzalloc(sizeof(struct page *) * (vdso32_pages + 2), + vdso32_pagelist = kcalloc(vdso32_pages + 2, sizeof(struct page *), GFP_KERNEL); BUG_ON(vdso32_pagelist == NULL); for (i = 0; i < vdso32_pages; i++) { @@ -803,7 +803,7 @@ static int __init vdso_init(void) #endif #ifdef CONFIG_PPC64 - vdso64_pagelist = kzalloc(sizeof(struct page *) * (vdso64_pages + 2), + vdso64_pagelist = kcalloc(vdso64_pages + 2, sizeof(struct page *), GFP_KERNEL); BUG_ON(vdso64_pagelist == NULL); for (i = 0; i < vdso64_pages; i++) { diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 7ac7e21b137e..39a00397d97b 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -110,7 +110,7 @@ int kvmppc_allocate_hpt(struct kvm_hpt_info *info, u32 order) npte = 1ul << (order - 4); /* Allocate reverse map array */ - rev = vmalloc(sizeof(struct revmap_entry) * npte); + rev = vmalloc(array_size(npte, sizeof(struct revmap_entry))); if (!rev) { pr_err("kvmppc_allocate_hpt: Couldn't alloc reverse map array\n"); if (cma) diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index e4f81f014206..2b6de3ff8d89 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -3470,7 +3470,7 @@ static int kvmppc_core_create_memslot_hv(struct kvm_memory_slot *slot, return 0; } - slot->arch.rmap = vzalloc(npages * sizeof(*slot->arch.rmap)); + slot->arch.rmap = vzalloc(array_size(npages, sizeof(*slot->arch.rmap))); if (!slot->arch.rmap) return -ENOMEM; diff --git a/arch/powerpc/lib/rheap.c b/arch/powerpc/lib/rheap.c index 94058c21a482..6aa774aa5b16 100644 --- a/arch/powerpc/lib/rheap.c +++ b/arch/powerpc/lib/rheap.c @@ -54,7 +54,7 @@ static int grow(rh_info_t * info, int max_blocks) new_blocks = max_blocks - info->max_blocks; - block = kmalloc(sizeof(rh_block_t) * max_blocks, GFP_ATOMIC); + block = kmalloc_array(max_blocks, sizeof(rh_block_t), GFP_ATOMIC); if (block == NULL) return -ENOMEM; diff --git a/arch/powerpc/mm/mmu_context_iommu.c b/arch/powerpc/mm/mmu_context_iommu.c index d735937d975c..02370f72fc5f 100644 --- a/arch/powerpc/mm/mmu_context_iommu.c +++ b/arch/powerpc/mm/mmu_context_iommu.c @@ -171,7 +171,7 @@ long mm_iommu_get(struct mm_struct *mm, unsigned long ua, unsigned long entries, * smaller than huge pages but still bigger than PAGE_SIZE. */ mem->pageshift = __ffs(ua | (entries << PAGE_SHIFT)); - mem->hpas = vzalloc(entries * sizeof(mem->hpas[0])); + mem->hpas = vzalloc(array_size(entries, sizeof(mem->hpas[0]))); if (!mem->hpas) { kfree(mem); ret = -ENOMEM; diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 417ea6db7b1d..d378fe1bed4f 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -1387,7 +1387,7 @@ int numa_update_cpu_topology(bool cpus_locked) if (!weight) return 0; - updates = kzalloc(weight * (sizeof(*updates)), GFP_KERNEL); + updates = kcalloc(weight, sizeof(*updates), GFP_KERNEL); if (!updates) return 0; diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index a9636d8cba15..5b061fc81df3 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -566,7 +566,7 @@ void bpf_jit_compile(struct bpf_prog *fp) if (!bpf_jit_enable) return; - addrs = kzalloc((flen+1) * sizeof(*addrs), GFP_KERNEL); + addrs = kcalloc(flen + 1, sizeof(*addrs), GFP_KERNEL); if (addrs == NULL) return; diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c index df15e4463f67..93ec56fbe0b8 100644 --- a/arch/powerpc/net/bpf_jit_comp64.c +++ b/arch/powerpc/net/bpf_jit_comp64.c @@ -999,7 +999,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) } flen = fp->len; - addrs = kzalloc((flen+1) * sizeof(*addrs), GFP_KERNEL); + addrs = kcalloc(flen + 1, sizeof(*addrs), GFP_KERNEL); if (addrs == NULL) { fp = org_fp; goto out; diff --git a/arch/powerpc/oprofile/cell/spu_profiler.c b/arch/powerpc/oprofile/cell/spu_profiler.c index 5182f2936af2..4e099e556645 100644 --- a/arch/powerpc/oprofile/cell/spu_profiler.c +++ b/arch/powerpc/oprofile/cell/spu_profiler.c @@ -210,8 +210,8 @@ int start_spu_profiling_cycles(unsigned int cycles_reset) timer.function = profile_spus; /* Allocate arrays for collecting SPU PC samples */ - samples = kzalloc(SPUS_PER_NODE * - TRACE_ARRAY_SIZE * sizeof(u32), GFP_KERNEL); + samples = kcalloc(SPUS_PER_NODE * TRACE_ARRAY_SIZE, sizeof(u32), + GFP_KERNEL); if (!samples) return -ENOMEM; diff --git a/arch/powerpc/platforms/4xx/hsta_msi.c b/arch/powerpc/platforms/4xx/hsta_msi.c index 9926ad67af76..1c18f2955f7d 100644 --- a/arch/powerpc/platforms/4xx/hsta_msi.c +++ b/arch/powerpc/platforms/4xx/hsta_msi.c @@ -156,7 +156,8 @@ static int hsta_msi_probe(struct platform_device *pdev) if (ret) goto out; - ppc4xx_hsta_msi.irq_map = kmalloc(sizeof(int) * irq_count, GFP_KERNEL); + ppc4xx_hsta_msi.irq_map = kmalloc_array(irq_count, sizeof(int), + GFP_KERNEL); if (!ppc4xx_hsta_msi.irq_map) { ret = -ENOMEM; goto out1; diff --git a/arch/powerpc/platforms/4xx/msi.c b/arch/powerpc/platforms/4xx/msi.c index d50417e23add..79a953af2d62 100644 --- a/arch/powerpc/platforms/4xx/msi.c +++ b/arch/powerpc/platforms/4xx/msi.c @@ -89,7 +89,7 @@ static int ppc4xx_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) if (type == PCI_CAP_ID_MSIX) pr_debug("ppc4xx msi: MSI-X untested, trying anyway.\n"); - msi_data->msi_virqs = kmalloc((msi_irqs) * sizeof(int), GFP_KERNEL); + msi_data->msi_virqs = kmalloc_array(msi_irqs, sizeof(int), GFP_KERNEL); if (!msi_data->msi_virqs) return -ENOMEM; diff --git a/arch/powerpc/platforms/4xx/pci.c b/arch/powerpc/platforms/4xx/pci.c index 256943af58aa..2f237027fdcc 100644 --- a/arch/powerpc/platforms/4xx/pci.c +++ b/arch/powerpc/platforms/4xx/pci.c @@ -1447,7 +1447,7 @@ static int __init ppc4xx_pciex_check_core_init(struct device_node *np) count = ppc4xx_pciex_hwops->core_init(np); if (count > 0) { ppc4xx_pciex_ports = - kzalloc(count * sizeof(struct ppc4xx_pciex_port), + kcalloc(count, sizeof(struct ppc4xx_pciex_port), GFP_KERNEL); if (ppc4xx_pciex_ports) { ppc4xx_pciex_port_count = count; diff --git a/arch/powerpc/platforms/powernv/opal-async.c b/arch/powerpc/platforms/powernv/opal-async.c index 45b3feb8aa2f..64b1c863206c 100644 --- a/arch/powerpc/platforms/powernv/opal-async.c +++ b/arch/powerpc/platforms/powernv/opal-async.c @@ -189,9 +189,9 @@ int __init opal_async_comp_init(void) goto out_opal_node; } - opal_async_responses = kzalloc( - sizeof(*opal_async_responses) * opal_max_async_tokens, - GFP_KERNEL); + opal_async_responses = kcalloc(opal_max_async_tokens, + sizeof(*opal_async_responses), + GFP_KERNEL); if (!opal_async_responses) { pr_err("%s: Out of memory, failed to do asynchronous " "completion init\n", __func__); diff --git a/arch/powerpc/platforms/powernv/opal-sysparam.c b/arch/powerpc/platforms/powernv/opal-sysparam.c index 23fb6647dced..c0b5cfd9e9b0 100644 --- a/arch/powerpc/platforms/powernv/opal-sysparam.c +++ b/arch/powerpc/platforms/powernv/opal-sysparam.c @@ -198,21 +198,21 @@ void __init opal_sys_param_init(void) goto out_param_buf; } - id = kzalloc(sizeof(*id) * count, GFP_KERNEL); + id = kcalloc(count, sizeof(*id), GFP_KERNEL); if (!id) { pr_err("SYSPARAM: Failed to allocate memory to read parameter " "id\n"); goto out_param_buf; } - size = kzalloc(sizeof(*size) * count, GFP_KERNEL); + size = kcalloc(count, sizeof(*size), GFP_KERNEL); if (!size) { pr_err("SYSPARAM: Failed to allocate memory to read parameter " "size\n"); goto out_free_id; } - perm = kzalloc(sizeof(*perm) * count, GFP_KERNEL); + perm = kcalloc(count, sizeof(*perm), GFP_KERNEL); if (!perm) { pr_err("SYSPARAM: Failed to allocate memory to read supported " "action on the parameter"); @@ -235,7 +235,7 @@ void __init opal_sys_param_init(void) goto out_free_perm; } - attr = kzalloc(sizeof(*attr) * count, GFP_KERNEL); + attr = kcalloc(count, sizeof(*attr), GFP_KERNEL); if (!attr) { pr_err("SYSPARAM: Failed to allocate memory for parameter " "attributes\n"); diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 205dec18d6b5..835348fc42c3 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -544,7 +544,7 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic) printk(KERN_INFO "mpic: Setting up HT PICs workarounds for U3/U4\n"); /* Allocate fixups array */ - mpic->fixups = kzalloc(128 * sizeof(*mpic->fixups), GFP_KERNEL); + mpic->fixups = kcalloc(128, sizeof(*mpic->fixups), GFP_KERNEL); BUG_ON(mpic->fixups == NULL); /* Init spinlock */ @@ -1326,7 +1326,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, if (psrc) { /* Allocate a bitmap with one bit per interrupt */ unsigned int mapsize = BITS_TO_LONGS(intvec_top + 1); - mpic->protected = kzalloc(mapsize*sizeof(long), GFP_KERNEL); + mpic->protected = kcalloc(mapsize, sizeof(long), GFP_KERNEL); BUG_ON(mpic->protected == NULL); for (i = 0; i < psize/sizeof(u32); i++) { if (psrc[i] > intvec_top) @@ -1641,8 +1641,9 @@ void __init mpic_init(struct mpic *mpic) #ifdef CONFIG_PM /* allocate memory to save mpic state */ - mpic->save_data = kmalloc(mpic->num_sources * sizeof(*mpic->save_data), - GFP_KERNEL); + mpic->save_data = kmalloc_array(mpic->num_sources, + sizeof(*mpic->save_data), + GFP_KERNEL); BUG_ON(mpic->save_data == NULL); #endif diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c index 30cdcbfa1c04..a0d003e8daf3 100644 --- a/arch/powerpc/sysdev/xive/native.c +++ b/arch/powerpc/sysdev/xive/native.c @@ -499,7 +499,7 @@ static bool xive_parse_provisioning(struct device_node *np) if (rc == 0) return true; - xive_provision_chips = kzalloc(4 * xive_provision_chip_count, + xive_provision_chips = kcalloc(4, xive_provision_chip_count, GFP_KERNEL); if (WARN_ON(!xive_provision_chips)) return false; diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index ef3fb1b9201f..f748b666e519 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -390,7 +390,7 @@ int appldata_register_ops(struct appldata_ops *ops) if (ops->size > APPLDATA_MAX_REC_SIZE) return -EINVAL; - ops->ctl_table = kzalloc(4 * sizeof(struct ctl_table), GFP_KERNEL); + ops->ctl_table = kcalloc(4, sizeof(struct ctl_table), GFP_KERNEL); if (!ops->ctl_table) return -ENOMEM; diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c index be8cc53204b5..a2945b289a29 100644 --- a/arch/s390/hypfs/hypfs_diag.c +++ b/arch/s390/hypfs/hypfs_diag.c @@ -239,7 +239,7 @@ static void *page_align_ptr(void *ptr) static void *diag204_alloc_vbuf(int pages) { /* The buffer has to be page aligned! */ - diag204_buf_vmalloc = vmalloc(PAGE_SIZE * (pages + 1)); + diag204_buf_vmalloc = vmalloc(array_size(PAGE_SIZE, (pages + 1))); if (!diag204_buf_vmalloc) return ERR_PTR(-ENOMEM); diag204_buf = page_align_ptr(diag204_buf_vmalloc); diff --git a/arch/s390/hypfs/hypfs_diag0c.c b/arch/s390/hypfs/hypfs_diag0c.c index dce87f1bec94..cebf05150cc1 100644 --- a/arch/s390/hypfs/hypfs_diag0c.c +++ b/arch/s390/hypfs/hypfs_diag0c.c @@ -49,7 +49,8 @@ static void *diag0c_store(unsigned int *count) get_online_cpus(); cpu_count = num_online_cpus(); - cpu_vec = kmalloc(sizeof(*cpu_vec) * num_possible_cpus(), GFP_KERNEL); + cpu_vec = kmalloc_array(num_possible_cpus(), sizeof(*cpu_vec), + GFP_KERNEL); if (!cpu_vec) goto fail_put_online_cpus; /* Note: Diag 0c needs 8 byte alignment and real storage */ diff --git a/arch/s390/include/asm/idals.h b/arch/s390/include/asm/idals.h index 15578fd762f6..ba5cf3cbf2a6 100644 --- a/arch/s390/include/asm/idals.h +++ b/arch/s390/include/asm/idals.h @@ -77,8 +77,8 @@ set_normalized_cda(struct ccw1 * ccw, void *vaddr) return -EINVAL; nridaws = idal_nr_words(vaddr, ccw->count); if (nridaws > 0) { - idal = kmalloc(nridaws * sizeof(unsigned long), - GFP_ATOMIC | GFP_DMA ); + idal = kmalloc_array(nridaws, sizeof(unsigned long), + GFP_ATOMIC | GFP_DMA ); if (idal == NULL) return -ENOMEM; idal_create_words(idal, vaddr, ccw->count); diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 05a9cf4ae9c2..6b8d06f425b5 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -197,14 +197,14 @@ debug_areas_alloc(int pages_per_area, int nr_areas) debug_entry_t*** areas; int i,j; - areas = kmalloc(nr_areas * - sizeof(debug_entry_t**), + areas = kmalloc_array(nr_areas, sizeof(debug_entry_t **), GFP_KERNEL); if (!areas) goto fail_malloc_areas; for (i = 0; i < nr_areas; i++) { - areas[i] = kmalloc(pages_per_area * - sizeof(debug_entry_t*),GFP_KERNEL); + areas[i] = kmalloc_array(pages_per_area, + sizeof(debug_entry_t *), + GFP_KERNEL); if (!areas[i]) { goto fail_malloc_areas2; } diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index b441e069e674..eb234eeae192 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c @@ -136,8 +136,7 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, /* Allocate one syminfo structure per symbol. */ me->arch.nsyms = symtab->sh_size / sizeof(Elf_Sym); - me->arch.syminfo = vmalloc(me->arch.nsyms * - sizeof(struct mod_arch_syminfo)); + me->arch.syminfo = vmalloc(array_size(sizeof(struct mod_arch_syminfo), me->arch.nsyms)); if (!me->arch.syminfo) return -ENOMEM; symbols = (void *) hdr + symtab->sh_offset; diff --git a/arch/s390/kernel/perf_cpum_cf_events.c b/arch/s390/kernel/perf_cpum_cf_events.c index 08bfa17ba0a0..fb8a769c7f22 100644 --- a/arch/s390/kernel/perf_cpum_cf_events.c +++ b/arch/s390/kernel/perf_cpum_cf_events.c @@ -390,7 +390,7 @@ static __init struct attribute **merge_attr(struct attribute **a, j++; j++; - new = kmalloc(sizeof(struct attribute *) * j, GFP_KERNEL); + new = kmalloc_array(j, sizeof(struct attribute *), GFP_KERNEL); if (!new) return NULL; j = 0; diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index eacda05b45d7..bfa5a0269139 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c @@ -311,7 +311,7 @@ static int __init vdso_init(void) + PAGE_SIZE - 1) >> PAGE_SHIFT) + 1; /* Make sure pages are in the correct state */ - vdso32_pagelist = kzalloc(sizeof(struct page *) * (vdso32_pages + 1), + vdso32_pagelist = kcalloc(vdso32_pages + 1, sizeof(struct page *), GFP_KERNEL); BUG_ON(vdso32_pagelist == NULL); for (i = 0; i < vdso32_pages - 1; i++) { @@ -329,7 +329,7 @@ static int __init vdso_init(void) + PAGE_SIZE - 1) >> PAGE_SHIFT) + 1; /* Make sure pages are in the correct state */ - vdso64_pagelist = kzalloc(sizeof(struct page *) * (vdso64_pages + 1), + vdso64_pagelist = kcalloc(vdso64_pages + 1, sizeof(struct page *), GFP_KERNEL); BUG_ON(vdso64_pagelist == NULL); for (i = 0; i < vdso64_pages - 1; i++) { diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c index c24bfa72baf7..f6df3b9820e5 100644 --- a/arch/s390/kvm/gaccess.c +++ b/arch/s390/kvm/gaccess.c @@ -847,7 +847,7 @@ int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data, nr_pages = (((ga & ~PAGE_MASK) + len - 1) >> PAGE_SHIFT) + 1; pages = pages_array; if (nr_pages > ARRAY_SIZE(pages_array)) - pages = vmalloc(nr_pages * sizeof(unsigned long)); + pages = vmalloc(array_size(nr_pages, sizeof(unsigned long))); if (!pages) return -ENOMEM; need_ipte_lock = psw_bits(*psw).dat && !asce.r; diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 46fee3f4dedd..749158f2d1b3 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -1671,7 +1671,7 @@ static int kvm_s390_set_cmma_bits(struct kvm *kvm, if (args->count == 0) return 0; - bits = vmalloc(sizeof(*bits) * args->count); + bits = vmalloc(array_size(sizeof(*bits), args->count)); if (!bits) return -ENOMEM; diff --git a/arch/s390/kvm/sthyi.c b/arch/s390/kvm/sthyi.c index ffba4617d108..3fdf1962d3bf 100644 --- a/arch/s390/kvm/sthyi.c +++ b/arch/s390/kvm/sthyi.c @@ -308,7 +308,7 @@ static void fill_diag(struct sthyi_sctns *sctns) if (pages <= 0) return; - diag204_buf = vmalloc(PAGE_SIZE * pages); + diag204_buf = vmalloc(array_size(pages, PAGE_SIZE)); if (!diag204_buf) return; diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 290e71e57541..84111a43ea29 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c @@ -103,7 +103,7 @@ static int scode_set; static int dcss_set_subcodes(void) { - char *name = kmalloc(8 * sizeof(char), GFP_KERNEL | GFP_DMA); + char *name = kmalloc(8, GFP_KERNEL | GFP_DMA); unsigned long rx, ry; int rc; diff --git a/arch/sh/drivers/dma/dmabrg.c b/arch/sh/drivers/dma/dmabrg.c index c0dd904483c7..e5a57a109d6c 100644 --- a/arch/sh/drivers/dma/dmabrg.c +++ b/arch/sh/drivers/dma/dmabrg.c @@ -154,7 +154,7 @@ static int __init dmabrg_init(void) unsigned long or; int ret; - dmabrg_handlers = kzalloc(10 * sizeof(struct dmabrg_handler), + dmabrg_handlers = kcalloc(10, sizeof(struct dmabrg_handler), GFP_KERNEL); if (!dmabrg_handlers) return -ENOMEM; diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index 0167a7352719..ab4c765846e2 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -539,7 +539,7 @@ static int __init sh7786_pcie_init(void) if (unlikely(nr_ports == 0)) return -ENODEV; - sh7786_pcie_ports = kzalloc(nr_ports * sizeof(struct sh7786_pcie_port), + sh7786_pcie_ports = kcalloc(nr_ports, sizeof(struct sh7786_pcie_port), GFP_KERNEL); if (unlikely(!sh7786_pcie_ports)) return -ENOMEM; diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index 28cc61216b64..ed5b758c650d 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -203,7 +203,7 @@ syscall_trace_entry: mov.l @(OFF_R7,r15), r7 ! arg3 mov.l @(OFF_R3,r15), r3 ! syscall_nr ! - mov.l 2f, r10 ! Number of syscalls + mov.l 6f, r10 ! Number of syscalls cmp/hs r10, r3 bf syscall_call mov #-ENOSYS, r0 @@ -357,7 +357,7 @@ ENTRY(system_call) tst r9, r8 bf syscall_trace_entry ! - mov.l 2f, r8 ! Number of syscalls + mov.l 6f, r8 ! Number of syscalls cmp/hs r8, r3 bt syscall_badsys ! @@ -396,7 +396,7 @@ syscall_exit: #if !defined(CONFIG_CPU_SH2) 1: .long TRA #endif -2: .long NR_syscalls +6: .long NR_syscalls 3: .long sys_call_table 7: .long do_syscall_trace_enter 8: .long do_syscall_trace_leave diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c index 048ad783ea3f..8babbeb30adf 100644 --- a/arch/sparc/kernel/nmi.c +++ b/arch/sparc/kernel/nmi.c @@ -166,7 +166,8 @@ static int __init check_nmi_watchdog(void) if (!atomic_read(&nmi_active)) return 0; - prev_nmi_count = kmalloc(nr_cpu_ids * sizeof(unsigned int), GFP_KERNEL); + prev_nmi_count = kmalloc_array(nr_cpu_ids, sizeof(unsigned int), + GFP_KERNEL); if (!prev_nmi_count) { err = -ENOMEM; goto error; diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index d79c1c74873c..a9de37a60863 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -577,7 +577,8 @@ SYSCALL_DEFINE5(utrap_install, utrap_entry_t, type, } if (!current_thread_info()->utraps) { current_thread_info()->utraps = - kzalloc((UT_TRAP_INSTRUCTION_31+1)*sizeof(long), GFP_KERNEL); + kcalloc(UT_TRAP_INSTRUCTION_31 + 1, sizeof(long), + GFP_KERNEL); if (!current_thread_info()->utraps) return -ENOMEM; current_thread_info()->utraps[0] = 1; @@ -587,8 +588,9 @@ SYSCALL_DEFINE5(utrap_install, utrap_entry_t, type, unsigned long *p = current_thread_info()->utraps; current_thread_info()->utraps = - kmalloc((UT_TRAP_INSTRUCTION_31+1)*sizeof(long), - GFP_KERNEL); + kmalloc_array(UT_TRAP_INSTRUCTION_31 + 1, + sizeof(long), + GFP_KERNEL); if (!current_thread_info()->utraps) { current_thread_info()->utraps = p; return -ENOMEM; diff --git a/arch/sparc/net/bpf_jit_comp_32.c b/arch/sparc/net/bpf_jit_comp_32.c index 3bd8ca95e521..a5ff88643d5c 100644 --- a/arch/sparc/net/bpf_jit_comp_32.c +++ b/arch/sparc/net/bpf_jit_comp_32.c @@ -335,7 +335,7 @@ void bpf_jit_compile(struct bpf_prog *fp) if (!bpf_jit_enable) return; - addrs = kmalloc(flen * sizeof(*addrs), GFP_KERNEL); + addrs = kmalloc_array(flen, sizeof(*addrs), GFP_KERNEL); if (addrs == NULL) return; diff --git a/arch/tile/kernel/vdso.c b/arch/tile/kernel/vdso.c index 5bc51d7dfdcb..029ad21b09ee 100644 --- a/arch/tile/kernel/vdso.c +++ b/arch/tile/kernel/vdso.c @@ -54,7 +54,7 @@ static struct page **vdso_setup(void *vdso_kbase, unsigned int pages) int i; struct page **pagelist; - pagelist = kzalloc(sizeof(struct page *) * (pages + 1), GFP_KERNEL); + pagelist = kcalloc(pages + 1, sizeof(struct page *), GFP_KERNEL); BUG_ON(pagelist == NULL); for (i = 0; i < pages - 1; i++) { struct page *pg = virt_to_page(vdso_kbase + i*PAGE_SIZE); diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index b55fe9bf5d3e..cf7126c095eb 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1139,9 +1139,9 @@ static int __init ubd_init(void) return -1; } - irq_req_buffer = kmalloc( - sizeof(struct io_thread_req *) * UBD_REQ_BUFFER_SIZE, - GFP_KERNEL + irq_req_buffer = kmalloc_array(UBD_REQ_BUFFER_SIZE, + sizeof(struct io_thread_req *), + GFP_KERNEL ); irq_remainder = 0; @@ -1149,9 +1149,9 @@ static int __init ubd_init(void) printk(KERN_ERR "Failed to initialize ubd buffering\n"); return -1; } - io_req_buffer = kmalloc( - sizeof(struct io_thread_req *) * UBD_REQ_BUFFER_SIZE, - GFP_KERNEL + io_req_buffer = kmalloc_array(UBD_REQ_BUFFER_SIZE, + sizeof(struct io_thread_req *), + GFP_KERNEL ); io_remainder = 0; diff --git a/arch/unicore32/kernel/pm.c b/arch/unicore32/kernel/pm.c index 784bc2db3b28..6f8164d91dc2 100644 --- a/arch/unicore32/kernel/pm.c +++ b/arch/unicore32/kernel/pm.c @@ -109,8 +109,9 @@ static int __init puv3_pm_init(void) return -EINVAL; } - sleep_save = kmalloc(puv3_cpu_pm_fns->save_count - * sizeof(unsigned long), GFP_KERNEL); + sleep_save = kmalloc_array(puv3_cpu_pm_fns->save_count, + sizeof(unsigned long), + GFP_KERNEL); if (!sleep_save) { printk(KERN_ERR "failed to alloc memory for pm save\n"); return -ENOMEM; diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index 9c7ea597eee6..bc2ed038988a 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -527,8 +527,14 @@ pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr # the size-dependent part now grows so fast. # # extra_bytes = (uncompressed_size >> 8) + 65536 +# +# ZSTD compressed data grows by at most 3 bytes per 128K, and only has a 22 +# byte fixed overhead but has a maximum block size of 128K, so it needs a +# larger margin. +# +# extra_bytes = (uncompressed_size >> 8) + 131072 -#define ZO_z_extra_bytes ((ZO_z_output_len >> 8) + 65536) +#define ZO_z_extra_bytes ((ZO_z_output_len >> 8) + 131072) #if ZO_z_output_len > ZO_z_input_len # define ZO_z_extract_offset (ZO_z_output_len + ZO_z_extra_bytes - \ ZO_z_input_len) diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig index e0c6292d05f9..bd6066fd5228 100644 --- a/arch/x86/configs/x86_64_cuttlefish_defconfig +++ b/arch/x86/configs/x86_64_cuttlefish_defconfig @@ -63,13 +63,13 @@ CONFIG_KSM=y CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 CONFIG_ZSMALLOC=y # CONFIG_MTRR is not set +CONFIG_EFI=y CONFIG_HZ_100=y CONFIG_KEXEC=y CONFIG_CRASH_DUMP=y CONFIG_PHYSICAL_START=0x200000 CONFIG_PHYSICAL_ALIGN=0x1000000 CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=ttyS0 reboot=p" CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -230,6 +230,7 @@ CONFIG_OF_UNITTEST=y # CONFIG_PNP_DEBUG_MESSAGES is not set CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_VIRTIO_BLK=y @@ -250,7 +251,7 @@ CONFIG_DM_ZERO=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y -CONFIG_DM_ANDROID_VERITY=y +CONFIG_DM_VERITY_AVB=y CONFIG_DM_BOW=y CONFIG_NETDEVICES=y CONFIG_DUMMY=y @@ -469,6 +470,7 @@ CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y CONFIG_HUGETLBFS=y +# CONFIG_EFIVAR_FS is not set CONFIG_SDCARD_FS=y CONFIG_PSTORE=y CONFIG_PSTORE_CONSOLE=y diff --git a/arch/x86/events/amd/iommu.c b/arch/x86/events/amd/iommu.c index 3641e24fdac5..263cceb97f2f 100644 --- a/arch/x86/events/amd/iommu.c +++ b/arch/x86/events/amd/iommu.c @@ -387,7 +387,7 @@ static __init int _init_events_attrs(void) while (amd_iommu_v2_event_descs[i].attr.attr.name) i++; - attrs = kzalloc(sizeof(struct attribute **) * (i + 1), GFP_KERNEL); + attrs = kcalloc(i + 1, sizeof(struct attribute **), GFP_KERNEL); if (!attrs) return -ENOMEM; diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index c1f7b3cb84a9..7a60f48e631a 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -1615,7 +1615,7 @@ __init struct attribute **merge_attr(struct attribute **a, struct attribute **b) j++; j++; - new = kmalloc(sizeof(struct attribute *) * j, GFP_KERNEL); + new = kmalloc_array(j, sizeof(struct attribute *), GFP_KERNEL); if (!new) return NULL; diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c index c56cb37b88e3..462bd189672d 100644 --- a/arch/x86/events/intel/uncore.c +++ b/arch/x86/events/intel/uncore.c @@ -810,7 +810,7 @@ static int __init uncore_type_init(struct intel_uncore_type *type, bool setid) size_t size; int i, j; - pmus = kzalloc(sizeof(*pmus) * type->num_boxes, GFP_KERNEL); + pmus = kcalloc(type->num_boxes, sizeof(*pmus), GFP_KERNEL); if (!pmus) return -ENOMEM; diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index bbe94b682119..5a1cb67cbcc0 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -1417,7 +1417,7 @@ int mce_threshold_create_device(unsigned int cpu) if (bp) return 0; - bp = kzalloc(sizeof(struct threshold_bank *) * mca_cfg.banks, + bp = kcalloc(mca_cfg.banks, sizeof(struct threshold_bank *), GFP_KERNEL); if (!bp) return -ENOMEM; diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c index c2987daa6a6b..01a2de01e5c9 100644 --- a/arch/x86/kernel/cpu/mtrr/if.c +++ b/arch/x86/kernel/cpu/mtrr/if.c @@ -43,7 +43,7 @@ mtrr_file_add(unsigned long base, unsigned long size, max = num_var_ranges; if (fcount == NULL) { - fcount = kzalloc(max * sizeof *fcount, GFP_KERNEL); + fcount = kcalloc(max, sizeof(*fcount), GFP_KERNEL); if (!fcount) return -ENOMEM; FILE_FCOUNT(file) = fcount; diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index df767e6de8dd..ff2703240cf5 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -611,7 +611,7 @@ static void hpet_msi_capability_lookup(unsigned int start_timer) if (!hpet_domain) return; - hpet_devs = kzalloc(sizeof(struct hpet_dev) * num_timers, GFP_KERNEL); + hpet_devs = kcalloc(num_timers, sizeof(struct hpet_dev), GFP_KERNEL); if (!hpet_devs) return; @@ -969,8 +969,8 @@ int __init hpet_enable(void) #endif cfg = hpet_readl(HPET_CFG); - hpet_boot_cfg = kmalloc((last + 2) * sizeof(*hpet_boot_cfg), - GFP_KERNEL); + hpet_boot_cfg = kmalloc_array(last + 2, sizeof(*hpet_boot_cfg), + GFP_KERNEL); if (hpet_boot_cfg) *hpet_boot_cfg = cfg; else diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c index 02abc134367f..f7833ae4e3f1 100644 --- a/arch/x86/kernel/i8259.c +++ b/arch/x86/kernel/i8259.c @@ -206,7 +206,7 @@ spurious_8259A_irq: * lets ACK and report it. [once per IRQ] */ if (!(spurious_irq_mask & irqmask)) { - printk(KERN_DEBUG + printk_deferred(KERN_DEBUG "spurious 8259A interrupt: IRQ%d.\n", irq); spurious_irq_mask |= irqmask; } diff --git a/arch/x86/kernel/ksysfs.c b/arch/x86/kernel/ksysfs.c index 8c1cc08f514f..163ae706a0d4 100644 --- a/arch/x86/kernel/ksysfs.c +++ b/arch/x86/kernel/ksysfs.c @@ -283,7 +283,7 @@ static int __init create_setup_data_nodes(struct kobject *parent) if (ret) goto out_setup_data_kobj; - kobjp = kmalloc(sizeof(*kobjp) * nr, GFP_KERNEL); + kobjp = kmalloc_array(nr, sizeof(*kobjp), GFP_KERNEL); if (!kobjp) { ret = -ENOMEM; goto out_setup_data_kobj; diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c index 4d193d491c92..626495c27d18 100644 --- a/arch/x86/kernel/unwind_orc.c +++ b/arch/x86/kernel/unwind_orc.c @@ -345,8 +345,11 @@ bool unwind_next_frame(struct unwind_state *state) /* * Find the orc_entry associated with the text address. * - * Decrement call return addresses by one so they work for sibling - * calls and calls to noreturn functions. + * For a call frame (as opposed to a signal frame), state->ip points to + * the instruction after the call. That instruction's stack layout + * could be different from the call instruction's layout, for example + * if the call was to a noreturn function. So get the ORC data for the + * call instruction itself. */ orc = orc_find(state->signal ? state->ip : state->ip - 1); if (!orc || orc->sp_reg == ORC_REG_UNDEFINED) @@ -549,6 +552,7 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task, state->sp = task->thread.sp; state->bp = READ_ONCE_NOCHECK(frame->bp); state->ip = READ_ONCE_NOCHECK(frame->ret_addr); + state->signal = (void *)state->ip == ret_from_fork; } if (get_stack_info((unsigned long *)state->sp, state->task, diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 5d34ea68298b..7f123b181aa8 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -357,6 +357,7 @@ SECTIONS .bss : AT(ADDR(.bss) - LOAD_OFFSET) { __bss_start = .; *(.bss..page_aligned) + . = ALIGN(PAGE_SIZE); *(BSS_MAIN) . = ALIGN(PAGE_SIZE); __bss_stop = .; diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 6ec1cfd0addd..2fc0e2619531 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -198,8 +198,7 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, goto out; r = -ENOMEM; if (cpuid->nent) { - cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry) * - cpuid->nent); + cpuid_entries = vmalloc(array_size(sizeof(struct kvm_cpuid_entry), cpuid->nent)); if (!cpuid_entries) goto out; r = -EFAULT; @@ -787,7 +786,7 @@ int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid, return -EINVAL; r = -ENOMEM; - cpuid_entries = vzalloc(sizeof(struct kvm_cpuid_entry2) * cpuid->nent); + cpuid_entries = vzalloc(array_size(sizeof(struct kvm_cpuid_entry2), cpuid->nent)); if (!cpuid_entries) goto out; diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 537c36b55b5d..d4fdf0e52144 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1918,7 +1918,7 @@ void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data) { struct kvm_lapic *apic = vcpu->arch.apic; - if (!lapic_in_kernel(vcpu) || apic_lvtt_oneshot(apic) || + if (!kvm_apic_present(vcpu) || apic_lvtt_oneshot(apic) || apic_lvtt_period(apic)) return; diff --git a/arch/x86/kvm/page_track.c b/arch/x86/kvm/page_track.c index ea67dc876316..9f93cdc10779 100644 --- a/arch/x86/kvm/page_track.c +++ b/arch/x86/kvm/page_track.c @@ -40,8 +40,9 @@ int kvm_page_track_create_memslot(struct kvm_memory_slot *slot, int i; for (i = 0; i < KVM_PAGE_TRACK_MAX; i++) { - slot->arch.gfn_track[i] = kvzalloc(npages * - sizeof(*slot->arch.gfn_track[i]), GFP_KERNEL); + slot->arch.gfn_track[i] = kvcalloc(npages, + sizeof(*slot->arch.gfn_track[i]), + GFP_KERNEL); if (!slot->arch.gfn_track[i]) goto track_free; } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 09f47c837c25..c8ec2de41edf 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3075,6 +3075,9 @@ static void kvm_steal_time_set_preempted(struct kvm_vcpu *vcpu) if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED)) return; + if (vcpu->arch.st.steal.preempted) + return; + vcpu->arch.st.steal.preempted = 1; kvm_write_guest_offset_cached(vcpu->kvm, &vcpu->arch.st.stime, @@ -8572,13 +8575,14 @@ int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, slot->base_gfn, level) + 1; slot->arch.rmap[i] = - kvzalloc(lpages * sizeof(*slot->arch.rmap[i]), GFP_KERNEL); + kvcalloc(lpages, sizeof(*slot->arch.rmap[i]), + GFP_KERNEL); if (!slot->arch.rmap[i]) goto out_free; if (i == 0) continue; - linfo = kvzalloc(lpages * sizeof(*linfo), GFP_KERNEL); + linfo = kvcalloc(lpages, sizeof(*linfo), GFP_KERNEL); if (!linfo) goto out_free; diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index 14a043f66669..2dfbe49947fc 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -1146,7 +1146,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) prog = tmp; } - addrs = kmalloc(prog->len * sizeof(*addrs), GFP_KERNEL); + addrs = kmalloc_array(prog->len, sizeof(*addrs), GFP_KERNEL); if (!addrs) { prog = orig_prog; goto out; diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index c4b3646bd04c..8be380e4e39f 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -168,7 +168,7 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) if (type == PCI_CAP_ID_MSI && nvec > 1) return 1; - v = kzalloc(sizeof(int) * max(1, nvec), GFP_KERNEL); + v = kcalloc(max(1, nvec), sizeof(int), GFP_KERNEL); if (!v) return -ENOMEM; diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index 34f9a9ce6236..cff0550ad391 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c @@ -2142,7 +2142,7 @@ static int __init init_per_cpu(int nuvhubs, int base_part_pnode) if (is_uv3_hub() || is_uv2_hub() || is_uv1_hub()) timeout_us = calculate_destination_timeout(); - vp = kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL); + vp = kmalloc_array(nuvhubs, sizeof(struct uvhub_desc), GFP_KERNEL); uvhub_descs = (struct uvhub_desc *)vp; memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc)); uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL); diff --git a/arch/x86/platform/uv/uv_time.c b/arch/x86/platform/uv/uv_time.c index b082d71b08ee..a36b368eea08 100644 --- a/arch/x86/platform/uv/uv_time.c +++ b/arch/x86/platform/uv/uv_time.c @@ -158,7 +158,7 @@ static __init int uv_rtc_allocate_timers(void) { int cpu; - blade_info = kzalloc(uv_possible_blades * sizeof(void *), GFP_KERNEL); + blade_info = kcalloc(uv_possible_blades, sizeof(void *), GFP_KERNEL); if (!blade_info) return -ENOMEM; diff --git a/block/bio.c b/block/bio.c index 0e9e16764586..6913e2ba4fdc 100644 --- a/block/bio.c +++ b/block/bio.c @@ -2206,7 +2206,8 @@ static int __init init_bio(void) { bio_slab_max = 2; bio_slab_nr = 0; - bio_slabs = kzalloc(bio_slab_max * sizeof(struct bio_slab), GFP_KERNEL); + bio_slabs = kcalloc(bio_slab_max, sizeof(struct bio_slab), + GFP_KERNEL); if (!bio_slabs) panic("bio: can't allocate bios\n"); diff --git a/block/blk-mq.c b/block/blk-mq.c index cf56bdad2e06..4d3264644d98 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1815,7 +1815,7 @@ struct blk_mq_tags *blk_mq_alloc_rq_map(struct blk_mq_tag_set *set, if (!tags) return NULL; - tags->rqs = kzalloc_node(nr_tags * sizeof(struct request *), + tags->rqs = kcalloc_node(nr_tags, sizeof(struct request *), GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY, node); if (!tags->rqs) { @@ -1823,9 +1823,9 @@ struct blk_mq_tags *blk_mq_alloc_rq_map(struct blk_mq_tag_set *set, return NULL; } - tags->static_rqs = kzalloc_node(nr_tags * sizeof(struct request *), - GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY, - node); + tags->static_rqs = kcalloc_node(nr_tags, sizeof(struct request *), + GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY, + node); if (!tags->static_rqs) { kfree(tags->rqs); blk_mq_free_tags(tags); @@ -2021,7 +2021,7 @@ static int blk_mq_init_hctx(struct request_queue *q, * Allocate space for all possible cpus to avoid allocation at * runtime */ - hctx->ctxs = kmalloc_node(nr_cpu_ids * sizeof(void *), + hctx->ctxs = kmalloc_array_node(nr_cpu_ids, sizeof(void *), GFP_KERNEL, node); if (!hctx->ctxs) goto unregister_cpu_notifier; @@ -2421,7 +2421,7 @@ struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, /* init q->mq_kobj and sw queues' kobjects */ blk_mq_sysfs_init(q); - q->queue_hw_ctx = kzalloc_node(nr_cpu_ids * sizeof(*(q->queue_hw_ctx)), + q->queue_hw_ctx = kcalloc_node(nr_cpu_ids, sizeof(*(q->queue_hw_ctx)), GFP_KERNEL, set->numa_node); if (!q->queue_hw_ctx) goto err_percpu; @@ -2636,14 +2636,14 @@ int blk_mq_alloc_tag_set(struct blk_mq_tag_set *set) if (set->nr_hw_queues > nr_cpu_ids) set->nr_hw_queues = nr_cpu_ids; - set->tags = kzalloc_node(nr_cpu_ids * sizeof(struct blk_mq_tags *), + set->tags = kcalloc_node(nr_cpu_ids, sizeof(struct blk_mq_tags *), GFP_KERNEL, set->numa_node); if (!set->tags) return -ENOMEM; ret = -ENOMEM; - set->mq_map = kzalloc_node(sizeof(*set->mq_map) * nr_cpu_ids, - GFP_KERNEL, set->numa_node); + set->mq_map = kcalloc_node(nr_cpu_ids, sizeof(*set->mq_map), + GFP_KERNEL, set->numa_node); if (!set->mq_map) goto out_free_tags; diff --git a/block/blk-tag.c b/block/blk-tag.c index 09f19c6c52ce..24b20d86bcbc 100644 --- a/block/blk-tag.c +++ b/block/blk-tag.c @@ -99,12 +99,12 @@ init_tag_map(struct request_queue *q, struct blk_queue_tag *tags, int depth) __func__, depth); } - tag_index = kzalloc(depth * sizeof(struct request *), GFP_ATOMIC); + tag_index = kcalloc(depth, sizeof(struct request *), GFP_ATOMIC); if (!tag_index) goto fail; nr_ulongs = ALIGN(depth, BITS_PER_LONG) / BITS_PER_LONG; - tag_map = kzalloc(nr_ulongs * sizeof(unsigned long), GFP_ATOMIC); + tag_map = kcalloc(nr_ulongs, sizeof(unsigned long), GFP_ATOMIC); if (!tag_map) goto fail; diff --git a/block/blk-zoned.c b/block/blk-zoned.c index 77fce6f09f78..5fa41d42bf53 100644 --- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -289,8 +289,8 @@ int blkdev_report_zones_ioctl(struct block_device *bdev, fmode_t mode, if (rep.nr_zones > INT_MAX / sizeof(struct blk_zone)) return -ERANGE; - zones = kvmalloc(rep.nr_zones * sizeof(struct blk_zone), - GFP_KERNEL | __GFP_ZERO); + zones = kvmalloc_array(rep.nr_zones, sizeof(struct blk_zone), + GFP_KERNEL | __GFP_ZERO); if (!zones) return -ENOMEM; diff --git a/block/partitions/check.c b/block/partitions/check.c index 720145c49066..ffe408fead0c 100644 --- a/block/partitions/check.c +++ b/block/partitions/check.c @@ -122,7 +122,7 @@ static struct parsed_partitions *allocate_partitions(struct gendisk *hd) return NULL; nr = disk_max_parts(hd); - state->parts = vzalloc(nr * sizeof(state->parts[0])); + state->parts = vzalloc(array_size(nr, sizeof(state->parts[0]))); if (!state->parts) { kfree(state); return NULL; diff --git a/block/partitions/ldm.c b/block/partitions/ldm.c index 2a365c756648..0417937dfe99 100644 --- a/block/partitions/ldm.c +++ b/block/partitions/ldm.c @@ -378,7 +378,7 @@ static bool ldm_validate_tocblocks(struct parsed_partitions *state, BUG_ON(!state || !ldb); ph = &ldb->ph; tb[0] = &ldb->toc; - tb[1] = kmalloc(sizeof(*tb[1]) * 3, GFP_KERNEL); + tb[1] = kmalloc_array(3, sizeof(*tb[1]), GFP_KERNEL); if (!tb[1]) { ldm_crit("Out of memory."); goto err; diff --git a/build-lto.sh b/build-lto.sh index a4276c643f81..2b4268b4de10 100644 --- a/build-lto.sh +++ b/build-lto.sh @@ -6,14 +6,14 @@ export KBUILD_BUILD_HOST=CuntsSpace make ARCH=arm64 \ O=${OUT_DIR} \ raphael_defconfig \ - -j4 + -j8 scripts/config --file ${OUT_DIR}/.config \ -e LTO \ -e LTO_CLANG \ + -e SHADOW_CALL_STACK \ -e TOOLS_SUPPORT_RELR \ - -e LD_LLD \ - -e LLVM_POLLY + -e LD_LLD cd ${OUT_DIR} make O=${OUT_DIR} \ @@ -24,17 +24,20 @@ cd ../ PATH=/home/utsavthecunt/proton-clang/bin/:$PATH make ARCH=arm64 \ - O=out \ + O=${OUT_DIR} \ CC="ccache clang" \ + LLVM_IAS=1 \ LD="ld.lld" \ AR="llvm-ar" \ NM="llvm-nm" \ OBJCOPY="llvm-objcopy" \ OBJDUMP="llvm-objdump" \ + OBJSIZE="llvm-size" \ + READELF="llvm-readelf" \ STRIP="llvm-strip" \ CLANG_TRIPLE="aarch64-linux-gnu-" \ CROSS_COMPILE="aarch64-linux-gnu-" \ CROSS_COMPILE_ARM32="arm-linux-gnueabi-" \ - -j4 + -j8 -rm out/.version +rm ${OUT_DIR}/.version diff --git a/build.sh b/build.sh index 89d689de1e03..0ddef5fe0729 100644 --- a/build.sh +++ b/build.sh @@ -6,14 +6,14 @@ export KBUILD_BUILD_HOST=CuntsSpace make ARCH=arm64 \ O=${OUT_DIR} \ raphael_defconfig \ - -j4 + -j8 scripts/config --file ${OUT_DIR}/.config \ -d LTO \ -d LTO_CLANG \ + -e SHADOW_CALL_STACK \ -e TOOLS_SUPPORT_RELR \ - -e LD_LLD \ - -e LLVM_POLLY + -e LD_LLD cd ${OUT_DIR} make O=${OUT_DIR} \ @@ -24,7 +24,7 @@ cd ../ PATH=/home/utsavthecunt/proton-clang/bin/:$PATH make ARCH=arm64 \ - O=out \ + O=${OUT_DIR} \ CC="ccache clang" \ LD="ld.lld" \ AR="llvm-ar" \ @@ -35,6 +35,6 @@ make ARCH=arm64 \ CLANG_TRIPLE="aarch64-linux-gnu-" \ CROSS_COMPILE="aarch64-linux-gnu-" \ CROSS_COMPILE_ARM32="arm-linux-gnueabi-" \ - -j4 + -j8 -rm out/.version +rm ${OUT_DIR}/.version diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 3f3b57f80bdb..10a7d6b0e85b 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -528,8 +528,8 @@ int af_alg_alloc_tsgl(struct sock *sk) sg = sgl->sg; if (!sg || sgl->cur >= MAX_SGL_ENTS) { - sgl = sock_kmalloc(sk, sizeof(*sgl) + - sizeof(sgl->sg[0]) * (MAX_SGL_ENTS + 1), + sgl = sock_kmalloc(sk, + struct_size(sgl, sg, (MAX_SGL_ENTS + 1)), GFP_KERNEL); if (!sgl) return -ENOMEM; diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c index 379e83c8aa52..622e132d12bd 100644 --- a/crypto/algif_aead.c +++ b/crypto/algif_aead.c @@ -256,8 +256,8 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg, processed - as); if (!areq->tsgl_entries) areq->tsgl_entries = 1; - areq->tsgl = sock_kmalloc(sk, sizeof(*areq->tsgl) * - areq->tsgl_entries, + areq->tsgl = sock_kmalloc(sk, + array_size(sizeof(*areq->tsgl), areq->tsgl_entries), GFP_KERNEL); if (!areq->tsgl) { err = -ENOMEM; diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index d9ec5dca8672..e328eecda03c 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -103,7 +103,8 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, areq->tsgl_entries = af_alg_count_tsgl(sk, len, 0); if (!areq->tsgl_entries) areq->tsgl_entries = 1; - areq->tsgl = sock_kmalloc(sk, sizeof(*areq->tsgl) * areq->tsgl_entries, + areq->tsgl = sock_kmalloc(sk, + array_size(sizeof(*areq->tsgl), areq->tsgl_entries), GFP_KERNEL); if (!areq->tsgl) { err = -ENOMEM; diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 77abff18fde6..84bf3d473ae2 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -430,7 +430,7 @@ static void test_mb_ahash_speed(const char *algo, unsigned int sec, unsigned int i, j, k; int ret; - data = kzalloc(sizeof(*data) * 8, GFP_KERNEL); + data = kcalloc(8, sizeof(*data), GFP_KERNEL); if (!data) return; diff --git a/crypto/testmgr.c b/crypto/testmgr.c index db88375bb40a..2074532a355d 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -604,7 +604,8 @@ static int __test_aead(struct crypto_aead *tfm, int enc, goto out_nooutbuf; /* avoid "the frame size is larger than 1024 bytes" compiler warning */ - sg = kmalloc(sizeof(*sg) * 8 * (diff_dst ? 4 : 2), GFP_KERNEL); + sg = kmalloc(array3_size(sizeof(*sg), 8, (diff_dst ? 4 : 2)), + GFP_KERNEL); if (!sg) goto out_nosg; sgout = &sg[16]; diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index ecd84d910ed2..1f32caa87686 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -83,7 +83,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev, if (count < 0) { return NULL; } else if (count > 0) { - resources = kzalloc(count * sizeof(struct resource), + resources = kcalloc(count, sizeof(struct resource), GFP_KERNEL); if (!resources) { dev_err(&adev->dev, "No memory for resources\n"); diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 7df7abde1fcb..45e4a1f4b36b 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -861,8 +861,9 @@ int acpi_video_get_levels(struct acpi_device *device, * in order to account for buggy BIOS which don't export the first two * special levels (see below) */ - br->levels = kmalloc((obj->package.count + ACPI_VIDEO_FIRST_LEVEL) * - sizeof(*br->levels), GFP_KERNEL); + br->levels = kmalloc_array(obj->package.count + ACPI_VIDEO_FIRST_LEVEL, + sizeof(*br->levels), + GFP_KERNEL); if (!br->levels) { result = -ENOMEM; goto out_free; diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 5b149d2d52f4..7115562de78e 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c @@ -524,7 +524,8 @@ retry: pr_warn(FW_WARN "too many record IDs!\n"); return 0; } - new_entries = kvmalloc(new_size * sizeof(entries[0]), GFP_KERNEL); + new_entries = kvmalloc_array(new_size, sizeof(entries[0]), + GFP_KERNEL); if (!new_entries) return -ENOMEM; memcpy(new_entries, entries, diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index 9cb74115a43d..b1e9f81ebeea 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c @@ -195,7 +195,8 @@ static int __init hest_ghes_dev_register(unsigned int ghes_count) struct ghes_arr ghes_arr; ghes_arr.count = 0; - ghes_arr.ghes_devs = kmalloc(sizeof(void *) * ghes_count, GFP_KERNEL); + ghes_arr.ghes_devs = kmalloc_array(ghes_count, sizeof(void *), + GFP_KERNEL); if (!ghes_arr.ghes_devs) return -ENOMEM; diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 6cf4988206f2..774b7d4a12d8 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -298,8 +298,8 @@ static int acpi_fan_get_fps(struct acpi_device *device) } fan->fps_count = obj->package.count - 1; /* minus revision field */ - fan->fps = devm_kzalloc(&device->dev, - fan->fps_count * sizeof(struct acpi_fan_fps), + fan->fps = devm_kcalloc(&device->dev, + fan->fps_count, sizeof(struct acpi_fan_fps), GFP_KERNEL); if (!fan->fps) { dev_err(&device->dev, "Not enough memory\n"); diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index 1872dc01be13..f8694680e5db 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -866,9 +866,10 @@ static int __nfit_mem_init(struct acpi_nfit_desc *acpi_desc, continue; nfit_mem->nfit_flush = nfit_flush; flush = nfit_flush->flush; - nfit_mem->flush_wpq = devm_kzalloc(acpi_desc->dev, - flush->hint_count - * sizeof(struct resource), GFP_KERNEL); + nfit_mem->flush_wpq = devm_kcalloc(acpi_desc->dev, + flush->hint_count, + sizeof(struct resource), + GFP_KERNEL); if (!nfit_mem->flush_wpq) return -ENOMEM; for (i = 0; i < flush->hint_count; i++) { diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index c7cf48ad5cb9..588a8b27d4e1 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -343,8 +343,9 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) pr->performance->state_count = pss->package.count; pr->performance->states = - kmalloc(sizeof(struct acpi_processor_px) * pss->package.count, - GFP_KERNEL); + kmalloc_array(pss->package.count, + sizeof(struct acpi_processor_px), + GFP_KERNEL); if (!pr->performance->states) { result = -ENOMEM; goto end; diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 9fdc13a2f2d5..62c0fe9ef412 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -534,8 +534,9 @@ static int acpi_processor_get_throttling_states(struct acpi_processor *pr) pr->throttling.state_count = tss->package.count; pr->throttling.states_tss = - kmalloc(sizeof(struct acpi_processor_tx_tss) * tss->package.count, - GFP_KERNEL); + kmalloc_array(tss->package.count, + sizeof(struct acpi_processor_tx_tss), + GFP_KERNEL); if (!pr->throttling.states_tss) { result = -ENOMEM; goto end; diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 1828b335c28a..5375e8894c0a 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -866,12 +866,12 @@ void acpi_irq_stats_init(void) num_gpes = acpi_current_gpe_count; num_counters = num_gpes + ACPI_NUM_FIXED_EVENTS + NUM_COUNTERS_EXTRA; - all_attrs = kzalloc(sizeof(struct attribute *) * (num_counters + 1), + all_attrs = kcalloc(num_counters + 1, sizeof(struct attribute *), GFP_KERNEL); if (all_attrs == NULL) return; - all_counters = kzalloc(sizeof(struct event_counter) * (num_counters), + all_counters = kcalloc(num_counters, sizeof(struct event_counter), GFP_KERNEL); if (all_counters == NULL) goto fail; @@ -880,7 +880,7 @@ void acpi_irq_stats_init(void) if (ACPI_FAILURE(status)) goto fail; - counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters), + counter_attrs = kcalloc(num_counters, sizeof(struct kobj_attribute), GFP_KERNEL); if (counter_attrs == NULL) goto fail; diff --git a/drivers/android/binderfs.c b/drivers/android/binderfs.c index 110e41f920c2..14a4bef358cd 100644 --- a/drivers/android/binderfs.c +++ b/drivers/android/binderfs.c @@ -657,7 +657,7 @@ static int binderfs_fill_super(struct super_block *sb, void *data, int silent) int ret; struct binderfs_info *info; struct inode *inode = NULL; - struct binderfs_device device_info = { 0 }; + struct binderfs_device device_info = { { 0 } }; const char *name; size_t len; diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index a3a65f5490c0..0eb1ec5941f9 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6980,7 +6980,7 @@ static void __init ata_parse_force_param(void) if (*p == ',') size++; - ata_force_tbl = kzalloc(sizeof(ata_force_tbl[0]) * size, GFP_KERNEL); + ata_force_tbl = kcalloc(size, sizeof(ata_force_tbl[0]), GFP_KERNEL); if (!ata_force_tbl) { printk(KERN_WARNING "ata: failed to extend force table, " "libata.force ignored\n"); diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index 7924d0635718..51eeaea65833 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c @@ -340,7 +340,7 @@ static int sata_pmp_init_links (struct ata_port *ap, int nr_ports) int i, err; if (!pmp_link) { - pmp_link = kzalloc(sizeof(pmp_link[0]) * SATA_PMP_MAX_PORTS, + pmp_link = kcalloc(SATA_PMP_MAX_PORTS, sizeof(pmp_link[0]), GFP_NOIO); if (!pmp_link) return -ENOMEM; diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 3b2246dded74..8c10c3e43880 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -4116,13 +4116,13 @@ static int mv_platform_probe(struct platform_device *pdev) if (!host || !hpriv) return -ENOMEM; - hpriv->port_clks = devm_kzalloc(&pdev->dev, - sizeof(struct clk *) * n_ports, + hpriv->port_clks = devm_kcalloc(&pdev->dev, + n_ports, sizeof(struct clk *), GFP_KERNEL); if (!hpriv->port_clks) return -ENOMEM; - hpriv->port_phys = devm_kzalloc(&pdev->dev, - sizeof(struct phy *) * n_ports, + hpriv->port_phys = devm_kcalloc(&pdev->dev, + n_ports, sizeof(struct phy *), GFP_KERNEL); if (!hpriv->port_phys) return -ENOMEM; diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index 0a1ad1a1d34f..de03d213bc76 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -2097,7 +2097,8 @@ static int fore200e_alloc_rx_buf(struct fore200e *fore200e) DPRINTK(2, "rx buffers %d / %d are being allocated\n", scheme, magn); /* allocate the array of receive buffers */ - buffer = bsq->buffer = kzalloc(nbr * sizeof(struct buffer), GFP_KERNEL); + buffer = bsq->buffer = kcalloc(nbr, sizeof(struct buffer), + GFP_KERNEL); if (buffer == NULL) return -ENOMEM; diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index 2b29598791e8..2658b75f0ca8 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -1619,7 +1619,7 @@ static int rx_init(struct atm_dev *dev) skb_queue_head_init(&iadev->rx_dma_q); iadev->rx_free_desc_qhead = NULL; - iadev->rx_open = kzalloc(4 * iadev->num_vc, GFP_KERNEL); + iadev->rx_open = kcalloc(4, iadev->num_vc, GFP_KERNEL); if (!iadev->rx_open) { printk(KERN_ERR DEV_LABEL "itf %d couldn't get free page\n", dev->number); diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 0df1a1c80b00..17283018269f 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -1291,7 +1291,8 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) card->using_dma = 1; if (1) { /* All known FPGA versions so far */ card->dma_alignment = 3; - card->dma_bounce = kmalloc(card->nr_ports * BUF_SIZE, GFP_KERNEL); + card->dma_bounce = kmalloc_array(card->nr_ports, + BUF_SIZE, GFP_KERNEL); if (!card->dma_bounce) { dev_warn(&card->dev->dev, "Failed to allocate DMA bounce buffers\n"); err = -ENOMEM; diff --git a/drivers/auxdisplay/cfag12864b.c b/drivers/auxdisplay/cfag12864b.c index 41ce4bd96813..d688e94635bb 100644 --- a/drivers/auxdisplay/cfag12864b.c +++ b/drivers/auxdisplay/cfag12864b.c @@ -347,8 +347,8 @@ static int __init cfag12864b_init(void) goto none; } - cfag12864b_cache = kmalloc(sizeof(unsigned char) * - CFAG12864B_SIZE, GFP_KERNEL); + cfag12864b_cache = kmalloc(CFAG12864B_SIZE, + GFP_KERNEL); if (cfag12864b_cache == NULL) { printk(KERN_ERR CFAG12864B_NAME ": ERROR: " "can't alloc cache buffer (%i bytes)\n", diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index 0d9e8a6d6789..c7f88586a7f9 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -192,7 +192,7 @@ int detect_share_cap_flag(void) if (cpumask_equal(topology_core_cpumask(cpu), policy->related_cpus)) { share_cap_level = share_cap_core; - cpufreq_cpu_put(policy); + cpufreq_cpu_put(policy); continue; } diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 5a537093b9a6..11027b2146bc 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -435,16 +435,6 @@ static int cpu_uevent(struct device *dev, struct kobj_uevent_env *env) } #endif -static int cpu_dev_pm_unset_is_prepared(unsigned int cpu) -{ - struct device *cpu_dev = get_cpu_device(cpu); - - if (cpu_dev) - cpu_dev->power.is_prepared = false; - - return 0; -} - /* * register_cpu - Setup a sysfs device for a CPU. * @cpu - cpu->hotpluggable field set to 1 will generate a control file in @@ -479,9 +469,7 @@ int register_cpu(struct cpu *cpu, int num) register_cpu_under_node(num, cpu_to_node(num)); dev_pm_qos_expose_latency_limit(&cpu->dev, 0); - return cpuhp_setup_state_nocalls(CPUHP_CPUDEV_PM_PREPARE, - "base/cpu/dev_pm:prepare", - cpu_dev_pm_unset_is_prepared, NULL); + return 0; } struct device *get_cpu_device(unsigned cpu) diff --git a/drivers/base/devres.c b/drivers/base/devres.c index e43a04a495a3..9b495725da13 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -91,9 +91,14 @@ static struct devres_group * node_to_group(struct devres_node *node) static __always_inline struct devres * alloc_dr(dr_release_t release, size_t size, gfp_t gfp, int nid) { - size_t tot_size = sizeof(struct devres) + size; + size_t tot_size; struct devres *dr; + /* We must catch any near-SIZE_MAX cases that could overflow. */ + if (unlikely(check_add_overflow(sizeof(struct devres), size, + &tot_size))) + return NULL; + dr = kmalloc_node_track_caller(tot_size, gfp, nid); if (unlikely(!dr)) return NULL; diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 364181591f77..3f795dea954b 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -382,9 +382,9 @@ static void fw_free_buf(struct firmware_buf *buf) static char fw_path_para[256]; static const char * const fw_path[] = { fw_path_para, - "/lib/firmware/updates/" UTS_RELEASE, + "/lib/firmware/updates/", UTS_RELEASE, "/lib/firmware/updates", - "/lib/firmware/" UTS_RELEASE, + "/lib/firmware/", UTS_RELEASE, "/lib/firmware" }; @@ -898,7 +898,7 @@ static int fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) buf->page_array_size * 2); struct page **new_pages; - new_pages = vmalloc(new_array_size * sizeof(void *)); + new_pages = vmalloc(array_size(new_array_size, sizeof(void *))); if (!new_pages) { fw_load_abort(fw_priv); return -ENOMEM; diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index b069a1cc729b..99ddcf8a9260 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -969,8 +969,20 @@ void pm_wakeup_clear(bool reset) void pm_system_irq_wakeup(unsigned int irq_number) { - + struct irq_desc *desc; + const char *name = "null"; if (pm_wakeup_irq == 0) { + if (msm_show_resume_irq_mask) { + desc = irq_to_desc(irq_number); + if (desc == NULL) + name = "stray irq"; + else if (desc->action && desc->action->name) + name = desc->action->name; + + pr_warn("%s: %d triggered %s\n", __func__, + irq_number, name); + + } pm_wakeup_irq = irq_number; pm_system_wakeup(); } diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index f49229b619c1..7df8dd32cfac 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c @@ -204,6 +204,9 @@ static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from, if (*ppos < 0 || !count) return -EINVAL; + if (count > (PAGE_SIZE << (MAX_ORDER - 1))) + count = PAGE_SIZE << (MAX_ORDER - 1); + buf = kmalloc(count, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -415,6 +418,9 @@ static ssize_t regmap_reg_ranges_read_file(struct file *file, if (*ppos < 0 || !count) return -EINVAL; + if (count > (PAGE_SIZE << (MAX_ORDER - 1))) + count = PAGE_SIZE << (MAX_ORDER - 1); + buf = kmalloc(count, GFP_KERNEL); if (!buf) return -ENOMEM; diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 255591ab3716..33ed2f9ff70c 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -5727,8 +5727,8 @@ static bool DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller, Controller->CombinedStatusBufferLength = NewStatusBufferLength; return true; } - NewStatusBuffer = kmalloc(2 * Controller->CombinedStatusBufferLength, - GFP_ATOMIC); + NewStatusBuffer = kmalloc_array(2, Controller->CombinedStatusBufferLength, + GFP_ATOMIC); if (NewStatusBuffer == NULL) { DAC960_Warning("Unable to expand Combined Status Buffer - Truncating\n", diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index b998e3abca7a..1ae93c30ae8c 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -513,7 +513,8 @@ static void drbd_calc_cpu_mask(cpumask_var_t *cpu_mask) { unsigned int *resources_per_cpu, min_index = ~0; - resources_per_cpu = kzalloc(nr_cpu_ids * sizeof(*resources_per_cpu), GFP_KERNEL); + resources_per_cpu = kcalloc(nr_cpu_ids, sizeof(*resources_per_cpu), + GFP_KERNEL); if (resources_per_cpu) { struct drbd_resource *resource; unsigned int cpu, min = ~0; diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 2bbd6bed1535..a1aaba8cbb83 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -225,24 +225,35 @@ static void __loop_update_dio(struct loop_device *lo, bool dio) blk_mq_unfreeze_queue(lo->lo_queue); } +/** + * loop_validate_block_size() - validates the passed in block size + * @bsize: size to validate + */ static int -figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit) +loop_validate_block_size(unsigned short bsize) +{ + if (bsize < 512 || bsize > PAGE_SIZE || !is_power_of_2(bsize)) + return -EINVAL; + + return 0; +} + +/** + * loop_set_size() - sets device size and notifies userspace + * @lo: struct loop_device to set the size for + * @size: new size of the loop device + * + * Callers must validate that the size passed into this function fits into + * a sector_t, eg using loop_validate_size() + */ +static void loop_set_size(struct loop_device *lo, loff_t size) { - loff_t size = get_size(offset, sizelimit, lo->lo_backing_file); - sector_t x = (sector_t)size; struct block_device *bdev = lo->lo_device; - if (unlikely((loff_t)x != size)) - return -EFBIG; - if (lo->lo_offset != offset) - lo->lo_offset = offset; - if (lo->lo_sizelimit != sizelimit) - lo->lo_sizelimit = sizelimit; - set_capacity(lo->lo_disk, x); - bd_set_size(bdev, (loff_t)get_capacity(bdev->bd_disk) << 9); + set_capacity(lo->lo_disk, size); + bd_set_size(bdev, size << 9); /* let user-space know about the new size */ kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE); - return 0; } static inline int @@ -502,7 +513,8 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd, __rq_for_each_bio(bio, rq) segments += bio_segments(bio); - bvec = kmalloc(sizeof(struct bio_vec) * segments, GFP_NOIO); + bvec = kmalloc_array(segments, sizeof(struct bio_vec), + GFP_NOIO); if (!bvec) return -EIO; cmd->bvec = bvec; @@ -884,94 +896,6 @@ static int loop_prepare_queue(struct loop_device *lo) return 0; } -static int loop_set_fd(struct loop_device *lo, fmode_t mode, - struct block_device *bdev, unsigned int arg) -{ - struct file *file; - struct inode *inode; - struct address_space *mapping; - int lo_flags = 0; - int error; - loff_t size; - - /* This is safe, since we have a reference from open(). */ - __module_get(THIS_MODULE); - - error = -EBADF; - file = fget(arg); - if (!file) - goto out; - - error = -EBUSY; - if (lo->lo_state != Lo_unbound) - goto out_putf; - - error = loop_validate_file(file, bdev); - if (error) - goto out_putf; - - mapping = file->f_mapping; - inode = mapping->host; - - if (!(file->f_mode & FMODE_WRITE) || !(mode & FMODE_WRITE) || - !file->f_op->write_iter) - lo_flags |= LO_FLAGS_READ_ONLY; - - error = -EFBIG; - size = get_loop_size(lo, file); - if ((loff_t)(sector_t)size != size) - goto out_putf; - error = loop_prepare_queue(lo); - if (error) - goto out_putf; - - error = 0; - - set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0); - - lo->use_dio = false; - lo->lo_device = bdev; - lo->lo_flags = lo_flags; - lo->lo_backing_file = file; - lo->transfer = NULL; - lo->ioctl = NULL; - lo->lo_sizelimit = 0; - lo->old_gfp_mask = mapping_gfp_mask(mapping); - mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); - - if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync) - blk_queue_write_cache(lo->lo_queue, true, false); - - loop_update_dio(lo); - set_capacity(lo->lo_disk, size); - bd_set_size(bdev, size << 9); - loop_sysfs_init(lo); - /* let user-space know about the new size */ - kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE); - - set_blocksize(bdev, S_ISBLK(inode->i_mode) ? - block_size(inode->i_bdev) : PAGE_SIZE); - - lo->lo_state = Lo_bound; - if (part_shift) - lo->lo_flags |= LO_FLAGS_PARTSCAN; - if (lo->lo_flags & LO_FLAGS_PARTSCAN) - loop_reread_partitions(lo, bdev); - - /* Grab the block_device to prevent its destruction after we - * put /dev/loopXX inode. Later in loop_clr_fd() we bdput(bdev). - */ - bdgrab(bdev); - return 0; - - out_putf: - fput(file); - out: - /* This is safe: open() is still holding a reference. */ - module_put(THIS_MODULE); - return error; -} - static int loop_release_xfer(struct loop_device *lo) { @@ -1009,6 +933,180 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer, return err; } +/** + * loop_set_status_from_info - configure device from loop_info + * @lo: struct loop_device to configure + * @info: struct loop_info64 to configure the device with + * + * Configures the loop device parameters according to the passed + * in loop_info64 configuration. + */ +static int +loop_set_status_from_info(struct loop_device *lo, + const struct loop_info64 *info) +{ + int err; + struct loop_func_table *xfer; + kuid_t uid = current_uid(); + + if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE) + return -EINVAL; + + err = loop_release_xfer(lo); + if (err) + return err; + + if (info->lo_encrypt_type) { + unsigned int type = info->lo_encrypt_type; + + if (type >= MAX_LO_CRYPT) + return -EINVAL; + xfer = xfer_funcs[type]; + if (xfer == NULL) + return -EINVAL; + } else + xfer = NULL; + + err = loop_init_xfer(lo, xfer, info); + if (err) + return err; + + lo->lo_offset = info->lo_offset; + lo->lo_sizelimit = info->lo_sizelimit; + memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE); + memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE); + lo->lo_file_name[LO_NAME_SIZE-1] = 0; + lo->lo_crypt_name[LO_NAME_SIZE-1] = 0; + + if (!xfer) + xfer = &none_funcs; + lo->transfer = xfer->transfer; + lo->ioctl = xfer->ioctl; + + lo->lo_flags = info->lo_flags; + + lo->lo_encrypt_key_size = info->lo_encrypt_key_size; + lo->lo_init[0] = info->lo_init[0]; + lo->lo_init[1] = info->lo_init[1]; + if (info->lo_encrypt_key_size) { + memcpy(lo->lo_encrypt_key, info->lo_encrypt_key, + info->lo_encrypt_key_size); + lo->lo_key_owner = uid; + } + + return 0; +} + +static int loop_configure(struct loop_device *lo, fmode_t mode, + struct block_device *bdev, + const struct loop_config *config) +{ + struct file *file; + struct inode *inode; + struct address_space *mapping; + int error; + loff_t size; + unsigned short bsize; + + /* This is safe, since we have a reference from open(). */ + __module_get(THIS_MODULE); + + error = -EBADF; + file = fget(config->fd); + if (!file) + goto out; + + error = -EBUSY; + if (lo->lo_state != Lo_unbound) + goto out_putf; + + error = loop_validate_file(file, bdev); + if (error) + goto out_putf; + + mapping = file->f_mapping; + inode = mapping->host; + + size = get_loop_size(lo, file); + + if ((config->info.lo_flags & ~LOOP_CONFIGURE_SETTABLE_FLAGS) != 0) { + error = -EINVAL; + goto out_putf; + } + + if (config->block_size) { + error = loop_validate_block_size(config->block_size); + if (error) + goto out_putf; + } + + error = loop_set_status_from_info(lo, &config->info); + if (error) + goto out_putf; + + if (!(file->f_mode & FMODE_WRITE) || !(mode & FMODE_WRITE) || + !file->f_op->write_iter) + lo->lo_flags |= LO_FLAGS_READ_ONLY; + + error = loop_prepare_queue(lo); + if (error) + goto out_putf; + + error = 0; + + set_device_ro(bdev, (lo->lo_flags & LO_FLAGS_READ_ONLY) != 0); + + lo->use_dio = lo->lo_flags & LO_FLAGS_DIRECT_IO; + lo->lo_device = bdev; + lo->lo_backing_file = file; + lo->old_gfp_mask = mapping_gfp_mask(mapping); + mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); + + if (!(lo->lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync) + blk_queue_write_cache(lo->lo_queue, true, false); + + if (io_is_direct(lo->lo_backing_file) && inode->i_sb->s_bdev) { + /* In case of direct I/O, match underlying block size */ + unsigned short bsize = bdev_logical_block_size( + inode->i_sb->s_bdev); + + blk_queue_logical_block_size(lo->lo_queue, bsize); + blk_queue_physical_block_size(lo->lo_queue, bsize); + blk_queue_io_min(lo->lo_queue, bsize); + } + + loop_update_dio(lo); + loop_sysfs_init(lo); + loop_set_size(lo, size); + + if (config->block_size) + bsize = config->block_size; + else + bsize = S_ISBLK(inode->i_mode) ? + block_size(inode->i_bdev) : PAGE_SIZE; + + set_blocksize(bdev, bsize); + + lo->lo_state = Lo_bound; + if (part_shift) + lo->lo_flags |= LO_FLAGS_PARTSCAN; + if (lo->lo_flags & LO_FLAGS_PARTSCAN) + loop_reread_partitions(lo, bdev); + + /* Grab the block_device to prevent its destruction after we + * put /dev/loopXX inode. Later in loop_clr_fd() we bdput(bdev). + */ + bdgrab(bdev); + return 0; + + out_putf: + fput(file); + out: + /* This is safe: open() is still holding a reference. */ + module_put(THIS_MODULE); + return error; +} + static int loop_clr_fd(struct loop_device *lo) { struct file *filp = lo->lo_backing_file; @@ -1097,20 +1195,21 @@ static int loop_set_status(struct loop_device *lo, const struct loop_info64 *info) { int err; - struct loop_func_table *xfer; kuid_t uid = current_uid(); + int prev_lo_flags; + bool size_changed = false; if (lo->lo_encrypt_key_size && !uid_eq(lo->lo_key_owner, uid) && !capable(CAP_SYS_ADMIN)) return -EPERM; - if (lo->lo_state != Lo_bound) + if (lo->lo_state != Lo_bound) { return -ENXIO; - if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE) - return -EINVAL; + } if (lo->lo_offset != info->lo_offset || lo->lo_sizelimit != info->lo_sizelimit) { + size_changed = true; sync_blockdev(lo->lo_device); invalidate_bdev(lo->lo_device); } @@ -1118,79 +1217,43 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) /* I/O need to be drained during transfer transition */ blk_mq_freeze_queue(lo->lo_queue); - err = loop_release_xfer(lo); + if (size_changed && lo->lo_device->bd_inode->i_mapping->nrpages) { + /* If any pages were dirtied after kill_bdev(), try again */ + err = -EAGAIN; + pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n", + __func__, lo->lo_number, lo->lo_file_name, + lo->lo_device->bd_inode->i_mapping->nrpages); + goto exit; + } + + prev_lo_flags = lo->lo_flags; + + err = loop_set_status_from_info(lo, info); if (err) goto exit; - if (info->lo_encrypt_type) { - unsigned int type = info->lo_encrypt_type; - - if (type >= MAX_LO_CRYPT) { - err = -EINVAL; - goto exit; - } - xfer = xfer_funcs[type]; - if (xfer == NULL) { - err = -EINVAL; - goto exit; - } - } else - xfer = NULL; - - err = loop_init_xfer(lo, xfer, info); - if (err) - goto exit; - - if (lo->lo_offset != info->lo_offset || - lo->lo_sizelimit != info->lo_sizelimit) { - /* kill_bdev should have truncated all the pages */ - if (lo->lo_device->bd_inode->i_mapping->nrpages) { - err = -EAGAIN; - pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n", - __func__, lo->lo_number, lo->lo_file_name, - lo->lo_device->bd_inode->i_mapping->nrpages); - goto exit; - } - if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) { - err = -EFBIG; - goto exit; - } + /* Mask out flags that can't be set using LOOP_SET_STATUS. */ + lo->lo_flags &= LOOP_SET_STATUS_SETTABLE_FLAGS; + /* For those flags, use the previous values instead */ + lo->lo_flags |= prev_lo_flags & ~LOOP_SET_STATUS_SETTABLE_FLAGS; + /* For flags that can't be cleared, use previous values too */ + lo->lo_flags |= prev_lo_flags & ~LOOP_SET_STATUS_CLEARABLE_FLAGS; + if (size_changed) { + loff_t new_size = get_size(lo->lo_offset, lo->lo_sizelimit, + lo->lo_backing_file); + loop_set_size(lo, new_size); } loop_config_discard(lo); - memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE); - memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE); - lo->lo_file_name[LO_NAME_SIZE-1] = 0; - lo->lo_crypt_name[LO_NAME_SIZE-1] = 0; - - if (!xfer) - xfer = &none_funcs; - lo->transfer = xfer->transfer; - lo->ioctl = xfer->ioctl; - - if ((lo->lo_flags & LO_FLAGS_AUTOCLEAR) != - (info->lo_flags & LO_FLAGS_AUTOCLEAR)) - lo->lo_flags ^= LO_FLAGS_AUTOCLEAR; - - lo->lo_encrypt_key_size = info->lo_encrypt_key_size; - lo->lo_init[0] = info->lo_init[0]; - lo->lo_init[1] = info->lo_init[1]; - if (info->lo_encrypt_key_size) { - memcpy(lo->lo_encrypt_key, info->lo_encrypt_key, - info->lo_encrypt_key_size); - lo->lo_key_owner = uid; - } - /* update dio if lo_offset or transfer is changed */ __loop_update_dio(lo, lo->use_dio); exit: blk_mq_unfreeze_queue(lo->lo_queue); - if (!err && (info->lo_flags & LO_FLAGS_PARTSCAN) && - !(lo->lo_flags & LO_FLAGS_PARTSCAN)) { - lo->lo_flags |= LO_FLAGS_PARTSCAN; + if (!err && (lo->lo_flags & LO_FLAGS_PARTSCAN) && + !(prev_lo_flags & LO_FLAGS_PARTSCAN)) { lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN; loop_reread_partitions(lo, lo->lo_device); } @@ -1350,10 +1413,15 @@ loop_get_status64(struct loop_device *lo, struct loop_info64 __user *arg) { static int loop_set_capacity(struct loop_device *lo) { + loff_t size; + if (unlikely(lo->lo_state != Lo_bound)) return -ENXIO; - return figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit); + size = get_loop_size(lo, lo->lo_backing_file); + loop_set_size(lo, size); + + return 0; } static int loop_set_dio(struct loop_device *lo, unsigned long arg) @@ -1377,8 +1445,9 @@ static int loop_set_block_size(struct loop_device *lo, unsigned long arg) if (lo->lo_state != Lo_bound) return -ENXIO; - if (arg < 512 || arg > PAGE_SIZE || !is_power_of_2(arg)) - return -EINVAL; + err = loop_validate_block_size(arg); + if (err) + return err; if (lo->lo_queue->limits.logical_block_size == arg) return 0; @@ -1411,13 +1480,34 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { struct loop_device *lo = bdev->bd_disk->private_data; + void __user *argp = (void __user *) arg; int err; mutex_lock_nested(&lo->lo_ctl_mutex, 1); switch (cmd) { - case LOOP_SET_FD: - err = loop_set_fd(lo, mode, bdev, arg); + case LOOP_SET_FD: { + /* + * Legacy case - pass in a zeroed out struct loop_config with + * only the file descriptor set , which corresponds with the + * default parameters we'd have used otherwise. + */ + struct loop_config config; + + memset(&config, 0, sizeof(config)); + config.fd = arg; + + err = loop_configure(lo, mode, bdev, &config); break; + } + case LOOP_CONFIGURE: { + struct loop_config config; + + if (copy_from_user(&config, argp, sizeof(config))) + return -EFAULT; + + err = loop_configure(lo, mode, bdev, &config); + break; + } case LOOP_CHANGE_FD: err = loop_change_fd(lo, bdev, arg); break; @@ -1430,21 +1520,19 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, case LOOP_SET_STATUS: err = -EPERM; if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) - err = loop_set_status_old(lo, - (struct loop_info __user *)arg); + err = loop_set_status_old(lo, argp); break; case LOOP_GET_STATUS: - err = loop_get_status_old(lo, (struct loop_info __user *) arg); + err = loop_get_status_old(lo, argp); /* loop_get_status() unlocks lo_ctl_mutex */ goto out_unlocked; case LOOP_SET_STATUS64: err = -EPERM; if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) - err = loop_set_status64(lo, - (struct loop_info64 __user *) arg); + err = loop_set_status64(lo, argp); break; case LOOP_GET_STATUS64: - err = loop_get_status64(lo, (struct loop_info64 __user *) arg); + err = loop_get_status64(lo, argp); /* loop_get_status() unlocks lo_ctl_mutex */ goto out_unlocked; case LOOP_SET_CAPACITY: @@ -1614,6 +1702,7 @@ static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode, case LOOP_CLR_FD: case LOOP_GET_STATUS64: case LOOP_SET_STATUS64: + case LOOP_CONFIGURE: arg = (unsigned long) compat_ptr(arg); case LOOP_SET_FD: case LOOP_CHANGE_FD: diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index b12e373aa956..1918c275c9a3 100644 --- a/drivers/block/null_blk.c +++ b/drivers/block/null_blk.c @@ -1687,12 +1687,12 @@ static int setup_commands(struct nullb_queue *nq) struct nullb_cmd *cmd; int i, tag_size; - nq->cmds = kzalloc(nq->queue_depth * sizeof(*cmd), GFP_KERNEL); + nq->cmds = kcalloc(nq->queue_depth, sizeof(*cmd), GFP_KERNEL); if (!nq->cmds) return -ENOMEM; tag_size = ALIGN(nq->queue_depth, BITS_PER_LONG) / BITS_PER_LONG; - nq->tag_map = kzalloc(tag_size * sizeof(unsigned long), GFP_KERNEL); + nq->tag_map = kcalloc(tag_size, sizeof(unsigned long), GFP_KERNEL); if (!nq->tag_map) { kfree(nq->cmds); return -ENOMEM; @@ -1710,8 +1710,9 @@ static int setup_commands(struct nullb_queue *nq) static int setup_queues(struct nullb *nullb) { - nullb->queues = kzalloc(nullb->dev->submit_queues * - sizeof(struct nullb_queue), GFP_KERNEL); + nullb->queues = kcalloc(nullb->dev->submit_queues, + sizeof(struct nullb_queue), + GFP_KERNEL); if (!nullb->queues) return -ENOMEM; diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c index 6a55959cbf78..a6744ee7cf67 100644 --- a/drivers/block/ps3vram.c +++ b/drivers/block/ps3vram.c @@ -407,8 +407,9 @@ static int ps3vram_cache_init(struct ps3_system_bus_device *dev) priv->cache.page_count = CACHE_PAGE_COUNT; priv->cache.page_size = CACHE_PAGE_SIZE; - priv->cache.tags = kzalloc(sizeof(struct ps3vram_tag) * - CACHE_PAGE_COUNT, GFP_KERNEL); + priv->cache.tags = kcalloc(CACHE_PAGE_COUNT, + sizeof(struct ps3vram_tag), + GFP_KERNEL); if (!priv->cache.tags) return -ENOMEM; diff --git a/drivers/block/rsxx/core.c b/drivers/block/rsxx/core.c index 6beafaa335c7..f3ab828abf85 100644 --- a/drivers/block/rsxx/core.c +++ b/drivers/block/rsxx/core.c @@ -873,7 +873,8 @@ static int rsxx_pci_probe(struct pci_dev *dev, dev_info(CARD_TO_DEV(card), "Failed reading the number of DMA targets\n"); - card->ctrl = kzalloc(card->n_targets * sizeof(*card->ctrl), GFP_KERNEL); + card->ctrl = kcalloc(card->n_targets, sizeof(*card->ctrl), + GFP_KERNEL); if (!card->ctrl) { st = -ENOMEM; goto failed_dma_setup; diff --git a/drivers/block/rsxx/dma.c b/drivers/block/rsxx/dma.c index 6a1b2177951c..b5d7ea121450 100644 --- a/drivers/block/rsxx/dma.c +++ b/drivers/block/rsxx/dma.c @@ -1039,7 +1039,7 @@ int rsxx_eeh_save_issued_dmas(struct rsxx_cardinfo *card) struct rsxx_dma *dma; struct list_head *issued_dmas; - issued_dmas = kzalloc(sizeof(*issued_dmas) * card->n_targets, + issued_dmas = kcalloc(card->n_targets, sizeof(*issued_dmas), GFP_KERNEL); if (!issued_dmas) return -ENOMEM; diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index e9fa4a1fc791..d33e72a649b2 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -139,7 +139,8 @@ static int xen_blkif_alloc_rings(struct xen_blkif *blkif) { unsigned int r; - blkif->rings = kzalloc(blkif->nr_rings * sizeof(struct xen_blkif_ring), GFP_KERNEL); + blkif->rings = kcalloc(blkif->nr_rings, sizeof(struct xen_blkif_ring), + GFP_KERNEL); if (!blkif->rings) return -ENOMEM; diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index e6887714fe0a..5b9488201b93 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -1907,7 +1907,9 @@ static int negotiate_mq(struct blkfront_info *info) if (!info->nr_rings) info->nr_rings = 1; - info->rinfo = kzalloc(sizeof(struct blkfront_ring_info) * info->nr_rings, GFP_KERNEL); + info->rinfo = kcalloc(info->nr_rings, + sizeof(struct blkfront_ring_info), + GFP_KERNEL); if (!info->rinfo) { xenbus_dev_fatal(info->xbdev, -ENOMEM, "allocating ring_info structure"); info->nr_rings = 0; @@ -2218,15 +2220,16 @@ static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo) } for (i = 0; i < BLK_RING_SIZE(info); i++) { - rinfo->shadow[i].grants_used = kzalloc( - sizeof(rinfo->shadow[i].grants_used[0]) * grants, - GFP_NOIO); - rinfo->shadow[i].sg = kzalloc(sizeof(rinfo->shadow[i].sg[0]) * psegs, GFP_NOIO); + rinfo->shadow[i].grants_used = kcalloc(grants, + sizeof(rinfo->shadow[i].grants_used[0]), + GFP_NOIO); + rinfo->shadow[i].sg = kcalloc(psegs, + sizeof(rinfo->shadow[i].sg[0]), + GFP_NOIO); if (info->max_indirect_segments) - rinfo->shadow[i].indirect_grants = kzalloc( - sizeof(rinfo->shadow[i].indirect_grants[0]) * - INDIRECT_GREFS(grants), - GFP_NOIO); + rinfo->shadow[i].indirect_grants = kcalloc(INDIRECT_GREFS(grants), + sizeof(rinfo->shadow[i].indirect_grants[0]), + GFP_NOIO); if ((rinfo->shadow[i].grants_used == NULL) || (rinfo->shadow[i].sg == NULL) || (info->max_indirect_segments && diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index 41c95c9b2ab4..87cefee10f36 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c @@ -197,8 +197,9 @@ static int z2_open(struct block_device *bdev, fmode_t mode) vaddr = (unsigned long)z_remap_nocache_nonser(paddr, size); #endif z2ram_map = - kmalloc((size/Z2RAM_CHUNKSIZE)*sizeof(z2ram_map[0]), - GFP_KERNEL); + kmalloc_array(size / Z2RAM_CHUNKSIZE, + sizeof(z2ram_map[0]), + GFP_KERNEL); if ( z2ram_map == NULL ) { printk( KERN_ERR DEVICE_NAME diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c index e9b08f356b5b..91adb747d585 100644 --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c @@ -36,7 +36,6 @@ static const char * const backends[] = { #if IS_ENABLED(CONFIG_CRYPTO_ZSTD) "zstd", #endif - NULL }; static void zcomp_strm_free(struct zcomp_strm *zstrm) @@ -44,19 +43,16 @@ static void zcomp_strm_free(struct zcomp_strm *zstrm) if (!IS_ERR_OR_NULL(zstrm->tfm)) crypto_free_comp(zstrm->tfm); free_pages((unsigned long)zstrm->buffer, 1); - kfree(zstrm); + zstrm->tfm = NULL; + zstrm->buffer = NULL; } /* - * allocate new zcomp_strm structure with ->tfm initialized by - * backend, return NULL on error + * Initialize zcomp_strm structure with ->tfm initialized by backend, and + * ->buffer. Return a negative value on error. */ -static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp) +static int zcomp_strm_init(struct zcomp_strm *zstrm, struct zcomp *comp) { - struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), GFP_KERNEL); - if (!zstrm) - return NULL; - zstrm->tfm = crypto_alloc_comp(comp->name, 0, 0); /* * allocate 2 pages. 1 for compressed data, plus 1 extra for the @@ -65,16 +61,16 @@ static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp) zstrm->buffer = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1); if (IS_ERR_OR_NULL(zstrm->tfm) || !zstrm->buffer) { zcomp_strm_free(zstrm); - zstrm = NULL; + return -ENOMEM; } - return zstrm; + return 0; } bool zcomp_available_algorithm(const char *comp) { int i; - i = __sysfs_match_string(backends, -1, comp); + i = sysfs_match_string(backends, comp); if (i >= 0) return true; @@ -93,9 +89,9 @@ ssize_t zcomp_available_show(const char *comp, char *buf) { bool known_algorithm = false; ssize_t sz = 0; - int i = 0; + int i; - for (; backends[i]; i++) { + for (i = 0; i < ARRAY_SIZE(backends); i++) { if (!strcmp(comp, backends[i])) { known_algorithm = true; sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2, @@ -120,7 +116,7 @@ ssize_t zcomp_available_show(const char *comp, char *buf) struct zcomp_strm *zcomp_stream_get(struct zcomp *comp) { - return *get_cpu_ptr(comp->stream); + return get_cpu_ptr(comp->stream); } void zcomp_stream_put(struct zcomp *comp) @@ -166,17 +162,13 @@ int zcomp_cpu_up_prepare(unsigned int cpu, struct hlist_node *node) { struct zcomp *comp = hlist_entry(node, struct zcomp, node); struct zcomp_strm *zstrm; + int ret; - if (WARN_ON(*per_cpu_ptr(comp->stream, cpu))) - return 0; - - zstrm = zcomp_strm_alloc(comp); - if (IS_ERR_OR_NULL(zstrm)) { + zstrm = per_cpu_ptr(comp->stream, cpu); + ret = zcomp_strm_init(zstrm, comp); + if (ret) pr_err("Can't allocate a compression stream\n"); - return -ENOMEM; - } - *per_cpu_ptr(comp->stream, cpu) = zstrm; - return 0; + return ret; } int zcomp_cpu_dead(unsigned int cpu, struct hlist_node *node) @@ -184,10 +176,8 @@ int zcomp_cpu_dead(unsigned int cpu, struct hlist_node *node) struct zcomp *comp = hlist_entry(node, struct zcomp, node); struct zcomp_strm *zstrm; - zstrm = *per_cpu_ptr(comp->stream, cpu); - if (!IS_ERR_OR_NULL(zstrm)) - zcomp_strm_free(zstrm); - *per_cpu_ptr(comp->stream, cpu) = NULL; + zstrm = per_cpu_ptr(comp->stream, cpu); + zcomp_strm_free(zstrm); return 0; } @@ -195,7 +185,7 @@ static int zcomp_init(struct zcomp *comp) { int ret; - comp->stream = alloc_percpu(struct zcomp_strm *); + comp->stream = alloc_percpu(struct zcomp_strm); if (!comp->stream) return -ENOMEM; diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h index 41c1002a7d7d..9e94095ce000 100644 --- a/drivers/block/zram/zcomp.h +++ b/drivers/block/zram/zcomp.h @@ -18,7 +18,7 @@ struct zcomp_strm { /* dynamic per-device compression frontend */ struct zcomp { - struct zcomp_strm * __percpu *stream; + struct zcomp_strm __percpu *stream; const char *name; struct hlist_node node; }; diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 9d7866ac40b8..35565a6c4997 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -208,14 +208,17 @@ static inline void zram_fill_page(void *ptr, unsigned long len, static bool page_same_filled(void *ptr, unsigned long *element) { - unsigned int pos; unsigned long *page; unsigned long val; + unsigned int pos, last_pos = PAGE_SIZE / sizeof(*page) - 1; page = (unsigned long *)ptr; val = page[0]; - for (pos = 1; pos < PAGE_SIZE / sizeof(*page); pos++) { + if (val != page[last_pos]) + return false; + + for (pos = 1; pos < last_pos; pos++) { if (val != page[pos]) return false; } @@ -614,7 +617,7 @@ static ssize_t writeback_store(struct device *dev, struct bio bio; struct bio_vec bio_vec; struct page *page; - ssize_t ret; + ssize_t ret = len; int mode; unsigned long blk_idx = 0; @@ -750,7 +753,6 @@ next: if (blk_idx) free_block_bdev(zram, blk_idx); - ret = len; __free_page(page); release_init_lock: up_read(&zram->init_lock); @@ -1157,7 +1159,7 @@ static bool zram_meta_alloc(struct zram *zram, u64 disksize) size_t num_pages; num_pages = disksize >> PAGE_SHIFT; - zram->table = vzalloc(num_pages * sizeof(*zram->table)); + zram->table = vzalloc(array_size(num_pages, sizeof(*zram->table))); if (!zram->table) return false; diff --git a/drivers/bus/mhi/controllers/mhi_qcom.c b/drivers/bus/mhi/controllers/mhi_qcom.c index 26811368e6c3..e0154b549b4f 100644 --- a/drivers/bus/mhi/controllers/mhi_qcom.c +++ b/drivers/bus/mhi/controllers/mhi_qcom.c @@ -33,7 +33,7 @@ struct firmware_info { }; static const struct firmware_info firmware_table[] = { - {.dev_id = 0x308, .fw_image = "sdx65m/sbl1.mbn", + {.dev_id = 0x308, .fw_image = "sdx65m/xbl.elf", .edl_image = "sdx65m/edl.mbn"}, {.dev_id = 0x307, .fw_image = "sdx60m/sbl1.mbn", .edl_image = "sdx60m/edl.mbn"}, diff --git a/drivers/bus/mhi/core/mhi_init.c b/drivers/bus/mhi/core/mhi_init.c index 10cf1a68fbbc..3d75e0748571 100644 --- a/drivers/bus/mhi/core/mhi_init.c +++ b/drivers/bus/mhi/core/mhi_init.c @@ -1289,8 +1289,7 @@ static int of_parse_ch_cfg(struct mhi_controller *mhi_cntrl, if (!of_node) return -EINVAL; - mhi_cntrl->mhi_chan = vzalloc(mhi_cntrl->max_chan * - sizeof(*mhi_cntrl->mhi_chan)); + mhi_cntrl->mhi_chan = vzalloc(array_size(sizeof(*mhi_cntrl->mhi_chan), mhi_cntrl->max_chan)); if (!mhi_cntrl->mhi_chan) return -ENOMEM; diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c index 2f900a82d031..dfdc2f43ce6a 100644 --- a/drivers/bus/mhi/core/mhi_main.c +++ b/drivers/bus/mhi/core/mhi_main.c @@ -1913,7 +1913,8 @@ int mhi_prepare_channel(struct mhi_controller *mhi_cntrl, return 0; error_dec_pendpkt: - atomic_dec(&mhi_cntrl->pending_pkts); + if (in_mission_mode) + atomic_dec(&mhi_cntrl->pending_pkts); error_pm_state: if (!mhi_chan->offload_ch) mhi_deinit_chan_ctxt(mhi_cntrl, mhi_chan); @@ -2604,6 +2605,7 @@ int mhi_get_remote_time_sync(struct mhi_device *mhi_dev, ret = -EIO; goto error_invalid_state; } + read_unlock_bh(&mhi_cntrl->pm_lock); /* disable link level low power modes */ ret = mhi_cntrl->lpm_disable(mhi_cntrl, mhi_cntrl->priv_data); @@ -2626,6 +2628,7 @@ int mhi_get_remote_time_sync(struct mhi_device *mhi_dev, mhi_cntrl->lpm_enable(mhi_cntrl, mhi_cntrl->priv_data); + read_lock_bh(&mhi_cntrl->pm_lock); error_invalid_state: mhi_cntrl->wake_put(mhi_cntrl, false); read_unlock_bh(&mhi_cntrl->pm_lock); diff --git a/drivers/bus/mhi/devices/mhi_netdev.c b/drivers/bus/mhi/devices/mhi_netdev.c index 28a619fef3c0..7690addfbf12 100644 --- a/drivers/bus/mhi/devices/mhi_netdev.c +++ b/drivers/bus/mhi/devices/mhi_netdev.c @@ -30,6 +30,7 @@ #define WATCHDOG_TIMEOUT (30 * HZ) #define IPC_LOG_PAGES (100) #define MAX_NETBUF_SIZE (128) +#define MHI_NETDEV_NAPI_POLL_WEIGHT (128) #ifdef CONFIG_MHI_DEBUG @@ -710,7 +711,7 @@ static int mhi_netdev_enable_iface(struct mhi_netdev *mhi_netdev) } netif_napi_add(mhi_netdev->ndev, mhi_netdev->napi, - mhi_netdev_poll, NAPI_POLL_WEIGHT); + mhi_netdev_poll, MHI_NETDEV_NAPI_POLL_WEIGHT); ret = register_netdev(mhi_netdev->ndev); if (ret) { MSG_ERR("Network device registration failed\n"); diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 1c90da4af94f..229dae26758a 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -2139,7 +2139,7 @@ static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf, */ nr = nframes; do { - cgc.buffer = kmalloc(CD_FRAMESIZE_RAW * nr, GFP_KERNEL); + cgc.buffer = kmalloc_array(nr, CD_FRAMESIZE_RAW, GFP_KERNEL); if (cgc.buffer) break; diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index e4d82ad0f0bb..2fc9f6ade535 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -653,12 +653,20 @@ static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd, static int dma_alloc_memory(dma_addr_t *region_phys, void **vaddr, size_t size, unsigned long dma_attr) { + int err = 0; struct fastrpc_apps *me = &gfa; if (me->dev == NULL) { pr_err("device adsprpc-mem is not initialized\n"); return -ENODEV; } + VERIFY(err, size > 0 && size < MAX_SIZE_LIMIT); + if (err) { + err = -EFAULT; + pr_err("adsprpc: %s: invalid allocation size 0x%zx\n", + __func__, size); + return err; + } *vaddr = dma_alloc_attrs(me->dev, size, region_phys, GFP_KERNEL, dma_attr); if (IS_ERR_OR_NULL(*vaddr)) { @@ -1605,9 +1613,10 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) PERF_END); for (i = bufs; i < bufs + handles; ++i) { struct fastrpc_mmap *map = ctx->maps[i]; - - pages[i].addr = map->phys; - pages[i].size = map->size; + if (map) { + pages[i].addr = map->phys; + pages[i].size = map->size; + } } fdlist = (uint64_t *)&pages[bufs + handles]; for (i = 0; i < M_FDLIST; i++) @@ -1685,7 +1694,8 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) } PERF_END); for (i = bufs; rpra && lrpra && i < bufs + handles; i++) { - rpra[i].dma.fd = lrpra[i].dma.fd = ctx->fds[i]; + if (ctx->fds) + rpra[i].dma.fd = lrpra[i].dma.fd = ctx->fds[i]; rpra[i].dma.len = lrpra[i].dma.len = (uint32_t)lpra[i].buf.len; rpra[i].dma.offset = lrpra[i].dma.offset = (uint32_t)(uintptr_t)lpra[i].buf.pv; @@ -3778,8 +3788,6 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb, ctx->ssrcount++; ctx->issubsystemup = 0; mutex_unlock(&me->channel[cid].smd_mutex); - if (cid == 0) - me->staticpd_flags = 0; } else if (code == SUBSYS_RAMDUMP_NOTIFICATION) { if (me->channel[0].remoteheap_ramdump_dev && notifdata->enable_ramdump) { diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index b450544dcaf0..6914e4f0ce98 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c @@ -85,7 +85,8 @@ static int amd_create_gatt_pages(int nr_tables) int retval = 0; int i; - tables = kzalloc((nr_tables + 1) * sizeof(struct amd_page_map *),GFP_KERNEL); + tables = kcalloc(nr_tables + 1, sizeof(struct amd_page_map *), + GFP_KERNEL); if (tables == NULL) return -ENOMEM; diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 88b4cbee4dac..20bf5f78a362 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -108,7 +108,8 @@ static int ati_create_gatt_pages(int nr_tables) int retval = 0; int i; - tables = kzalloc((nr_tables + 1) * sizeof(struct ati_page_map *),GFP_KERNEL); + tables = kcalloc(nr_tables + 1, sizeof(struct ati_page_map *), + GFP_KERNEL); if (tables == NULL) return -ENOMEM; diff --git a/drivers/char/agp/compat_ioctl.c b/drivers/char/agp/compat_ioctl.c index 2053f70ef66b..52ffe1706ce0 100644 --- a/drivers/char/agp/compat_ioctl.c +++ b/drivers/char/agp/compat_ioctl.c @@ -98,11 +98,15 @@ static int compat_agpioc_reserve_wrap(struct agp_file_private *priv, void __user if (ureserve.seg_count >= 16384) return -EINVAL; - usegment = kmalloc(sizeof(*usegment) * ureserve.seg_count, GFP_KERNEL); + usegment = kmalloc_array(ureserve.seg_count, + sizeof(*usegment), + GFP_KERNEL); if (!usegment) return -ENOMEM; - ksegment = kmalloc(sizeof(*ksegment) * kreserve.seg_count, GFP_KERNEL); + ksegment = kmalloc_array(kreserve.seg_count, + sizeof(*ksegment), + GFP_KERNEL); if (!ksegment) { kfree(usegment); return -ENOMEM; diff --git a/drivers/char/agp/isoch.c b/drivers/char/agp/isoch.c index fc8e1bc3347d..4d5241124406 100644 --- a/drivers/char/agp/isoch.c +++ b/drivers/char/agp/isoch.c @@ -93,7 +93,7 @@ static int agp_3_5_isochronous_node_enable(struct agp_bridge_data *bridge, * We'll work with an array of isoch_data's (one for each * device in dev_list) throughout this function. */ - if ((master = kmalloc(ndevs * sizeof(*master), GFP_KERNEL)) == NULL) { + if ((master = kmalloc_array(ndevs, sizeof(*master), GFP_KERNEL)) == NULL) { ret = -ENOMEM; goto get_out; } diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c index 3051c73bc383..e7d5bdc02d93 100644 --- a/drivers/char/agp/sgi-agp.c +++ b/drivers/char/agp/sgi-agp.c @@ -280,9 +280,9 @@ static int agp_sgi_init(void) else return 0; - sgi_tioca_agp_bridges = kmalloc(tioca_gart_found * - sizeof(struct agp_bridge_data *), - GFP_KERNEL); + sgi_tioca_agp_bridges = kmalloc_array(tioca_gart_found, + sizeof(struct agp_bridge_data *), + GFP_KERNEL); if (!sgi_tioca_agp_bridges) return -ENOMEM; diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index 03be4ac79b0d..71ea2cac20d0 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c @@ -96,7 +96,7 @@ static int serverworks_create_gatt_pages(int nr_tables) int retval = 0; int i; - tables = kzalloc((nr_tables + 1) * sizeof(struct serverworks_page_map *), + tables = kcalloc(nr_tables + 1, sizeof(struct serverworks_page_map *), GFP_KERNEL); if (tables == NULL) return -ENOMEM; diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index 79d8c84693a1..31fcd0430426 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c @@ -402,7 +402,9 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge) if (table == NULL) return -ENOMEM; - uninorth_priv.pages_arr = kmalloc((1 << page_order) * sizeof(struct page*), GFP_KERNEL); + uninorth_priv.pages_arr = kmalloc_array(1 << page_order, + sizeof(struct page *), + GFP_KERNEL); if (uninorth_priv.pages_arr == NULL) goto enomem; diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c index 0e7c657807dd..49ee66f248f2 100644 --- a/drivers/char/diag/diag_debugfs.c +++ b/drivers/char/diag/diag_debugfs.c @@ -60,7 +60,7 @@ static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf, int ret, i; unsigned int buf_size; - buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL); + buf = kzalloc(DEBUG_BUF_SIZE, GFP_KERNEL); if (!buf) return -ENOMEM; buf_size = ksize(buf); @@ -227,7 +227,7 @@ static ssize_t diag_dbgfs_read_power(struct file *file, char __user *ubuf, int ret; unsigned int buf_size; - buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL); + buf = kzalloc(DEBUG_BUF_SIZE, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -355,7 +355,7 @@ static ssize_t diag_dbgfs_read_mempool(struct file *file, char __user *ubuf, return 0; } - buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL); + buf = kzalloc(DEBUG_BUF_SIZE, GFP_KERNEL); if (ZERO_OR_NULL_PTR(buf)) { pr_err("diag: %s, Error allocating memory\n", __func__); return -ENOMEM; @@ -420,7 +420,7 @@ static ssize_t diag_dbgfs_read_usbinfo(struct file *file, char __user *ubuf, return 0; } - buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL); + buf = kzalloc(DEBUG_BUF_SIZE, GFP_KERNEL); if (ZERO_OR_NULL_PTR(buf)) { pr_err("diag: %s, Error allocating memory\n", __func__); return -ENOMEM; @@ -559,7 +559,7 @@ static ssize_t diag_dbgfs_read_socketinfo(struct file *file, char __user *ubuf, return 0; } - buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL); + buf = kzalloc(DEBUG_BUF_SIZE, GFP_KERNEL); if (ZERO_OR_NULL_PTR(buf)) { pr_err("diag: %s, Error allocating memory\n", __func__); return -ENOMEM; @@ -665,7 +665,7 @@ static ssize_t diag_dbgfs_read_rpmsginfo(struct file *file, char __user *ubuf, return 0; } - buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL); + buf = kzalloc(DEBUG_BUF_SIZE, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -802,7 +802,7 @@ static ssize_t diag_dbgfs_read_hsicinfo(struct file *file, char __user *ubuf, return 0; } - buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL); + buf = kzalloc(DEBUG_BUF_SIZE, GFP_KERNEL); if (ZERO_OR_NULL_PTR(buf)) { pr_err("diag: %s, Error allocating memory\n", __func__); return -ENOMEM; @@ -874,7 +874,7 @@ static ssize_t diag_dbgfs_read_mhiinfo(struct file *file, char __user *ubuf, return 0; } - buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL); + buf = kzalloc(DEBUG_BUF_SIZE, GFP_KERNEL); if (ZERO_OR_NULL_PTR(buf)) { pr_err("diag: %s, Error allocating memory\n", __func__); return -ENOMEM; @@ -947,7 +947,7 @@ static ssize_t diag_dbgfs_read_bridge(struct file *file, char __user *ubuf, return 0; } - buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL); + buf = kzalloc(DEBUG_BUF_SIZE, GFP_KERNEL); if (ZERO_OR_NULL_PTR(buf)) { pr_err("diag: %s, Error allocating memory\n", __func__); return -ENOMEM; @@ -1131,8 +1131,9 @@ int diag_debugfs_init(void) diag_dbgfs_dci_finished = 0; /* DCI related structures */ - dci_traffic = kzalloc(sizeof(struct diag_dci_data_info) * - DIAG_DCI_DEBUG_CNT, GFP_KERNEL); + dci_traffic = kcalloc(DIAG_DCI_DEBUG_CNT, + sizeof(struct diag_dci_data_info), + GFP_KERNEL); if (ZERO_OR_NULL_PTR(dci_traffic)) pr_warn("diag: could not allocate memory for dci debug info\n"); diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index 848ca8422015..ea053d354804 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -2684,7 +2684,7 @@ static int diag_cmd_register_tbl(struct diag_cmd_reg_tbl_t *reg_tbl) return -EFAULT; } - entries = kzalloc(count * entry_len, GFP_KERNEL); + entries = kcalloc(entry_len, count, GFP_KERNEL); if (!entries) return -ENOMEM; diff --git a/drivers/char/diag/diagfwd_peripheral.c b/drivers/char/diag/diagfwd_peripheral.c index b348e3c2bbbe..047131e45a91 100644 --- a/drivers/char/diag/diagfwd_peripheral.c +++ b/drivers/char/diag/diagfwd_peripheral.c @@ -863,9 +863,9 @@ int diagfwd_peripheral_init(void) struct diagfwd_info *fwd_info = NULL; for (transport = 0; transport < NUM_TRANSPORT; transport++) { - early_init_info[transport] = kzalloc( - sizeof(struct diagfwd_info) * NUM_PERIPHERALS, - GFP_KERNEL); + early_init_info[transport] = kcalloc(NUM_PERIPHERALS, + sizeof(struct diagfwd_info), + GFP_KERNEL); if (!early_init_info[transport]) return -ENOMEM; kmemleak_not_leak(early_init_info[transport]); diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index cf87bfe971e6..6c3026a3de76 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -1834,7 +1834,8 @@ static unsigned short *ssif_address_list(void) list_for_each_entry(info, &ssif_infos, link) count++; - address_list = kzalloc(sizeof(*address_list) * (count + 1), GFP_KERNEL); + address_list = kcalloc(count + 1, sizeof(*address_list), + GFP_KERNEL); if (!address_list) return NULL; diff --git a/drivers/char/random.c b/drivers/char/random.c index e66bc563c2cd..61b5afbea2f0 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1233,6 +1233,7 @@ void add_interrupt_randomness(int irq, int irq_flags) fast_mix(fast_pool); add_interrupt_bench(cycles); + this_cpu_add(net_rand_state.s1, fast_pool->pool[cycles & 3]); if (unlikely(crng_init == 0)) { if ((fast_pool->count >= 64) && diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 293167c6e254..9d4a917710b8 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c @@ -321,7 +321,7 @@ static int __init raw_init(void) max_raw_minors = MAX_RAW_MINORS; } - raw_devices = vzalloc(sizeof(struct raw_device_data) * max_raw_minors); + raw_devices = vzalloc(array_size(max_raw_minors, sizeof(struct raw_device_data))); if (!raw_devices) { printk(KERN_ERR "Not enough memory for raw device structures\n"); ret = -ENOMEM; diff --git a/drivers/char/tile-srom.c b/drivers/char/tile-srom.c index 3d4cca64b2d4..8bc5c0f6c1c8 100644 --- a/drivers/char/tile-srom.c +++ b/drivers/char/tile-srom.c @@ -362,7 +362,7 @@ static int srom_init(void) * Start with a plausible number of partitions; the krealloc() call * below will yield about log(srom_devs) additional allocations. */ - srom_devices = kmalloc(4 * sizeof(struct srom_dev), GFP_KERNEL); + srom_devices = kmalloc_array(4, sizeof(struct srom_dev), GFP_KERNEL); /* Discover the number of srom partitions. */ for (i = 0; ; i++) { diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index dd64b3b37400..7cf613ba13bf 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -1027,7 +1027,7 @@ static int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip) goto out; } - chip->cc_attrs_tbl = devm_kzalloc(&chip->dev, 4 * nr_commands, + chip->cc_attrs_tbl = devm_kcalloc(&chip->dev, 4, nr_commands, GFP_KERNEL); if (!chip->cc_attrs_tbl) { rc = -ENOMEM; diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 6a57237e46db..747d03b90011 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -433,8 +433,7 @@ static struct port_buffer *alloc_buf(struct virtio_device *vdev, size_t buf_size * Allocate buffer and the sg list. The sg list array is allocated * directly after the port_buffer struct. */ - buf = kmalloc(sizeof(*buf) + sizeof(struct scatterlist) * pages, - GFP_KERNEL); + buf = kmalloc(struct_size(buf, sg, pages), GFP_KERNEL); if (!buf) goto fail; @@ -1894,13 +1893,14 @@ static int init_vqs(struct ports_device *portdev) nr_ports = portdev->max_nr_ports; nr_queues = use_multiport(portdev) ? (nr_ports + 1) * 2 : 2; - vqs = kmalloc(nr_queues * sizeof(struct virtqueue *), GFP_KERNEL); - io_callbacks = kmalloc(nr_queues * sizeof(vq_callback_t *), GFP_KERNEL); - io_names = kmalloc(nr_queues * sizeof(char *), GFP_KERNEL); - portdev->in_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *), - GFP_KERNEL); - portdev->out_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *), - GFP_KERNEL); + vqs = kmalloc_array(nr_queues, sizeof(struct virtqueue *), GFP_KERNEL); + io_callbacks = kmalloc_array(nr_queues, sizeof(vq_callback_t *), + GFP_KERNEL); + io_names = kmalloc_array(nr_queues, sizeof(char *), GFP_KERNEL); + portdev->in_vqs = kmalloc_array(nr_ports, sizeof(struct virtqueue *), + GFP_KERNEL); + portdev->out_vqs = kmalloc_array(nr_ports, sizeof(struct virtqueue *), + GFP_KERNEL); if (!vqs || !io_callbacks || !io_names || !portdev->in_vqs || !portdev->out_vqs) { err = -ENOMEM; diff --git a/drivers/char/vservices_serial.c b/drivers/char/vservices_serial.c index 0194eacc563a..985befd6134d 100644 --- a/drivers/char/vservices_serial.c +++ b/drivers/char/vservices_serial.c @@ -576,8 +576,8 @@ static int __init vs_serial_init(void) if (max_ttys == 0) return -EINVAL; - alloced_ttys = kzalloc(sizeof(unsigned long) * BITS_TO_LONGS(max_ttys), - GFP_KERNEL); + alloced_ttys = kcalloc(BITS_TO_LONGS(max_ttys), sizeof(unsigned long), + GFP_KERNEL); if (!alloced_ttys) { err = -ENOMEM; goto fail_alloc_ttys; diff --git a/drivers/clk/bcm/clk-bcm2835-aux.c b/drivers/clk/bcm/clk-bcm2835-aux.c index bd750cf2238d..72b9d7bf8f0a 100644 --- a/drivers/clk/bcm/clk-bcm2835-aux.c +++ b/drivers/clk/bcm/clk-bcm2835-aux.c @@ -41,8 +41,9 @@ static int bcm2835_aux_clk_probe(struct platform_device *pdev) if (IS_ERR(reg)) return PTR_ERR(reg); - onecell = devm_kmalloc(dev, sizeof(*onecell) + sizeof(*onecell->hws) * - BCM2835_AUX_CLOCK_COUNT, GFP_KERNEL); + onecell = devm_kmalloc(dev, + struct_size(onecell, hws, BCM2835_AUX_CLOCK_COUNT), + GFP_KERNEL); if (!onecell) return -ENOMEM; onecell->num = BCM2835_AUX_CLOCK_COUNT; diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 6db4204e5d5d..5518a164bdd1 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -768,7 +768,7 @@ static int bcm2835_pll_debug_init(struct clk_hw *hw, const struct bcm2835_pll_data *data = pll->data; struct debugfs_reg32 *regs; - regs = devm_kzalloc(cprman->dev, 7 * sizeof(*regs), GFP_KERNEL); + regs = devm_kcalloc(cprman->dev, 7, sizeof(*regs), GFP_KERNEL); if (!regs) return -ENOMEM; @@ -899,7 +899,7 @@ static int bcm2835_pll_divider_debug_init(struct clk_hw *hw, const struct bcm2835_pll_divider_data *data = divider->data; struct debugfs_reg32 *regs; - regs = devm_kzalloc(cprman->dev, 7 * sizeof(*regs), GFP_KERNEL); + regs = devm_kcalloc(cprman->dev, 7, sizeof(*regs), GFP_KERNEL); if (!regs) return -ENOMEM; diff --git a/drivers/clk/berlin/bg2.c b/drivers/clk/berlin/bg2.c index e7331ace0337..45fb888bf0a0 100644 --- a/drivers/clk/berlin/bg2.c +++ b/drivers/clk/berlin/bg2.c @@ -509,8 +509,7 @@ static void __init berlin2_clock_setup(struct device_node *np) u8 avpll_flags = 0; int n, ret; - clk_data = kzalloc(sizeof(*clk_data) + - sizeof(*clk_data->hws) * MAX_CLKS, GFP_KERNEL); + clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL); if (!clk_data) return; clk_data->num = MAX_CLKS; diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c index 67c270b143f7..db7364e15c8b 100644 --- a/drivers/clk/berlin/bg2q.c +++ b/drivers/clk/berlin/bg2q.c @@ -295,8 +295,7 @@ static void __init berlin2q_clock_setup(struct device_node *np) struct clk_hw **hws; int n, ret; - clk_data = kzalloc(sizeof(*clk_data) + - sizeof(*clk_data->hws) * MAX_CLKS, GFP_KERNEL); + clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL); if (!clk_data) return; clk_data->num = MAX_CLKS; diff --git a/drivers/clk/clk-asm9260.c b/drivers/clk/clk-asm9260.c index bf0582cbbf38..44b544157121 100644 --- a/drivers/clk/clk-asm9260.c +++ b/drivers/clk/clk-asm9260.c @@ -273,8 +273,7 @@ static void __init asm9260_acc_init(struct device_node *np) int n; u32 accuracy = 0; - clk_data = kzalloc(sizeof(*clk_data) + - sizeof(*clk_data->hws) * MAX_CLKS, GFP_KERNEL); + clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL); if (!clk_data) return; clk_data->num = MAX_CLKS; diff --git a/drivers/clk/clk-efm32gg.c b/drivers/clk/clk-efm32gg.c index f674778fb3ac..f37cf08ff7aa 100644 --- a/drivers/clk/clk-efm32gg.c +++ b/drivers/clk/clk-efm32gg.c @@ -25,8 +25,8 @@ static void __init efm32gg_cmu_init(struct device_node *np) void __iomem *base; struct clk_hw **hws; - clk_data = kzalloc(sizeof(*clk_data) + - sizeof(*clk_data->hws) * CMU_MAX_CLKS, GFP_KERNEL); + clk_data = kzalloc(struct_size(clk_data, hws, CMU_MAX_CLKS), + GFP_KERNEL); if (!clk_data) return; diff --git a/drivers/clk/clk-gemini.c b/drivers/clk/clk-gemini.c index 5e66e6c0205e..5f044063f410 100644 --- a/drivers/clk/clk-gemini.c +++ b/drivers/clk/clk-gemini.c @@ -399,9 +399,8 @@ static void __init gemini_cc_init(struct device_node *np) int ret; int i; - gemini_clk_data = kzalloc(sizeof(*gemini_clk_data) + - sizeof(*gemini_clk_data->hws) * GEMINI_NUM_CLKS, - GFP_KERNEL); + gemini_clk_data = kzalloc(struct_size(gemini_clk_data, hws, GEMINI_NUM_CLKS), + GFP_KERNEL); if (!gemini_clk_data) return; diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index f5d74e8db432..4080d4e78e8e 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -147,8 +147,8 @@ static int s2mps11_clk_probe(struct platform_device *pdev) if (!s2mps11_clks) return -ENOMEM; - clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data) + - sizeof(*clk_data->hws) * S2MPS11_CLKS_NUM, + clk_data = devm_kzalloc(&pdev->dev, + struct_size(clk_data, hws, S2MPS11_CLKS_NUM), GFP_KERNEL); if (!clk_data) return -ENOMEM; diff --git a/drivers/clk/clk-stm32h7.c b/drivers/clk/clk-stm32h7.c index 61c3e40507d3..61d327836c34 100644 --- a/drivers/clk/clk-stm32h7.c +++ b/drivers/clk/clk-stm32h7.c @@ -1214,9 +1214,8 @@ static void __init stm32h7_rcc_init(struct device_node *np) const char *hse_clk, *lse_clk, *i2s_clk; struct regmap *pdrm; - clk_data = kzalloc(sizeof(*clk_data) + - sizeof(*clk_data->hws) * STM32H7_MAX_CLKS, - GFP_KERNEL); + clk_data = kzalloc(struct_size(clk_data, hws, STM32H7_MAX_CLKS), + GFP_KERNEL); if (!clk_data) return; diff --git a/drivers/clk/msm/clock-a7.c b/drivers/clk/msm/clock-a7.c index 679ecd29c0e4..4b6a39e5fa50 100644 --- a/drivers/clk/msm/clock-a7.c +++ b/drivers/clk/msm/clock-a7.c @@ -196,23 +196,23 @@ static int of_get_fmax_vdd_class(struct platform_device *pdev, struct clk *c, } prop_len /= 2; - vdd->level_votes = devm_kzalloc(&pdev->dev, prop_len * sizeof(int), + vdd->level_votes = devm_kcalloc(&pdev->dev, prop_len, sizeof(int), GFP_KERNEL); if (!vdd->level_votes) return -ENOMEM; - vdd->vdd_uv = devm_kzalloc(&pdev->dev, prop_len * sizeof(int), + vdd->vdd_uv = devm_kcalloc(&pdev->dev, prop_len, sizeof(int), GFP_KERNEL); if (!vdd->vdd_uv) return -ENOMEM; - c->fmax = devm_kzalloc(&pdev->dev, prop_len * sizeof(unsigned long), + c->fmax = devm_kcalloc(&pdev->dev, prop_len, sizeof(unsigned long), GFP_KERNEL); if (!c->fmax) return -ENOMEM; array = devm_kzalloc(&pdev->dev, - prop_len * sizeof(u32) * 2, GFP_KERNEL); + array3_size(prop_len, sizeof(u32), 2), GFP_KERNEL); if (!array) return -ENOMEM; diff --git a/drivers/clk/msm/clock-local2.c b/drivers/clk/msm/clock-local2.c index 3721865fbc09..4aa9db362945 100644 --- a/drivers/clk/msm/clock-local2.c +++ b/drivers/clk/msm/clock-local2.c @@ -2485,7 +2485,7 @@ struct clk_src *msmclk_parse_clk_src(struct device *dev, } num_parents = prop_len / len; - clks = devm_kzalloc(dev, sizeof(*clks) * num_parents, GFP_KERNEL); + clks = devm_kcalloc(dev, num_parents, sizeof(*clks), GFP_KERNEL); if (!clks) return ERR_PTR(-ENOMEM); @@ -2538,8 +2538,8 @@ static int rcg_parse_freq_tbl(struct device *dev, num_rows = prop_len / 6; /* Array is null terminated. */ - rcg->freq_tbl = devm_kzalloc(dev, - sizeof(*rcg->freq_tbl) * (num_rows + 1), + rcg->freq_tbl = devm_kcalloc(dev, + num_rows + 1, sizeof(*rcg->freq_tbl), GFP_KERNEL); if (!rcg->freq_tbl) { @@ -2646,8 +2646,8 @@ static int parse_rec_parents(struct device *dev, if (mux->num_rec_parents <= 0) return 0; - mux->rec_parents = devm_kzalloc(dev, - sizeof(*mux->rec_parents) * mux->num_rec_parents, + mux->rec_parents = devm_kcalloc(dev, + mux->num_rec_parents, sizeof(*mux->rec_parents), GFP_KERNEL); if (!mux->rec_parents) { diff --git a/drivers/clk/msm/gdsc.c b/drivers/clk/msm/gdsc.c index 0614cd86eeea..ecf76698aa36 100644 --- a/drivers/clk/msm/gdsc.c +++ b/drivers/clk/msm/gdsc.c @@ -530,8 +530,8 @@ static int gdsc_probe(struct platform_device *pdev) return -EINVAL; } - sc->clocks = devm_kzalloc(&pdev->dev, - sizeof(struct clk *) * sc->clock_count, GFP_KERNEL); + sc->clocks = devm_kcalloc(&pdev->dev, + sc->clock_count, sizeof(struct clk *), GFP_KERNEL); if (!sc->clocks) return -ENOMEM; @@ -616,9 +616,9 @@ static int gdsc_probe(struct platform_device *pdev) return -EINVAL; } - sc->reset_clocks = devm_kzalloc(&pdev->dev, - sizeof(struct reset_control *) * + sc->reset_clocks = devm_kcalloc(&pdev->dev, sc->reset_count, + sizeof(struct reset_control *), GFP_KERNEL); if (!sc->reset_clocks) return -ENOMEM; diff --git a/drivers/clk/msm/msm-clock-controller.c b/drivers/clk/msm/msm-clock-controller.c index 88f2e0b143e7..08ad7754bf6c 100644 --- a/drivers/clk/msm/msm-clock-controller.c +++ b/drivers/clk/msm/msm-clock-controller.c @@ -75,8 +75,8 @@ static int generic_vdd_parse_regulators(struct device *dev, return -EINVAL; } - vdd->regulator = devm_kzalloc(dev, - sizeof(*vdd->regulator) * num_regulators, + vdd->regulator = devm_kcalloc(dev, + num_regulators, sizeof(*vdd->regulator), GFP_KERNEL); if (!vdd->regulator) { dt_err(np, "memory alloc failure\n"); @@ -121,10 +121,10 @@ static int generic_vdd_parse_levels(struct device *dev, } vdd->num_levels = len / vdd->num_regulators; - vdd->vdd_uv = devm_kzalloc(dev, len * sizeof(*vdd->vdd_uv), + vdd->vdd_uv = devm_kcalloc(dev, len, sizeof(*vdd->vdd_uv), GFP_KERNEL); - vdd->level_votes = devm_kzalloc(dev, - vdd->num_levels * sizeof(*vdd->level_votes), + vdd->level_votes = devm_kcalloc(dev, + vdd->num_levels, sizeof(*vdd->level_votes), GFP_KERNEL); if (!vdd->vdd_uv || !vdd->level_votes) { @@ -150,7 +150,7 @@ static int generic_vdd_parse_levels(struct device *dev, return -EINVAL; } - vdd->vdd_ua = devm_kzalloc(dev, len * sizeof(*vdd->vdd_ua), + vdd->vdd_ua = devm_kcalloc(dev, len, sizeof(*vdd->vdd_ua), GFP_KERNEL); if (!vdd->vdd_ua) return -ENOMEM; @@ -290,7 +290,8 @@ static int generic_clk_parse_fmax(struct device *dev, struct clk *c, return rc; } - c->fmax = devm_kzalloc(dev, sizeof(*c->fmax) * c->num_fmax, GFP_KERNEL); + c->fmax = devm_kcalloc(dev, c->num_fmax, sizeof(*c->fmax), + GFP_KERNEL); if (!c->fmax) return -ENOMEM; diff --git a/drivers/clk/mvebu/armada-37xx-tbg.c b/drivers/clk/mvebu/armada-37xx-tbg.c index aa80db11f543..7ff041f73b55 100644 --- a/drivers/clk/mvebu/armada-37xx-tbg.c +++ b/drivers/clk/mvebu/armada-37xx-tbg.c @@ -91,8 +91,8 @@ static int armada_3700_tbg_clock_probe(struct platform_device *pdev) void __iomem *reg; int i, ret; - hw_tbg_data = devm_kzalloc(&pdev->dev, sizeof(*hw_tbg_data) - + sizeof(*hw_tbg_data->hws) * NUM_TBG, + hw_tbg_data = devm_kzalloc(&pdev->dev, + struct_size(hw_tbg_data, hws, NUM_TBG), GFP_KERNEL); if (!hw_tbg_data) return -ENOMEM; diff --git a/drivers/clk/qcom/clk-cpu-osm.c b/drivers/clk/qcom/clk-cpu-osm.c index ef6cbe663ddf..180de2df3fb6 100644 --- a/drivers/clk/qcom/clk-cpu-osm.c +++ b/drivers/clk/qcom/clk-cpu-osm.c @@ -68,6 +68,7 @@ struct osm_entry { }; struct clk_osm { + struct device *dev; struct clk_hw hw; struct osm_entry osm_table[OSM_TABLE_SIZE]; struct dentry *debugfs; @@ -643,13 +644,30 @@ static unsigned int osm_cpufreq_get(unsigned int cpu) return policy->freq_table[index].frequency; } +static bool osm_dt_find_freq(u32 *of_table, int of_len, long frequency) +{ + int i; + + if (!of_table) + return true; + + for (i = 0; i < of_len; i++) { + if (frequency == of_table[i]) + return true; + } + + return false; +} + static int osm_cpufreq_cpu_init(struct cpufreq_policy *policy) { struct cpufreq_frequency_table *table; struct clk_osm *c, *parent; struct clk_hw *p_hw; - int ret; + int ret, of_len; unsigned int i; + u32 *of_table = NULL; + char tbl_name[] = "qcom,cpufreq-table-##"; c = osm_configure_policy(policy); if (!c) { @@ -666,6 +684,26 @@ static int osm_cpufreq_cpu_init(struct cpufreq_policy *policy) parent = to_clk_osm(p_hw); c->vbase = parent->vbase; + snprintf(tbl_name, sizeof(tbl_name), "qcom,cpufreq-table-%d", policy->cpu); + if (of_find_property(parent->dev->of_node, tbl_name, &of_len) && of_len > 0) { + of_len /= sizeof(*of_table); + + of_table = kcalloc(of_len, sizeof(*of_table), GFP_KERNEL); + if (!of_table) { + pr_err("failed to allocate DT frequency table memory for CPU%d\n", + policy->cpu); + return -ENOMEM; + } + + ret = of_property_read_u32_array(parent->dev->of_node, tbl_name, + of_table, of_len); + if (ret) { + pr_err("failed to read DT frequency table for CPU%d, err=%d\n", + policy->cpu, ret); + return ret; + } + } + table = kcalloc(parent->osm_table_size + 1, sizeof(*table), GFP_KERNEL); if (!table) return -ENOMEM; @@ -686,6 +724,10 @@ static int osm_cpufreq_cpu_init(struct cpufreq_policy *policy) table[i].frequency = (XO_RATE * lval) / 1000; table[i].driver_data = table[i].frequency; + /* Ignore frequency if not present in DT table */ + if (!osm_dt_find_freq(of_table, of_len, table[i].frequency)) + table[i].frequency = CPUFREQ_ENTRY_INVALID; + if (core_count == SINGLE_CORE_COUNT) table[i].frequency = CPUFREQ_ENTRY_INVALID; @@ -715,9 +757,11 @@ static int osm_cpufreq_cpu_init(struct cpufreq_policy *policy) cpumask_copy(policy->cpus, &c->related_cpus); + kfree(of_table); return 0; err: + kfree(of_table); kfree(table); return ret; } @@ -946,6 +990,7 @@ static int clk_osm_read_lut(struct platform_device *pdev, struct clk_osm *c) { u32 data, src, lval, i, j = c->osm_table_size; + c->dev = &pdev->dev; for (i = 0; i < c->osm_table_size; i++) { data = clk_osm_read_reg(c, FREQ_REG + i * OSM_REG_SIZE); src = ((data & GENMASK(31, 30)) >> 30); diff --git a/drivers/clk/qcom/clk-cpu-qcs405.c b/drivers/clk/qcom/clk-cpu-qcs405.c index 3623924a1dc4..c71b5f5abee2 100644 --- a/drivers/clk/qcom/clk-cpu-qcs405.c +++ b/drivers/clk/qcom/clk-cpu-qcs405.c @@ -367,23 +367,24 @@ static int cpucc_clk_get_fmax_vdd_class(struct platform_device *pdev, } prop_len /= num; - vdd->level_votes = devm_kzalloc(&pdev->dev, prop_len * sizeof(int), + vdd->level_votes = devm_kcalloc(&pdev->dev, prop_len, sizeof(int), GFP_KERNEL); if (!vdd->level_votes) return -ENOMEM; vdd->vdd_uv = devm_kzalloc(&pdev->dev, - prop_len * sizeof(int) * (num - 1), GFP_KERNEL); + array3_size(prop_len, sizeof(int), (num - 1)), + GFP_KERNEL); if (!vdd->vdd_uv) return -ENOMEM; - clk_intd->rate_max = devm_kzalloc(&pdev->dev, - prop_len * sizeof(unsigned long), GFP_KERNEL); + clk_intd->rate_max = devm_kcalloc(&pdev->dev, + prop_len, sizeof(unsigned long), GFP_KERNEL); if (!clk_intd->rate_max) return -ENOMEM; array = devm_kzalloc(&pdev->dev, - prop_len * sizeof(u32) * num, GFP_KERNEL); + array3_size(prop_len, num, sizeof(u32)), GFP_KERNEL); if (!array) return -ENOMEM; diff --git a/drivers/clk/qcom/clk-cpu-sdxprairie.c b/drivers/clk/qcom/clk-cpu-sdxprairie.c index be011b4021ee..038a14e7cbc8 100644 --- a/drivers/clk/qcom/clk-cpu-sdxprairie.c +++ b/drivers/clk/qcom/clk-cpu-sdxprairie.c @@ -326,23 +326,24 @@ static int cpucc_clk_get_fmax_vdd_class(struct platform_device *pdev, } prop_len /= num; - vdd->level_votes = devm_kzalloc(&pdev->dev, prop_len * sizeof(int), + vdd->level_votes = devm_kcalloc(&pdev->dev, prop_len, sizeof(int), GFP_KERNEL); if (!vdd->level_votes) return -ENOMEM; vdd->vdd_uv = devm_kzalloc(&pdev->dev, - prop_len * sizeof(int) * (num - 1), GFP_KERNEL); + array3_size(prop_len, sizeof(int), (num - 1)), + GFP_KERNEL); if (!vdd->vdd_uv) return -ENOMEM; - clk_intd->rate_max = devm_kzalloc(&pdev->dev, - prop_len * sizeof(unsigned long), GFP_KERNEL); + clk_intd->rate_max = devm_kcalloc(&pdev->dev, + prop_len, sizeof(unsigned long), GFP_KERNEL); if (!clk_intd->rate_max) return -ENOMEM; array = devm_kzalloc(&pdev->dev, - prop_len * sizeof(u32) * num, GFP_KERNEL); + array3_size(prop_len, num, sizeof(u32)), GFP_KERNEL); if (!array) return -ENOMEM; diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 32f4b87a2448..c601d002f13c 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -349,9 +349,6 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f, clk_flags = clk_hw_get_flags(hw); p = clk_hw_get_parent_by_index(hw, index); - if (!p) - return -EINVAL; - if (clk_flags & CLK_SET_RATE_PARENT) { if (f->pre_div) { if (!rate) @@ -1623,8 +1620,9 @@ int clk_rcg2_get_dfs_clock_rate(struct clk_rcg2 *clk, struct device *dev, if (!(val & SE_CMD_DFS_EN)) return ret; - dfs_freq_tbl = devm_kzalloc(dev, MAX_PERF_LEVEL * - sizeof(struct freq_tbl), GFP_KERNEL); + dfs_freq_tbl = devm_kcalloc(dev, + MAX_PERF_LEVEL, sizeof(struct freq_tbl), + GFP_KERNEL); if (!dfs_freq_tbl) return -ENOMEM; diff --git a/drivers/clk/qcom/clk-spmi-pmic-div.c b/drivers/clk/qcom/clk-spmi-pmic-div.c index c22eccacc860..7bae2ef6a755 100644 --- a/drivers/clk/qcom/clk-spmi-pmic-div.c +++ b/drivers/clk/qcom/clk-spmi-pmic-div.c @@ -240,8 +240,7 @@ static int spmi_pmic_clkdiv_probe(struct platform_device *pdev) if (!nclks) return -EINVAL; - cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*cc->clks) * nclks, - GFP_KERNEL); + cc = devm_kzalloc(dev, struct_size(cc, clks, nclks), GFP_KERNEL); if (!cc) return -ENOMEM; cc->nclks = nclks; diff --git a/drivers/clk/qcom/debugcc-atoll.c b/drivers/clk/qcom/debugcc-atoll.c index 81a92cc30df2..076769c53deb 100644 --- a/drivers/clk/qcom/debugcc-atoll.c +++ b/drivers/clk/qcom/debugcc-atoll.c @@ -738,8 +738,8 @@ static int clk_debug_atoll_probe(struct platform_device *pdev) return -EINVAL; } - gcc_debug_mux.regmap = devm_kzalloc(&pdev->dev, - sizeof(struct regmap *) * count, GFP_KERNEL); + gcc_debug_mux.regmap = devm_kcalloc(&pdev->dev, + count, sizeof(struct regmap *), GFP_KERNEL); if (!gcc_debug_mux.regmap) return -ENOMEM; diff --git a/drivers/clk/qcom/debugcc-sdmmagpie.c b/drivers/clk/qcom/debugcc-sdmmagpie.c index 7f9c9701138e..8c4378784485 100644 --- a/drivers/clk/qcom/debugcc-sdmmagpie.c +++ b/drivers/clk/qcom/debugcc-sdmmagpie.c @@ -789,8 +789,8 @@ static int clk_debug_sdmmagpie_probe(struct platform_device *pdev) return -EINVAL; } - gcc_debug_mux.regmap = devm_kzalloc(&pdev->dev, - sizeof(struct regmap *) * count, GFP_KERNEL); + gcc_debug_mux.regmap = devm_kcalloc(&pdev->dev, + count, sizeof(struct regmap *), GFP_KERNEL); if (!gcc_debug_mux.regmap) return -ENOMEM; diff --git a/drivers/clk/qcom/gdsc-regulator.c b/drivers/clk/qcom/gdsc-regulator.c index f689661cfc3d..dc585123dcd1 100644 --- a/drivers/clk/qcom/gdsc-regulator.c +++ b/drivers/clk/qcom/gdsc-regulator.c @@ -772,8 +772,8 @@ static int gdsc_probe(struct platform_device *pdev) return -EINVAL; } - sc->clocks = devm_kzalloc(&pdev->dev, - sizeof(struct clk *) * sc->clock_count, GFP_KERNEL); + sc->clocks = devm_kcalloc(&pdev->dev, + sc->clock_count, sizeof(struct clk *), GFP_KERNEL); if (!sc->clocks) return -ENOMEM; @@ -938,9 +938,9 @@ static int gdsc_probe(struct platform_device *pdev) goto err; } - sc->reset_clocks = devm_kzalloc(&pdev->dev, - sizeof(struct reset_control *) * sc->reset_count, - GFP_KERNEL); + sc->reset_clocks = devm_kcalloc(&pdev->dev, + sc->reset_count, sizeof(struct reset_control *), + GFP_KERNEL); if (!sc->reset_clocks) { ret = -ENOMEM; goto err; diff --git a/drivers/clk/qcom/mdss/mdss-pll-util.c b/drivers/clk/qcom/mdss/mdss-pll-util.c index 3e60d93f08f4..fa2209f47517 100644 --- a/drivers/clk/qcom/mdss/mdss-pll-util.c +++ b/drivers/clk/qcom/mdss/mdss-pll-util.c @@ -172,8 +172,9 @@ static int mdss_pll_util_parse_dt_supply(struct platform_device *pdev, } pr_debug("vreg found. count=%d\n", mp->num_vreg); - mp->vreg_config = devm_kzalloc(&pdev->dev, sizeof(struct dss_vreg) * - mp->num_vreg, GFP_KERNEL); + mp->vreg_config = devm_kcalloc(&pdev->dev, + mp->num_vreg, sizeof(struct dss_vreg), + GFP_KERNEL); if (!mp->vreg_config) { rc = -ENOMEM; return rc; @@ -299,8 +300,8 @@ static int mdss_pll_util_parse_dt_clock(struct platform_device *pdev, goto clk_err; } - mp->clk_config = devm_kzalloc(&pdev->dev, - sizeof(struct dss_clk) * mp->num_clk, GFP_KERNEL); + mp->clk_config = devm_kcalloc(&pdev->dev, + mp->num_clk, sizeof(struct dss_clk), GFP_KERNEL); if (!mp->clk_config) { rc = -ENOMEM; mp->num_clk = 0; diff --git a/drivers/clk/qcom/mdss/mdss-pll.h b/drivers/clk/qcom/mdss/mdss-pll.h index c0dd61eaccd9..14ff934a1a29 100644 --- a/drivers/clk/qcom/mdss/mdss-pll.h +++ b/drivers/clk/qcom/mdss/mdss-pll.h @@ -218,8 +218,13 @@ static inline bool is_gdsc_disabled(struct mdss_pll_resources *pll_res) WARN(1, "gdsc_base register is not defined\n"); return true; } - ret = ((readl_relaxed(pll_res->gdsc_base + 0x4) & BIT(31)) && - (!(readl_relaxed(pll_res->gdsc_base) & BIT(0)))) ? false : true; + if (pll_res->pll_interface_type == MDSS_DSI_PLL_12NM) + ret = ((readl_relaxed(pll_res->gdsc_base + 0x4) & BIT(31)) && + (!(readl_relaxed(pll_res->gdsc_base) & BIT(0)))) ? + false : true; + else + ret = readl_relaxed(pll_res->gdsc_base) & BIT(31) ? + false : true; return ret; } diff --git a/drivers/clk/qcom/npucc-atoll.c b/drivers/clk/qcom/npucc-atoll.c index b2be104de7f6..a58d96d0c017 100644 --- a/drivers/clk/qcom/npucc-atoll.c +++ b/drivers/clk/qcom/npucc-atoll.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -357,13 +357,13 @@ static struct clk_rcg2 npu_cc_core_clk_src = { }; static const struct freq_tbl ftbl_npu_dsp_core_clk_src[] = { - F(250000000, P_NPU_Q6SS_PLL_OUT_MAIN, 1, 0, 0), - F(300000000, P_NPU_Q6SS_PLL_OUT_MAIN, 1, 0, 0), - F(400000000, P_NPU_Q6SS_PLL_OUT_MAIN, 1, 0, 0), - F(500000000, P_NPU_Q6SS_PLL_OUT_MAIN, 1, 0, 0), - F(600000000, P_NPU_Q6SS_PLL_OUT_MAIN, 1, 0, 0), - F(660000000, P_NPU_Q6SS_PLL_OUT_MAIN, 1, 0, 0), - F(800000000, P_NPU_Q6SS_PLL_OUT_MAIN, 1, 0, 0), + F(250000000, P_NPU_Q6SS_PLL_OUT_MAIN, 2, 0, 0), + F(300000000, P_NPU_Q6SS_PLL_OUT_MAIN, 2, 0, 0), + F(400000000, P_NPU_Q6SS_PLL_OUT_MAIN, 2, 0, 0), + F(500000000, P_NPU_Q6SS_PLL_OUT_MAIN, 2, 0, 0), + F(600000000, P_NPU_Q6SS_PLL_OUT_MAIN, 2, 0, 0), + F(660000000, P_NPU_Q6SS_PLL_OUT_MAIN, 2, 0, 0), + F(800000000, P_NPU_Q6SS_PLL_OUT_MAIN, 2, 0, 0), { } }; diff --git a/drivers/clk/renesas/clk-r8a7740.c b/drivers/clk/renesas/clk-r8a7740.c index 2f7ce6696b6c..718a65ac84f1 100644 --- a/drivers/clk/renesas/clk-r8a7740.c +++ b/drivers/clk/renesas/clk-r8a7740.c @@ -161,7 +161,7 @@ static void __init r8a7740_cpg_clocks_init(struct device_node *np) } cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); - clks = kzalloc(num_clks * sizeof(*clks), GFP_KERNEL); + clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL); if (cpg == NULL || clks == NULL) { /* We're leaking memory on purpose, there's no point in cleaning * up as the system won't boot anyway. diff --git a/drivers/clk/renesas/clk-r8a7779.c b/drivers/clk/renesas/clk-r8a7779.c index 27fbfafaf2cd..5adcca4656c3 100644 --- a/drivers/clk/renesas/clk-r8a7779.c +++ b/drivers/clk/renesas/clk-r8a7779.c @@ -138,7 +138,7 @@ static void __init r8a7779_cpg_clocks_init(struct device_node *np) } cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); - clks = kzalloc(CPG_NUM_CLOCKS * sizeof(*clks), GFP_KERNEL); + clks = kcalloc(CPG_NUM_CLOCKS, sizeof(*clks), GFP_KERNEL); if (cpg == NULL || clks == NULL) { /* We're leaking memory on purpose, there's no point in cleaning * up as the system won't boot anyway. diff --git a/drivers/clk/renesas/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c index 0b2e56d0d94b..563bb70362ef 100644 --- a/drivers/clk/renesas/clk-rcar-gen2.c +++ b/drivers/clk/renesas/clk-rcar-gen2.c @@ -418,7 +418,7 @@ static void __init rcar_gen2_cpg_clocks_init(struct device_node *np) } cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); - clks = kzalloc(num_clks * sizeof(*clks), GFP_KERNEL); + clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL); if (cpg == NULL || clks == NULL) { /* We're leaking memory on purpose, there's no point in cleaning * up as the system won't boot anyway. diff --git a/drivers/clk/renesas/clk-rz.c b/drivers/clk/renesas/clk-rz.c index 5adb934326d1..e582ee6e25ad 100644 --- a/drivers/clk/renesas/clk-rz.c +++ b/drivers/clk/renesas/clk-rz.c @@ -97,7 +97,7 @@ static void __init rz_cpg_clocks_init(struct device_node *np) return; cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); - clks = kzalloc(num_clks * sizeof(*clks), GFP_KERNEL); + clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL); BUG_ON(!cpg || !clks); cpg->data.clks = clks; diff --git a/drivers/clk/rockchip/clk-rockchip.c b/drivers/clk/rockchip/clk-rockchip.c index 2c9bb81144c9..1feb4e233d48 100644 --- a/drivers/clk/rockchip/clk-rockchip.c +++ b/drivers/clk/rockchip/clk-rockchip.c @@ -58,7 +58,7 @@ static void __init rk2928_gate_clk_init(struct device_node *node) return; } - clk_data->clks = kzalloc(qty * sizeof(struct clk *), GFP_KERNEL); + clk_data->clks = kcalloc(qty, sizeof(struct clk *), GFP_KERNEL); if (!clk_data->clks) { kfree(clk_data); iounmap(reg); diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c index b117783ed404..2c3b15b48586 100644 --- a/drivers/clk/samsung/clk-exynos-audss.c +++ b/drivers/clk/samsung/clk-exynos-audss.c @@ -151,8 +151,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) epll = ERR_PTR(-ENODEV); clk_data = devm_kzalloc(&pdev->dev, - sizeof(*clk_data) + - sizeof(*clk_data->hws) * EXYNOS_AUDSS_MAX_CLKS, + struct_size(clk_data, hws, EXYNOS_AUDSS_MAX_CLKS), GFP_KERNEL); if (!clk_data) return -ENOMEM; diff --git a/drivers/clk/samsung/clk-s5pv210-audss.c b/drivers/clk/samsung/clk-s5pv210-audss.c index b9641414ddc6..22b18e728b88 100644 --- a/drivers/clk/samsung/clk-s5pv210-audss.c +++ b/drivers/clk/samsung/clk-s5pv210-audss.c @@ -81,8 +81,7 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev) } clk_data = devm_kzalloc(&pdev->dev, - sizeof(*clk_data) + - sizeof(*clk_data->hws) * AUDSS_MAX_CLKS, + struct_size(clk_data, hws, AUDSS_MAX_CLKS), GFP_KERNEL); if (!clk_data) diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c index 14819d919df1..a79d81985c4e 100644 --- a/drivers/clk/st/clkgen-fsyn.c +++ b/drivers/clk/st/clkgen-fsyn.c @@ -874,7 +874,7 @@ static void __init st_of_create_quadfs_fsynths( return; clk_data->clk_num = QUADFS_MAX_CHAN; - clk_data->clks = kzalloc(QUADFS_MAX_CHAN * sizeof(struct clk *), + clk_data->clks = kcalloc(QUADFS_MAX_CHAN, sizeof(struct clk *), GFP_KERNEL); if (!clk_data->clks) { diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c index 25bda48a5d35..7a7106dc80bf 100644 --- a/drivers/clk/st/clkgen-pll.c +++ b/drivers/clk/st/clkgen-pll.c @@ -738,7 +738,7 @@ static void __init clkgen_c32_pll_setup(struct device_node *np, return; clk_data->clk_num = num_odfs; - clk_data->clks = kzalloc(clk_data->clk_num * sizeof(struct clk *), + clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *), GFP_KERNEL); if (!clk_data->clks) diff --git a/drivers/clk/sunxi/clk-usb.c b/drivers/clk/sunxi/clk-usb.c index fe0c3d169377..917fc27a33dd 100644 --- a/drivers/clk/sunxi/clk-usb.c +++ b/drivers/clk/sunxi/clk-usb.c @@ -122,7 +122,7 @@ static void __init sunxi_usb_clk_setup(struct device_node *node, if (!clk_data) return; - clk_data->clks = kzalloc((qty+1) * sizeof(struct clk *), GFP_KERNEL); + clk_data->clks = kcalloc(qty + 1, sizeof(struct clk *), GFP_KERNEL); if (!clk_data->clks) { kfree(clk_data); return; diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index ba923f0d5953..e64b41dd2837 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -216,14 +216,15 @@ struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks) if (WARN_ON(banks > ARRAY_SIZE(periph_regs))) return NULL; - periph_clk_enb_refcnt = kzalloc(32 * banks * - sizeof(*periph_clk_enb_refcnt), GFP_KERNEL); + periph_clk_enb_refcnt = kcalloc(32 * banks, + sizeof(*periph_clk_enb_refcnt), + GFP_KERNEL); if (!periph_clk_enb_refcnt) return NULL; periph_banks = banks; - clks = kzalloc(num * sizeof(struct clk *), GFP_KERNEL); + clks = kcalloc(num, sizeof(struct clk *), GFP_KERNEL); if (!clks) kfree(periph_clk_enb_refcnt); diff --git a/drivers/clk/ti/adpll.c b/drivers/clk/ti/adpll.c index d6036c788fab..688e403333b9 100644 --- a/drivers/clk/ti/adpll.c +++ b/drivers/clk/ti/adpll.c @@ -501,8 +501,9 @@ static int ti_adpll_init_dco(struct ti_adpll_data *d) const char *postfix; int width, err; - d->outputs.clks = devm_kzalloc(d->dev, sizeof(struct clk *) * + d->outputs.clks = devm_kcalloc(d->dev, MAX_ADPLL_OUTPUTS, + sizeof(struct clk *), GFP_KERNEL); if (!d->outputs.clks) return -ENOMEM; @@ -915,8 +916,9 @@ static int ti_adpll_probe(struct platform_device *pdev) if (err) return err; - d->clocks = devm_kzalloc(d->dev, sizeof(struct ti_adpll_clock) * + d->clocks = devm_kcalloc(d->dev, TI_ADPLL_NR_CLOCKS, + sizeof(struct ti_adpll_clock), GFP_KERNEL); if (!d->clocks) return -ENOMEM; diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c index 83b148f8037c..30453a4e5b2c 100644 --- a/drivers/clk/ti/apll.c +++ b/drivers/clk/ti/apll.c @@ -205,7 +205,7 @@ static void __init of_dra7_apll_setup(struct device_node *node) goto cleanup; } - parent_names = kzalloc(sizeof(char *) * init->num_parents, GFP_KERNEL); + parent_names = kcalloc(init->num_parents, sizeof(char *), GFP_KERNEL); if (!parent_names) goto cleanup; diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c index 88f04a4cb890..82136450b2c5 100644 --- a/drivers/clk/ti/divider.c +++ b/drivers/clk/ti/divider.c @@ -364,7 +364,7 @@ int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, num_dividers = i; - tmp = kzalloc(sizeof(*tmp) * (valid_div + 1), GFP_KERNEL); + tmp = kcalloc(valid_div + 1, sizeof(*tmp), GFP_KERNEL); if (!tmp) return -ENOMEM; @@ -493,7 +493,7 @@ __init ti_clk_get_div_table(struct device_node *node) return ERR_PTR(-EINVAL); } - table = kzalloc(sizeof(*table) * (valid_div + 1), GFP_KERNEL); + table = kcalloc(valid_div + 1, sizeof(*table), GFP_KERNEL); if (!table) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c index d4e4444bc5ca..69280f37e3c0 100644 --- a/drivers/clk/ti/dpll.c +++ b/drivers/clk/ti/dpll.c @@ -398,7 +398,7 @@ static void __init of_ti_dpll_setup(struct device_node *node, goto cleanup; } - parent_names = kzalloc(sizeof(char *) * init->num_parents, GFP_KERNEL); + parent_names = kcalloc(init->num_parents, sizeof(char *), GFP_KERNEL); if (!parent_names) goto cleanup; diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 3cd62f7c33e3..d8fd71b303f8 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -1004,7 +1004,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev) /* Allocate and setup the channels. */ cmt->num_channels = hweight8(cmt->hw_channels); - cmt->channels = kzalloc(cmt->num_channels * sizeof(*cmt->channels), + cmt->channels = kcalloc(cmt->num_channels, sizeof(*cmt->channels), GFP_KERNEL); if (cmt->channels == NULL) { ret = -ENOMEM; diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index 53aa7e92a7d7..6812e099b6a3 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c @@ -418,7 +418,7 @@ static int sh_mtu2_setup(struct sh_mtu2_device *mtu, /* Allocate and setup the channels. */ mtu->num_channels = 3; - mtu->channels = kzalloc(sizeof(*mtu->channels) * mtu->num_channels, + mtu->channels = kcalloc(mtu->num_channels, sizeof(*mtu->channels), GFP_KERNEL); if (mtu->channels == NULL) { ret = -ENOMEM; diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 31d881621e41..c74a6c543ca2 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -569,7 +569,7 @@ static int sh_tmu_setup(struct sh_tmu_device *tmu, struct platform_device *pdev) } /* Allocate and setup the channels. */ - tmu->channels = kzalloc(sizeof(*tmu->channels) * tmu->num_channels, + tmu->channels = kcalloc(tmu->num_channels, sizeof(*tmu->channels), GFP_KERNEL); if (tmu->channels == NULL) { ret = -ENOMEM; diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 4597d3232709..be399b9e50f4 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -230,6 +230,24 @@ config CPU_FREQ_GOV_SCHEDUTIL If in doubt, say N. +if CPU_FREQ_GOV_SCHEDUTIL + +config SCHEDUTIL_UP_RATE_LIMIT + int "Default up rate-limit for schedutil" + default 1000 + help + This sets schedutil's default frequency up rate-limit in + microseconds. + +config SCHEDUTIL_DOWN_RATE_LIMIT + int "Default down rate-limit for schedutil" + default 1000 + help + This sets schedutil's default frequency down rate-limit in + microseconds. + +endif + config CPU_FREQ_GOV_INTERACTIVE tristate "'interactive' cpufreq policy governor" depends on CPU_FREQ @@ -250,6 +268,33 @@ config CPU_FREQ_GOV_INTERACTIVE If in doubt, say N. +config CPU_FREQ_DEFAULT_LITTLE_MIN + int "Default minimum frequency for the little cluster" + default 0 + help + This sets the default minimum frequency (in kHz) for the little CPU + cluster. + + If in doubt, say 0 to use the hardware's minimum frequency. + +config CPU_FREQ_DEFAULT_BIG_MIN + int "Default minimum frequency for the big cluster" + default 0 + help + This sets the default minimum frequency (in kHz) for the big CPU + cluster. + + If in doubt, say 0 to use the hardware's minimum frequency. + +config CPU_FREQ_DEFAULT_PRIME_MIN + int "Default minimum frequency for the prime cluster" + default 0 + help + This sets the default minimum frequency (in kHz) for the prime CPU + cluster. + + If in doubt, say 0 to use the hardware's minimum frequency. + config CPU_INPUT_BOOST bool "CPU Input Boost" help @@ -262,30 +307,12 @@ config CPU_INPUT_BOOST if CPU_INPUT_BOOST -config INPUT_BOOST_DURATION_MS - int "Input boost duration" - default "100" - help - Input boost duration in milliseconds. - config WAKE_BOOST_DURATION_MS int "Wake boost duration" default "1000" help Wake boost duration in milliseconds. -config INPUT_BOOST_FREQ_LP - int "Low-power cluster boost freq" - default "0" - help - Input boost frequency for the low-power CPU cluster. - -config INPUT_BOOST_FREQ_PERF - int "Performance cluster boost freq" - default "0" - help - Input boost frequency for the performance CPU cluster. - config MAX_BOOST_FREQ_LP int "Low-power cluster max-boost freq" default "0" @@ -298,17 +325,12 @@ config MAX_BOOST_FREQ_PERF help Max-boost frequency for the performance CPU cluster. -config MIN_FREQ_LP - int "LP cluster min boost to set after boost" +config MAX_BOOST_FREQ_PERFP + int "Prime cluster max-boost freq" default "0" help - Min freq to set for lp cluster when boost is over. + Max-boost frequency for the prime CPU cluster. -config MIN_FREQ_PERF - int "HP cluster min boost to set after boost" - default "0" - help - Min freq to set for hp cluster when boost is over. endif comment "CPU frequency scaling drivers" diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 51a3c15ace09..5073db1ef6b1 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -759,8 +759,8 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) goto err_unreg; } - freq_table = kzalloc(sizeof(*freq_table) * - (perf->state_count+1), GFP_KERNEL); + freq_table = kcalloc(perf->state_count + 1, sizeof(*freq_table), + GFP_KERNEL); if (!freq_table) { result = -ENOMEM; goto err_unreg; diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index 0c41ab3b16eb..82db77f91c62 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c @@ -280,7 +280,7 @@ static int merge_cluster_tables(void) for (i = 0; i < MAX_CLUSTERS; i++) count += get_table_count(freq_table[i]); - table = kzalloc(sizeof(*table) * count, GFP_KERNEL); + table = kcalloc(count, sizeof(*table), GFP_KERNEL); if (!table) return -ENOMEM; diff --git a/drivers/cpufreq/at32ap-cpufreq.c b/drivers/cpufreq/at32ap-cpufreq.c index 7b612c8bb09e..55b5f0fe1795 100644 --- a/drivers/cpufreq/at32ap-cpufreq.c +++ b/drivers/cpufreq/at32ap-cpufreq.c @@ -77,8 +77,8 @@ static int at32_cpufreq_driver_init(struct cpufreq_policy *policy) * frequency table. */ steps = fls(frequency / min_freq) + 1; - freq_table = kzalloc(steps * sizeof(struct cpufreq_frequency_table), - GFP_KERNEL); + freq_table = kcalloc(steps, sizeof(struct cpufreq_frequency_table), + GFP_KERNEL); if (!freq_table) { retval = -ENOMEM; goto out_err_put_clk; diff --git a/drivers/cpufreq/bmips-cpufreq.c b/drivers/cpufreq/bmips-cpufreq.c index 1653151b77df..56a4ebbf00e0 100644 --- a/drivers/cpufreq/bmips-cpufreq.c +++ b/drivers/cpufreq/bmips-cpufreq.c @@ -71,7 +71,7 @@ bmips_cpufreq_get_freq_table(const struct cpufreq_policy *policy) cpu_freq = htp_freq_to_cpu_freq(priv->clk_mult); - table = kmalloc((priv->max_freqs + 1) * sizeof(*table), GFP_KERNEL); + table = kmalloc_array(priv->max_freqs + 1, sizeof(*table), GFP_KERNEL); if (!table) return ERR_PTR(-ENOMEM); diff --git a/drivers/cpufreq/brcmstb-avs-cpufreq.c b/drivers/cpufreq/brcmstb-avs-cpufreq.c index 39c462711eae..267416966e93 100644 --- a/drivers/cpufreq/brcmstb-avs-cpufreq.c +++ b/drivers/cpufreq/brcmstb-avs-cpufreq.c @@ -494,7 +494,7 @@ brcm_avs_get_freq_table(struct device *dev, struct private_data *priv) if (ret) return ERR_PTR(ret); - table = devm_kzalloc(dev, (AVS_PSTATE_MAX + 1) * sizeof(*table), + table = devm_kcalloc(dev, AVS_PSTATE_MAX + 1, sizeof(*table), GFP_KERNEL); if (!table) return ERR_PTR(-ENOMEM); diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index c9ce716247c1..251873356ce5 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -258,7 +258,8 @@ static int __init cppc_cpufreq_init(void) if (acpi_disabled) return -ENODEV; - all_cpu_data = kzalloc(sizeof(void *) * num_possible_cpus(), GFP_KERNEL); + all_cpu_data = kcalloc(num_possible_cpus(), sizeof(void *), + GFP_KERNEL); if (!all_cpu_data) return -ENOMEM; diff --git a/drivers/cpufreq/cpu-boost.c b/drivers/cpufreq/cpu-boost.c index da4884795cdf..b6ceb2133b9b 100644 --- a/drivers/cpufreq/cpu-boost.c +++ b/drivers/cpufreq/cpu-boost.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2013-2015,2017, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 XiaoMi, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -17,46 +18,60 @@ #include #include #include +#include #include #include #include #include #include +#include + +#include struct cpu_sync { int cpu; unsigned int input_boost_min; unsigned int input_boost_freq; + unsigned int powerkey_input_boost_freq; +}; + +enum input_boost_type { + default_input_boost, + powerkey_input_boost }; static DEFINE_PER_CPU(struct cpu_sync, sync_info); -static struct workqueue_struct *cpu_boost_wq; -static struct work_struct input_boost_work; +static struct kthread_work input_boost_work; + +static struct kthread_work powerkey_input_boost_work; static bool input_boost_enabled; static unsigned int input_boost_ms = 40; module_param(input_boost_ms, uint, 0644); +static unsigned int powerkey_input_boost_ms = 400; +module_param(powerkey_input_boost_ms, uint, 0644); + static unsigned int sched_boost_on_input; module_param(sched_boost_on_input, uint, 0644); -static bool sched_boost_active; +static bool sched_boost_on_powerkey_input = true; +module_param(sched_boost_on_powerkey_input, bool, 0644); -#ifdef CONFIG_DYNAMIC_STUNE_BOOST -static int dynamic_stune_boost = 1; -module_param(dynamic_stune_boost, uint, 0644); -static bool stune_boost_active; -static int boost_slot; -static unsigned int dynamic_stune_boost_ms = 40; -module_param(dynamic_stune_boost_ms, uint, 0644); -static struct delayed_work dynamic_stune_boost_rem; -#endif /* CONFIG_DYNAMIC_STUNE_BOOST */ +static bool sched_boost_active; static struct delayed_work input_boost_rem; static u64 last_input_time; -#define MIN_INPUT_INTERVAL (150 * USEC_PER_MSEC) + +static struct kthread_worker cpu_boost_worker; +static struct task_struct *cpu_boost_worker_thread; + +static struct kthread_worker powerkey_cpu_boost_worker; +static struct task_struct *powerkey_cpu_boost_worker_thread; + +#define MIN_INPUT_INTERVAL (100 * USEC_PER_MSEC) static int set_input_boost_freq(const char *buf, const struct kernel_param *kp) { @@ -64,6 +79,12 @@ static int set_input_boost_freq(const char *buf, const struct kernel_param *kp) unsigned int val, cpu; const char *cp = buf; bool enabled = false; + enum input_boost_type type; + + if (strstr(kp->name, "input_boost_freq")) + type = default_input_boost; + if (strstr(kp->name, "powerkey_input_boost_freq")) + type = powerkey_input_boost; while ((cp = strpbrk(cp + 1, " :"))) ntokens++; @@ -72,8 +93,12 @@ static int set_input_boost_freq(const char *buf, const struct kernel_param *kp) if (!ntokens) { if (sscanf(buf, "%u\n", &val) != 1) return -EINVAL; - for_each_possible_cpu(i) - per_cpu(sync_info, i).input_boost_freq = val; + for_each_possible_cpu(i) { + if (type == default_input_boost) + per_cpu(sync_info, i).input_boost_freq = val; + else if (type == powerkey_input_boost) + per_cpu(sync_info, i).powerkey_input_boost_freq = val; + } goto check_enable; } @@ -88,14 +113,18 @@ static int set_input_boost_freq(const char *buf, const struct kernel_param *kp) if (cpu >= num_possible_cpus()) return -EINVAL; - per_cpu(sync_info, cpu).input_boost_freq = val; + if (type == default_input_boost) + per_cpu(sync_info, cpu).input_boost_freq = val; + else if (type == powerkey_input_boost) + per_cpu(sync_info, cpu).powerkey_input_boost_freq = val; cp = strnchr(cp, PAGE_SIZE - (cp - buf), ' '); cp++; } check_enable: for_each_possible_cpu(i) { - if (per_cpu(sync_info, i).input_boost_freq) { + if (per_cpu(sync_info, i).input_boost_freq + || per_cpu(sync_info, i).powerkey_input_boost_freq) { enabled = true; break; } @@ -109,11 +138,22 @@ static int get_input_boost_freq(char *buf, const struct kernel_param *kp) { int cnt = 0, cpu; struct cpu_sync *s; + unsigned int boost_freq = 0; + enum input_boost_type type; + + if (strstr(kp->name, "input_boost_freq")) + type = default_input_boost; + if (strstr(kp->name, "powerkey_input_boost_freq")) + type = powerkey_input_boost; for_each_possible_cpu(cpu) { s = &per_cpu(sync_info, cpu); + if (type == default_input_boost) + boost_freq = s->input_boost_freq; + else if(type == powerkey_input_boost) + boost_freq = s->powerkey_input_boost_freq; cnt += snprintf(buf + cnt, PAGE_SIZE - cnt, - "%d:%u ", cpu, s->input_boost_freq); + "%d:%u ", cpu, boost_freq); } cnt += snprintf(buf + cnt, PAGE_SIZE - cnt, "\n"); return cnt; @@ -125,6 +165,8 @@ static const struct kernel_param_ops param_ops_input_boost_freq = { }; module_param_cb(input_boost_freq, ¶m_ops_input_boost_freq, NULL, 0644); +module_param_cb(powerkey_input_boost_freq, ¶m_ops_input_boost_freq, NULL, 0644); + /* * The CPUFREQ_ADJUST notifier is used to override the current policy min to * make sure policy min >= boost_min. The cpufreq framework then does the job @@ -197,38 +239,17 @@ static void do_input_boost_rem(struct work_struct *work) } } -#ifdef CONFIG_DYNAMIC_STUNE_BOOST -static void do_dynamic_stune_boost_rem(struct work_struct *work) -{ - /* Reset dynamic stune boost value to the default value */ - if (stune_boost_active) { - reset_stune_boost("top-app", boost_slot); - stune_boost_active = false; - } -} -#endif /* CONFIG_DYNAMIC_STUNE_BOOST */ - -static void do_input_boost(struct work_struct *work) +static void do_input_boost(struct kthread_work *work) { unsigned int i, ret; struct cpu_sync *i_sync_info; -#ifdef CONFIG_DYNAMIC_STUNE_BOOST - cancel_delayed_work_sync(&dynamic_stune_boost_rem); -#endif /* CONFIG_DYNAMIC_STUNE_BOOST */ cancel_delayed_work_sync(&input_boost_rem); if (sched_boost_active) { sched_set_boost(0); sched_boost_active = false; } -#ifdef CONFIG_DYNAMIC_STUNE_BOOST - if (stune_boost_active) { - reset_stune_boost("top-app", boost_slot); - stune_boost_active = false; - } -#endif /* CONFIG_DYNAMIC_STUNE_BOOST */ - /* Set the input_boost_min for all CPUs in the system */ pr_debug("Setting input boost min for all CPUs\n"); for_each_possible_cpu(i) { @@ -248,18 +269,41 @@ static void do_input_boost(struct work_struct *work) sched_boost_active = true; } -#ifdef CONFIG_DYNAMIC_STUNE_BOOST - /* Set dynamic stune boost value */ - ret = do_stune_boost("top-app", dynamic_stune_boost, &boost_slot); - if (!ret) - stune_boost_active = true; + schedule_delayed_work(&input_boost_rem, msecs_to_jiffies(input_boost_ms)); +} - queue_delayed_work(cpu_boost_wq, &dynamic_stune_boost_rem, - msecs_to_jiffies(dynamic_stune_boost_ms)); -#endif /* CONFIG_DYNAMIC_STUNE_BOOST */ +static void do_powerkey_input_boost(struct kthread_work *work) +{ - queue_delayed_work(cpu_boost_wq, &input_boost_rem, - msecs_to_jiffies(input_boost_ms)); + unsigned int i, ret; + struct cpu_sync *i_sync_info; + cancel_delayed_work_sync(&input_boost_rem); + if (sched_boost_active) { + sched_set_boost(0); + sched_boost_active = false; + } + + /* Set the powerkey_input_boost_min for all CPUs in the system */ + pr_debug("Setting powerkey input boost min for all CPUs\n"); + for_each_possible_cpu(i) { + i_sync_info = &per_cpu(sync_info, i); + i_sync_info->input_boost_min = i_sync_info->powerkey_input_boost_freq; + } + + /* Update policies for all online CPUs */ + update_policy_online(); + + /* Enable scheduler boost to migrate tasks to big cluster */ + if (sched_boost_on_powerkey_input) { + ret = sched_set_boost(1); + if (ret) + pr_err("cpu-boost: HMP boost enable failed\n"); + else + sched_boost_active = true; + } + + schedule_delayed_work(&input_boost_rem, + msecs_to_jiffies(powerkey_input_boost_ms)); } static void cpuboost_input_event(struct input_handle *handle, @@ -274,13 +318,40 @@ static void cpuboost_input_event(struct input_handle *handle, if (now - last_input_time < MIN_INPUT_INTERVAL) return; - if (work_pending(&input_boost_work)) + if (queuing_blocked(&cpu_boost_worker, &input_boost_work)) return; - queue_work(cpu_boost_wq, &input_boost_work); + kthread_queue_work(&cpu_boost_worker, &input_boost_work); + + if ((type == EV_KEY && code == KEY_POWER) || + (type == EV_KEY && code == KEY_WAKEUP)) { + kthread_queue_work(&cpu_boost_worker, &powerkey_input_boost_work); + } else { + kthread_queue_work(&cpu_boost_worker, &input_boost_work); + } last_input_time = ktime_to_us(ktime_get()); } +void touch_irq_boost(void) +{ + u64 now; + + if (!input_boost_enabled) + return; + + now = ktime_to_us(ktime_get()); + if (now - last_input_time < MIN_INPUT_INTERVAL) + return; + + if (queuing_blocked(&cpu_boost_worker, &input_boost_work)) + return; + + kthread_queue_work(&cpu_boost_worker, &input_boost_work); + + last_input_time = ktime_to_us(ktime_get()); +} +EXPORT_SYMBOL(touch_irq_boost); + static int cpuboost_input_connect(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id) { @@ -313,11 +384,6 @@ err2: static void cpuboost_input_disconnect(struct input_handle *handle) { -#ifdef CONFIG_DYNAMIC_STUNE_BOOST - /* Reset dynamic stune boost value to the default value */ - reset_stune_boost("top-app", boost_slot); -#endif /* CONFIG_DYNAMIC_STUNE_BOOST */ - input_close_device(handle); input_unregister_handle(handle); kfree(handle); @@ -359,18 +425,52 @@ static struct input_handler cpuboost_input_handler = { static int cpu_boost_init(void) { - int cpu, ret; + int cpu, ret, i; struct cpu_sync *s; + struct sched_param param = { .sched_priority = 2 }; + cpumask_t sys_bg_mask; - cpu_boost_wq = alloc_workqueue("cpuboost_wq", WQ_HIGHPRI, 0); - if (!cpu_boost_wq) + /* Hardcode the cpumask to bind the kthread to it */ + cpumask_clear(&sys_bg_mask); + for (i = 0; i <= 3; i++) { + cpumask_set_cpu(i, &sys_bg_mask); + } + + kthread_init_worker(&cpu_boost_worker); + cpu_boost_worker_thread = kthread_create(kthread_worker_fn, + &cpu_boost_worker, "cpu_boost_worker_thread"); + if (IS_ERR(cpu_boost_worker_thread)) { + pr_err("cpu-boost: Failed to init kworker!\n"); return -EFAULT; + } - INIT_WORK(&input_boost_work, do_input_boost); + ret = sched_setscheduler(cpu_boost_worker_thread, SCHED_FIFO, ¶m); + if (ret) + pr_err("cpu-boost: Failed to set SCHED_FIFO!\n"); + + kthread_init_worker(&powerkey_cpu_boost_worker); + powerkey_cpu_boost_worker_thread = kthread_create(kthread_worker_fn, + &powerkey_cpu_boost_worker, "powerkey_cpu_boost_worker_thread"); + if (IS_ERR(powerkey_cpu_boost_worker_thread)) { + pr_err("powerkey_cpu-boost: Failed to init kworker!\n"); + return -EFAULT; + } + + ret = sched_setscheduler(powerkey_cpu_boost_worker_thread, SCHED_FIFO, ¶m); + if (ret) + pr_err("powerkey_cpu-boost: Failed to set SCHED_FIFO!\n"); + + /* Now bind it to the cpumask */ + kthread_bind_mask(cpu_boost_worker_thread, &sys_bg_mask); + kthread_bind_mask(powerkey_cpu_boost_worker_thread, &sys_bg_mask); + + /* Wake it up! */ + wake_up_process(cpu_boost_worker_thread); + wake_up_process(powerkey_cpu_boost_worker_thread); + + kthread_init_work(&input_boost_work, do_input_boost); + kthread_init_work(&powerkey_input_boost_work, do_powerkey_input_boost); INIT_DELAYED_WORK(&input_boost_rem, do_input_boost_rem); -#ifdef CONFIG_DYNAMIC_STUNE_BOOST - INIT_DELAYED_WORK(&dynamic_stune_boost_rem, do_dynamic_stune_boost_rem); -#endif /* CONFIG_DYNAMIC_STUNE_BOOST */ for_each_possible_cpu(cpu) { s = &per_cpu(sync_info, cpu); diff --git a/drivers/cpufreq/cpu_input_boost.c b/drivers/cpufreq/cpu_input_boost.c index bf158fb06951..65c6d7f47fe7 100644 --- a/drivers/cpufreq/cpu_input_boost.c +++ b/drivers/cpufreq/cpu_input_boost.c @@ -7,11 +7,11 @@ #include #include -#include #include #include -#include +#include #include +#include /* The sched_param struct is located elsewhere in newer kernels */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) @@ -20,12 +20,10 @@ enum { SCREEN_OFF, - INPUT_BOOST, MAX_BOOST }; struct boost_drv { - struct delayed_work input_unboost; struct delayed_work max_unboost; struct notifier_block cpu_notif; struct notifier_block msm_drm_notif; @@ -34,79 +32,55 @@ struct boost_drv { unsigned long state; }; -static void input_unboost_worker(struct work_struct *work); static void max_unboost_worker(struct work_struct *work); static struct boost_drv boost_drv_g __read_mostly = { - .input_unboost = __DELAYED_WORK_INITIALIZER(boost_drv_g.input_unboost, - input_unboost_worker, 0), .max_unboost = __DELAYED_WORK_INITIALIZER(boost_drv_g.max_unboost, max_unboost_worker, 0), .boost_waitq = __WAIT_QUEUE_HEAD_INITIALIZER(boost_drv_g.boost_waitq) }; -static unsigned int get_input_boost_freq(struct cpufreq_policy *policy) -{ - unsigned int freq; - - if (cpumask_test_cpu(policy->cpu, cpu_lp_mask)) - freq = max(CONFIG_INPUT_BOOST_FREQ_LP, CONFIG_MIN_FREQ_LP); - else if (cpumask_test_cpu(policy->cpu, cpu_perf_mask)) - freq = max(CONFIG_INPUT_BOOST_FREQ_PERF, CONFIG_MIN_FREQ_PERF); - else - freq = policy->min; - - return min(freq, policy->max); -} - static unsigned int get_max_boost_freq(struct cpufreq_policy *policy) { unsigned int freq; if (cpumask_test_cpu(policy->cpu, cpu_lp_mask)) freq = CONFIG_MAX_BOOST_FREQ_LP; - else + else if (cpumask_test_cpu(policy->cpu, cpu_perf_mask)) freq = CONFIG_MAX_BOOST_FREQ_PERF; + else + freq = CONFIG_MAX_BOOST_FREQ_PERFP; return min(freq, policy->max); } +static unsigned int get_min_freq(struct cpufreq_policy *policy) +{ + unsigned int freq; + + if (cpumask_test_cpu(policy->cpu, cpu_lp_mask)) + freq = CONFIG_CPU_FREQ_DEFAULT_LITTLE_MIN; + else if (cpumask_test_cpu(policy->cpu, cpu_perf_mask)) + freq = CONFIG_CPU_FREQ_DEFAULT_BIG_MIN; + else + freq = CONFIG_CPU_FREQ_DEFAULT_PRIME_MIN; + + return max(freq, policy->cpuinfo.min_freq); +} + static void update_online_cpu_policy(void) { unsigned int cpu; + /* Only one CPU from each cluster needs to be updated */ get_online_cpus(); - for_each_possible_cpu(cpu) { - if (cpu_online(cpu)) { - if (cpumask_intersects(cpumask_of(cpu), cpu_lp_mask)) - cpufreq_update_policy(cpu); - if (cpumask_intersects(cpumask_of(cpu), cpu_perf_mask)) - cpufreq_update_policy(cpu); - if (cpumask_intersects(cpumask_of(cpu), cpu_perfp_mask)) - cpufreq_update_policy(cpu); - } - } + cpu = cpumask_first_and(cpu_lp_mask, cpu_online_mask); + cpufreq_update_policy(cpu); + cpu = cpumask_first_and(cpu_perf_mask, cpu_online_mask); + cpufreq_update_policy(cpu); put_online_cpus(); } -static void __cpu_input_boost_kick(struct boost_drv *b) -{ - if (test_bit(SCREEN_OFF, &b->state) || (CONFIG_INPUT_BOOST_DURATION_MS == 0)) - return; - - set_bit(INPUT_BOOST, &b->state); - if (!mod_delayed_work(system_unbound_wq, &b->input_unboost, - msecs_to_jiffies(CONFIG_INPUT_BOOST_DURATION_MS))) - wake_up(&b->boost_waitq); -} - -void cpu_input_boost_kick(void) -{ - struct boost_drv *b = &boost_drv_g; - - __cpu_input_boost_kick(b); -} - static void __cpu_input_boost_kick_max(struct boost_drv *b, unsigned int duration_ms) { @@ -139,15 +113,6 @@ void cpu_input_boost_kick_max(unsigned int duration_ms) __cpu_input_boost_kick_max(b, duration_ms); } -static void input_unboost_worker(struct work_struct *work) -{ - struct boost_drv *b = container_of(to_delayed_work(work), - typeof(*b), input_unboost); - - clear_bit(INPUT_BOOST, &b->state); - wake_up(&b->boost_waitq); -} - static void max_unboost_worker(struct work_struct *work) { struct boost_drv *b = container_of(to_delayed_work(work), @@ -195,10 +160,8 @@ static int cpu_notifier_cb(struct notifier_block *nb, unsigned long action, return NOTIFY_OK; /* Unboost when the screen is off */ - if (test_bit(SCREEN_OFF, &b->state)) { - policy->min = policy->cpuinfo.min_freq; - return NOTIFY_OK; - } + if (test_bit(SCREEN_OFF, &b->state)) + goto min; /* Boost CPU to max frequency for max boost */ if (test_bit(MAX_BOOST, &b->state)) { @@ -206,19 +169,9 @@ static int cpu_notifier_cb(struct notifier_block *nb, unsigned long action, return NOTIFY_OK; } - /* - * Boost to policy->max if the boost frequency is higher. When - * unboosting, set policy->min to the absolute min freq for the CPU. - */ - if (test_bit(INPUT_BOOST, &b->state)) - policy->min = get_input_boost_freq(policy); - else if (cpumask_test_cpu(policy->cpu, cpu_lp_mask)) - policy->min = CONFIG_MIN_FREQ_LP; - else if (cpumask_test_cpu(policy->cpu, cpu_perf_mask)) - policy->min = CONFIG_MIN_FREQ_PERF; - else - policy->min = policy->cpuinfo.min_freq; - +min: + /* Set policy->min to the absolute min freq for the CPU */ + policy->min = get_min_freq(policy); return NOTIFY_OK; } @@ -245,88 +198,6 @@ static int msm_drm_notifier_cb(struct notifier_block *nb, unsigned long action, return NOTIFY_OK; } -static void cpu_input_boost_input_event(struct input_handle *handle, - unsigned int type, unsigned int code, - int value) -{ - struct boost_drv *b = handle->handler->private; - - __cpu_input_boost_kick(b); -} - -static int cpu_input_boost_input_connect(struct input_handler *handler, - struct input_dev *dev, - const struct input_device_id *id) -{ - struct input_handle *handle; - int ret; - - handle = kzalloc(sizeof(*handle), GFP_KERNEL); - if (!handle) - return -ENOMEM; - - handle->dev = dev; - handle->handler = handler; - handle->name = "cpu_input_boost_handle"; - - ret = input_register_handle(handle); - if (ret) - goto free_handle; - - ret = input_open_device(handle); - if (ret) - goto unregister_handle; - - return 0; - -unregister_handle: - input_unregister_handle(handle); -free_handle: - kfree(handle); - return ret; -} - -static void cpu_input_boost_input_disconnect(struct input_handle *handle) -{ - input_close_device(handle); - input_unregister_handle(handle); - kfree(handle); -} - -static const struct input_device_id cpu_input_boost_ids[] = { - /* Multi-touch touchscreen */ - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | - INPUT_DEVICE_ID_MATCH_ABSBIT, - .evbit = { BIT_MASK(EV_ABS) }, - .absbit = { [BIT_WORD(ABS_MT_POSITION_X)] = - BIT_MASK(ABS_MT_POSITION_X) | - BIT_MASK(ABS_MT_POSITION_Y) } - }, - /* Touchpad */ - { - .flags = INPUT_DEVICE_ID_MATCH_KEYBIT | - INPUT_DEVICE_ID_MATCH_ABSBIT, - .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, - .absbit = { [BIT_WORD(ABS_X)] = - BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) } - }, - /* Keypad */ - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT, - .evbit = { BIT_MASK(EV_KEY) } - }, - { } -}; - -static struct input_handler cpu_input_boost_input_handler = { - .event = cpu_input_boost_input_event, - .connect = cpu_input_boost_input_connect, - .disconnect = cpu_input_boost_input_disconnect, - .name = "cpu_input_boost_handler", - .id_table = cpu_input_boost_ids -}; - static int __init cpu_input_boost_init(void) { struct boost_drv *b = &boost_drv_g; @@ -340,22 +211,15 @@ static int __init cpu_input_boost_init(void) return ret; } - cpu_input_boost_input_handler.private = b; - ret = input_register_handler(&cpu_input_boost_input_handler); - if (ret) { - pr_err("Failed to register input handler, err: %d\n", ret); - goto unregister_cpu_notif; - } - b->msm_drm_notif.notifier_call = msm_drm_notifier_cb; b->msm_drm_notif.priority = INT_MAX; ret = msm_drm_register_client(&b->msm_drm_notif); if (ret) { pr_err("Failed to register msm_drm notifier, err: %d\n", ret); - goto unregister_handler; + goto unregister_cpu_notif; } - thread = kthread_run_perf_critical(cpu_boost_thread, b, "cpu_boostd"); + thread = kthread_run(cpu_boost_thread, b, "cpu_boostd"); if (IS_ERR(thread)) { ret = PTR_ERR(thread); pr_err("Failed to start CPU boost thread, err: %d\n", ret); @@ -366,8 +230,6 @@ static int __init cpu_input_boost_init(void) unregister_fb_notif: msm_drm_unregister_client(&b->msm_drm_notif); -unregister_handler: - input_unregister_handler(&cpu_input_boost_input_handler); unregister_cpu_notif: cpufreq_unregister_notifier(&b->cpu_notif, CPUFREQ_POLICY_NOTIFIER); return ret; diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index a9c484519369..db33268b47fa 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -727,6 +727,9 @@ static ssize_t store_##file_name \ int ret, temp; \ struct cpufreq_policy new_policy; \ \ + if (&policy->object == &policy->min) \ + return count; \ + \ memcpy(&new_policy, policy, sizeof(*policy)); \ new_policy.min = policy->user_policy.min; \ new_policy.max = policy->user_policy.max; \ diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c index d5f95a4edc1b..735900c3a1e5 100644 --- a/drivers/cpufreq/cpufreq_times.c +++ b/drivers/cpufreq/cpufreq_times.c @@ -489,8 +489,7 @@ void cpufreq_times_create_policy(struct cpufreq_policy *policy) cpufreq_for_each_valid_entry(pos, table) count++; - tmp = kzalloc(sizeof(*freqs) + sizeof(freqs->freq_table[0]) * count, - GFP_KERNEL); + tmp = kzalloc(struct_size(freqs, freq_table, count), GFP_KERNEL); if (!tmp) return; diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index 7f205ec61244..060b5c03ea9c 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -61,6 +61,19 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, if (max_freq > cpuinfo_max_freq_cached) cpuinfo_max_freq_cached = max_freq; +#if CONFIG_CPU_FREQ_DEFAULT_LITTLE_MIN + if (cpumask_test_cpu(policy->cpu, cpu_lp_mask)) + policy->min = CONFIG_CPU_FREQ_DEFAULT_LITTLE_MIN; +#endif +#if CONFIG_CPU_FREQ_DEFAULT_BIG_MIN + if (cpumask_test_cpu(policy->cpu, cpu_perf_mask)) + policy->min = CONFIG_CPU_FREQ_DEFAULT_BIG_MIN; +#endif +#if CONFIG_CPU_FREQ_DEFAULT_PRIME_MIN + if (cpumask_test_cpu(policy->cpu, cpu_perfp_mask)) + policy->min = CONFIG_CPU_FREQ_DEFAULT_PRIME_MIN; +#endif + if (policy->min == ~0) return -EINVAL; else diff --git a/drivers/cpufreq/ia64-acpi-cpufreq.c b/drivers/cpufreq/ia64-acpi-cpufreq.c index a757c0a1e7b5..247f30f9ddb1 100644 --- a/drivers/cpufreq/ia64-acpi-cpufreq.c +++ b/drivers/cpufreq/ia64-acpi-cpufreq.c @@ -241,8 +241,8 @@ acpi_cpufreq_cpu_init ( } /* alloc freq_table */ - freq_table = kzalloc(sizeof(*freq_table) * - (data->acpi_data.state_count + 1), + freq_table = kcalloc(data->acpi_data.state_count + 1, + sizeof(*freq_table), GFP_KERNEL); if (!freq_table) { result = -ENOMEM; diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index 63d28323a29c..88ecfda4eecf 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c @@ -288,7 +288,8 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) } /* Make imx6_soc_volt array's size same as arm opp number */ - imx6_soc_volt = devm_kzalloc(cpu_dev, sizeof(*imx6_soc_volt) * num, GFP_KERNEL); + imx6_soc_volt = devm_kcalloc(cpu_dev, num, sizeof(*imx6_soc_volt), + GFP_KERNEL); if (imx6_soc_volt == NULL) { ret = -ENOMEM; goto free_freq_table; diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 1aa0b05c8cbd..dd9c850c01ad 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -2338,7 +2338,7 @@ hwp_cpu_matched: pr_info("Intel P-state driver initializing\n"); - all_cpu_data = vzalloc(sizeof(void *) * num_possible_cpus()); + all_cpu_data = vzalloc(array_size(sizeof(void *), num_possible_cpus())); if (!all_cpu_data) return -ENOMEM; diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index 859a62ea6120..7a2fdd9f688a 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c @@ -474,8 +474,8 @@ static int longhaul_get_ranges(void) return -EINVAL; } - longhaul_table = kzalloc((numscales + 1) * sizeof(*longhaul_table), - GFP_KERNEL); + longhaul_table = kcalloc(numscales + 1, sizeof(*longhaul_table), + GFP_KERNEL); if (!longhaul_table) return -ENOMEM; diff --git a/drivers/cpufreq/pxa3xx-cpufreq.c b/drivers/cpufreq/pxa3xx-cpufreq.c index a01275900389..4d49f6e2ff60 100644 --- a/drivers/cpufreq/pxa3xx-cpufreq.c +++ b/drivers/cpufreq/pxa3xx-cpufreq.c @@ -93,7 +93,7 @@ static int setup_freqs_table(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table; int i; - table = kzalloc((num + 1) * sizeof(*table), GFP_KERNEL); + table = kcalloc(num + 1, sizeof(*table), GFP_KERNEL); if (table == NULL) return -ENOMEM; diff --git a/drivers/cpufreq/qcom-cpufreq.c b/drivers/cpufreq/qcom-cpufreq.c index 735db9250a16..07055cd4f9b4 100644 --- a/drivers/cpufreq/qcom-cpufreq.c +++ b/drivers/cpufreq/qcom-cpufreq.c @@ -382,7 +382,7 @@ static struct cpufreq_frequency_table *cpufreq_parse_dt(struct device *dev, if (nf == 0) return ERR_PTR(-EINVAL); - data = devm_kzalloc(dev, nf * sizeof(*data), GFP_KERNEL); + data = devm_kcalloc(dev, nf, sizeof(*data), GFP_KERNEL); if (!data) return ERR_PTR(-ENOMEM); @@ -390,7 +390,7 @@ static struct cpufreq_frequency_table *cpufreq_parse_dt(struct device *dev, if (ret) return ERR_PTR(ret); - ftbl = devm_kzalloc(dev, (nf + 1) * sizeof(*ftbl), GFP_KERNEL); + ftbl = devm_kcalloc(dev, nf + 1, sizeof(*ftbl), GFP_KERNEL); if (!ftbl) return ERR_PTR(-ENOMEM); diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c index 6bebc1f9f55a..4181a6f62f02 100644 --- a/drivers/cpufreq/s3c24xx-cpufreq.c +++ b/drivers/cpufreq/s3c24xx-cpufreq.c @@ -567,7 +567,7 @@ static int s3c_cpufreq_build_freq(void) size = cpu_cur.info->calc_freqtable(&cpu_cur, NULL, 0); size++; - ftab = kzalloc(sizeof(*ftab) * size, GFP_KERNEL); + ftab = kcalloc(size, sizeof(*ftab), GFP_KERNEL); if (!ftab) { pr_err("%s: no memory for tables\n", __func__); return -ENOMEM; diff --git a/drivers/cpufreq/sfi-cpufreq.c b/drivers/cpufreq/sfi-cpufreq.c index 3779742f86e3..346403ecb7d4 100644 --- a/drivers/cpufreq/sfi-cpufreq.c +++ b/drivers/cpufreq/sfi-cpufreq.c @@ -94,8 +94,8 @@ static int __init sfi_cpufreq_init(void) if (ret) return ret; - freq_table = kzalloc(sizeof(*freq_table) * - (num_freq_table_entries + 1), GFP_KERNEL); + freq_table = kcalloc(num_freq_table_entries + 1, sizeof(*freq_table), + GFP_KERNEL); if (!freq_table) { ret = -ENOMEM; goto err_free_array; diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c index 4894924a3ca2..1c8e8c3a5f1b 100644 --- a/drivers/cpufreq/spear-cpufreq.c +++ b/drivers/cpufreq/spear-cpufreq.c @@ -195,7 +195,7 @@ static int spear_cpufreq_probe(struct platform_device *pdev) cnt = prop->length / sizeof(u32); val = prop->value; - freq_tbl = kzalloc(sizeof(*freq_tbl) * (cnt + 1), GFP_KERNEL); + freq_tbl = kcalloc(cnt + 1, sizeof(*freq_tbl), GFP_KERNEL); if (!freq_tbl) { ret = -ENOMEM; goto out_put_node; diff --git a/drivers/cpuidle/lpm-levels-of.c b/drivers/cpuidle/lpm-levels-of.c index f2f0bd4d0023..c8bfecd8f902 100644 --- a/drivers/cpuidle/lpm-levels-of.c +++ b/drivers/cpuidle/lpm-levels-of.c @@ -157,8 +157,8 @@ static int create_lvl_avail_nodes(const char *name, goto failed; } - attr = devm_kzalloc(&lpm_pdev->dev, - sizeof(*attr) * (LPM_TYPE_NR + 1), GFP_KERNEL); + attr = devm_kcalloc(&lpm_pdev->dev, + LPM_TYPE_NR + 1, sizeof(*attr), GFP_KERNEL); if (!attr) { ret = -ENOMEM; goto failed; @@ -218,8 +218,10 @@ static int create_cpu_lvl_nodes(struct lpm_cluster *p, struct kobject *parent) int ret = 0; struct list_head *pos; - cpu_kobj = devm_kzalloc(&lpm_pdev->dev, sizeof(*cpu_kobj) * - cpumask_weight(&p->child_cpus), GFP_KERNEL); + cpu_kobj = devm_kcalloc(&lpm_pdev->dev, + cpumask_weight(&p->child_cpus), + sizeof(*cpu_kobj), + GFP_KERNEL); if (!cpu_kobj) return -ENOMEM; @@ -236,8 +238,8 @@ static int create_cpu_lvl_nodes(struct lpm_cluster *p, struct kobject *parent) goto release_kobj; } - level_list = devm_kzalloc(&lpm_pdev->dev, - lpm_cpu->nlevels * sizeof(*level_list), + level_list = devm_kcalloc(&lpm_pdev->dev, + lpm_cpu->nlevels, sizeof(*level_list), GFP_KERNEL); if (!level_list) { ret = -ENOMEM; diff --git a/drivers/cpuidle/lpm-levels.c b/drivers/cpuidle/lpm-levels.c index 7c9e55c16f4d..0a9e6042651e 100644 --- a/drivers/cpuidle/lpm-levels.c +++ b/drivers/cpuidle/lpm-levels.c @@ -1164,7 +1164,8 @@ static void cluster_prepare(struct lpm_cluster *cluster, if (cluster_configure(cluster, i, from_idle, predicted)) goto failed; - cluster->stats->sleep_time = start_time; + if (!IS_ERR_OR_NULL(cluster->stats)) + cluster->stats->sleep_time = start_time; cluster_prepare(cluster->parent, &cluster->num_children_in_sync, i, from_idle, start_time); @@ -1172,7 +1173,8 @@ static void cluster_prepare(struct lpm_cluster *cluster, return; failed: spin_unlock(&cluster->sync_lock); - cluster->stats->sleep_time = 0; + if (!IS_ERR_OR_NULL(cluster->stats)) + cluster->stats->sleep_time = 0; } static void cluster_unprepare(struct lpm_cluster *cluster, @@ -1211,7 +1213,7 @@ static void cluster_unprepare(struct lpm_cluster *cluster, if (!first_cpu || cluster->last_level == cluster->default_level) goto unlock_return; - if (cluster->stats->sleep_time) + if (!IS_ERR_OR_NULL(cluster->stats) && cluster->stats->sleep_time) cluster->stats->sleep_time = end_time - cluster->stats->sleep_time; lpm_stats_cluster_exit(cluster->stats, cluster->last_level, success); @@ -1648,6 +1650,9 @@ static void register_cluster_lpm_stats(struct lpm_cluster *cl, cl->stats = lpm_stats_config_level(cl->cluster_name, level_name, cl->nlevels, parent ? parent->stats : NULL, NULL); + if (IS_ERR_OR_NULL(cl->stats)) + pr_info("Cluster (%s) stats not registered\n", + cl->cluster_name); kfree(level_name); diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c index d1d041de7f8a..b68a4f232f6d 100644 --- a/drivers/crypto/amcc/crypto4xx_core.c +++ b/drivers/crypto/amcc/crypto4xx_core.c @@ -198,8 +198,8 @@ static u32 crypto4xx_build_pdr(struct crypto4xx_device *dev) if (!dev->pdr) return -ENOMEM; - dev->pdr_uinfo = kzalloc(sizeof(struct pd_uinfo) * PPC4XX_NUM_PD, - GFP_KERNEL); + dev->pdr_uinfo = kcalloc(PPC4XX_NUM_PD, sizeof(struct pd_uinfo), + GFP_KERNEL); if (!dev->pdr_uinfo) { dma_free_coherent(dev->core_dev->device, sizeof(struct ce_pd) * PPC4XX_NUM_PD, diff --git a/drivers/crypto/cavium/nitrox/nitrox_isr.c b/drivers/crypto/cavium/nitrox/nitrox_isr.c index dbead5f45df3..ee0d70ba25d5 100644 --- a/drivers/crypto/cavium/nitrox/nitrox_isr.c +++ b/drivers/crypto/cavium/nitrox/nitrox_isr.c @@ -254,7 +254,7 @@ static int nitrox_enable_msix(struct nitrox_device *ndev) * Entry 192: NPS_CORE_INT_ACTIVE */ nr_entries = (ndev->nr_queues * NR_RING_VECTORS) + 1; - entries = kzalloc_node(nr_entries * sizeof(struct msix_entry), + entries = kcalloc_node(nr_entries, sizeof(struct msix_entry), GFP_KERNEL, ndev->node); if (!entries) return -ENOMEM; diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c index 330853a2702f..43b74cf0787e 100644 --- a/drivers/crypto/ccp/ccp-ops.c +++ b/drivers/crypto/ccp/ccp-ops.c @@ -1783,8 +1783,9 @@ ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) LSB_ITEM_SIZE); break; default: + kfree(hmac_buf); ret = -EINVAL; - goto e_ctx; + goto e_data; } memset(&hmac_cmd, 0, sizeof(hmac_cmd)); diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c index 69f29776591a..221ad7468aaf 100644 --- a/drivers/crypto/inside-secure/safexcel_hash.c +++ b/drivers/crypto/inside-secure/safexcel_hash.c @@ -901,7 +901,7 @@ static int safexcel_hmac_setkey(const char *alg, const u8 *key, crypto_ahash_clear_flags(tfm, ~0); blocksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); - ipad = kzalloc(2 * blocksize, GFP_KERNEL); + ipad = kcalloc(2, blocksize, GFP_KERNEL); if (!ipad) { ret = -ENOMEM; goto free_request; diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c index 6e7a5c77a00a..b92424e3178b 100644 --- a/drivers/crypto/marvell/cesa.c +++ b/drivers/crypto/marvell/cesa.c @@ -476,7 +476,7 @@ static int mv_cesa_probe(struct platform_device *pdev) sram_size = CESA_SA_MIN_SRAM_SIZE; cesa->sram_size = sram_size; - cesa->engines = devm_kzalloc(dev, caps->nengines * sizeof(*engines), + cesa->engines = devm_kcalloc(dev, caps->nengines, sizeof(*engines), GFP_KERNEL); if (!cesa->engines) return -ENOMEM; diff --git a/drivers/crypto/marvell/hash.c b/drivers/crypto/marvell/hash.c index e61b08566093..e34d80b6b7e5 100644 --- a/drivers/crypto/marvell/hash.c +++ b/drivers/crypto/marvell/hash.c @@ -1198,7 +1198,7 @@ static int mv_cesa_ahmac_setkey(const char *hash_alg_name, blocksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); - ipad = kzalloc(2 * blocksize, GFP_KERNEL); + ipad = kcalloc(2, blocksize, GFP_KERNEL); if (!ipad) { ret = -ENOMEM; goto free_req; diff --git a/drivers/crypto/msm/ice.c b/drivers/crypto/msm/ice.c index 90238a5299bc..04698dce55bf 100644 --- a/drivers/crypto/msm/ice.c +++ b/drivers/crypto/msm/ice.c @@ -596,7 +596,7 @@ static int qcom_ice_parse_clock_info(struct platform_device *pdev, if (len != cnt) goto out; - clkfreq = devm_kzalloc(dev, len * sizeof(*clkfreq), GFP_KERNEL); + clkfreq = devm_kcalloc(dev, len, sizeof(*clkfreq), GFP_KERNEL); if (!clkfreq) { ret = -ENOMEM; goto out; diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c index 699ee5a9a8f9..545ceae44ea0 100644 --- a/drivers/crypto/n2_core.c +++ b/drivers/crypto/n2_core.c @@ -1907,12 +1907,12 @@ static int grab_global_resources(void) goto out_hvapi_release; err = -ENOMEM; - cpu_to_cwq = kzalloc(sizeof(struct spu_queue *) * NR_CPUS, + cpu_to_cwq = kcalloc(NR_CPUS, sizeof(struct spu_queue *), GFP_KERNEL); if (!cpu_to_cwq) goto out_queue_cache_destroy; - cpu_to_mau = kzalloc(sizeof(struct spu_queue *) * NR_CPUS, + cpu_to_mau = kcalloc(NR_CPUS, sizeof(struct spu_queue *), GFP_KERNEL); if (!cpu_to_mau) goto out_free_cwq_table; diff --git a/drivers/crypto/qat/qat_common/adf_isr.c b/drivers/crypto/qat/qat_common/adf_isr.c index 06d49017a52b..cd1cdf5305bc 100644 --- a/drivers/crypto/qat/qat_common/adf_isr.c +++ b/drivers/crypto/qat/qat_common/adf_isr.c @@ -238,7 +238,7 @@ static int adf_isr_alloc_msix_entry_table(struct adf_accel_dev *accel_dev) if (!accel_dev->pf.vf_info) msix_num_entries += hw_data->num_banks; - entries = kzalloc_node(msix_num_entries * sizeof(*entries), + entries = kcalloc_node(msix_num_entries, sizeof(*entries), GFP_KERNEL, dev_to_node(&GET_DEV(accel_dev))); if (!entries) return -ENOMEM; diff --git a/drivers/crypto/qat/qat_common/qat_uclo.c b/drivers/crypto/qat/qat_common/qat_uclo.c index e2454d90d949..506e9a7d9acb 100644 --- a/drivers/crypto/qat/qat_common/qat_uclo.c +++ b/drivers/crypto/qat/qat_common/qat_uclo.c @@ -1159,8 +1159,9 @@ static int qat_uclo_map_suof(struct icp_qat_fw_loader_handle *handle, suof_handle->img_table.num_simgs = suof_ptr->num_chunks - 1; if (suof_handle->img_table.num_simgs != 0) { - suof_img_hdr = kzalloc(suof_handle->img_table.num_simgs * - sizeof(img_header), GFP_KERNEL); + suof_img_hdr = kcalloc(suof_handle->img_table.num_simgs, + sizeof(img_header), + GFP_KERNEL); if (!suof_img_hdr) return -ENOMEM; suof_handle->img_table.simg_hdr = suof_img_hdr; diff --git a/drivers/crypto/stm32/stm32-hash.c b/drivers/crypto/stm32/stm32-hash.c index 4909f820e953..230922ed6987 100644 --- a/drivers/crypto/stm32/stm32-hash.c +++ b/drivers/crypto/stm32/stm32-hash.c @@ -968,8 +968,9 @@ static int stm32_hash_export(struct ahash_request *req, void *out) while (!(stm32_hash_read(hdev, HASH_SR) & HASH_SR_DATA_INPUT_READY)) cpu_relax(); - rctx->hw_context = kmalloc(sizeof(u32) * (3 + HASH_CSR_REGISTER_NUMBER), - GFP_KERNEL); + rctx->hw_context = kmalloc_array(3 + HASH_CSR_REGISTER_NUMBER, + sizeof(u32), + GFP_KERNEL); preg = rctx->hw_context; diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 6c8a03a1132f..a54f16a43b35 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -3326,8 +3326,9 @@ static int talitos_probe(struct platform_device *ofdev) } } - priv->chan = kzalloc(sizeof(struct talitos_channel) * - priv->num_channels, GFP_KERNEL); + priv->chan = kcalloc(priv->num_channels, + sizeof(struct talitos_channel), + GFP_KERNEL); if (!priv->chan) { dev_err(dev, "failed to allocate channel management space\n"); err = -ENOMEM; @@ -3344,8 +3345,9 @@ static int talitos_probe(struct platform_device *ofdev) spin_lock_init(&priv->chan[i].head_lock); spin_lock_init(&priv->chan[i].tail_lock); - priv->chan[i].fifo = kzalloc(sizeof(struct talitos_request) * - priv->fifo_len, GFP_KERNEL); + priv->chan[i].fifo = kcalloc(priv->fifo_len, + sizeof(struct talitos_request), + GFP_KERNEL); if (!priv->chan[i].fifo) { dev_err(dev, "failed to allocate request fifo %d\n", i); err = -ENOMEM; diff --git a/drivers/crypto/virtio/virtio_crypto_algs.c b/drivers/crypto/virtio/virtio_crypto_algs.c index e6b889ce395e..7205c05324fe 100644 --- a/drivers/crypto/virtio/virtio_crypto_algs.c +++ b/drivers/crypto/virtio/virtio_crypto_algs.c @@ -373,7 +373,7 @@ __virtio_crypto_ablkcipher_do_req(struct virtio_crypto_sym_request *vc_sym_req, /* Why 3? outhdr + iv + inhdr */ sg_total = src_nents + dst_nents + 3; - sgs = kzalloc_node(sg_total * sizeof(*sgs), GFP_ATOMIC, + sgs = kcalloc_node(sg_total, sizeof(*sgs), GFP_ATOMIC, dev_to_node(&vcrypto->vdev->dev)); if (!sgs) return -ENOMEM; diff --git a/drivers/devfreq/arm-memlat-mon.c b/drivers/devfreq/arm-memlat-mon.c index 740dc6f8d04f..d4e4a85c9de5 100644 --- a/drivers/devfreq/arm-memlat-mon.c +++ b/drivers/devfreq/arm-memlat-mon.c @@ -308,13 +308,17 @@ static int arm_memlat_mon_driver_probe(struct platform_device *pdev) } hw->num_cores = cpumask_weight(&cpu_grp->cpus); - hw->core_stats = devm_kzalloc(dev, hw->num_cores * - sizeof(*(hw->core_stats)), GFP_KERNEL); + hw->core_stats = devm_kcalloc(dev, + hw->num_cores, + sizeof(*(hw->core_stats)), + GFP_KERNEL); if (!hw->core_stats) return -ENOMEM; - cpu_grp->cpustats = devm_kzalloc(dev, hw->num_cores * - sizeof(*(cpu_grp->cpustats)), GFP_KERNEL); + cpu_grp->cpustats = devm_kcalloc(dev, + hw->num_cores, + sizeof(*(cpu_grp->cpustats)), + GFP_KERNEL); if (!cpu_grp->cpustats) return -ENOMEM; diff --git a/drivers/devfreq/bimc-bwmon.c b/drivers/devfreq/bimc-bwmon.c index 8b924abf781f..db13cc3f7f82 100644 --- a/drivers/devfreq/bimc-bwmon.c +++ b/drivers/devfreq/bimc-bwmon.c @@ -1155,7 +1155,7 @@ static int bimc_bwmon_driver_probe(struct platform_device *pdev) return -EINVAL; } - m->clks = devm_kzalloc(dev, sizeof(struct clk *) * m->nr_clks, + m->clks = devm_kcalloc(dev, m->nr_clks, sizeof(struct clk *), GFP_KERNEL); if (!m->clks) return -ENOMEM; diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index cf000d78e8e9..dc0643a6a55e 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -595,13 +595,11 @@ struct devfreq *devfreq_add_device(struct device *dev, } devfreq->trans_table = devm_kzalloc(&devfreq->dev, - sizeof(unsigned int) * - devfreq->profile->max_state * - devfreq->profile->max_state, + array3_size(sizeof(unsigned int), devfreq->profile->max_state, devfreq->profile->max_state), GFP_KERNEL); - devfreq->time_in_state = devm_kzalloc(&devfreq->dev, - sizeof(unsigned long) * + devfreq->time_in_state = devm_kcalloc(&devfreq->dev, devfreq->profile->max_state, + sizeof(unsigned long), GFP_KERNEL); devfreq->last_stat_updated = jiffies; diff --git a/drivers/devfreq/devfreq_simple_dev.c b/drivers/devfreq/devfreq_simple_dev.c index 8566e98af079..9f49184f4356 100644 --- a/drivers/devfreq/devfreq_simple_dev.c +++ b/drivers/devfreq/devfreq_simple_dev.c @@ -105,11 +105,11 @@ static int parse_freq_table(struct device *dev, struct dev_data *d) d->freq_in_khz = true; len /= sizeof(*data); - data = devm_kzalloc(dev, len * sizeof(*data), GFP_KERNEL); + data = devm_kcalloc(dev, len, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; - p->freq_table = devm_kzalloc(dev, len * sizeof(*p->freq_table), + p->freq_table = devm_kcalloc(dev, len, sizeof(*p->freq_table), GFP_KERNEL); if (!p->freq_table) return -ENOMEM; diff --git a/drivers/devfreq/event/exynos-ppmu.c b/drivers/devfreq/event/exynos-ppmu.c index d96e3dc71cf8..3cd6a184fe7c 100644 --- a/drivers/devfreq/event/exynos-ppmu.c +++ b/drivers/devfreq/event/exynos-ppmu.c @@ -518,7 +518,7 @@ static int of_get_devfreq_events(struct device_node *np, event_ops = exynos_bus_get_ops(np); count = of_get_child_count(events_np); - desc = devm_kzalloc(dev, sizeof(*desc) * count, GFP_KERNEL); + desc = devm_kcalloc(dev, count, sizeof(*desc), GFP_KERNEL); if (!desc) return -ENOMEM; info->num_events = count; diff --git a/drivers/devfreq/governor_memlat.c b/drivers/devfreq/governor_memlat.c index 3b6e6fee0c79..78c5c7718b62 100644 --- a/drivers/devfreq/governor_memlat.c +++ b/drivers/devfreq/governor_memlat.c @@ -447,8 +447,8 @@ static struct core_dev_map *init_core_dev_map(struct device *dev, return NULL; nf = len / NUM_COLS; - tbl = devm_kzalloc(dev, (nf + 1) * sizeof(struct core_dev_map), - GFP_KERNEL); + tbl = devm_kcalloc(dev, nf + 1, sizeof(struct core_dev_map), + GFP_KERNEL); if (!tbl) return NULL; diff --git a/drivers/dma/bcm-sba-raid.c b/drivers/dma/bcm-sba-raid.c index 6c2c44724637..eae1cde3f059 100644 --- a/drivers/dma/bcm-sba-raid.c +++ b/drivers/dma/bcm-sba-raid.c @@ -1513,9 +1513,8 @@ static int sba_prealloc_channel_resources(struct sba_device *sba) for (i = 0; i < sba->max_req; i++) { req = devm_kzalloc(sba->dev, - sizeof(*req) + - sba->max_cmd_per_req * sizeof(req->cmds[0]), - GFP_KERNEL); + struct_size(req, cmds, sba->max_cmd_per_req), + GFP_KERNEL); if (!req) { ret = -ENOMEM; goto fail_free_cmds_pool; diff --git a/drivers/dma/bestcomm/bestcomm.c b/drivers/dma/bestcomm/bestcomm.c index 7a67b8345092..d91cbbe7a48f 100644 --- a/drivers/dma/bestcomm/bestcomm.c +++ b/drivers/dma/bestcomm/bestcomm.c @@ -87,7 +87,8 @@ bcom_task_alloc(int bd_count, int bd_size, int priv_size) /* Init the BDs, if needed */ if (bd_count) { - tsk->cookie = kmalloc(sizeof(void*) * bd_count, GFP_KERNEL); + tsk->cookie = kmalloc_array(bd_count, sizeof(void *), + GFP_KERNEL); if (!tsk->cookie) goto error; diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index 57a49fe713fd..d4e60ac2f7e0 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -1073,8 +1073,7 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg( return NULL; } - edesc = kzalloc(sizeof(*edesc) + sg_len * sizeof(edesc->pset[0]), - GFP_ATOMIC); + edesc = kzalloc(struct_size(edesc, pset, sg_len), GFP_ATOMIC); if (!edesc) return NULL; @@ -1191,8 +1190,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy( nslots = 2; } - edesc = kzalloc(sizeof(*edesc) + nslots * sizeof(edesc->pset[0]), - GFP_ATOMIC); + edesc = kzalloc(struct_size(edesc, pset, nslots), GFP_ATOMIC); if (!edesc) return NULL; @@ -1314,8 +1312,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic( } } - edesc = kzalloc(sizeof(*edesc) + nslots * sizeof(edesc->pset[0]), - GFP_ATOMIC); + edesc = kzalloc(struct_size(edesc, pset, nslots), GFP_ATOMIC); if (!edesc) return NULL; diff --git a/drivers/dma/ioat/init.c b/drivers/dma/ioat/init.c index 9103a0425f75..758e1a450cb3 100644 --- a/drivers/dma/ioat/init.c +++ b/drivers/dma/ioat/init.c @@ -322,10 +322,10 @@ static int ioat_dma_self_test(struct ioatdma_device *ioat_dma) unsigned long tmo; unsigned long flags; - src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL); + src = kzalloc(IOAT_TEST_SIZE, GFP_KERNEL); if (!src) return -ENOMEM; - dest = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL); + dest = kzalloc(IOAT_TEST_SIZE, GFP_KERNEL); if (!dest) { kfree(src); return -ENOMEM; diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index ed76044ce4b9..8fb7268fd53c 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -910,7 +910,7 @@ out: /* Called with ichan->chan_mutex held */ static int idmac_desc_alloc(struct idmac_channel *ichan, int n) { - struct idmac_tx_desc *desc = vmalloc(n * sizeof(struct idmac_tx_desc)); + struct idmac_tx_desc *desc = vmalloc(array_size(n, sizeof(struct idmac_tx_desc))); struct idmac *idmac = to_idmac(ichan->dma_chan.device); if (!desc) diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c index 803045c92f3b..6a5f0cc9c8c0 100644 --- a/drivers/dma/k3dma.c +++ b/drivers/dma/k3dma.c @@ -847,8 +847,8 @@ static int k3_dma_probe(struct platform_device *op) return -ENOMEM; /* init phy channel */ - d->phy = devm_kzalloc(&op->dev, - d->dma_channels * sizeof(struct k3_dma_phy), GFP_KERNEL); + d->phy = devm_kcalloc(&op->dev, + d->dma_channels, sizeof(struct k3_dma_phy), GFP_KERNEL); if (d->phy == NULL) return -ENOMEM; @@ -877,8 +877,8 @@ static int k3_dma_probe(struct platform_device *op) d->slave.copy_align = DMAENGINE_ALIGN_8_BYTES; /* init virtual channel */ - d->chans = devm_kzalloc(&op->dev, - d->dma_requests * sizeof(struct k3_dma_chan), GFP_KERNEL); + d->chans = devm_kcalloc(&op->dev, + d->dma_requests, sizeof(struct k3_dma_chan), GFP_KERNEL); if (d->chans == NULL) return -ENOMEM; diff --git a/drivers/dma/mic_x100_dma.c b/drivers/dma/mic_x100_dma.c index 5ba5714d0b7c..54d9446c3df5 100644 --- a/drivers/dma/mic_x100_dma.c +++ b/drivers/dma/mic_x100_dma.c @@ -385,7 +385,7 @@ static int mic_dma_alloc_desc_ring(struct mic_dma_chan *ch) if (dma_mapping_error(dev, ch->desc_ring_micpa)) goto map_error; - ch->tx_array = vzalloc(MIC_DMA_DESC_RX_SIZE * sizeof(*ch->tx_array)); + ch->tx_array = vzalloc(array_size(MIC_DMA_DESC_RX_SIZE, sizeof(*ch->tx_array))); if (!ch->tx_array) goto tx_error; return 0; diff --git a/drivers/dma/moxart-dma.c b/drivers/dma/moxart-dma.c index e1a5c2242f6f..e04499c1f27f 100644 --- a/drivers/dma/moxart-dma.c +++ b/drivers/dma/moxart-dma.c @@ -309,7 +309,7 @@ static struct dma_async_tx_descriptor *moxart_prep_slave_sg( return NULL; } - d = kzalloc(sizeof(*d) + sg_len * sizeof(d->sg[0]), GFP_ATOMIC); + d = kzalloc(struct_size(d, sg, sg_len), GFP_ATOMIC); if (!d) return NULL; diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 1c57577f49fe..abc8d3e0487b 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -777,11 +777,11 @@ static int mv_chan_memcpy_self_test(struct mv_xor_chan *mv_chan) struct dmaengine_unmap_data *unmap; int err = 0; - src = kmalloc(sizeof(u8) * PAGE_SIZE, GFP_KERNEL); + src = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!src) return -ENOMEM; - dest = kzalloc(sizeof(u8) * PAGE_SIZE, GFP_KERNEL); + dest = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!dest) { kfree(src); return -ENOMEM; diff --git a/drivers/dma/mv_xor_v2.c b/drivers/dma/mv_xor_v2.c index 75eef589d0ec..d349fedf4ab2 100644 --- a/drivers/dma/mv_xor_v2.c +++ b/drivers/dma/mv_xor_v2.c @@ -809,8 +809,9 @@ static int mv_xor_v2_probe(struct platform_device *pdev) } /* alloc memory for the SW descriptors */ - xor_dev->sw_desq = devm_kzalloc(&pdev->dev, sizeof(*sw_desc) * - MV_XOR_V2_DESC_NUM, GFP_KERNEL); + xor_dev->sw_desq = devm_kcalloc(&pdev->dev, + MV_XOR_V2_DESC_NUM, sizeof(*sw_desc), + GFP_KERNEL); if (!xor_dev->sw_desq) { ret = -ENOMEM; goto free_hw_desq; diff --git a/drivers/dma/nbpfaxi.c b/drivers/dma/nbpfaxi.c index d3f918a9ee76..a45889e0fc93 100644 --- a/drivers/dma/nbpfaxi.c +++ b/drivers/dma/nbpfaxi.c @@ -1306,8 +1306,8 @@ static int nbpf_probe(struct platform_device *pdev) cfg = of_id->data; num_channels = cfg->num_channels; - nbpf = devm_kzalloc(dev, sizeof(*nbpf) + num_channels * - sizeof(nbpf->chan[0]), GFP_KERNEL); + nbpf = devm_kzalloc(dev, struct_size(nbpf, chan, num_channels), + GFP_KERNEL); if (!nbpf) return -ENOMEM; diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index 14b560facf77..8297ff7a7e27 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -917,7 +917,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg( } /* Now allocate and setup the descriptor. */ - d = kzalloc(sizeof(*d) + sglen * sizeof(d->sg[0]), GFP_ATOMIC); + d = kzalloc(struct_size(d, sg, sglen), GFP_ATOMIC); if (!d) return NULL; diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index b4fa555a243f..cbcba1f022ce 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -1767,7 +1767,7 @@ static int dmac_alloc_threads(struct pl330_dmac *pl330) int i; /* Allocate 1 Manager and 'chans' Channel threads */ - pl330->channels = kzalloc((1 + chans) * sizeof(*thrd), + pl330->channels = kcalloc(1 + chans, sizeof(*thrd), GFP_KERNEL); if (!pl330->channels) return -ENOMEM; @@ -2885,7 +2885,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) pl330->num_peripherals = num_chan; - pl330->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL); + pl330->peripherals = kcalloc(num_chan, sizeof(*pch), GFP_KERNEL); if (!pl330->peripherals) { ret = -ENOMEM; goto probe_err2; diff --git a/drivers/dma/qcom/gpi.c b/drivers/dma/qcom/gpi.c index b7ed93155534..6455e21a4d38 100644 --- a/drivers/dma/qcom/gpi.c +++ b/drivers/dma/qcom/gpi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -261,6 +261,7 @@ static const char *const gpi_cb_event_str[MSM_GPI_QUP_MAX_EVENT] = { [MSM_GPI_QUP_NOTIFY] = "NOTIFY", [MSM_GPI_QUP_ERROR] = "GLOBAL ERROR", [MSM_GPI_QUP_CH_ERROR] = "CHAN ERROR", + [MSM_GPI_QUP_FW_ERROR] = "UNHANDLED ERROR", [MSM_GPI_QUP_PENDING_EVENT] = "PENDING EVENT", [MSM_GPI_QUP_EOT_DESC_MISMATCH] = "EOT/DESC MISMATCH", [MSM_GPI_QUP_SW_ERROR] = "SW ERROR", @@ -2165,6 +2166,10 @@ int gpi_terminate_all(struct dma_chan *chan) if (ret) { GPII_ERR(gpii, gpii_chan->chid, "Error resetting channel ret:%d\n", ret); + if (!gpii->reg_table_dump) { + gpi_dump_debug_reg(gpii); + gpii->reg_table_dump = true; + } goto terminate_exit; } @@ -2980,8 +2985,8 @@ static int gpi_probe(struct platform_device *pdev) return ret; } - gpi_dev->gpiis = devm_kzalloc(gpi_dev->dev, - sizeof(*gpi_dev->gpiis) * gpi_dev->max_gpii, + gpi_dev->gpiis = devm_kcalloc(gpi_dev->dev, + gpi_dev->max_gpii, sizeof(*gpi_dev->gpiis), GFP_KERNEL); if (!gpi_dev->gpiis) return -ENOMEM; diff --git a/drivers/dma/s3c24xx-dma.c b/drivers/dma/s3c24xx-dma.c index f04c4702d98b..7bd6f6439826 100644 --- a/drivers/dma/s3c24xx-dma.c +++ b/drivers/dma/s3c24xx-dma.c @@ -1216,9 +1216,9 @@ static int s3c24xx_dma_probe(struct platform_device *pdev) if (IS_ERR(s3cdma->base)) return PTR_ERR(s3cdma->base); - s3cdma->phy_chans = devm_kzalloc(&pdev->dev, - sizeof(struct s3c24xx_dma_phy) * - pdata->num_phy_channels, + s3cdma->phy_chans = devm_kcalloc(&pdev->dev, + pdata->num_phy_channels, + sizeof(struct s3c24xx_dma_phy), GFP_KERNEL); if (!s3cdma->phy_chans) return -ENOMEM; diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c index 1adeb3265085..0137d5316571 100644 --- a/drivers/dma/sa11x0-dma.c +++ b/drivers/dma/sa11x0-dma.c @@ -557,7 +557,7 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_slave_sg( } } - txd = kzalloc(sizeof(*txd) + j * sizeof(txd->sg[0]), GFP_ATOMIC); + txd = kzalloc(struct_size(txd, sg, j), GFP_ATOMIC); if (!txd) { dev_dbg(chan->device->dev, "vchan %p: kzalloc failed\n", &c->vc); return NULL; @@ -627,7 +627,7 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_dma_cyclic( if (sglen == 0) return NULL; - txd = kzalloc(sizeof(*txd) + sglen * sizeof(txd->sg[0]), GFP_ATOMIC); + txd = kzalloc(struct_size(txd, sg, sglen), GFP_ATOMIC); if (!txd) { dev_dbg(chan->device->dev, "vchan %p: kzalloc failed\n", &c->vc); return NULL; diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c index 12fa48e380cf..6b5626e299b2 100644 --- a/drivers/dma/sh/shdma-base.c +++ b/drivers/dma/sh/shdma-base.c @@ -1045,8 +1045,9 @@ EXPORT_SYMBOL(shdma_cleanup); static int __init shdma_enter(void) { - shdma_slave_used = kzalloc(DIV_ROUND_UP(slave_num, BITS_PER_LONG) * - sizeof(long), GFP_KERNEL); + shdma_slave_used = kcalloc(DIV_ROUND_UP(slave_num, BITS_PER_LONG), + sizeof(long), + GFP_KERNEL); if (!shdma_slave_used) return -ENOMEM; return 0; diff --git a/drivers/dma/sh/usb-dmac.c b/drivers/dma/sh/usb-dmac.c index 31a145154e9f..1bb1a8e09025 100644 --- a/drivers/dma/sh/usb-dmac.c +++ b/drivers/dma/sh/usb-dmac.c @@ -269,7 +269,7 @@ static int usb_dmac_desc_alloc(struct usb_dmac_chan *chan, unsigned int sg_len, struct usb_dmac_desc *desc; unsigned long flags; - desc = kzalloc(sizeof(*desc) + sg_len * sizeof(desc->sg[0]), gfp); + desc = kzalloc(struct_size(desc, sg, sg_len), gfp); if (!desc) return -ENOMEM; diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c index 6d86d05e53aa..11bd68f0ce30 100644 --- a/drivers/dma/xilinx/zynqmp_dma.c +++ b/drivers/dma/xilinx/zynqmp_dma.c @@ -463,7 +463,7 @@ static int zynqmp_dma_alloc_chan_resources(struct dma_chan *dchan) struct zynqmp_dma_desc_sw *desc; int i; - chan->sw_desc_pool = kzalloc(sizeof(*desc) * ZYNQMP_DMA_NUM_DESCS, + chan->sw_desc_pool = kcalloc(ZYNQMP_DMA_NUM_DESCS, sizeof(*desc), GFP_KERNEL); if (!chan->sw_desc_pool) return -ENOMEM; diff --git a/drivers/dma/zx_dma.c b/drivers/dma/zx_dma.c index 2bb695315300..2571bc7693df 100644 --- a/drivers/dma/zx_dma.c +++ b/drivers/dma/zx_dma.c @@ -798,8 +798,8 @@ static int zx_dma_probe(struct platform_device *op) return -ENOMEM; /* init phy channel */ - d->phy = devm_kzalloc(&op->dev, - d->dma_channels * sizeof(struct zx_dma_phy), GFP_KERNEL); + d->phy = devm_kcalloc(&op->dev, + d->dma_channels, sizeof(struct zx_dma_phy), GFP_KERNEL); if (!d->phy) return -ENOMEM; @@ -834,8 +834,8 @@ static int zx_dma_probe(struct platform_device *op) d->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; /* init virtual channel */ - d->chans = devm_kzalloc(&op->dev, - d->dma_requests * sizeof(struct zx_dma_chan), GFP_KERNEL); + d->chans = devm_kcalloc(&op->dev, + d->dma_requests, sizeof(struct zx_dma_chan), GFP_KERNEL); if (!d->chans) return -ENOMEM; diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 21c5f95596be..3878065e1bcd 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -3473,7 +3473,7 @@ static int __init amd64_edac_init(void) opstate_init(); err = -ENOMEM; - ecc_stngs = kzalloc(amd_nb_num() * sizeof(ecc_stngs[0]), GFP_KERNEL); + ecc_stngs = kcalloc(amd_nb_num(), sizeof(ecc_stngs[0]), GFP_KERNEL); if (!ecc_stngs) goto err_free; diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 2054a24b41d7..59bf8612d439 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -461,7 +461,7 @@ static struct i7core_dev *alloc_i7core_dev(u8 socket, if (!i7core_dev) return NULL; - i7core_dev->pdev = kzalloc(sizeof(*i7core_dev->pdev) * table->n_devs, + i7core_dev->pdev = kcalloc(table->n_devs, sizeof(*i7core_dev->pdev), GFP_KERNEL); if (!i7core_dev->pdev) { kfree(i7core_dev); diff --git a/drivers/edac/qcom_llcc_edac.c b/drivers/edac/qcom_llcc_edac.c index ddf6776a2494..ba6946376088 100644 --- a/drivers/edac/qcom_llcc_edac.c +++ b/drivers/edac/qcom_llcc_edac.c @@ -427,8 +427,8 @@ static int qcom_llcc_erp_probe(struct platform_device *pdev) drv->num_banks = num_banks; drv->llcc_map = llcc_map; - drv->llcc_banks = devm_kzalloc(&pdev->dev, - sizeof(u32) * drv->num_banks, GFP_KERNEL); + drv->llcc_banks = devm_kcalloc(&pdev->dev, + drv->num_banks, sizeof(u32), GFP_KERNEL); if (!drv->llcc_banks) { dev_err(dev, "Cannot allocate memory for llcc_banks\n"); diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index 97bd841334e4..427f6d25b3fc 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c @@ -1185,8 +1185,9 @@ int extcon_dev_register(struct extcon_dev *edev) char *str; struct extcon_cable *cable; - edev->cables = kzalloc(sizeof(struct extcon_cable) * - edev->max_supported, GFP_KERNEL); + edev->cables = kcalloc(edev->max_supported, + sizeof(struct extcon_cable), + GFP_KERNEL); if (!edev->cables) { ret = -ENOMEM; goto err_sysfs_alloc; @@ -1195,7 +1196,7 @@ int extcon_dev_register(struct extcon_dev *edev) cable = &edev->cables[index]; snprintf(buf, 10, "cable.%d", index); - str = kzalloc(sizeof(char) * (strlen(buf) + 1), + str = kzalloc(strlen(buf) + 1, GFP_KERNEL); if (!str) { for (index--; index >= 0; index--) { @@ -1236,15 +1237,17 @@ int extcon_dev_register(struct extcon_dev *edev) for (index = 0; edev->mutually_exclusive[index]; index++) ; - edev->attrs_muex = kzalloc(sizeof(struct attribute *) * - (index + 1), GFP_KERNEL); + edev->attrs_muex = kcalloc(index + 1, + sizeof(struct attribute *), + GFP_KERNEL); if (!edev->attrs_muex) { ret = -ENOMEM; goto err_muex; } - edev->d_attrs_muex = kzalloc(sizeof(struct device_attribute) * - index, GFP_KERNEL); + edev->d_attrs_muex = kcalloc(index, + sizeof(struct device_attribute), + GFP_KERNEL); if (!edev->d_attrs_muex) { ret = -ENOMEM; kfree(edev->attrs_muex); @@ -1253,7 +1256,7 @@ int extcon_dev_register(struct extcon_dev *edev) for (index = 0; edev->mutually_exclusive[index]; index++) { sprintf(buf, "0x%x", edev->mutually_exclusive[index]); - name = kzalloc(sizeof(char) * (strlen(buf) + 1), + name = kzalloc(strlen(buf) + 1, GFP_KERNEL); if (!name) { for (index--; index >= 0; index--) { @@ -1279,8 +1282,9 @@ int extcon_dev_register(struct extcon_dev *edev) if (edev->max_supported) { edev->extcon_dev_type.groups = - kzalloc(sizeof(struct attribute_group *) * - (edev->max_supported + 2), GFP_KERNEL); + kcalloc(edev->max_supported + 2, + sizeof(struct attribute_group *), + GFP_KERNEL); if (!edev->extcon_dev_type.groups) { ret = -ENOMEM; goto err_alloc_groups; @@ -1313,8 +1317,8 @@ int extcon_dev_register(struct extcon_dev *edev) goto err_dev; } - edev->bnh = devm_kzalloc(&edev->dev, - sizeof(*edev->bnh) * edev->max_supported, GFP_KERNEL); + edev->bnh = devm_kcalloc(&edev->dev, + edev->max_supported, sizeof(*edev->bnh), GFP_KERNEL); if (!edev->bnh) { ret = -ENOMEM; goto err_dev; diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c index 38c0aa60b2cb..051327a951b1 100644 --- a/drivers/firewire/core-iso.c +++ b/drivers/firewire/core-iso.c @@ -45,8 +45,8 @@ int fw_iso_buffer_alloc(struct fw_iso_buffer *buffer, int page_count) buffer->page_count = 0; buffer->page_count_mapped = 0; - buffer->pages = kmalloc(page_count * sizeof(buffer->pages[0]), - GFP_KERNEL); + buffer->pages = kmalloc_array(page_count, sizeof(buffer->pages[0]), + GFP_KERNEL); if (buffer->pages == NULL) return -ENOMEM; diff --git a/drivers/firewire/core-topology.c b/drivers/firewire/core-topology.c index 939d259ddf19..7db234d3fbdd 100644 --- a/drivers/firewire/core-topology.c +++ b/drivers/firewire/core-topology.c @@ -112,8 +112,7 @@ static struct fw_node *fw_node_create(u32 sid, int port_count, int color) { struct fw_node *node; - node = kzalloc(sizeof(*node) + port_count * sizeof(node->ports[0]), - GFP_ATOMIC); + node = kzalloc(struct_size(node, ports, port_count), GFP_ATOMIC); if (node == NULL) return NULL; diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 215f4f71b943..2479c5b475d1 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1125,7 +1125,7 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) max_receive = 1U << (dev->card->max_receive + 1); num_packets = (FWNET_ISO_PAGE_COUNT * PAGE_SIZE) / max_receive; - ptrptr = kmalloc(sizeof(void *) * num_packets, GFP_KERNEL); + ptrptr = kmalloc_array(num_packets, sizeof(void *), GFP_KERNEL); if (!ptrptr) { retval = -ENOMEM; goto failed; diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index 7da9f1b83ebe..f17b895e5e32 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -930,7 +930,7 @@ static int scpi_alloc_xfer_list(struct device *dev, struct scpi_chan *ch) int i; struct scpi_xfer *xfers; - xfers = devm_kzalloc(dev, MAX_SCPI_XFERS * sizeof(*xfers), GFP_KERNEL); + xfers = devm_kcalloc(dev, MAX_SCPI_XFERS, sizeof(*xfers), GFP_KERNEL); if (!xfers) return -ENOMEM; diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c index 53f27a6e2d76..ccefa84f7305 100644 --- a/drivers/firmware/dell_rbu.c +++ b/drivers/firmware/dell_rbu.c @@ -147,7 +147,7 @@ static int create_packet(void *data, size_t length) packet_array_size = max( (unsigned int)(allocation_floor / rbu_data.packetsize), (unsigned int)1); - invalid_addr_packet_array = kzalloc(packet_array_size * sizeof(void*), + invalid_addr_packet_array = kcalloc(packet_array_size, sizeof(void *), GFP_KERNEL); if (!invalid_addr_packet_array) { diff --git a/drivers/firmware/efi/capsule.c b/drivers/firmware/efi/capsule.c index 901b9306bf94..4938c29b7c5d 100644 --- a/drivers/firmware/efi/capsule.c +++ b/drivers/firmware/efi/capsule.c @@ -231,7 +231,7 @@ int efi_capsule_update(efi_capsule_header_t *capsule, phys_addr_t *pages) count = DIV_ROUND_UP(imagesize, PAGE_SIZE); sg_count = sg_pages_num(count); - sg_pages = kzalloc(sg_count * sizeof(*sg_pages), GFP_KERNEL); + sg_pages = kcalloc(sg_count, sizeof(*sg_pages), GFP_KERNEL); if (!sg_pages) return -ENOMEM; diff --git a/drivers/firmware/efi/runtime-map.c b/drivers/firmware/efi/runtime-map.c index f377609ff141..84a11d0a8023 100644 --- a/drivers/firmware/efi/runtime-map.c +++ b/drivers/firmware/efi/runtime-map.c @@ -166,7 +166,7 @@ int __init efi_runtime_map_init(struct kobject *efi_kobj) if (!efi_enabled(EFI_MEMMAP)) return 0; - map_entries = kzalloc(efi.memmap.nr_map * sizeof(entry), GFP_KERNEL); + map_entries = kcalloc(efi.memmap.nr_map, sizeof(entry), GFP_KERNEL); if (!map_entries) { ret = -ENOMEM; goto out; diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 1620722115cd..a7e9d4798758 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -1862,9 +1862,9 @@ static int ti_sci_probe(struct platform_device *pdev) if (!minfo->xfer_block) return -ENOMEM; - minfo->xfer_alloc_table = devm_kzalloc(dev, - BITS_TO_LONGS(desc->max_msgs) - * sizeof(unsigned long), + minfo->xfer_alloc_table = devm_kcalloc(dev, + BITS_TO_LONGS(desc->max_msgs), + sizeof(unsigned long), GFP_KERNEL); if (!minfo->xfer_alloc_table) return -ENOMEM; diff --git a/drivers/fmc/fmc-sdb.c b/drivers/fmc/fmc-sdb.c index ffdc1762b580..d0e65b86dc22 100644 --- a/drivers/fmc/fmc-sdb.c +++ b/drivers/fmc/fmc-sdb.c @@ -48,8 +48,8 @@ static struct sdb_array *__fmc_scan_sdb_tree(struct fmc_device *fmc, arr = kzalloc(sizeof(*arr), GFP_KERNEL); if (!arr) return ERR_PTR(-ENOMEM); - arr->record = kzalloc(sizeof(arr->record[0]) * n, GFP_KERNEL); - arr->subtree = kzalloc(sizeof(arr->subtree[0]) * n, GFP_KERNEL); + arr->record = kcalloc(n, sizeof(arr->record[0]), GFP_KERNEL); + arr->subtree = kcalloc(n, sizeof(arr->subtree[0]), GFP_KERNEL); if (!arr->record || !arr->subtree) { kfree(arr->record); kfree(arr->subtree); diff --git a/drivers/gnsssirf/gnss_sirf.c b/drivers/gnsssirf/gnss_sirf.c index d10749166767..91d6198eaa7c 100644 --- a/drivers/gnsssirf/gnss_sirf.c +++ b/drivers/gnsssirf/gnss_sirf.c @@ -238,10 +238,6 @@ static int gnss_sirf_probe(struct platform_device *pdev) onOffPin = of_get_named_gpio(pdev->dev.of_node, "ssVonoff-gpio", 0); ret = configurePins(pdev); - if (ret == 0) { - snprintf(boot_marker, sizeof(boot_marker), - "M - DRIVER GNSS Ready"); - place_marker(boot_marker); } } } diff --git a/drivers/gpio/gpio-adnp.c b/drivers/gpio/gpio-adnp.c index ee923b1b820c..6c1280830b62 100644 --- a/drivers/gpio/gpio-adnp.c +++ b/drivers/gpio/gpio-adnp.c @@ -432,7 +432,7 @@ static int adnp_irq_setup(struct adnp *adnp) * is chosen to match the register layout of the hardware in that * each segment contains the corresponding bits for all interrupts. */ - adnp->irq_enable = devm_kzalloc(chip->parent, num_regs * 6, + adnp->irq_enable = devm_kcalloc(chip->parent, num_regs, 6, GFP_KERNEL); if (!adnp->irq_enable) return -ENOMEM; diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c index dfcf56ee3c61..5e7af55a18ef 100644 --- a/drivers/gpio/gpio-bcm-kona.c +++ b/drivers/gpio/gpio-bcm-kona.c @@ -600,9 +600,10 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev) GPIO_MAX_BANK_NUM); return -ENXIO; } - kona_gpio->banks = devm_kzalloc(dev, - kona_gpio->num_bank * - sizeof(*kona_gpio->banks), GFP_KERNEL); + kona_gpio->banks = devm_kcalloc(dev, + kona_gpio->num_bank, + sizeof(*kona_gpio->banks), + GFP_KERNEL); if (!kona_gpio->banks) return -ENOMEM; diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index e4b3d7db68c9..72b1847d3ce5 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -197,8 +197,8 @@ static int davinci_gpio_probe(struct platform_device *pdev) ngpio = ARCH_NR_GPIOS; nbank = DIV_ROUND_UP(ngpio, 32); - chips = devm_kzalloc(dev, - nbank * sizeof(struct davinci_gpio_controller), + chips = devm_kcalloc(dev, + nbank, sizeof(struct davinci_gpio_controller), GFP_KERNEL); if (!chips) return -ENOMEM; diff --git a/drivers/gpio/gpio-etraxfs.c b/drivers/gpio/gpio-etraxfs.c index 94db1bf4bfdb..403e7de849e7 100644 --- a/drivers/gpio/gpio-etraxfs.c +++ b/drivers/gpio/gpio-etraxfs.c @@ -380,7 +380,8 @@ static int etraxfs_gpio_probe(struct platform_device *pdev) info = match->data; - chips = devm_kzalloc(dev, sizeof(*chips) * info->num_ports, GFP_KERNEL); + chips = devm_kcalloc(dev, info->num_ports, sizeof(*chips), + GFP_KERNEL); if (!chips) return -ENOMEM; diff --git a/drivers/gpio/gpio-htc-egpio.c b/drivers/gpio/gpio-htc-egpio.c index 271356effb2e..c1e0b2170b3f 100644 --- a/drivers/gpio/gpio-htc-egpio.c +++ b/drivers/gpio/gpio-htc-egpio.c @@ -320,8 +320,8 @@ static int __init egpio_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ei); ei->nchips = pdata->num_chips; - ei->chip = devm_kzalloc(&pdev->dev, - sizeof(struct egpio_chip) * ei->nchips, + ei->chip = devm_kcalloc(&pdev->dev, + ei->nchips, sizeof(struct egpio_chip), GFP_KERNEL); if (!ei->chip) { ret = -ENOMEM; diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c index 1022fe8d09c7..a10af0628591 100644 --- a/drivers/gpio/gpio-ml-ioh.c +++ b/drivers/gpio/gpio-ml-ioh.c @@ -443,7 +443,7 @@ static int ioh_gpio_probe(struct pci_dev *pdev, goto err_iomap; } - chip_save = kzalloc(sizeof(*chip) * 8, GFP_KERNEL); + chip_save = kcalloc(8, sizeof(*chip), GFP_KERNEL); if (chip_save == NULL) { dev_err(&pdev->dev, "%s : kzalloc failed", __func__); ret = -ENOMEM; diff --git a/drivers/gpio/gpio-thunderx.c b/drivers/gpio/gpio-thunderx.c index 10523ce00c38..21e4dceb2f23 100644 --- a/drivers/gpio/gpio-thunderx.c +++ b/drivers/gpio/gpio-thunderx.c @@ -517,16 +517,17 @@ static int thunderx_gpio_probe(struct pci_dev *pdev, txgpio->base_msi = (c >> 8) & 0xff; } - txgpio->msix_entries = devm_kzalloc(dev, - sizeof(struct msix_entry) * ngpio, + txgpio->msix_entries = devm_kcalloc(dev, + ngpio, sizeof(struct msix_entry), GFP_KERNEL); if (!txgpio->msix_entries) { err = -ENOMEM; goto out; } - txgpio->line_entries = devm_kzalloc(dev, - sizeof(struct thunderx_line) * ngpio, + txgpio->line_entries = devm_kcalloc(dev, + ngpio, + sizeof(struct thunderx_line), GFP_KERNEL); if (!txgpio->line_entries) { err = -ENOMEM; diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index d5b42cc86d71..fdf39dcf6e95 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -3579,8 +3579,7 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev, if (count < 0) return ERR_PTR(count); - descs = kzalloc(sizeof(*descs) + sizeof(descs->desc[0]) * count, - GFP_KERNEL); + descs = kzalloc(struct_size(descs, desc, count), GFP_KERNEL); if (!descs) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c index a52795d9b458..2877567bd047 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c @@ -300,20 +300,20 @@ static int acp_hw_init(void *handle) pm_genpd_init(&adev->acp.acp_genpd->gpd, NULL, false); } - adev->acp.acp_cell = kzalloc(sizeof(struct mfd_cell) * ACP_DEVS, + adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell), GFP_KERNEL); if (adev->acp.acp_cell == NULL) return -ENOMEM; - adev->acp.acp_res = kzalloc(sizeof(struct resource) * 4, GFP_KERNEL); + adev->acp.acp_res = kcalloc(4, sizeof(struct resource), GFP_KERNEL); if (adev->acp.acp_res == NULL) { kfree(adev->acp.acp_cell); return -ENOMEM; } - i2s_pdata = kzalloc(sizeof(struct i2s_platform_data) * 2, GFP_KERNEL); + i2s_pdata = kcalloc(2, sizeof(struct i2s_platform_data), GFP_KERNEL); if (i2s_pdata == NULL) { kfree(adev->acp.acp_res); kfree(adev->acp.acp_cell); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index bb4b804255a8..42bb16404779 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c @@ -973,7 +973,9 @@ static int amdgpu_cgs_acpi_eval_object(struct cgs_device *cgs_device, /* parse input parameters */ if (input.count > 0) { input.pointer = params = - kzalloc(sizeof(union acpi_object) * input.count, GFP_KERNEL); + kcalloc(input.count, + sizeof(union acpi_object), + GFP_KERNEL); if (params == NULL) return -EINVAL; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c index 1cb52fd19060..911624b101c2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c @@ -432,7 +432,7 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) ATOM_PPLIB_PhaseSheddingLimits_Record *entry; adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries = - kzalloc(psl->ucNumEntries * + kcalloc(psl->ucNumEntries, sizeof(struct amdgpu_phase_shedding_limits_entry), GFP_KERNEL); if (!adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index f4370081f6e6..eed93151b816 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c @@ -375,7 +375,7 @@ int amdgpu_gart_init(struct amdgpu_device *adev) #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS /* Allocate pages table */ - adev->gart.pages = vzalloc(sizeof(void *) * adev->gart.num_cpu_pages); + adev->gart.pages = vzalloc(array_size(sizeof(void *), adev->gart.num_cpu_pages)); if (adev->gart.pages == NULL) { amdgpu_gart_fini(adev); return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index c93e72d8ac5f..22d9ec80a2ff 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -527,8 +527,9 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file return n ? -EFAULT : 0; } case AMDGPU_INFO_DEV_INFO: { - struct drm_amdgpu_info_device dev_info = {}; + struct drm_amdgpu_info_device dev_info; + memset(&dev_info, 0, sizeof(dev_info)); dev_info.device_id = dev->pdev->device; dev_info.chip_rev = adev->rev_id; dev_info.external_rev = adev->external_rev_id; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c index b35b0741fd97..284554614368 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c @@ -52,7 +52,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev) n -= adev->irq.ih.ring_size; n /= size; - gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL); + gtt_obj = kcalloc(n, sizeof(*gtt_obj), GFP_KERNEL); if (!gtt_obj) { DRM_ERROR("Failed to allocate %d pointers\n", n); r = 1; diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c index d69aa2e179bb..868bef501a5f 100644 --- a/drivers/gpu/drm/amd/amdgpu/atom.c +++ b/drivers/gpu/drm/amd/amdgpu/atom.c @@ -1221,7 +1221,7 @@ static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, ectx.abort = false; ectx.last_jump = 0; if (ws) - ectx.ws = kzalloc(4 * ws, GFP_KERNEL); + ectx.ws = kcalloc(4, ws, GFP_KERNEL); else ectx.ws = NULL; diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index cb508a211b2f..57fd92b8e0d9 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c @@ -5705,8 +5705,9 @@ static int ci_parse_power_table(struct amdgpu_device *adev) (mode_info->atom_context->bios + data_offset + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); - adev->pm.dpm.ps = kzalloc(sizeof(struct amdgpu_ps) * - state_array->ucNumEntries, GFP_KERNEL); + adev->pm.dpm.ps = kcalloc(state_array->ucNumEntries, + sizeof(struct amdgpu_ps), + GFP_KERNEL); if (!adev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; @@ -5953,7 +5954,9 @@ static int ci_dpm_init(struct amdgpu_device *adev) ci_set_private_data_variables_based_on_pptable(adev); adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries = - kzalloc(4 * sizeof(struct amdgpu_clock_voltage_dependency_entry), GFP_KERNEL); + kcalloc(4, + sizeof(struct amdgpu_clock_voltage_dependency_entry), + GFP_KERNEL); if (!adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) { ci_dpm_fini(adev); return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c index c76073b422d6..f94a27e0d482 100644 --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c @@ -2718,8 +2718,9 @@ static int kv_parse_power_table(struct amdgpu_device *adev) (mode_info->atom_context->bios + data_offset + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); - adev->pm.dpm.ps = kzalloc(sizeof(struct amdgpu_ps) * - state_array->ucNumEntries, GFP_KERNEL); + adev->pm.dpm.ps = kcalloc(state_array->ucNumEntries, + sizeof(struct amdgpu_ps), + GFP_KERNEL); if (!adev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c index 55613f425931..66481cfcdd1a 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c @@ -7233,8 +7233,9 @@ static int si_parse_power_table(struct amdgpu_device *adev) (mode_info->atom_context->bios + data_offset + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); - adev->pm.dpm.ps = kzalloc(sizeof(struct amdgpu_ps) * - state_array->ucNumEntries, GFP_KERNEL); + adev->pm.dpm.ps = kcalloc(state_array->ucNumEntries, + sizeof(struct amdgpu_ps), + GFP_KERNEL); if (!adev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; @@ -7337,7 +7338,9 @@ static int si_dpm_init(struct amdgpu_device *adev) return ret; adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries = - kzalloc(4 * sizeof(struct amdgpu_clock_voltage_dependency_entry), GFP_KERNEL); + kcalloc(4, + sizeof(struct amdgpu_clock_voltage_dependency_entry), + GFP_KERNEL); if (!adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) { amdgpu_free_extended_power_table(adev); return -ENOMEM; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c index 9547f265a8bb..ff23a397a078 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c @@ -150,7 +150,7 @@ static int hw_init_power_state_table(struct pp_hwmgr *hwmgr) hwmgr->ps_size = size = hwmgr->hwmgr_func->get_power_state_size(hwmgr) + sizeof(struct pp_power_state); - hwmgr->ps = kzalloc(size * table_entries, GFP_KERNEL); + hwmgr->ps = kcalloc(table_entries, size, GFP_KERNEL); if (hwmgr->ps == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/bridge/lt9611.c b/drivers/gpu/drm/bridge/lt9611.c index 443a43d3b128..01072beac003 100644 --- a/drivers/gpu/drm/bridge/lt9611.c +++ b/drivers/gpu/drm/bridge/lt9611.c @@ -1343,8 +1343,10 @@ static int lt9611_get_dt_supply(struct device *dev, } pr_debug("vreg found. count=%d\n", pdata->num_vreg); - pdata->vreg_config = devm_kzalloc(dev, sizeof(struct lt9611_vreg) * - pdata->num_vreg, GFP_KERNEL); + pdata->vreg_config = devm_kcalloc(dev, + pdata->num_vreg, + sizeof(struct lt9611_vreg), + GFP_KERNEL); if (!pdata->vreg_config) return -ENOMEM; diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index eab36a460638..2a83b91ee054 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -562,13 +562,15 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set, * Allocate space for the backup of all (non-pointer) encoder and * connector data. */ - save_encoder_crtcs = kzalloc(dev->mode_config.num_encoder * - sizeof(struct drm_crtc *), GFP_KERNEL); + save_encoder_crtcs = kcalloc(dev->mode_config.num_encoder, + sizeof(struct drm_crtc *), + GFP_KERNEL); if (!save_encoder_crtcs) return -ENOMEM; - save_connector_encoders = kzalloc(dev->mode_config.num_connector * - sizeof(struct drm_encoder *), GFP_KERNEL); + save_connector_encoders = kcalloc(dev->mode_config.num_connector, + sizeof(struct drm_encoder *), + GFP_KERNEL); if (!save_connector_encoders) { kfree(save_encoder_crtcs); return -ENOMEM; diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index df5fe163cfec..ee1a76e1a632 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -1618,7 +1618,8 @@ struct edid *drm_do_get_edid(struct drm_connector *connector, edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions; edid[0x7e] = valid_extensions; - new = kmalloc((valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL); + new = kmalloc_array(valid_extensions + 1, EDID_LENGTH, + GFP_KERNEL); if (!new) goto out; diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index eb6bf881c465..e58b6d9cfc8f 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -2261,8 +2261,9 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, if (modes[n] == NULL) return best_score; - crtcs = kzalloc(fb_helper->connector_count * - sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL); + crtcs = kcalloc(fb_helper->connector_count, + sizeof(struct drm_fb_helper_crtc *), + GFP_KERNEL); if (!crtcs) return best_score; diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index d2c042af36b8..470a79eef254 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -730,9 +730,6 @@ err: * @file_priv: drm file-private structure * * Open an object using the global name, returning a handle and the size. - * - * This handle (of course) holds a reference to the object, so the object - * will not go away until the handle is deleted. */ int drm_gem_open_ioctl(struct drm_device *dev, void *data, @@ -757,14 +754,15 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data, /* drm_gem_handle_create_tail unlocks dev->object_name_lock. */ ret = drm_gem_handle_create_tail(file_priv, obj, &handle); - drm_gem_object_put_unlocked(obj); if (ret) - return ret; + goto err; args->handle = handle; args->size = obj->size; - return 0; +err: + drm_gem_object_put_unlocked(obj); + return ret; } /** diff --git a/drivers/gpu/drm/drm_hashtab.c b/drivers/gpu/drm/drm_hashtab.c index dae18e58e79b..c92b00d42ece 100644 --- a/drivers/gpu/drm/drm_hashtab.c +++ b/drivers/gpu/drm/drm_hashtab.c @@ -47,7 +47,7 @@ int drm_ht_create(struct drm_open_hash *ht, unsigned int order) if (size <= PAGE_SIZE / sizeof(*ht->table)) ht->table = kcalloc(size, sizeof(*ht->table), GFP_KERNEL); else - ht->table = vzalloc(size*sizeof(*ht->table)); + ht->table = vzalloc(array_size(size, sizeof(*ht->table))); if (!ht->table) { DRM_ERROR("Out of memory for hash table\n"); return -ENOMEM; diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c index fc0ebd273ef8..b3a37807629c 100644 --- a/drivers/gpu/drm/drm_memory.c +++ b/drivers/gpu/drm/drm_memory.c @@ -80,7 +80,7 @@ static void *agp_remap(unsigned long offset, unsigned long size, * page-table instead (that's probably faster anyhow...). */ /* note: use vmalloc() because num_pages could be large... */ - page_map = vmalloc(num_pages * sizeof(struct page *)); + page_map = vmalloc(array_size(num_pages, sizeof(struct page *))); if (!page_map) return NULL; diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index 06aee1741e96..759ed93f4ba8 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -354,7 +354,7 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, /* Find current connectors for CRTC */ num_connectors = get_connectors_for_crtc(crtc, NULL, 0); BUG_ON(num_connectors == 0); - connector_list = kzalloc(num_connectors * sizeof(*connector_list), + connector_list = kcalloc(num_connectors, sizeof(*connector_list), GFP_KERNEL); if (!connector_list) return -ENOMEM; diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 366c975cde5b..9b33809be85b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1744,8 +1744,8 @@ static int exynos_dsi_probe(struct platform_device *pdev) return ret; } - dsi->clks = devm_kzalloc(dev, - sizeof(*dsi->clks) * dsi->driver_data->num_clks, + dsi->clks = devm_kcalloc(dev, + dsi->driver_data->num_clks, sizeof(*dsi->clks), GFP_KERNEL); if (!dsi->clks) return -ENOMEM; diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 0109ff40b1db..b730f1b86f05 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -1577,7 +1577,7 @@ static int hdmi_clk_init(struct hdmi_context *hdata) if (!count) return 0; - clks = devm_kzalloc(dev, sizeof(*clks) * count, GFP_KERNEL); + clks = devm_kcalloc(dev, count, sizeof(*clks), GFP_KERNEL); if (!clks) return -ENOMEM; diff --git a/drivers/gpu/drm/gma500/mid_bios.c b/drivers/gpu/drm/gma500/mid_bios.c index d75ecb3bdee7..a833568c782b 100644 --- a/drivers/gpu/drm/gma500/mid_bios.c +++ b/drivers/gpu/drm/gma500/mid_bios.c @@ -235,7 +235,7 @@ static int mid_get_vbt_data_r10(struct drm_psb_private *dev_priv, u32 addr) if (read_vbt_r10(addr, &vbt)) return -1; - gct = kmalloc(sizeof(*gct) * vbt.panel_count, GFP_KERNEL); + gct = kmalloc_array(vbt.panel_count, sizeof(*gct), GFP_KERNEL); if (!gct) return -1; diff --git a/drivers/gpu/drm/i915/gvt/mmio.c b/drivers/gpu/drm/i915/gvt/mmio.c index 980ec8906b1e..9a432f0c7ca5 100644 --- a/drivers/gpu/drm/i915/gvt/mmio.c +++ b/drivers/gpu/drm/i915/gvt/mmio.c @@ -328,7 +328,7 @@ int intel_vgpu_init_mmio(struct intel_vgpu *vgpu) { const struct intel_gvt_device_info *info = &vgpu->gvt->device_info; - vgpu->mmio.vreg = vzalloc(info->mmio_size * 2); + vgpu->mmio.vreg = vzalloc(array_size(info->mmio_size, 2)); if (!vgpu->mmio.vreg) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c index e9f9063dbf63..b23eb4856009 100644 --- a/drivers/gpu/drm/i915/gvt/vgpu.c +++ b/drivers/gpu/drm/i915/gvt/vgpu.c @@ -118,7 +118,7 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt) high_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE; num_types = sizeof(vgpu_types) / sizeof(vgpu_types[0]); - gvt->types = kzalloc(num_types * sizeof(struct intel_vgpu_type), + gvt->types = kcalloc(num_types, sizeof(struct intel_vgpu_type), GFP_KERNEL); if (!gvt->types) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/selftests/intel_uncore.c b/drivers/gpu/drm/i915/selftests/intel_uncore.c index 3cac22eb47ce..7ee3bd09fe22 100644 --- a/drivers/gpu/drm/i915/selftests/intel_uncore.c +++ b/drivers/gpu/drm/i915/selftests/intel_uncore.c @@ -126,7 +126,7 @@ static int intel_uncore_check_forcewake_domains(struct drm_i915_private *dev_pri if (IS_BROADWELL(dev_priv)) /* XXX random GPU hang afterwards! */ return 0; - valid = kzalloc(BITS_TO_LONGS(FW_RANGE) * sizeof(*valid), + valid = kcalloc(BITS_TO_LONGS(FW_RANGE), sizeof(*valid), GFP_KERNEL); if (!valid) return -ENOMEM; diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c index a89a51c5b0ff..cbcf25921d6c 100644 --- a/drivers/gpu/drm/msm/dp/dp_parser.c +++ b/drivers/gpu/drm/msm/dp/dp_parser.c @@ -43,8 +43,8 @@ static int dp_parser_reg(struct dp_parser *parser) } io->len = reg_count; - io->data = devm_kzalloc(dev, sizeof(struct dp_io_data) * reg_count, - GFP_KERNEL); + io->data = devm_kcalloc(dev, reg_count, sizeof(struct dp_io_data), + GFP_KERNEL); if (!io->data) return -ENOMEM; @@ -287,8 +287,8 @@ static int dp_parser_gpio(struct dp_parser *parser) if (of_find_property(of_node, "qcom,dp-gpio-aux-switch", NULL)) parser->gpio_aux_switch = true; - mp->gpio_config = devm_kzalloc(dev, - sizeof(struct dss_gpio) * ARRAY_SIZE(dp_gpios), GFP_KERNEL); + mp->gpio_config = devm_kcalloc(dev, + ARRAY_SIZE(dp_gpios), sizeof(struct dss_gpio), GFP_KERNEL); if (!mp->gpio_config) return -ENOMEM; @@ -354,8 +354,8 @@ static int dp_parser_get_vreg(struct dp_parser *parser, pr_debug("vreg found. count=%d\n", mp->num_vreg); } - mp->vreg_config = devm_kzalloc(&parser->pdev->dev, - sizeof(struct dss_vreg) * mp->num_vreg, GFP_KERNEL); + mp->vreg_config = devm_kcalloc(&parser->pdev->dev, + mp->num_vreg, sizeof(struct dss_vreg), GFP_KERNEL); if (!mp->vreg_config) { rc = -ENOMEM; goto error; @@ -558,8 +558,8 @@ static int dp_parser_init_clk_data(struct dp_parser *parser) } core_power->num_clk = core_clk_count; - core_power->clk_config = devm_kzalloc(dev, - sizeof(struct dss_clk) * core_power->num_clk, + core_power->clk_config = devm_kcalloc(dev, + core_power->num_clk, sizeof(struct dss_clk), GFP_KERNEL); if (!core_power->clk_config) { rc = -EINVAL; @@ -571,8 +571,8 @@ static int dp_parser_init_clk_data(struct dp_parser *parser) pr_debug("no strm0 clocks are defined\n"); } else { strm0_power->num_clk = strm0_clk_count; - strm0_power->clk_config = devm_kzalloc(dev, - sizeof(struct dss_clk) * strm0_power->num_clk, + strm0_power->clk_config = devm_kcalloc(dev, + strm0_power->num_clk, sizeof(struct dss_clk), GFP_KERNEL); if (!strm0_power->clk_config) { strm0_power->num_clk = 0; @@ -586,8 +586,8 @@ static int dp_parser_init_clk_data(struct dp_parser *parser) pr_debug("no strm1 clocks are defined\n"); } else { strm1_power->num_clk = strm1_clk_count; - strm1_power->clk_config = devm_kzalloc(dev, - sizeof(struct dss_clk) * strm1_power->num_clk, + strm1_power->clk_config = devm_kcalloc(dev, + strm1_power->num_clk, sizeof(struct dss_clk), GFP_KERNEL); if (!strm1_power->clk_config) { strm1_power->num_clk = 0; @@ -604,8 +604,8 @@ static int dp_parser_init_clk_data(struct dp_parser *parser) } link_power->num_clk = link_clk_count; - link_power->clk_config = devm_kzalloc(dev, - sizeof(struct dss_clk) * link_power->num_clk, + link_power->clk_config = devm_kcalloc(dev, + link_power->num_clk, sizeof(struct dss_clk), GFP_KERNEL); if (!link_power->clk_config) { link_power->num_clk = 0; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_clk.h b/drivers/gpu/drm/msm/dsi-staging/dsi_clk.h index e77f337a282b..a1121a9b6126 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_clk.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_clk.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -116,10 +116,10 @@ struct dsi_link_lp_clk_info { /** * struct link_clk_freq - Clock frequency information for Link clocks - * @byte_clk_rate: Frequency of DSI byte_clk in KHz. - * @byte_intf_clk_rate: Frequency of DSI byte_intf_clk in KHz. - * @pixel_clk_rate: Frequency of DSI pixel_clk in KHz. - * @esc_clk_rate: Frequency of DSI escape clock in KHz. + * @byte_clk_rate: Frequency of DSI byte_clk in Hz. + * @byte_intf_clk_rate: Frequency of DSI byte_intf_clk in Hz. + * @pixel_clk_rate: Frequency of DSI pixel_clk in Hz. + * @esc_clk_rate: Frequency of DSI escape clock in Hz. */ struct link_clk_freq { u32 byte_clk_rate; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c b/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c index 63f003fd1c8e..3868504391a6 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -139,7 +139,7 @@ int dsi_clk_set_pixel_clk_rate(void *client, u64 pixel_clk, u32 index) * dsi_clk_set_byte_clk_rate() - set frequency for byte clock * @client: DSI clock client pointer. * @byte_clk: Byte clock rate in Hz. - * @byte_intf_clk: Byte interface clock rate in Hz. + * @byte_intf_clk: Byte interface clock rate in Hz. * @index: Index of the DSI controller. * return: error code in case of failure or 0 for success. */ @@ -159,13 +159,13 @@ int dsi_clk_set_byte_clk_rate(void *client, u64 byte_clk, if (mngr->link_clks[index].hs_clks.byte_intf_clk) { rc = clk_set_rate(mngr->link_clks[index].hs_clks.byte_intf_clk, - byte_intf_clk); + byte_intf_clk); if (rc) pr_err("failed to set clk rate for byte intf clk=%d\n", rc); else - mngr->link_clks[index].freq.byte_intf_clk_rate - = byte_intf_clk; + mngr->link_clks[index].freq.byte_intf_clk_rate = + byte_intf_clk; } return rc; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c index f13020b8e9df..b358947f842e 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -844,14 +844,13 @@ static int dsi_ctrl_update_link_freqs(struct dsi_ctrl *dsi_ctrl, { int rc = 0; u32 num_of_lanes = 0; - u32 bpp; + u32 bpp, byte_intf_clk_div; u64 refresh_rate = TICKS_IN_MICRO_SECOND; u64 h_period, v_period, bit_rate, pclk_rate, bit_rate_per_lane, - byte_clk_rate, byte_intf_clk_rate; + byte_clk_rate, byte_intf_clk_rate; struct dsi_host_common_cfg *host_cfg = &config->common_config; struct dsi_split_link_config *split_link = &host_cfg->split_link; struct dsi_mode_info *timing = &config->video_timing; - u32 bits_per_symbol = 16, num_of_symbols = 7; /* For Cphy */ /* Get bits per pxl in desitnation format */ bpp = dsi_ctrl_pixel_format_to_bpp(host_cfg->dst_format); @@ -883,43 +882,30 @@ static int dsi_ctrl_update_link_freqs(struct dsi_ctrl *dsi_ctrl, bit_rate = h_period * v_period * refresh_rate * bpp; } else { bit_rate = config->bit_clk_rate_hz_override * num_of_lanes; - if (host_cfg->phy_type == DSI_PHY_TYPE_CPHY) { - bit_rate *= bits_per_symbol; - do_div(bit_rate, num_of_symbols); - } } + bit_rate_per_lane = bit_rate; + do_div(bit_rate_per_lane, num_of_lanes); pclk_rate = bit_rate; do_div(pclk_rate, bpp); - if (host_cfg->phy_type == DSI_PHY_TYPE_DPHY) { - bit_rate_per_lane = bit_rate; - do_div(bit_rate_per_lane, num_of_lanes); - byte_clk_rate = bit_rate_per_lane; - do_div(byte_clk_rate, 8); - byte_intf_clk_rate = byte_clk_rate; - do_div(byte_intf_clk_rate, 2); - config->bit_clk_rate_hz = byte_clk_rate * 8; - } else { - do_div(bit_rate, bits_per_symbol); - bit_rate *= num_of_symbols; - bit_rate_per_lane = bit_rate; - do_div(bit_rate_per_lane, num_of_lanes); - byte_clk_rate = bit_rate_per_lane; - do_div(byte_clk_rate, 7); - /* For CPHY, byte_intf_clk is same as byte_clk */ - byte_intf_clk_rate = byte_clk_rate; - config->bit_clk_rate_hz = byte_clk_rate * 7; - } + byte_clk_rate = bit_rate_per_lane; + do_div(byte_clk_rate, 8); + byte_intf_clk_rate = byte_clk_rate; + byte_intf_clk_div = host_cfg->byte_intf_clk_div; + do_div(byte_intf_clk_rate, byte_intf_clk_div); + pr_debug("bit_clk_rate = %llu, bit_clk_rate_per_lane = %llu\n", bit_rate, bit_rate_per_lane); - pr_debug("byte_clk_rate = %llu, byte_intf_clk_rate = %llu\n", - byte_clk_rate, byte_intf_clk_rate); - pr_debug("pclk_rate = %llu\n", pclk_rate); + pr_debug("bit_clk_rate = %llu, byte_intf_clk_rate = %llu\n", + bit_rate, byte_intf_clk_rate); + pr_debug("byte_clk_rate = %llu, pclk_rate = %llu\n", + byte_clk_rate, pclk_rate); dsi_ctrl->clk_freq.byte_clk_rate = byte_clk_rate; - dsi_ctrl->clk_freq.byte_intf_clk_rate = byte_intf_clk_rate; dsi_ctrl->clk_freq.pix_clk_rate = pclk_rate; dsi_ctrl->clk_freq.esc_clk_rate = config->esc_clk_rate_hz; + dsi_ctrl->clk_freq.byte_intf_clk_rate = byte_intf_clk_rate; + config->bit_clk_rate_hz = dsi_ctrl->clk_freq.byte_clk_rate * 8; rc = dsi_clk_set_link_frequencies(clk_handle, dsi_ctrl->clk_freq, dsi_ctrl->cell_index); diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h index b839f23ce582..a978beb2aff7 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c index a7b79708a848..f8629b13615e 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -102,6 +102,14 @@ void dsi_ctrl_hw_cmn_host_setup(struct dsi_ctrl_hw *ctrl, dsi_setup_trigger_controls(ctrl, cfg); dsi_split_link_setup(ctrl, cfg); + /* Setup T_CLK_PRE extend register */ + reg_value = DSI_R32(ctrl, DSI_TEST_PATTERN_GEN_VIDEO_ENABLE); + if (cfg->t_clk_pre_extend) + reg_value |= BIT(0); + else + reg_value &= ~BIT(0); + DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_VIDEO_ENABLE, reg_value); + /* Setup clocking timing controls */ reg_value = ((cfg->t_clk_post & 0x3F) << 8); reg_value |= (cfg->t_clk_pre & 0x3F); @@ -127,9 +135,6 @@ void dsi_ctrl_hw_cmn_host_setup(struct dsi_ctrl_hw *ctrl, DSI_W32(ctrl, DSI_CTRL, reg_value); - if (cfg->phy_type == DSI_PHY_TYPE_CPHY) - DSI_W32(ctrl, DSI_CPHY_MODE_CTRL, BIT(0)); - if (ctrl->phy_isolation_enabled) DSI_W32(ctrl, DSI_DEBUG_CTRL, BIT(28)); pr_debug("[DSI_%d]Host configuration complete\n", ctrl->index); diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_reg.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_reg.h index 9f3c8c893794..72ac12dfd4b6 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_reg.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_reg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -153,7 +153,6 @@ #define DSI_SECURE_DISPLAY_STATUS (0x02CC) #define DSI_SECURE_DISPLAY_BLOCK_COMMAND_COLOR (0x02D0) #define DSI_SECURE_DISPLAY_BLOCK_VIDEO_COLOR (0x02D4) -#define DSI_CPHY_MODE_CTRL (0x02D8) #define DSI_LOGICAL_LANE_SWAP_CTRL (0x0310) #define DSI_SPLIT_LINK (0x0330) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h index fdd0299516e8..8b1b559dae28 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -476,6 +476,8 @@ struct dsi_split_link_config { * @t_clk_pre: Number of byte clock cycles that the high spped clock * shall be driven prior to data lane transitions from LP * to HS mode. + * @t_clk_pre_extend: Increment t_clk_pre counter by 2 byteclk if set to + * true, otherwise increment by 1 byteclk. * @ignore_rx_eot: Ignore Rx EOT packets if set to true. * @append_tx_eot: Append EOT packets for forward transmissions if set to * true. @@ -483,8 +485,8 @@ struct dsi_split_link_config { * @ext_bridge_map: External bridge config reg needs to match with the port * reg config. * @force_hs_clk_lane: Send continuous clock to the panel. - * @phy_type: DPHY/CPHY is enabled for this panel. * @dsi_split_link_config: Split Link Configuration. + * @byte_intf_clk_div: Determines the factor for calculating byte intf clock. */ struct dsi_host_common_cfg { enum dsi_pixel_format dst_format; @@ -501,13 +503,14 @@ struct dsi_host_common_cfg { bool bit_swap_blue; u32 t_clk_post; u32 t_clk_pre; + bool t_clk_pre_extend; bool ignore_rx_eot; bool append_tx_eot; u32 ext_bridge_num; u32 ext_bridge_map[MAX_DSI_CTRLS_PER_DISPLAY]; bool force_hs_clk_lane; - enum dsi_phy_type phy_type; struct dsi_split_link_config split_link; + u32 byte_intf_clk_div; }; /** @@ -563,7 +566,7 @@ struct dsi_cmd_engine_cfg { * @common_config: Host configuration common to both Video and Cmd mode. * @video_engine: Video engine configuration if panel is in video mode. * @cmd_engine: Cmd engine configuration if panel is in cmd mode. - * @esc_clk_rate_khz: Esc clock frequency in Hz. + * @esc_clk_rate_hz: Esc clock frequency in Hz. * @bit_clk_rate_hz: Bit clock frequency in Hz. * @bit_clk_rate_hz_override: DSI bit clk rate override from dt/sysfs. * @video_timing: Video timing information of a frame. diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c index 5022317f89f2..6d0864d92525 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2340,6 +2340,28 @@ error: return rc; } +static int dsi_display_phy_idle_pc(struct dsi_display *display, + bool idle_pc_enabled) +{ + struct dsi_display_ctrl *ctrl; + int i, rc = 0; + + display_for_each_ctrl(i, display) { + ctrl = &display->ctrl[i]; + if (!ctrl->phy) + continue; + + rc = dsi_phy_set_idle_pc(ctrl->phy, idle_pc_enabled); + if (rc) { + pr_err("[%s] Failed to set idle pc, rc=%d\n", + ctrl->ctrl->name, rc); + goto error; + } + } +error: + return rc; +} + static int dsi_display_set_clk_src(struct dsi_display *display, bool on) { int rc = 0; @@ -2347,20 +2369,6 @@ static int dsi_display_set_clk_src(struct dsi_display *display, bool on) struct dsi_display_ctrl *m_ctrl, *ctrl; struct dsi_clk_link_set *src; - /* - * For CPHY mode, the parent of mux_clks need to be set - * to Cphy_clks to have correct dividers for byte and - * pixel clocks. - */ - if (display->panel->host_config.phy_type == DSI_PHY_TYPE_CPHY) { - rc = dsi_clk_update_parent(&display->clock_info.cphy_clks, - &display->clock_info.mux_clks); - if (rc) { - pr_err("failed update mux parent to CPHY\n"); - return rc; - } - } - /* if XO clk is defined, select XO clk src when DSI is disabled */ if (on) src = &display->clock_info.mux_clks; @@ -3074,14 +3082,12 @@ static int dsi_display_clocks_init(struct dsi_display *display) const char *clk_name; const char *src_byte = "src_byte", *src_pixel = "src_pixel"; const char *mux_byte = "mux_byte", *mux_pixel = "mux_pixel"; - const char *cphy_byte = "cphy_byte", *cphy_pixel = "cphy_pixel"; const char *shadow_byte = "shadow_byte", *shadow_pixel = "shadow_pixel"; const char *shadow_cphybyte = "shadow_cphybyte", *shadow_cphypixel = "shadow_cphypixel"; struct clk *dsi_clk; struct dsi_clk_link_set *src = &display->clock_info.src_clks; struct dsi_clk_link_set *mux = &display->clock_info.mux_clks; - struct dsi_clk_link_set *cphy = &display->clock_info.cphy_clks; struct dsi_clk_link_set *shadow = &display->clock_info.shadow_clks; struct dsi_clk_link_set *shadow_cphy = &display->clock_info.shadow_cphy_clks; @@ -3116,15 +3122,6 @@ static int dsi_display_clocks_init(struct dsi_display *display) goto error; } - if (dsi_display_check_prefix(cphy_byte, clk_name)) { - cphy->byte_clk = NULL; - goto error; - } - if (dsi_display_check_prefix(cphy_pixel, clk_name)) { - cphy->pixel_clk = NULL; - goto error; - } - if (dyn_clk_caps->dyn_clk_support && (display->panel->panel_mode == DSI_OP_VIDEO_MODE)) { @@ -3162,16 +3159,6 @@ static int dsi_display_clocks_init(struct dsi_display *display) continue; } - if (dsi_display_check_prefix(cphy_byte, clk_name)) { - cphy->byte_clk = dsi_clk; - continue; - } - - if (dsi_display_check_prefix(cphy_pixel, clk_name)) { - cphy->pixel_clk = dsi_clk; - continue; - } - if (dsi_display_check_prefix(mux_byte, clk_name)) { mux->byte_clk = dsi_clk; continue; @@ -3524,6 +3511,12 @@ int dsi_pre_clkon_cb(void *priv, pr_debug("%s: Enable DSI core power\n", __func__); } + if ((clk_type & DSI_LINK_CLK) && (new_state == DSI_CLK_ON) && + !display->is_cont_splash_enabled) { + /* Enabling LINK clocks: disable PHY idle power collapse */ + dsi_display_phy_idle_pc(display, false); + } + return rc; } @@ -3787,8 +3780,6 @@ static int dsi_display_res_init(struct dsi_display *display) phy->cfg.force_clk_lane_hs = display->panel->host_config.force_hs_clk_lane; - phy->cfg.phy_type = - display->panel->host_config.phy_type; } rc = dsi_display_parse_lane_map(display); @@ -3961,6 +3952,22 @@ static bool dsi_display_is_seamless_dfps_possible( return true; } +void dsi_display_update_byte_intf_div(struct dsi_display *display) +{ + struct dsi_host_common_cfg *config; + struct dsi_display_ctrl *m_ctrl; + int phy_ver; + + m_ctrl = &display->ctrl[display->cmd_master_idx]; + config = &display->panel->host_config; + + phy_ver = dsi_phy_get_version(m_ctrl->phy); + if (phy_ver <= DSI_PHY_VERSION_2_0) + config->byte_intf_clk_div = 1; + else + config->byte_intf_clk_div = 2; +} + static int dsi_display_update_dsi_bitrate(struct dsi_display *display, u32 bit_clk_rate) { @@ -3983,10 +3990,9 @@ static int dsi_display_update_dsi_bitrate(struct dsi_display *display, display_for_each_ctrl(i, display) { struct dsi_display_ctrl *dsi_disp_ctrl = &display->ctrl[i]; struct dsi_ctrl *ctrl = dsi_disp_ctrl->ctrl; - u32 num_of_lanes = 0, bpp; + u32 num_of_lanes = 0, bpp, byte_intf_clk_div; u64 bit_rate, pclk_rate, bit_rate_per_lane, byte_clk_rate, - byte_intf_clk_rate; - u32 bits_per_symbol = 16, num_of_symbols = 7; /* For Cphy */ + byte_intf_clk_rate; struct dsi_host_common_cfg *host_cfg; mutex_lock(&ctrl->ctrl_lock); @@ -4010,31 +4016,22 @@ static int dsi_display_update_dsi_bitrate(struct dsi_display *display, bpp = dsi_pixel_format_to_bpp(host_cfg->dst_format); bit_rate = display->config.bit_clk_rate_hz * num_of_lanes; - + bit_rate_per_lane = bit_rate; + do_div(bit_rate_per_lane, num_of_lanes); pclk_rate = bit_rate; do_div(pclk_rate, bpp); - if (host_cfg->phy_type == DSI_PHY_TYPE_DPHY) { - bit_rate_per_lane = bit_rate; - do_div(bit_rate_per_lane, num_of_lanes); - byte_clk_rate = bit_rate_per_lane; - do_div(byte_clk_rate, 8); - byte_intf_clk_rate = byte_clk_rate; - do_div(byte_intf_clk_rate, 2); - } else { - bit_rate_per_lane = bit_clk_rate; - pclk_rate *= bits_per_symbol; - do_div(pclk_rate, num_of_symbols); - byte_clk_rate = bit_clk_rate; - do_div(byte_clk_rate, num_of_symbols); - /* For CPHY, byte_intf_clk is same as byte_clk */ - byte_intf_clk_rate = byte_clk_rate; - } + byte_clk_rate = bit_rate_per_lane; + do_div(byte_clk_rate, 8); + byte_intf_clk_rate = byte_clk_rate; + byte_intf_clk_div = host_cfg->byte_intf_clk_div; + do_div(byte_intf_clk_rate, byte_intf_clk_div); pr_debug("bit_clk_rate = %llu, bit_clk_rate_per_lane = %llu\n", bit_rate, bit_rate_per_lane); - pr_debug("byte_clk_rate = %llu, byte_intf_clk_rate = %llu\n", - byte_clk_rate, byte_intf_clk_rate); - pr_debug("pclk_rate = %llu\n", pclk_rate); + pr_debug("bit_clk_rate = %llu, byte_intf_clk_rate = %llu\n", + bit_rate, byte_intf_clk_rate); + pr_debug("byte_clk_rate = %llu, pclk_rate = %llu\n", + byte_clk_rate, pclk_rate); ctrl->clk_freq.byte_clk_rate = byte_clk_rate; ctrl->clk_freq.byte_intf_clk_rate = byte_intf_clk_rate; @@ -4068,18 +4065,19 @@ static void _dsi_display_calc_pipe_delay(struct dsi_display *display, struct dsi_display_ctrl *m_ctrl; struct dsi_ctrl *dsi_ctrl; struct dsi_phy_cfg *cfg; + int phy_ver; m_ctrl = &display->ctrl[display->clk_master_idx]; dsi_ctrl = m_ctrl->ctrl; cfg = &(m_ctrl->phy->cfg); - esc_clk_rate_hz = dsi_ctrl->clk_freq.esc_clk_rate * 1000; - pclk_to_esc_ratio = ((dsi_ctrl->clk_freq.pix_clk_rate * 1000) / + esc_clk_rate_hz = dsi_ctrl->clk_freq.esc_clk_rate; + pclk_to_esc_ratio = (dsi_ctrl->clk_freq.pix_clk_rate / esc_clk_rate_hz); - byte_to_esc_ratio = ((dsi_ctrl->clk_freq.byte_clk_rate * 1000) / + byte_to_esc_ratio = (dsi_ctrl->clk_freq.byte_clk_rate / esc_clk_rate_hz); - hr_bit_to_esc_ratio = ((dsi_ctrl->clk_freq.byte_clk_rate * 4 * 1000) / + hr_bit_to_esc_ratio = ((dsi_ctrl->clk_freq.byte_clk_rate * 4) / esc_clk_rate_hz); hsync_period = DSI_H_TOTAL_DSC(&mode->timing); @@ -4105,8 +4103,17 @@ static void _dsi_display_calc_pipe_delay(struct dsi_display *display, ((cfg->timing.lane_v3[4] >> 1) + 1)) / hr_bit_to_esc_ratio); - /* 130 us pll delay recommended by h/w doc */ - delay->pll_delay = ((130 * esc_clk_rate_hz) / 1000000) * 2; + /* + * 100us pll delay recommended for phy ver 2.0 and 3.0 + * 25us pll delay recommended for phy ver 4.0 + */ + phy_ver = dsi_phy_get_version(m_ctrl->phy); + if (phy_ver <= DSI_PHY_VERSION_3_0) + delay->pll_delay = 100; + else + delay->pll_delay = 25; + + delay->pll_delay = ((delay->pll_delay * esc_clk_rate_hz) / 1000000); } static int _dsi_display_dyn_update_clks(struct dsi_display *display, @@ -4215,8 +4222,8 @@ recover_byte_clk: if (!ctrl->ctrl) continue; dsi_clk_set_byte_clk_rate(display->dsi_clk_handle, - bkp_freq->byte_clk_rate, - bkp_freq->byte_intf_clk_rate, i); + bkp_freq->byte_clk_rate, + bkp_freq->byte_intf_clk_rate, i); } exit: @@ -5429,6 +5436,7 @@ static int dsi_display_bind(struct device *dev, } } + dsi_display_update_byte_intf_div(display); rc = dsi_display_mipi_host_init(display); if (rc) { pr_err("[%s] failed to initialize mipi host, rc=%d\n", diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h index dc86e3f3dbdd..677e3776010a 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h @@ -121,7 +121,6 @@ struct dsi_display_boot_param { struct dsi_display_clk_info { struct dsi_clk_link_set src_clks; struct dsi_clk_link_set mux_clks; - struct dsi_clk_link_set cphy_clks; struct dsi_clk_link_set shadow_clks; struct dsi_clk_link_set shadow_cphy_clks; struct dsi_clk_link_set xo_clks; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index 561aa6d02413..51c17039b35c 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -1319,7 +1319,6 @@ static int dsi_panel_parse_misc_host_config(struct dsi_host_common_cfg *host, { u32 val = 0; int rc = 0; - bool panel_cphy_mode = false; rc = utils->read_u32(utils->data, "qcom,mdss-dsi-t-clk-post", &val); if (!rc) { @@ -1334,6 +1333,9 @@ static int dsi_panel_parse_misc_host_config(struct dsi_host_common_cfg *host, pr_debug("[%s] t_clk_pre = %d\n", name, val); } + host->t_clk_pre_extend = utils->read_bool(utils->data, + "qcom,mdss-dsi-t-clk-pre-extend"); + host->ignore_rx_eot = utils->read_bool(utils->data, "qcom,mdss-dsi-rx-eot-ignore"); @@ -1342,11 +1344,6 @@ static int dsi_panel_parse_misc_host_config(struct dsi_host_common_cfg *host, host->force_hs_clk_lane = utils->read_bool(utils->data, "qcom,mdss-dsi-force-clock-lane-hs"); - panel_cphy_mode = utils->read_bool(utils->data, - "qcom,panel-cphy-mode"); - host->phy_type = panel_cphy_mode ? DSI_PHY_TYPE_CPHY - : DSI_PHY_TYPE_DPHY; - return 0; } @@ -2192,7 +2189,8 @@ static int dsi_panel_parse_misc_features(struct dsi_panel *panel) pr_info("%s: ulps feature %s\n", __func__, (panel->ulps_feature_enabled ? "enabled" : "disabled")); - panel->ulps_suspend_enabled = true; + panel->ulps_suspend_enabled = + utils->read_bool(utils->data, "qcom,suspend-ulps-enabled"); pr_info("%s: ulps during suspend feature %s", __func__, (panel->ulps_suspend_enabled ? "enabled" : "disabled")); @@ -3353,7 +3351,7 @@ int dsi_panel_parse_esd_reg_read_configs(struct dsi_panel *panel) } esd_config->status_value = - kzalloc(sizeof(u32) * status_len * esd_config->groups, + kzalloc(array3_size(sizeof(u32), status_len, esd_config->groups), GFP_KERNEL); if (!esd_config->status_value) { rc = -ENOMEM; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_parser.c b/drivers/gpu/drm/msm/dsi-staging/dsi_parser.c index c66824ee2259..d6e743754da7 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_parser.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_parser.c @@ -254,7 +254,7 @@ static bool dsi_parser_parse_prop(struct device *dev, if (dsi_parser_get_strings(dev, prop, buf)) goto end; - prop->items = devm_kzalloc(dev, strlen(buf) * 2, GFP_KERNEL); + prop->items = devm_kcalloc(dev, strlen(buf), 2, GFP_KERNEL); if (!prop->items) goto end; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c index fddb34745a76..0abbfdbae161 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c @@ -103,6 +103,11 @@ static const struct of_device_id msm_dsi_phy_of_match[] = { {} }; +int dsi_phy_get_version(struct msm_dsi_phy *phy) +{ + return phy->ver_info->version; +} + static int dsi_phy_regmap_init(struct platform_device *pdev, struct msm_dsi_phy *phy) { @@ -755,6 +760,28 @@ error: return rc; } +int dsi_phy_set_idle_pc(struct msm_dsi_phy *dsi_phy, bool idle_pc_enabled) +{ + int rc = 0; + + if (!dsi_phy) { + pr_err("PHY is NULL!!!\n"); + return -EINVAL; + } + + /* If PHY does not require special IdlePC handling, go out early */ + if (!dsi_phy->hw.ops.set_idle_pc) + return 0; + + mutex_lock(&dsi_phy->phy_lock); + + dsi_phy->hw.ops.set_idle_pc(&dsi_phy->hw, idle_pc_enabled); + + mutex_unlock(&dsi_phy->phy_lock); + + return rc; +} + static int dsi_phy_enable_ulps(struct msm_dsi_phy *phy, struct dsi_host_config *config, bool clamp_enabled) { diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.h b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.h index 5282dbf631ce..203d6c0a8fb0 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.h @@ -129,6 +129,14 @@ struct msm_dsi_phy *dsi_phy_get(struct device_node *of_node); */ void dsi_phy_put(struct msm_dsi_phy *dsi_phy); +/** + * dsi_phy_get_version() - returns dsi phy version + * @dsi_phy: DSI PHY handle. + * + * Return: phy version + */ +int dsi_phy_get_version(struct msm_dsi_phy *phy); + /** * dsi_phy_drv_init() - initialize dsi phy driver * @dsi_phy: DSI PHY handle. @@ -171,6 +179,12 @@ int dsi_phy_validate_mode(struct msm_dsi_phy *dsi_phy, */ int dsi_phy_set_power_state(struct msm_dsi_phy *dsi_phy, bool enable); +/** + * dsi_phy_set_idle_pc() - set/unset idle dsi phy idle power collapse + * + */ +int dsi_phy_set_idle_pc(struct msm_dsi_phy *dsi_phy, bool idle_pc_enabled); + /** * dsi_phy_enable() - enable DSI PHY hardware * @dsi_phy: DSI PHY handle. diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw.h b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw.h index e1353631361e..e95a4e370b6a 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw.h @@ -96,7 +96,6 @@ struct dsi_phy_per_lane_cfgs { * @lane_map: DSI logical to PHY lane mapping. * @lane_pnswap: P/N swap status on each lane. * @force_clk_lane_hs:Boolean whether to force clock lane in HS mode. - * @phy_type: Phy-type (Dphy/Cphy). * @bit_clk_rate_hz: DSI bit clk rate in HZ. */ struct dsi_phy_cfg { @@ -109,7 +108,6 @@ struct dsi_phy_cfg { struct dsi_lane_map lane_map; u8 lane_pnswap; bool force_clk_lane_hs; - enum dsi_phy_type phy_type; unsigned long bit_clk_rate_hz; }; @@ -265,6 +263,12 @@ struct dsi_phy_hw_ops { */ void (*phy_idle_off)(struct dsi_phy_hw *phy); + /** + * set_idle_pc() - Enter/exit PHY idle power collapse + */ + + void (*set_idle_pc)(struct dsi_phy_hw *phy, bool idle_pc_enabled); + /** * calculate_timing_params() - calculates timing parameters. * @phy: Pointer to DSI PHY hardware object. diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v3_0.c b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v3_0.c index ca19bf454573..18d479557e75 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v3_0.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v3_0.c @@ -176,40 +176,7 @@ static void dsi_phy_hw_v3_0_lane_swap_config(struct dsi_phy_hw *phy, (lane_map->lane_map_v2[DSI_LOGICAL_LANE_3] << 4))); } -static void dsi_phy_hw_v3_0_cphy_lane_settings(struct dsi_phy_hw *phy, - struct dsi_phy_cfg *cfg) -{ - int i; - - /* Strength ctrl settings */ - for (i = DSI_LOGICAL_LANE_0; i < DSI_LOGICAL_LANE_3; i++) { - DSI_W32(phy, DSIPHY_LNX_LPTX_STR_CTRL(i), - cfg->strength.lane[i][0]); - /* - * Disable LPRX and CDRX for all lanes. And later on, it will - * be only enabled for the physical data lane corresponding - * to the logical data lane 0 - */ - DSI_W32(phy, DSIPHY_LNX_LPRX_CTRL(i), 0); - DSI_W32(phy, DSIPHY_LNX_PIN_SWAP(i), 0x0); - DSI_W32(phy, DSIPHY_LNX_HSTX_STR_CTRL(i), 0x88); - } - dsi_phy_hw_v3_0_config_lpcdrx(phy, cfg, true); - - /* other settings */ - for (i = DSI_LOGICAL_LANE_0; i < DSI_LOGICAL_LANE_3; i++) { - DSI_W32(phy, DSIPHY_LNX_CFG0(i), cfg->lanecfg.lane[i][0]); - DSI_W32(phy, DSIPHY_LNX_CFG1(i), cfg->lanecfg.lane[i][1]); - DSI_W32(phy, DSIPHY_LNX_CFG2(i), cfg->lanecfg.lane[i][2]); - DSI_W32(phy, DSIPHY_LNX_CFG3(i), 0x0A); - DSI_W32(phy, DSIPHY_LNX_OFFSET_TOP_CTRL(i), 0x0); - DSI_W32(phy, DSIPHY_LNX_OFFSET_BOT_CTRL(i), 0x0); - } - - DSI_W32(phy, DSIPHY_LNX_TX_DCTRL(3), 0x02); -} - -static void dsi_phy_hw_v3_0_dphy_lane_settings(struct dsi_phy_hw *phy, +static void dsi_phy_hw_v3_0_lane_settings(struct dsi_phy_hw *phy, struct dsi_phy_cfg *cfg) { int i; @@ -267,83 +234,60 @@ void dsi_phy_hw_v3_0_clamp_ctrl(struct dsi_phy_hw *phy, bool enable) wmb(); /* Ensure that the freezeio bit is toggled */ } -/** - * cphy_enable() - Enable CPHY hardware - * @phy: Pointer to DSI PHY hardware object. - * @cfg: Per lane configurations for timing, strength and lane - * configurations. - */ -static void dsi_phy_hw_cphy_enable(struct dsi_phy_hw *phy, - struct dsi_phy_cfg *cfg) +void dsi_phy_hw_v3_0_set_idle_pc(struct dsi_phy_hw *phy, bool idle_pc_enabled) { - struct dsi_phy_per_lane_cfgs *timing = &cfg->timing; - u32 data; + u32 reg; - /* de-assert digital and pll power down */ - data = BIT(6) | BIT(5); - DSI_W32(phy, DSIPHY_CMN_CTRL_0, data); + pr_debug("PHY: %s idle power collapse\n", + idle_pc_enabled ? "Enabling" : "Disabling"); - /* Assert PLL core reset */ - DSI_W32(phy, DSIPHY_CMN_PLL_CNTRL, 0x00); + /* Does SDM845 support PHY idle power collapse, or just FreezeIO? */ + if (!of_machine_is_compatible("qcom,msm8998")) + return; - /* turn off resync FIFO */ - DSI_W32(phy, DSIPHY_CMN_RBUF_CTRL, 0x00); - - DSI_W32(phy, DSIPHY_CMN_GLBL_CTRL, 0x40); - - /* Enable LDO */ - DSI_W32(phy, DSIPHY_CMN_VREG_CTRL, 0x59); - - /* Configure PHY lane swap */ - dsi_phy_hw_v3_0_lane_swap_config(phy, &cfg->lane_map); - - /* DSI PHY timings */ - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_0, timing->lane_v3[0]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_4, timing->lane_v3[4]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_5, timing->lane_v3[5]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_6, timing->lane_v3[6]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_7, timing->lane_v3[7]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_8, timing->lane_v3[8]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_9, timing->lane_v3[9]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_10, timing->lane_v3[10]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_11, timing->lane_v3[11]); - - /* Remove power down from all blocks */ - DSI_W32(phy, DSIPHY_CMN_CTRL_0, 0x7f); - - DSI_W32(phy, DSIPHY_CMN_LANE_CTRL0, 0x07); - - switch (cfg->pll_source) { - case DSI_PLL_SOURCE_STANDALONE: - case DSI_PLL_SOURCE_NATIVE: - data = 0x0; /* internal PLL */ - break; - case DSI_PLL_SOURCE_NON_NATIVE: - data = 0x1; /* external PLL */ - break; - default: - break; + if (idle_pc_enabled) { + pr_err("PHY: Enable idlepc not supported\n"); + return; } - DSI_W32(phy, DSIPHY_CMN_CLK_CFG1, (data << 2)); /* set PLL src */ - /* DSI lane settings */ - dsi_phy_hw_v3_0_cphy_lane_settings(phy, cfg); + reg = DSI_R32(phy, DSIPHY_CMN_CTRL_1); + DSI_W32(phy, DSIPHY_CMN_CTRL_1, reg | BIT(5)); + wmb(); + usleep_range(10, 15); - pr_debug("[DSI_%d]C-Phy enabled ", phy->index); + reg = DSI_R32(phy, DSIPHY_CMN_CTRL_1); + reg &= ~(BIT(5)); + DSI_W32(phy, DSIPHY_CMN_CTRL_1, reg); + wmb(); } - /** - * dphy_enable() - Enable DPHY hardware + * enable() - Enable PHY hardware * @phy: Pointer to DSI PHY hardware object. * @cfg: Per lane configurations for timing, strength and lane * configurations. */ -static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy, +void dsi_phy_hw_v3_0_enable(struct dsi_phy_hw *phy, struct dsi_phy_cfg *cfg) { + int rc = 0; + u32 status; + u32 const delay_us = 5; + u32 const timeout_us = 1000; struct dsi_phy_per_lane_cfgs *timing = &cfg->timing; u32 data; + + if (dsi_phy_hw_v3_0_is_pll_on(phy)) + pr_warn("PLL turned on before configuring PHY\n"); + + /* wait for REFGEN READY */ + rc = readl_poll_timeout_atomic(phy->base + DSIPHY_CMN_PHY_STATUS, + status, (status & BIT(0)), delay_us, timeout_us); + if (rc) { + pr_err("Ref gen not ready. Aborting\n"); + return; + } + /* de-assert digital and pll power down */ data = BIT(6) | BIT(5); DSI_W32(phy, DSIPHY_CMN_CTRL_0, data); @@ -404,40 +348,9 @@ static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy, DSI_W32(phy, DSIPHY_CMN_CLK_CFG1, (data << 2)); /* set PLL src */ /* DSI lane settings */ - dsi_phy_hw_v3_0_dphy_lane_settings(phy, cfg); - - pr_debug("[DSI_%d]D-Phy enabled", phy->index); -} - -/** - * enable() - Enable PHY hardware - * @phy: Pointer to DSI PHY hardware object. - * @cfg: Per lane configurations for timing, strength and lane - * configurations. - */ -void dsi_phy_hw_v3_0_enable(struct dsi_phy_hw *phy, - struct dsi_phy_cfg *cfg) -{ - int rc = 0; - u32 status; - u32 const delay_us = 5; - u32 const timeout_us = 1000; - - if (dsi_phy_hw_v3_0_is_pll_on(phy)) - pr_warn("PLL turned on before configuring PHY\n"); - - /* wait for REFGEN READY */ - rc = readl_poll_timeout_atomic(phy->base + DSIPHY_CMN_PHY_STATUS, - status, (status & BIT(0)), delay_us, timeout_us); - if (rc) { - pr_err("Ref gen not ready. Aborting\n"); - return; - } - if (cfg->phy_type == DSI_PHY_TYPE_CPHY) - dsi_phy_hw_cphy_enable(phy, cfg); - else /* Default PHY type is DPHY */ - dsi_phy_hw_dphy_enable(phy, cfg); + dsi_phy_hw_v3_0_lane_settings(phy, cfg); + pr_debug("[DSI_%d]Phy enabled ", phy->index); } /** @@ -590,6 +503,8 @@ void dsi_phy_hw_v3_0_ulps_exit(struct dsi_phy_hw *phy, * to be in stop state. */ DSI_W32(phy, DSIPHY_CMN_LANE_CTRL3, reg); + usleep_range(5, 15); + DSI_W32(phy, DSIPHY_CMN_LANE_CTRL3, 0); usleep_range(100, 110); } diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v4_0.c b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v4_0.c index f76d5459bb1d..b0db818ce39d 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v4_0.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v4_0.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -144,98 +144,21 @@ static void dsi_phy_hw_v4_0_lane_settings(struct dsi_phy_hw *phy, (cfg->lane_pnswap >> i) & 0x1); } - if (cfg->phy_type == DSI_PHY_TYPE_CPHY) - DSI_W32(phy, DSIPHY_LNX_TX_DCTRL(3), 0x02); - } /** - * cphy_enable() - Enable CPHY hardware + * enable() - Enable PHY hardware * @phy: Pointer to DSI PHY hardware object. * @cfg: Per lane configurations for timing, strength and lane * configurations. */ -static void dsi_phy_hw_cphy_enable(struct dsi_phy_hw *phy, - struct dsi_phy_cfg *cfg) -{ - struct dsi_phy_per_lane_cfgs *timing = &cfg->timing; - u32 data; - /* For C-PHY, no low power settings for lower clk rate */ - u32 vreg_ctrl_0 = 0x5A; - u32 glbl_str_swi_cal_sel_ctrl = 0x03; - u32 glbl_hstx_str_ctrl_0 = 0x66; - - /* de-assert digital and pll power down */ - data = BIT(6) | BIT(5); - DSI_W32(phy, DSIPHY_CMN_CTRL_0, data); - - /* Assert PLL core reset */ - DSI_W32(phy, DSIPHY_CMN_PLL_CNTRL, 0x00); - - /* turn off resync FIFO */ - DSI_W32(phy, DSIPHY_CMN_RBUF_CTRL, 0x00); - - /* Configure PHY lane swap */ - dsi_phy_hw_v4_0_lane_swap_config(phy, &cfg->lane_map); - - DSI_W32(phy, DSIPHY_CMN_GLBL_CTRL, BIT(6)); - - /* Enable LDO */ - DSI_W32(phy, DSIPHY_CMN_VREG_CTRL_0, vreg_ctrl_0); - DSI_W32(phy, DSIPHY_CMN_VREG_CTRL_1, 0x5c); - - DSI_W32(phy, DSIPHY_CMN_GLBL_STR_SWI_CAL_SEL_CTRL, - glbl_str_swi_cal_sel_ctrl); - DSI_W32(phy, DSIPHY_CMN_GLBL_HSTX_STR_CTRL_0, glbl_hstx_str_ctrl_0); - DSI_W32(phy, DSIPHY_CMN_GLBL_PEMPH_CTRL_0, 0x00); - DSI_W32(phy, DSIPHY_CMN_GLBL_RESCODE_OFFSET_TOP_CTRL, 0x03); - DSI_W32(phy, DSIPHY_CMN_GLBL_RESCODE_OFFSET_BOT_CTRL, 0x3c); - DSI_W32(phy, DSIPHY_CMN_GLBL_LPTX_STR_CTRL, 0x55); - - /* Remove power down from all blocks */ - DSI_W32(phy, DSIPHY_CMN_CTRL_0, 0x7f); - - DSI_W32(phy, DSIPHY_CMN_LANE_CTRL0, 0x17); - - switch (cfg->pll_source) { - case DSI_PLL_SOURCE_STANDALONE: - case DSI_PLL_SOURCE_NATIVE: - data = 0x0; /* internal PLL */ - break; - case DSI_PLL_SOURCE_NON_NATIVE: - data = 0x1; /* external PLL */ - break; - default: - break; - } - DSI_W32(phy, DSIPHY_CMN_CLK_CFG1, (data << 2)); /* set PLL src */ - - /* DSI PHY timings */ - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_0, timing->lane_v4[0]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_4, timing->lane_v4[4]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_5, timing->lane_v4[5]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_6, timing->lane_v4[6]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_7, timing->lane_v4[7]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_8, timing->lane_v4[8]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_9, timing->lane_v4[9]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_10, timing->lane_v4[10]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_11, timing->lane_v4[11]); - - /* DSI lane settings */ - dsi_phy_hw_v4_0_lane_settings(phy, cfg); - - pr_debug("[DSI_%d] C-Phy enabled ", phy->index); -} - -/** - * dphy_enable() - Enable DPHY hardware - * @phy: Pointer to DSI PHY hardware object. - * @cfg: Per lane configurations for timing, strength and lane - * configurations. - */ -static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy, +void dsi_phy_hw_v4_0_enable(struct dsi_phy_hw *phy, struct dsi_phy_cfg *cfg) { + int rc = 0; + u32 status; + u32 const delay_us = 5; + u32 const timeout_us = 1000; struct dsi_phy_per_lane_cfgs *timing = &cfg->timing; u32 data; bool less_than_1500_mhz = false; @@ -243,6 +166,17 @@ static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy, u32 glbl_str_swi_cal_sel_ctrl = 0; u32 glbl_hstx_str_ctrl_0 = 0; + if (dsi_phy_hw_v4_0_is_pll_on(phy)) + pr_warn("PLL turned on before configuring PHY\n"); + + /* wait for REFGEN READY */ + rc = readl_poll_timeout_atomic(phy->base + DSIPHY_CMN_PHY_STATUS, + status, (status & BIT(0)), delay_us, timeout_us); + if (rc) { + pr_err("Ref gen not ready. Aborting\n"); + return; + } + /* Alter PHY configurations if data rate less than 1.5GHZ*/ if (cfg->bit_clk_rate_hz < 1500000000) less_than_1500_mhz = true; @@ -266,7 +200,6 @@ static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy, /* Enable LDO */ DSI_W32(phy, DSIPHY_CMN_VREG_CTRL_0, vreg_ctrl_0); DSI_W32(phy, DSIPHY_CMN_VREG_CTRL_1, 0x5c); - DSI_W32(phy, DSIPHY_CMN_CTRL_3, 0x00); DSI_W32(phy, DSIPHY_CMN_GLBL_STR_SWI_CAL_SEL_CTRL, glbl_str_swi_cal_sel_ctrl); @@ -316,39 +249,7 @@ static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy, /* DSI lane settings */ dsi_phy_hw_v4_0_lane_settings(phy, cfg); - pr_debug("[DSI_%d] D-Phy enabled ", phy->index); -} - -/** - * enable() - Enable PHY hardware - * @phy: Pointer to DSI PHY hardware object. - * @cfg: Per lane configurations for timing, strength and lane - * configurations. - */ -void dsi_phy_hw_v4_0_enable(struct dsi_phy_hw *phy, - struct dsi_phy_cfg *cfg) -{ - int rc = 0; - u32 status; - u32 const delay_us = 5; - u32 const timeout_us = 1000; - - if (dsi_phy_hw_v4_0_is_pll_on(phy)) - pr_warn("PLL turned on before configuring PHY\n"); - - /* wait for REFGEN READY */ - rc = readl_poll_timeout_atomic(phy->base + DSIPHY_CMN_PHY_STATUS, - status, (status & BIT(0)), delay_us, timeout_us); - if (rc) { - pr_err("Ref gen not ready. Aborting\n"); - return; - } - - if (cfg->phy_type == DSI_PHY_TYPE_CPHY) - dsi_phy_hw_cphy_enable(phy, cfg); - else /* Default PHY type is DPHY */ - dsi_phy_hw_dphy_enable(phy, cfg); - + pr_debug("[DSI_%d]Phy enabled ", phy->index); } /** diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index f3509e723c0f..eb53bb9db219 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -157,8 +157,10 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev) hdmi->qfprom_mmio = NULL; } - hdmi->hpd_regs = devm_kzalloc(&pdev->dev, sizeof(hdmi->hpd_regs[0]) * - config->hpd_reg_cnt, GFP_KERNEL); + hdmi->hpd_regs = devm_kcalloc(&pdev->dev, + config->hpd_reg_cnt, + sizeof(hdmi->hpd_regs[0]), + GFP_KERNEL); if (!hdmi->hpd_regs) { ret = -ENOMEM; goto fail; @@ -178,8 +180,10 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev) hdmi->hpd_regs[i] = reg; } - hdmi->pwr_regs = devm_kzalloc(&pdev->dev, sizeof(hdmi->pwr_regs[0]) * - config->pwr_reg_cnt, GFP_KERNEL); + hdmi->pwr_regs = devm_kcalloc(&pdev->dev, + config->pwr_reg_cnt, + sizeof(hdmi->pwr_regs[0]), + GFP_KERNEL); if (!hdmi->pwr_regs) { ret = -ENOMEM; goto fail; @@ -199,8 +203,10 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev) hdmi->pwr_regs[i] = reg; } - hdmi->hpd_clks = devm_kzalloc(&pdev->dev, sizeof(hdmi->hpd_clks[0]) * - config->hpd_clk_cnt, GFP_KERNEL); + hdmi->hpd_clks = devm_kcalloc(&pdev->dev, + config->hpd_clk_cnt, + sizeof(hdmi->hpd_clks[0]), + GFP_KERNEL); if (!hdmi->hpd_clks) { ret = -ENOMEM; goto fail; @@ -219,8 +225,10 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev) hdmi->hpd_clks[i] = clk; } - hdmi->pwr_clks = devm_kzalloc(&pdev->dev, sizeof(hdmi->pwr_clks[0]) * - config->pwr_clk_cnt, GFP_KERNEL); + hdmi->pwr_clks = devm_kcalloc(&pdev->dev, + config->pwr_clk_cnt, + sizeof(hdmi->pwr_clks[0]), + GFP_KERNEL); if (!hdmi->pwr_clks) { ret = -ENOMEM; goto fail; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c index 534ce5b49781..16987d8679e0 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c @@ -21,12 +21,12 @@ static int msm_hdmi_phy_resource_init(struct hdmi_phy *phy) struct device *dev = &phy->pdev->dev; int i, ret; - phy->regs = devm_kzalloc(dev, sizeof(phy->regs[0]) * cfg->num_regs, + phy->regs = devm_kcalloc(dev, cfg->num_regs, sizeof(phy->regs[0]), GFP_KERNEL); if (!phy->regs) return -ENOMEM; - phy->clks = devm_kzalloc(dev, sizeof(phy->clks[0]) * cfg->num_clks, + phy->clks = devm_kcalloc(dev, cfg->num_clks, sizeof(phy->clks[0]), GFP_KERNEL); if (!phy->clks) return -ENOMEM; diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 16d0edb68a09..42c47cb27229 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -725,8 +725,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) } dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); - msm_gem_shrinker_init(ddev); - switch (get_mdp_ver(pdev)) { case KMS_MDP4: kms = mdp4_kms_init(ddev); @@ -945,7 +943,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) } drm_kms_helper_poll_init(ddev); - place_marker("M - DISPLAY Driver Ready"); return 0; diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 032d9d43c012..c0d439c9ec6d 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c index 5338ec08ce93..624ab85b32f0 100644 --- a/drivers/gpu/drm/msm/sde/sde_connector.c +++ b/drivers/gpu/drm/msm/sde/sde_connector.c @@ -1254,7 +1254,7 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector, if (idx == CONNECTOR_PROP_HDR_METADATA) { rc = _sde_connector_set_ext_hdr_info(c_conn, - c_state, (void *)(uintptr_t)val); + c_state, (void __user *)(uintptr_t)val); if (rc) SDE_ERROR_CONN(c_conn, "cannot set hdr info %d\n", rc); } diff --git a/drivers/gpu/drm/msm/sde/sde_core_irq.c b/drivers/gpu/drm/msm/sde/sde_core_irq.c index b082778a4590..2fe931e12c32 100644 --- a/drivers/gpu/drm/msm/sde/sde_core_irq.c +++ b/drivers/gpu/drm/msm/sde/sde_core_irq.c @@ -44,8 +44,6 @@ static void sde_core_irq_callback_handler(void *arg, int irq_idx) &sde_kms->irq_obj.enable_counts[irq_idx]); } - atomic_inc(&irq_obj->irq_counts[irq_idx]); - /* * Perform registered function callback */ @@ -72,15 +70,6 @@ static void sde_core_irq_callback_handler(void *arg, int irq_idx) SDE_EVT32_IRQ(irq_idx, enable_counts, SDE_EVTLOG_ERROR); } } - - /* - * Clear pending interrupt status in HW. - * NOTE: sde_core_irq_callback_handler is protected by top-level - * spinlock, so it is safe to clear any interrupt status here. - */ - sde_kms->hw_intr->ops.clear_intr_status_nolock( - sde_kms->hw_intr, - irq_idx); } int sde_core_irq_idx_lookup(struct sde_kms *sde_kms, @@ -105,8 +94,7 @@ static int _sde_core_irq_enable(struct sde_kms *sde_kms, int irq_idx) int ret = 0; if (!sde_kms || !sde_kms->hw_intr || - !sde_kms->irq_obj.enable_counts || - !sde_kms->irq_obj.irq_counts) { + !sde_kms->irq_obj.enable_counts) { SDE_ERROR("invalid params\n"); return -EINVAL; } @@ -412,15 +400,14 @@ static int sde_debugfs_core_irq_show(struct seq_file *s, void *v) for (i = 0; i < irq_obj->total_irqs; i++) { spin_lock_irqsave(&irq_obj->cb_lock, irq_flags); cb_count = 0; - irq_count = atomic_read(&irq_obj->irq_counts[i]); enable_count = atomic_read(&irq_obj->enable_counts[i]); list_for_each_entry(cb, &irq_obj->irq_cb_tbl[i], list) cb_count++; spin_unlock_irqrestore(&irq_obj->cb_lock, irq_flags); if (irq_count || enable_count || cb_count) - seq_printf(s, "idx:%d irq:%d enable:%d cb:%d\n", - i, irq_count, enable_count, cb_count); + seq_printf(s, "idx:%d enable:%d cb:%d\n", + i, enable_count, cb_count); } return 0; @@ -494,10 +481,7 @@ void sde_core_irq_preinstall(struct sde_kms *sde_kms) sizeof(struct list_head), GFP_KERNEL); sde_kms->irq_obj.enable_counts = kcalloc(sde_kms->irq_obj.total_irqs, sizeof(atomic_t), GFP_KERNEL); - sde_kms->irq_obj.irq_counts = kcalloc(sde_kms->irq_obj.total_irqs, - sizeof(atomic_t), GFP_KERNEL); - if (!sde_kms->irq_obj.irq_cb_tbl || !sde_kms->irq_obj.enable_counts - || !sde_kms->irq_obj.irq_counts) + if (!sde_kms->irq_obj.irq_cb_tbl || !sde_kms->irq_obj.enable_counts) return; for (i = 0; i < sde_kms->irq_obj.total_irqs; i++) { @@ -505,8 +489,6 @@ void sde_core_irq_preinstall(struct sde_kms *sde_kms) INIT_LIST_HEAD(&sde_kms->irq_obj.irq_cb_tbl[i]); if (sde_kms->irq_obj.enable_counts) atomic_set(&sde_kms->irq_obj.enable_counts[i], 0); - if (sde_kms->irq_obj.irq_counts) - atomic_set(&sde_kms->irq_obj.irq_counts[i], 0); } } @@ -554,10 +536,8 @@ void sde_core_irq_uninstall(struct sde_kms *sde_kms) spin_lock_irqsave(&sde_kms->irq_obj.cb_lock, irq_flags); kfree(sde_kms->irq_obj.irq_cb_tbl); kfree(sde_kms->irq_obj.enable_counts); - kfree(sde_kms->irq_obj.irq_counts); sde_kms->irq_obj.irq_cb_tbl = NULL; sde_kms->irq_obj.enable_counts = NULL; - sde_kms->irq_obj.irq_counts = NULL; sde_kms->irq_obj.total_irqs = 0; spin_unlock_irqrestore(&sde_kms->irq_obj.cb_lock, irq_flags); } @@ -661,15 +641,6 @@ int sde_core_irq_domain_fini(struct sde_kms *sde_kms) irqreturn_t sde_core_irq(struct sde_kms *sde_kms) { - /* - * Read interrupt status from all sources. Interrupt status are - * stored within hw_intr. - * Function will also clear the interrupt status after reading. - * Individual interrupt status bit will only get stored if it - * is enabled. - */ - sde_kms->hw_intr->ops.get_interrupt_statuses(sde_kms->hw_intr); - /* * Dispatch to HW driver to handle interrupt lookup that is being * fired. When matching interrupt is located, HW driver will call to diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c index dd280942e08c..176ccac24fd1 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.c +++ b/drivers/gpu/drm/msm/sde/sde_crtc.c @@ -2872,7 +2872,7 @@ void sde_crtc_prepare_commit(struct drm_crtc *crtc, struct sde_crtc_state *cstate; struct drm_connector *conn; struct drm_encoder *encoder; - struct drm_connector_list_iter conn_iter; + int i; if (!crtc || !crtc->state) { SDE_ERROR("invalid crtc\n"); @@ -2886,24 +2886,16 @@ void sde_crtc_prepare_commit(struct drm_crtc *crtc, SDE_ATRACE_BEGIN("sde_crtc_prepare_commit"); - /* identify connectors attached to this crtc */ - cstate->num_connectors = 0; - - drm_connector_list_iter_begin(dev, &conn_iter); - drm_for_each_connector_iter(conn, &conn_iter) - if (conn->state && conn->state->crtc == crtc && - cstate->num_connectors < MAX_CONNECTORS) { - encoder = conn->state->best_encoder; - if (encoder) - sde_encoder_register_frame_event_callback( - encoder, - sde_crtc_frame_event_cb, - crtc); - - cstate->connectors[cstate->num_connectors++] = conn; - sde_connector_prepare_fence(conn); - } - drm_connector_list_iter_end(&conn_iter); + for (i = 0; i < cstate->num_connectors; i++) { + conn = cstate->connectors[i]; + encoder = conn->state->best_encoder; + if (encoder) + sde_encoder_register_frame_event_callback( + encoder, + sde_crtc_frame_event_cb, + crtc); + sde_connector_prepare_fence(conn); + } /* prepare main output fence */ sde_fence_prepare(sde_crtc->output_fence); @@ -3761,9 +3753,9 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc, return; } - if (!crtc->state->enable) { - SDE_DEBUG("crtc%d -> enable %d, skip atomic_begin\n", - crtc->base.id, crtc->state->enable); + if (!crtc->state->active) { + SDE_DEBUG("crtc%d -> active %d, skip atomic_begin\n", + crtc->base.id, crtc->state->active); return; } diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.h b/drivers/gpu/drm/msm/sde/sde_crtc.h index 6d0031b083b1..d86fb58e01cf 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.h +++ b/drivers/gpu/drm/msm/sde/sde_crtc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c index 79361a65f36a..64a2556161a6 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder.c @@ -5516,14 +5516,21 @@ struct drm_encoder *sde_encoder_init_with_ops( if (phys->ops.is_master && phys->ops.is_master(phys)) intf_index = phys->intf_idx - INTF_0; } - snprintf(name, SDE_NAME_SIZE, "rsc_enc%u", drm_enc->base.id); - sde_enc->rsc_client = sde_rsc_client_create(SDE_RSC_INDEX, name, - disp_info->is_primary ? SDE_RSC_PRIMARY_DISP_CLIENT : - SDE_RSC_EXTERNAL_DISP_CLIENT, intf_index + 1); - if (IS_ERR_OR_NULL(sde_enc->rsc_client)) { - SDE_DEBUG("sde rsc client create failed :%ld\n", - PTR_ERR(sde_enc->rsc_client)); - sde_enc->rsc_client = NULL; + /* + * if phy is inited from external, we'll let external drivers to + * create rsc client if needed. + */ + if (!sde_enc->ops.phys_init) { + snprintf(name, SDE_NAME_SIZE, "rsc_enc%u", drm_enc->base.id); + sde_enc->rsc_client = + sde_rsc_client_create(SDE_RSC_INDEX, name, + disp_info->is_primary ? SDE_RSC_PRIMARY_DISP_CLIENT : + SDE_RSC_EXTERNAL_DISP_CLIENT, intf_index + 1); + if (IS_ERR_OR_NULL(sde_enc->rsc_client)) { + SDE_DEBUG("sde rsc client create failed :%ld\n", + PTR_ERR(sde_enc->rsc_client)); + sde_enc->rsc_client = NULL; + } } if (disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) { diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.h b/drivers/gpu/drm/msm/sde/sde_encoder.h index edb546064ef1..eb0415ed5553 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder.h +++ b/drivers/gpu/drm/msm/sde/sde_encoder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h index 55b63480d731..5c1ef9614127 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h +++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c index 4b8f7024990e..1e50e8ff76ee 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c index 34ebe8d2503d..0f73d4c7bf42 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c index 2e81e31288b0..12164d37f186 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog.c b/drivers/gpu/drm/msm/sde/sde_hw_catalog.c index 155645567ce2..b25e352bc16b 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_catalog.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog.c @@ -1411,9 +1411,9 @@ static int sde_sspp_parse_dt(struct device_node *np, if (snp) { dgm_count = of_get_child_count(snp); if (dgm_count > 0 && dgm_count <= SSPP_SUBBLK_COUNT_MAX) { - dgm_prop_value = kzalloc(dgm_count * DMA_PROP_MAX * - sizeof(struct sde_prop_value), - GFP_KERNEL); + dgm_prop_value = kcalloc(dgm_count * DMA_PROP_MAX, + sizeof(struct sde_prop_value), + GFP_KERNEL); if (!dgm_prop_value) { rc = -ENOMEM; goto end; @@ -1564,8 +1564,8 @@ static int sde_ctl_parse_dt(struct device_node *np, goto end; } - prop_value = kzalloc(HW_PROP_MAX * - sizeof(struct sde_prop_value), GFP_KERNEL); + prop_value = kcalloc(HW_PROP_MAX, sizeof(struct sde_prop_value), + GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; @@ -1597,7 +1597,8 @@ static int sde_ctl_parse_dt(struct device_node *np, ctl_prop[HW_DISP].prop_name, i, &disp_pref); if (disp_pref && !strcmp(disp_pref, "primary")) set_bit(SDE_CTL_PRIMARY_PREF, &ctl->features); - if (i < MAX_SPLIT_DISPLAY_CTL) + if ((i < MAX_SPLIT_DISPLAY_CTL) && + !(IS_SDE_CTL_REV_100(sde_cfg->ctl_rev))) set_bit(SDE_CTL_SPLIT_DISPLAY, &ctl->features); if (i < MAX_PP_SPLIT_DISPLAY_CTL) set_bit(SDE_CTL_PINGPONG_SPLIT, &ctl->features); @@ -1661,9 +1662,9 @@ static int sde_mixer_parse_dt(struct device_node *np, /* get mixer feature dt properties if they exist */ snp = of_get_child_by_name(np, mixer_prop[MIXER_BLOCKS].prop_name); if (snp) { - blocks_prop_value = kzalloc(MIXER_BLOCKS_PROP_MAX * - MAX_SDE_HW_BLK * sizeof(struct sde_prop_value), - GFP_KERNEL); + blocks_prop_value = kcalloc(MIXER_BLOCKS_PROP_MAX * MAX_SDE_HW_BLK, + sizeof(struct sde_prop_value), + GFP_KERNEL); if (!blocks_prop_value) { rc = -ENOMEM; goto end; @@ -1679,8 +1680,9 @@ static int sde_mixer_parse_dt(struct device_node *np, } /* get the blend_op register offsets */ - blend_prop_value = kzalloc(MIXER_BLEND_PROP_MAX * - sizeof(struct sde_prop_value), GFP_KERNEL); + blend_prop_value = kcalloc(MIXER_BLEND_PROP_MAX, + sizeof(struct sde_prop_value), + GFP_KERNEL); if (!blend_prop_value) { rc = -ENOMEM; goto end; @@ -1802,8 +1804,8 @@ static int sde_intf_parse_dt(struct device_node *np, goto end; } - prop_value = kzalloc(INTF_PROP_MAX * - sizeof(struct sde_prop_value), GFP_KERNEL); + prop_value = kcalloc(INTF_PROP_MAX, sizeof(struct sde_prop_value), + GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; @@ -1885,8 +1887,8 @@ static int sde_wb_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) goto end; } - prop_value = kzalloc(WB_PROP_MAX * - sizeof(struct sde_prop_value), GFP_KERNEL); + prop_value = kcalloc(WB_PROP_MAX, sizeof(struct sde_prop_value), + GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; @@ -2259,8 +2261,8 @@ static int sde_dspp_top_parse_dt(struct device_node *np, goto end; } - prop_value = kzalloc(DSPP_TOP_PROP_MAX * - sizeof(struct sde_prop_value), GFP_KERNEL); + prop_value = kcalloc(DSPP_TOP_PROP_MAX, sizeof(struct sde_prop_value), + GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; @@ -2314,8 +2316,8 @@ static int sde_dspp_parse_dt(struct device_node *np, goto end; } - prop_value = kzalloc(DSPP_PROP_MAX * - sizeof(struct sde_prop_value), GFP_KERNEL); + prop_value = kcalloc(DSPP_PROP_MAX, sizeof(struct sde_prop_value), + GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; @@ -2352,9 +2354,9 @@ static int sde_dspp_parse_dt(struct device_node *np, /* get DSPP feature dt properties if they exist */ snp = of_get_child_by_name(np, dspp_prop[DSPP_BLOCKS].prop_name); if (snp) { - blocks_prop_value = kzalloc(DSPP_BLOCKS_PROP_MAX * - MAX_SDE_HW_BLK * sizeof(struct sde_prop_value), - GFP_KERNEL); + blocks_prop_value = kcalloc(DSPP_BLOCKS_PROP_MAX * MAX_SDE_HW_BLK, + sizeof(struct sde_prop_value), + GFP_KERNEL); if (!blocks_prop_value) { rc = -ENOMEM; goto end; @@ -2432,8 +2434,9 @@ static int sde_ds_parse_dt(struct device_node *np, } /* Parse the dest scaler top register offset and capabilities */ - top_prop_value = kzalloc(DS_TOP_PROP_MAX * - sizeof(struct sde_prop_value), GFP_KERNEL); + top_prop_value = kcalloc(DS_TOP_PROP_MAX, + sizeof(struct sde_prop_value), + GFP_KERNEL); if (!top_prop_value) { rc = -ENOMEM; goto end; @@ -2537,8 +2540,8 @@ static int sde_dsc_parse_dt(struct device_node *np, goto end; } - prop_value = kzalloc(DSC_PROP_MAX * - sizeof(struct sde_prop_value), GFP_KERNEL); + prop_value = kcalloc(DSC_PROP_MAX, sizeof(struct sde_prop_value), + GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; @@ -2591,8 +2594,8 @@ static int sde_cdm_parse_dt(struct device_node *np, goto end; } - prop_value = kzalloc(HW_PROP_MAX * - sizeof(struct sde_prop_value), GFP_KERNEL); + prop_value = kcalloc(HW_PROP_MAX, sizeof(struct sde_prop_value), + GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; @@ -2647,8 +2650,8 @@ static int sde_vbif_parse_dt(struct device_node *np, goto end; } - prop_value = kzalloc(VBIF_PROP_MAX * - sizeof(struct sde_prop_value), GFP_KERNEL); + prop_value = kcalloc(VBIF_PROP_MAX, sizeof(struct sde_prop_value), + GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; @@ -2860,8 +2863,8 @@ static int sde_pp_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) goto end; } - prop_value = kzalloc(PP_PROP_MAX * - sizeof(struct sde_prop_value), GFP_KERNEL); + prop_value = kcalloc(PP_PROP_MAX, sizeof(struct sde_prop_value), + GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; @@ -3066,8 +3069,9 @@ static int sde_limit_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) goto end; } - sde_limit_value = kzalloc(cfg->limit_count * LIMIT_PROP_MAX * - sizeof(struct sde_prop_value), GFP_KERNEL); + sde_limit_value = kcalloc(cfg->limit_count * LIMIT_PROP_MAX, + sizeof(struct sde_prop_value), + GFP_KERNEL); if (!sde_limit_value) { rc = -ENOMEM; goto end; @@ -3102,8 +3106,8 @@ static int sde_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) goto end; } - prop_value = kzalloc(SDE_PROP_MAX * - sizeof(struct sde_prop_value), GFP_KERNEL); + prop_value = kcalloc(SDE_PROP_MAX, sizeof(struct sde_prop_value), + GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; @@ -3328,8 +3332,8 @@ static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) goto end; } - prop_value = kzalloc(PERF_PROP_MAX * - sizeof(struct sde_prop_value), GFP_KERNEL); + prop_value = kcalloc(PERF_PROP_MAX, sizeof(struct sde_prop_value), + GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; @@ -3694,8 +3698,8 @@ static int sde_qdss_parse_dt(struct device_node *np, goto end; } - prop_value = kzalloc(HW_PROP_MAX * - sizeof(struct sde_prop_value), GFP_KERNEL); + prop_value = kcalloc(HW_PROP_MAX, sizeof(struct sde_prop_value), + GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; diff --git a/drivers/gpu/drm/msm/sde/sde_hw_ctl.c b/drivers/gpu/drm/msm/sde/sde_hw_ctl.c index 53efad2778e1..d5818034653f 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_ctl.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_ctl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and diff --git a/drivers/gpu/drm/msm/sde/sde_hw_ctl.h b/drivers/gpu/drm/msm/sde/sde_hw_ctl.h index e1ee9f89c7e6..6c7d293f7839 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_ctl.h +++ b/drivers/gpu/drm/msm/sde/sde_hw_ctl.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and diff --git a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c b/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c index c34aed434dca..d6b4f8a462fc 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c @@ -880,13 +880,17 @@ static void sde_hw_intr_dispatch_irq(struct sde_hw_intr *intr, return; /* - * The dispatcher will save the IRQ status before calling here. * Now need to go through each IRQ status and find matching * irq lookup index. */ spin_lock_irqsave(&intr->irq_lock, irq_flags); for (reg_idx = 0; reg_idx < intr->sde_irq_size; reg_idx++) { - irq_status = intr->save_irq_status[reg_idx]; + /* Read interrupt status */ + irq_status = SDE_REG_READ(&intr->hw, + intr->sde_irq_tbl[reg_idx].status_off); + + if (!irq_status) + continue; /* get the global offset in 'sde_irq_map' */ sde_irq_idx = intr->sde_irq_tbl[reg_idx].sde_irq_idx; @@ -912,20 +916,13 @@ static void sde_hw_intr_dispatch_irq(struct sde_hw_intr *intr, for (irq_idx = start_idx; (irq_idx < end_idx) && irq_status; irq_idx++) - if ((irq_status & sde_irq_map[irq_idx].irq_mask) && - (sde_irq_map[irq_idx].reg_idx == reg_idx)) { + if (irq_status & sde_irq_map[irq_idx].irq_mask) { /* * Once a match on irq mask, perform a callback - * to the given cbfunc. cbfunc will take care - * the interrupt status clearing. If cbfunc is - * not provided, then the interrupt clearing - * is here. + * to the given cbfunc. */ if (cbfunc) cbfunc(arg, irq_idx); - else - intr->ops.clear_intr_status_nolock( - intr, irq_idx); /* * When callback finish, clear the irq_status @@ -934,7 +931,15 @@ static void sde_hw_intr_dispatch_irq(struct sde_hw_intr *intr, */ irq_status &= ~sde_irq_map[irq_idx].irq_mask; } + + /* Clear the interrupt */ + SDE_REG_WRITE(&intr->hw, intr->sde_irq_tbl[reg_idx].clr_off, + 0xffffffff); } + + /* ensure register writes go through */ + wmb(); + spin_unlock_irqrestore(&intr->irq_lock, irq_flags); } @@ -1115,40 +1120,6 @@ static int sde_hw_intr_get_interrupt_sources(struct sde_hw_intr *intr, return 0; } -static void sde_hw_intr_get_interrupt_statuses(struct sde_hw_intr *intr) -{ - int i; - u32 enable_mask; - unsigned long irq_flags; - - if (!intr) - return; - - spin_lock_irqsave(&intr->irq_lock, irq_flags); - for (i = 0; i < intr->sde_irq_size; i++) { - /* Read interrupt status */ - intr->save_irq_status[i] = SDE_REG_READ(&intr->hw, - intr->sde_irq_tbl[i].status_off); - - /* Read enable mask */ - enable_mask = SDE_REG_READ(&intr->hw, - intr->sde_irq_tbl[i].en_off); - - /* and clear the interrupt */ - if (intr->save_irq_status[i]) - SDE_REG_WRITE(&intr->hw, intr->sde_irq_tbl[i].clr_off, - intr->save_irq_status[i]); - - /* Finally update IRQ status based on enable mask */ - intr->save_irq_status[i] &= enable_mask; - } - - /* ensure register writes go through */ - wmb(); - - spin_unlock_irqrestore(&intr->irq_lock, irq_flags); -} - static void sde_hw_intr_clear_intr_status_force_mask(struct sde_hw_intr *intr, int irq_idx, u32 irq_mask) { @@ -1321,7 +1292,6 @@ static void __setup_intr_ops(struct sde_hw_intr_ops *ops) ops->disable_all_irqs = sde_hw_intr_disable_irqs; ops->get_valid_interrupts = sde_hw_intr_get_valid_interrupts; ops->get_interrupt_sources = sde_hw_intr_get_interrupt_sources; - ops->get_interrupt_statuses = sde_hw_intr_get_interrupt_statuses; ops->clear_interrupt_status = sde_hw_intr_clear_interrupt_status; ops->clear_intr_status_nolock = sde_hw_intr_clear_intr_status_nolock; ops->clear_intr_status_force_mask = @@ -1469,7 +1439,6 @@ void sde_hw_intr_destroy(struct sde_hw_intr *intr) if (intr) { kfree(intr->sde_irq_tbl); kfree(intr->cache_irq_mask); - kfree(intr->save_irq_status); kfree(intr); } } @@ -1578,13 +1547,6 @@ struct sde_hw_intr *sde_hw_intr_init(void __iomem *addr, goto exit; } - intr->save_irq_status = kcalloc(intr->sde_irq_size, sizeof(u32), - GFP_KERNEL); - if (intr->save_irq_status == NULL) { - ret = -ENOMEM; - goto exit; - } - spin_lock_init(&intr->irq_lock); return intr; @@ -1592,7 +1554,6 @@ struct sde_hw_intr *sde_hw_intr_init(void __iomem *addr, exit: kfree(intr->sde_irq_tbl); kfree(intr->cache_irq_mask); - kfree(intr->save_irq_status); kfree(intr); return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.h b/drivers/gpu/drm/msm/sde/sde_hw_interrupts.h index 1d5a8427d0aa..e2de0e33bd59 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.h +++ b/drivers/gpu/drm/msm/sde/sde_hw_interrupts.h @@ -188,14 +188,6 @@ struct sde_hw_intr_ops { void (*cbfunc)(void *arg, int irq_idx), void *arg); - /** - * get_interrupt_statuses - Gets and store value from all interrupt - * status registers that are currently fired. - * @intr: HW interrupt handle - */ - void (*get_interrupt_statuses)( - struct sde_hw_intr *intr); - /** * clear_interrupt_status - Clears HW interrupt status based on given * lookup IRQ index. @@ -292,7 +284,6 @@ struct sde_hw_intr_ops { * @hw: virtual address mapping * @ops: function pointer mapping for IRQ handling * @cache_irq_mask: array of IRQ enable masks reg storage created during init - * @save_irq_status: array of IRQ status reg storage created during init * @irq_idx_tbl_size: total number of irq_idx mapped in the hw_interrupts * @irq_lock: spinlock for accessing IRQ resources * @sde_irq_size: total number of elements of the sde_irq_tbl @@ -303,7 +294,6 @@ struct sde_hw_intr { struct sde_hw_blk_reg_map hw; struct sde_hw_intr_ops ops; u32 *cache_irq_mask; - u32 *save_irq_status; u32 irq_idx_tbl_size; u32 sde_irq_size; struct sde_intr_reg *sde_irq_tbl; diff --git a/drivers/gpu/drm/msm/sde/sde_hw_intf.c b/drivers/gpu/drm/msm/sde/sde_hw_intf.c index b88d4b525db2..21b671164786 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_intf.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_intf.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and diff --git a/drivers/gpu/drm/msm/sde/sde_hw_mdss.h b/drivers/gpu/drm/msm/sde/sde_hw_mdss.h index 145da74946f2..bd3ef45df834 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_mdss.h +++ b/drivers/gpu/drm/msm/sde/sde_hw_mdss.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and diff --git a/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c b/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c index e76943052102..b7a48e08508d 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c @@ -1944,7 +1944,7 @@ static int reg_dmav1_setup_vig_igc_common(struct sde_hw_reg_dma_ops *dma_ops, hw_cfg->len, sizeof(struct drm_msm_igc_lut)); } - data = kzalloc(VIG_1D_LUT_IGC_LEN * sizeof(u32), GFP_KERNEL); + data = kcalloc(VIG_1D_LUT_IGC_LEN, sizeof(u32), GFP_KERNEL); if (!data) return -ENOMEM; @@ -2205,7 +2205,7 @@ void reg_dmav1_setup_dma_igcv5(struct sde_hw_pipe *ctx, void *cfg, return; } - data = kzalloc(DMA_1D_LUT_IGC_LEN * sizeof(u32), GFP_KERNEL); + data = kcalloc(DMA_1D_LUT_IGC_LEN, sizeof(u32), GFP_KERNEL); if (!data) { DRM_ERROR("failed to allocate memory for igc\n"); return; diff --git a/drivers/gpu/drm/msm/sde/sde_hw_rot.c b/drivers/gpu/drm/msm/sde/sde_hw_rot.c index 24c6a3a15141..f627d2d5822b 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_rot.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_rot.c @@ -749,8 +749,8 @@ static const struct sde_format_extended *sde_hw_rot_get_format_caps( sde_rotator_inline_get_pixfmt_caps(pdev, true, v4l_pixfmts, len); /* allocate one more to indicate termination */ - drm_pixfmts = kzalloc((len + 1) * sizeof(struct sde_format_extended), - GFP_KERNEL); + drm_pixfmts = kcalloc(len + 1, sizeof(struct sde_format_extended), + GFP_KERNEL); if (!drm_pixfmts) goto done; diff --git a/drivers/gpu/drm/msm/sde/sde_hw_sspp.c b/drivers/gpu/drm/msm/sde/sde_hw_sspp.c index 35b1e099fcbe..ca3608040f1c 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_sspp.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_sspp.c @@ -220,7 +220,10 @@ static void sde_hw_sspp_setup_multirect(struct sde_hw_pipe *ctx, mode_mask = 0; } else { mode_mask = SDE_REG_READ(&ctx->hw, SSPP_MULTIRECT_OPMODE + idx); - mode_mask |= index; + if (mode == SDE_SSPP_MULTIRECT_NONE) + mode_mask |= index; + else + mode_mask |= SDE_SSPP_RECT_MAX; if (mode == SDE_SSPP_MULTIRECT_TIME_MX) mode_mask |= BIT(2); else diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c index d8765b0c1531..4c717c80d9e8 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.c +++ b/drivers/gpu/drm/msm/sde/sde_kms.c @@ -1235,7 +1235,7 @@ static void sde_kms_prepare_fence(struct msm_kms *kms, { struct drm_crtc *crtc; struct drm_crtc_state *old_crtc_state; - int i, rc; + int i; if (!kms || !old_state || !old_state->dev || !old_state->acquire_ctx) { SDE_ERROR("invalid argument(s)\n"); @@ -1243,15 +1243,6 @@ static void sde_kms_prepare_fence(struct msm_kms *kms, } SDE_ATRACE_BEGIN("sde_kms_prepare_fence"); -retry: - /* attempt to acquire ww mutex for connection */ - rc = drm_modeset_lock(&old_state->dev->mode_config.connection_mutex, - old_state->acquire_ctx); - - if (rc == -EDEADLK) { - drm_modeset_backoff(old_state->acquire_ctx); - goto retry; - } /* old_state actually contains updated crtc pointers */ for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) { @@ -2768,11 +2759,11 @@ retry: crtc_state->active = true; ret = drm_atomic_set_crtc_for_connector(conn_state, enc->crtc); if (ret) - goto end; + SDE_ERROR("error %d setting the crtc\n", ret); ret = drm_atomic_commit(state); - if (ret != -EDEADLK) - goto end; + if (ret) + SDE_ERROR("Error %d doing the atomic commit\n", ret); end: if (state) diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h index 3c011d10fd71..38d3e1d45052 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.h +++ b/drivers/gpu/drm/msm/sde/sde_kms.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -202,7 +202,6 @@ struct sde_irq { u32 total_irqs; struct list_head *irq_cb_tbl; atomic_t *enable_counts; - atomic_t *irq_counts; spinlock_t cb_lock; struct dentry *debugfs_file; }; diff --git a/drivers/gpu/drm/msm/sde_power_handle.c b/drivers/gpu/drm/msm/sde_power_handle.c index 2e5f4179a70e..59ead5d82bf1 100644 --- a/drivers/gpu/drm/msm/sde_power_handle.c +++ b/drivers/gpu/drm/msm/sde_power_handle.c @@ -164,8 +164,9 @@ static int sde_power_parse_dt_supply(struct platform_device *pdev, } pr_debug("vreg found. count=%d\n", mp->num_vreg); - mp->vreg_config = devm_kzalloc(&pdev->dev, sizeof(struct dss_vreg) * - mp->num_vreg, GFP_KERNEL); + mp->vreg_config = devm_kcalloc(&pdev->dev, + mp->num_vreg, sizeof(struct dss_vreg), + GFP_KERNEL); if (!mp->vreg_config) { rc = -ENOMEM; return rc; @@ -299,8 +300,8 @@ static int sde_power_parse_dt_clock(struct platform_device *pdev, } mp->num_clk = num_clk; - mp->clk_config = devm_kzalloc(&pdev->dev, - sizeof(struct dss_clk) * num_clk, GFP_KERNEL); + mp->clk_config = devm_kcalloc(&pdev->dev, + num_clk, sizeof(struct dss_clk), GFP_KERNEL); if (!mp->clk_config) { rc = -ENOMEM; mp->num_clk = 0; diff --git a/drivers/gpu/drm/msm/shp/shp_drm.c b/drivers/gpu/drm/msm/shp/shp_drm.c index d2b3ecebf9fb..2a27d1799bb2 100644 --- a/drivers/gpu/drm/msm/shp/shp_drm.c +++ b/drivers/gpu/drm/msm/shp/shp_drm.c @@ -428,8 +428,8 @@ static int shp_parse(struct platform_device *pdev, struct shp_device *shp) system_count = priv->num_planes; total_count = dup_count + system_count; - shp->planes = devm_kzalloc(&pdev->dev, - sizeof(*shp_plane) * total_count, GFP_KERNEL); + shp->planes = devm_kcalloc(&pdev->dev, + total_count, sizeof(*shp_plane), GFP_KERNEL); if (!shp->planes) { rc = -ENOMEM; goto out; diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c index bd7a8a1e4ad9..4f70573163ad 100644 --- a/drivers/gpu/drm/nouveau/nv84_fence.c +++ b/drivers/gpu/drm/nouveau/nv84_fence.c @@ -155,7 +155,7 @@ nv84_fence_suspend(struct nouveau_drm *drm) struct nv84_fence_priv *priv = drm->fence; int i; - priv->suspend = vmalloc(priv->base.contexts * sizeof(u32)); + priv->suspend = vmalloc(array_size(sizeof(u32), priv->base.contexts)); if (priv->suspend) { for (i = 0; i < priv->base.contexts; i++) priv->suspend[i] = nouveau_bo_rd32(priv->bo, i*4); diff --git a/drivers/gpu/drm/nouveau/nvif/object.c b/drivers/gpu/drm/nouveau/nvif/object.c index c3fb6a20f567..cd399bcdc3b3 100644 --- a/drivers/gpu/drm/nouveau/nvif/object.c +++ b/drivers/gpu/drm/nouveau/nvif/object.c @@ -83,7 +83,7 @@ nvif_object_sclass_get(struct nvif_object *object, struct nvif_sclass **psclass) return ret; } - *psclass = kzalloc(sizeof(**psclass) * args->sclass.count, GFP_KERNEL); + *psclass = kcalloc(args->sclass.count, sizeof(**psclass), GFP_KERNEL); if (*psclass) { for (i = 0; i < args->sclass.count; i++) { (*psclass)[i].oclass = args->sclass.oclass[i].oclass; diff --git a/drivers/gpu/drm/nouveau/nvkm/core/event.c b/drivers/gpu/drm/nouveau/nvkm/core/event.c index 4e8d3fa042df..5e44bbb74177 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/event.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/event.c @@ -84,7 +84,7 @@ int nvkm_event_init(const struct nvkm_event_func *func, int types_nr, int index_nr, struct nvkm_event *event) { - event->refs = kzalloc(sizeof(*event->refs) * index_nr * types_nr, + event->refs = kzalloc(array3_size(index_nr, types_nr, sizeof(*event->refs)), GFP_KERNEL); if (!event->refs) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/core/ramht.c b/drivers/gpu/drm/nouveau/nvkm/core/ramht.c index 89da47234016..9031f0ea0081 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/ramht.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/ramht.c @@ -143,8 +143,7 @@ nvkm_ramht_new(struct nvkm_device *device, u32 size, u32 align, struct nvkm_ramht *ramht; int ret, i; - if (!(ramht = *pramht = vzalloc(sizeof(*ramht) + - (size >> 3) * sizeof(*ramht->data)))) + if (!(ramht = *pramht = vzalloc(struct_size(ramht, data, (size >> 3))))) return -ENOMEM; ramht->device = device; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index 0b632dc0cf7d..c1919901ad5a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -781,7 +781,7 @@ gk104_fifo_oneinit(struct nvkm_fifo *base) nvkm_debug(subdev, "%d PBDMA(s)\n", fifo->pbdma_nr); /* Read PBDMA->runlist(s) mapping from HW. */ - if (!(map = kzalloc(sizeof(*map) * fifo->pbdma_nr, GFP_KERNEL))) + if (!(map = kcalloc(fifo->pbdma_nr, sizeof(*map), GFP_KERNEL))) return -ENOMEM; for (i = 0; i < fifo->pbdma_nr; i++) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c index dde89a4a0f5b..be89ad80b0f5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c @@ -779,8 +779,8 @@ nvkm_perfdom_new(struct nvkm_pm *pm, const char *name, u32 mask, sdom = spec; while (sdom->signal_nr) { - dom = kzalloc(sizeof(*dom) + sdom->signal_nr * - sizeof(*dom->signal), GFP_KERNEL); + dom = kzalloc(struct_size(dom, signal, sdom->signal_nr), + GFP_KERNEL); if (!dom) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c index 23caef8df17f..12b5046ac475 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c @@ -73,7 +73,8 @@ nvbios_iccsense_parse(struct nvkm_bios *bios, struct nvbios_iccsense *iccsense) } iccsense->nr_entry = cnt; - iccsense->rail = kmalloc(sizeof(struct pwr_rail_t) * cnt, GFP_KERNEL); + iccsense->rail = kmalloc_array(cnt, sizeof(struct pwr_rail_t), + GFP_KERNEL); if (!iccsense->rail) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c index f10664372161..0cf2098b3ebe 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c @@ -170,7 +170,7 @@ gt215_link_train(struct gt215_ram *ram) return -ENOSYS; /* XXX: Multiple partitions? */ - result = kmalloc(64 * sizeof(u32), GFP_KERNEL); + result = kmalloc_array(64, sizeof(u32), GFP_KERNEL); if (!result) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index 455da298227f..5f70de882ed2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -382,7 +382,7 @@ nvkm_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, vm->fpde = offset >> (mmu->func->pgt_bits + 12); vm->lpde = (offset + length - 1) >> (mmu->func->pgt_bits + 12); - vm->pgt = vzalloc((vm->lpde - vm->fpde + 1) * sizeof(*vm->pgt)); + vm->pgt = vzalloc(array_size(sizeof(*vm->pgt), (vm->lpde - vm->fpde + 1))); if (!vm->pgt) { kfree(vm); return -ENOMEM; diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c index 32901c6fe3df..46d2621b988e 100644 --- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c +++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c @@ -939,8 +939,8 @@ int tiler_map_show(struct seq_file *s, void *arg) h_adj = omap_dmm->container_height / ydiv; w_adj = omap_dmm->container_width / xdiv; - map = kmalloc(h_adj * sizeof(*map), GFP_KERNEL); - global_map = kmalloc((w_adj + 1) * h_adj, GFP_KERNEL); + map = kmalloc_array(h_adj, sizeof(*map), GFP_KERNEL); + global_map = kmalloc_array(w_adj + 1, h_adj, GFP_KERNEL); if (!map || !global_map) goto error; diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index 5c5c86ddd6f4..45252fe1cb05 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -246,7 +246,7 @@ static int omap_gem_attach_pages(struct drm_gem_object *obj) * DSS, GPU, etc. are not cache coherent: */ if (omap_obj->flags & (OMAP_BO_WC|OMAP_BO_UNCACHED)) { - addrs = kmalloc(npages * sizeof(*addrs), GFP_KERNEL); + addrs = kmalloc_array(npages, sizeof(*addrs), GFP_KERNEL); if (!addrs) { ret = -ENOMEM; goto free_pages; @@ -270,7 +270,7 @@ static int omap_gem_attach_pages(struct drm_gem_object *obj) } } } else { - addrs = kzalloc(npages * sizeof(*addrs), GFP_KERNEL); + addrs = kcalloc(npages, sizeof(*addrs), GFP_KERNEL); if (!addrs) { ret = -ENOMEM; goto free_pages; diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c index 844c4a31ca13..70dfb847ab71 100644 --- a/drivers/gpu/drm/qxl/qxl_fb.c +++ b/drivers/gpu/drm/qxl/qxl_fb.c @@ -243,7 +243,7 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, QXL_INFO(qdev, "%s: %dx%d %d\n", __func__, mode_cmd.width, mode_cmd.height, mode_cmd.pitches[0]); - shadow = vmalloc(mode_cmd.pitches[0] * mode_cmd.height); + shadow = vmalloc(array_size(mode_cmd.pitches[0], mode_cmd.height)); /* TODO: what's the usual response to memory allocation errors? */ BUG_ON(!shadow); QXL_INFO(qdev, diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index 20ca0a75e685..2412d317d992 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c @@ -200,8 +200,8 @@ int qxl_device_init(struct qxl_device *qdev, (~(uint64_t)0) >> (qdev->slot_id_bits + qdev->slot_gen_bits); qdev->mem_slots = - kmalloc(qdev->n_mem_slots * sizeof(struct qxl_memslot), - GFP_KERNEL); + kmalloc_array(qdev->n_mem_slots, sizeof(struct qxl_memslot), + GFP_KERNEL); idr_init(&qdev->release_idr); spin_lock_init(&qdev->release_idr_lock); diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 6a2e091aa7b6..e55cbeee7a53 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -1176,7 +1176,7 @@ static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32 ectx.abort = false; ectx.last_jump = 0; if (ws) - ectx.ws = kzalloc(4 * ws, GFP_KERNEL); + ectx.ws = kcalloc(4, ws, GFP_KERNEL); else ectx.ws = NULL; diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c index 95652e643da1..0aef4937c901 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.c +++ b/drivers/gpu/drm/radeon/btc_dpm.c @@ -2581,7 +2581,9 @@ int btc_dpm_init(struct radeon_device *rdev) return ret; rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries = - kzalloc(4 * sizeof(struct radeon_clock_voltage_dependency_entry), GFP_KERNEL); + kcalloc(4, + sizeof(struct radeon_clock_voltage_dependency_entry), + GFP_KERNEL); if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) { r600_free_extended_power_table(rdev); return -ENOMEM; diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 6e607cc7b6e5..cfbf0fa36a21 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -5546,8 +5546,9 @@ static int ci_parse_power_table(struct radeon_device *rdev) (mode_info->atom_context->bios + data_offset + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); - rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) * - state_array->ucNumEntries, GFP_KERNEL); + rdev->pm.dpm.ps = kcalloc(state_array->ucNumEntries, + sizeof(struct radeon_ps), + GFP_KERNEL); if (!rdev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; @@ -5747,7 +5748,9 @@ int ci_dpm_init(struct radeon_device *rdev) ci_set_private_data_variables_based_on_pptable(rdev); rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries = - kzalloc(4 * sizeof(struct radeon_clock_voltage_dependency_entry), GFP_KERNEL); + kcalloc(4, + sizeof(struct radeon_clock_voltage_dependency_entry), + GFP_KERNEL); if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) { ci_dpm_fini(rdev); return -ENOMEM; diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index ae1529b0ef6f..f055d6ea3522 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c @@ -2660,8 +2660,9 @@ static int kv_parse_power_table(struct radeon_device *rdev) (mode_info->atom_context->bios + data_offset + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); - rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) * - state_array->ucNumEntries, GFP_KERNEL); + rdev->pm.dpm.ps = kcalloc(state_array->ucNumEntries, + sizeof(struct radeon_ps), + GFP_KERNEL); if (!rdev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index d491b3aa124f..f86ca163dcf3 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c @@ -3998,8 +3998,9 @@ static int ni_parse_power_table(struct radeon_device *rdev) return -EINVAL; power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); - rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) * - power_info->pplib.ucNumStates, GFP_KERNEL); + rdev->pm.dpm.ps = kcalloc(power_info->pplib.ucNumStates, + sizeof(struct radeon_ps), + GFP_KERNEL); if (!rdev->pm.dpm.ps) return -ENOMEM; @@ -4075,7 +4076,9 @@ int ni_dpm_init(struct radeon_device *rdev) return ret; rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries = - kzalloc(4 * sizeof(struct radeon_clock_voltage_dependency_entry), GFP_KERNEL); + kcalloc(4, + sizeof(struct radeon_clock_voltage_dependency_entry), + GFP_KERNEL); if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) { r600_free_extended_power_table(rdev); return -ENOMEM; diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c index 31d1b4710844..73d4c5348116 100644 --- a/drivers/gpu/drm/radeon/r600_dpm.c +++ b/drivers/gpu/drm/radeon/r600_dpm.c @@ -991,7 +991,7 @@ int r600_parse_extended_power_table(struct radeon_device *rdev) ATOM_PPLIB_PhaseSheddingLimits_Record *entry; rdev->pm.dpm.dyn_state.phase_shedding_limits_table.entries = - kzalloc(psl->ucNumEntries * + kcalloc(psl->ucNumEntries, sizeof(struct radeon_phase_shedding_limits_entry), GFP_KERNEL); if (!rdev->pm.dpm.dyn_state.phase_shedding_limits_table.entries) { diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 4134759a6823..a4c47d31147e 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -2126,13 +2126,16 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; if (num_modes == 0) return state_index; - rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * num_modes, GFP_KERNEL); + rdev->pm.power_state = kcalloc(num_modes, + sizeof(struct radeon_power_state), + GFP_KERNEL); if (!rdev->pm.power_state) return state_index; /* last mode is usually default, array is low to high */ for (i = 0; i < num_modes; i++) { rdev->pm.power_state[state_index].clock_info = - kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); + kcalloc(1, sizeof(struct radeon_pm_clock_info), + GFP_KERNEL); if (!rdev->pm.power_state[state_index].clock_info) return state_index; rdev->pm.power_state[state_index].num_clock_modes = 1; @@ -2587,8 +2590,9 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev) radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); if (power_info->pplib.ucNumStates == 0) return state_index; - rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * - power_info->pplib.ucNumStates, GFP_KERNEL); + rdev->pm.power_state = kcalloc(power_info->pplib.ucNumStates, + sizeof(struct radeon_power_state), + GFP_KERNEL); if (!rdev->pm.power_state) return state_index; /* first mode is usually default, followed by low to high */ @@ -2603,9 +2607,8 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev) le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) + (power_state->v1.ucNonClockStateIndex * power_info->pplib.ucNonClockSize)); - rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) * - ((power_info->pplib.ucStateEntrySize - 1) ? - (power_info->pplib.ucStateEntrySize - 1) : 1), + rdev->pm.power_state[i].clock_info = kcalloc((power_info->pplib.ucStateEntrySize - 1) ? (power_info->pplib.ucStateEntrySize - 1) : 1, + sizeof(struct radeon_pm_clock_info), GFP_KERNEL); if (!rdev->pm.power_state[i].clock_info) return state_index; @@ -2688,8 +2691,9 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); if (state_array->ucNumEntries == 0) return state_index; - rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * - state_array->ucNumEntries, GFP_KERNEL); + rdev->pm.power_state = kcalloc(state_array->ucNumEntries, + sizeof(struct radeon_power_state), + GFP_KERNEL); if (!rdev->pm.power_state) return state_index; power_state_offset = (u8 *)state_array->states; @@ -2699,9 +2703,8 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) non_clock_array_index = power_state->v2.nonClockInfoIndex; non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) &non_clock_info_array->nonClockInfo[non_clock_array_index]; - rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) * - (power_state->v2.ucNumDPMLevels ? - power_state->v2.ucNumDPMLevels : 1), + rdev->pm.power_state[i].clock_info = kcalloc(power_state->v2.ucNumDPMLevels ? power_state->v2.ucNumDPMLevels : 1, + sizeof(struct radeon_pm_clock_info), GFP_KERNEL); if (!rdev->pm.power_state[i].clock_info) return state_index; @@ -2782,7 +2785,9 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL); if (rdev->pm.power_state) { rdev->pm.power_state[0].clock_info = - kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); + kcalloc(1, + sizeof(struct radeon_pm_clock_info), + GFP_KERNEL); if (rdev->pm.power_state[0].clock_info) { /* add the default mode */ rdev->pm.power_state[state_index].type = diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 3178ba0c537c..60a61d33f607 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -2642,13 +2642,16 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev) rdev->pm.default_power_state_index = -1; /* allocate 2 power states */ - rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * 2, GFP_KERNEL); + rdev->pm.power_state = kcalloc(2, sizeof(struct radeon_power_state), + GFP_KERNEL); if (rdev->pm.power_state) { /* allocate 1 clock mode per state */ rdev->pm.power_state[0].clock_info = - kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); + kcalloc(1, sizeof(struct radeon_pm_clock_info), + GFP_KERNEL); rdev->pm.power_state[1].clock_info = - kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); + kcalloc(1, sizeof(struct radeon_pm_clock_info), + GFP_KERNEL); if (!rdev->pm.power_state[0].clock_info || !rdev->pm.power_state[1].clock_info) goto pm_failed; diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 0b3ec35515f3..41746d0e80ad 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c @@ -347,13 +347,12 @@ int radeon_gart_init(struct radeon_device *rdev) DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n", rdev->gart.num_cpu_pages, rdev->gart.num_gpu_pages); /* Allocate pages table */ - rdev->gart.pages = vzalloc(sizeof(void *) * rdev->gart.num_cpu_pages); + rdev->gart.pages = vzalloc(array_size(sizeof(void *), rdev->gart.num_cpu_pages)); if (rdev->gart.pages == NULL) { radeon_gart_fini(rdev); return -ENOMEM; } - rdev->gart.pages_entry = vmalloc(sizeof(uint64_t) * - rdev->gart.num_gpu_pages); + rdev->gart.pages_entry = vmalloc(array_size(sizeof(uint64_t), rdev->gart.num_gpu_pages)); if (rdev->gart.pages_entry == NULL) { radeon_gart_fini(rdev); return -ENOMEM; diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index f5e9abfadb56..48f4b273e316 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c @@ -59,7 +59,7 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag) n = rdev->mc.gtt_size - rdev->gart_pin_size; n /= size; - gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL); + gtt_obj = kcalloc(n, sizeof(*gtt_obj), GFP_KERNEL); if (!gtt_obj) { DRM_ERROR("Failed to allocate %d pointers\n", n); r = 1; diff --git a/drivers/gpu/drm/radeon/rs780_dpm.c b/drivers/gpu/drm/radeon/rs780_dpm.c index b5e4e09a8996..694b7b3e9799 100644 --- a/drivers/gpu/drm/radeon/rs780_dpm.c +++ b/drivers/gpu/drm/radeon/rs780_dpm.c @@ -804,8 +804,9 @@ static int rs780_parse_power_table(struct radeon_device *rdev) return -EINVAL; power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); - rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) * - power_info->pplib.ucNumStates, GFP_KERNEL); + rdev->pm.dpm.ps = kcalloc(power_info->pplib.ucNumStates, + sizeof(struct radeon_ps), + GFP_KERNEL); if (!rdev->pm.dpm.ps) return -ENOMEM; diff --git a/drivers/gpu/drm/radeon/rv6xx_dpm.c b/drivers/gpu/drm/radeon/rv6xx_dpm.c index d91aa3944593..6986051fbb89 100644 --- a/drivers/gpu/drm/radeon/rv6xx_dpm.c +++ b/drivers/gpu/drm/radeon/rv6xx_dpm.c @@ -1888,8 +1888,9 @@ static int rv6xx_parse_power_table(struct radeon_device *rdev) return -EINVAL; power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); - rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) * - power_info->pplib.ucNumStates, GFP_KERNEL); + rdev->pm.dpm.ps = kcalloc(power_info->pplib.ucNumStates, + sizeof(struct radeon_ps), + GFP_KERNEL); if (!rdev->pm.dpm.ps) return -ENOMEM; diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index cb2a7ec4e217..c765ae7ea806 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c @@ -2282,8 +2282,9 @@ int rv7xx_parse_power_table(struct radeon_device *rdev) return -EINVAL; power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); - rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) * - power_info->pplib.ucNumStates, GFP_KERNEL); + rdev->pm.dpm.ps = kcalloc(power_info->pplib.ucNumStates, + sizeof(struct radeon_ps), + GFP_KERNEL); if (!rdev->pm.dpm.ps) return -ENOMEM; diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 9e5645e4cb55..46031fc33c19 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -6833,8 +6833,9 @@ static int si_parse_power_table(struct radeon_device *rdev) (mode_info->atom_context->bios + data_offset + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); - rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) * - state_array->ucNumEntries, GFP_KERNEL); + rdev->pm.dpm.ps = kcalloc(state_array->ucNumEntries, + sizeof(struct radeon_ps), + GFP_KERNEL); if (!rdev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; @@ -6942,7 +6943,9 @@ int si_dpm_init(struct radeon_device *rdev) return ret; rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries = - kzalloc(4 * sizeof(struct radeon_clock_voltage_dependency_entry), GFP_KERNEL); + kcalloc(4, + sizeof(struct radeon_clock_voltage_dependency_entry), + GFP_KERNEL); if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) { r600_free_extended_power_table(rdev); return -ENOMEM; diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c index fd4804829e46..1e4975f3374c 100644 --- a/drivers/gpu/drm/radeon/sumo_dpm.c +++ b/drivers/gpu/drm/radeon/sumo_dpm.c @@ -1482,8 +1482,9 @@ static int sumo_parse_power_table(struct radeon_device *rdev) (mode_info->atom_context->bios + data_offset + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); - rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) * - state_array->ucNumEntries, GFP_KERNEL); + rdev->pm.dpm.ps = kcalloc(state_array->ucNumEntries, + sizeof(struct radeon_ps), + GFP_KERNEL); if (!rdev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c index 2ef7c4e5e495..5d317f763eea 100644 --- a/drivers/gpu/drm/radeon/trinity_dpm.c +++ b/drivers/gpu/drm/radeon/trinity_dpm.c @@ -1757,8 +1757,9 @@ static int trinity_parse_power_table(struct radeon_device *rdev) (mode_info->atom_context->bios + data_offset + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); - rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) * - state_array->ucNumEntries, GFP_KERNEL); + rdev->pm.dpm.ps = kcalloc(state_array->ucNumEntries, + sizeof(struct radeon_ps), + GFP_KERNEL); if (!rdev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; diff --git a/drivers/gpu/drm/savage/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c index 2a5b8466d806..35dc74883f83 100644 --- a/drivers/gpu/drm/savage/savage_bci.c +++ b/drivers/gpu/drm/savage/savage_bci.c @@ -298,8 +298,9 @@ static int savage_dma_init(drm_savage_private_t * dev_priv) dev_priv->nr_dma_pages = dev_priv->cmd_dma->size / (SAVAGE_DMA_PAGE_SIZE * 4); - dev_priv->dma_pages = kmalloc(sizeof(drm_savage_dma_page_t) * - dev_priv->nr_dma_pages, GFP_KERNEL); + dev_priv->dma_pages = kmalloc_array(dev_priv->nr_dma_pages, + sizeof(drm_savage_dma_page_t), + GFP_KERNEL); if (dev_priv->dma_pages == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c b/drivers/gpu/drm/selftests/test-drm_mm.c index 86eb4c185a28..c3ec1645751b 100644 --- a/drivers/gpu/drm/selftests/test-drm_mm.c +++ b/drivers/gpu/drm/selftests/test-drm_mm.c @@ -389,7 +389,7 @@ static int __igt_reserve(unsigned int count, u64 size) if (!order) goto err; - nodes = vzalloc(sizeof(*nodes) * count); + nodes = vzalloc(array_size(count, sizeof(*nodes))); if (!nodes) goto err_order; @@ -579,7 +579,7 @@ static int __igt_insert(unsigned int count, u64 size, bool replace) DRM_MM_BUG_ON(!size); ret = -ENOMEM; - nodes = vmalloc(count * sizeof(*nodes)); + nodes = vmalloc(array_size(count, sizeof(*nodes))); if (!nodes) goto err; @@ -887,7 +887,7 @@ static int __igt_insert_range(unsigned int count, u64 size, u64 start, u64 end) */ ret = -ENOMEM; - nodes = vzalloc(count * sizeof(*nodes)); + nodes = vzalloc(array_size(count, sizeof(*nodes))); if (!nodes) goto err; @@ -1042,7 +1042,7 @@ static int igt_align(void *ignored) * meets our requirements. */ - nodes = vzalloc(max_count * sizeof(*nodes)); + nodes = vzalloc(array_size(max_count, sizeof(*nodes))); if (!nodes) goto err; @@ -1411,7 +1411,7 @@ static int igt_evict(void *ignored) */ ret = -ENOMEM; - nodes = vzalloc(size * sizeof(*nodes)); + nodes = vzalloc(array_size(size, sizeof(*nodes))); if (!nodes) goto err; @@ -1521,7 +1521,7 @@ static int igt_evict_range(void *ignored) */ ret = -ENOMEM; - nodes = vzalloc(size * sizeof(*nodes)); + nodes = vzalloc(array_size(size, sizeof(*nodes))); if (!nodes) goto err; @@ -1622,11 +1622,11 @@ static int igt_topdown(void *ignored) */ ret = -ENOMEM; - nodes = vzalloc(count * sizeof(*nodes)); + nodes = vzalloc(array_size(count, sizeof(*nodes))); if (!nodes) goto err; - bitmap = kzalloc(count / BITS_PER_LONG * sizeof(unsigned long), + bitmap = kcalloc(count / BITS_PER_LONG, sizeof(unsigned long), GFP_KERNEL); if (!bitmap) goto err_nodes; @@ -1736,11 +1736,11 @@ static int igt_bottomup(void *ignored) */ ret = -ENOMEM; - nodes = vzalloc(count * sizeof(*nodes)); + nodes = vzalloc(array_size(count, sizeof(*nodes))); if (!nodes) goto err; - bitmap = kzalloc(count / BITS_PER_LONG * sizeof(unsigned long), + bitmap = kcalloc(count / BITS_PER_LONG, sizeof(unsigned long), GFP_KERNEL); if (!bitmap) goto err_nodes; @@ -2093,7 +2093,7 @@ static int igt_color_evict(void *ignored) */ ret = -ENOMEM; - nodes = vzalloc(total_size * sizeof(*nodes)); + nodes = vzalloc(array_size(total_size, sizeof(*nodes))); if (!nodes) goto err; @@ -2194,7 +2194,7 @@ static int igt_color_evict_range(void *ignored) */ ret = -ENOMEM; - nodes = vzalloc(total_size * sizeof(*nodes)); + nodes = vzalloc(array_size(total_size, sizeof(*nodes))); if (!nodes) goto err; diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index 80540c1c66dc..2da9f8a971a3 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -123,7 +123,7 @@ static struct tegra_fb *tegra_fb_alloc(struct drm_device *drm, if (!fb) return ERR_PTR(-ENOMEM); - fb->planes = kzalloc(num_planes * sizeof(*planes), GFP_KERNEL); + fb->planes = kcalloc(num_planes, sizeof(*planes), GFP_KERNEL); if (!fb->planes) { kfree(fb); return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c index 623a9140493c..84d765866ffb 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c @@ -32,8 +32,8 @@ static int __init kfree_table_init(struct kfree_table *kft) { kft->total = 32; kft->num = 0; - kft->table = kmalloc(kft->total * sizeof(*kft->table), - GFP_KERNEL); + kft->table = kmalloc_array(kft->total, sizeof(*kft->table), + GFP_KERNEL); if (!kft->table) return -ENOMEM; diff --git a/drivers/gpu/drm/tinydrm/repaper.c b/drivers/gpu/drm/tinydrm/repaper.c index 30dc97b3ff21..cd36ec4e862a 100644 --- a/drivers/gpu/drm/tinydrm/repaper.c +++ b/drivers/gpu/drm/tinydrm/repaper.c @@ -554,7 +554,7 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb, DRM_DEBUG("Flushing [FB:%d] st=%ums\n", fb->base.id, epd->factored_stage_time); - buf = kmalloc(fb->width * fb->height, GFP_KERNEL); + buf = kmalloc_array(fb->width, fb->height, GFP_KERNEL); if (!buf) { ret = -ENOMEM; goto out_unlock; diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 91f9263f3c3b..b84e0d0023e4 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -318,8 +318,9 @@ static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free, if (use_static) pages_to_free = static_buf; else - pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), - GFP_KERNEL); + pages_to_free = kmalloc_array(npages_to_free, + sizeof(struct page *), + GFP_KERNEL); if (!pages_to_free) { pr_err("Failed to allocate memory for pool free operation\n"); return 0; @@ -504,7 +505,8 @@ static int ttm_alloc_new_pages(struct list_head *pages, gfp_t gfp_flags, (unsigned)(PAGE_SIZE/sizeof(struct page *))); /* allocate array for page caching change */ - caching_array = kmalloc(max_cpages*sizeof(struct page *), GFP_KERNEL); + caching_array = kmalloc_array(max_cpages, sizeof(struct page *), + GFP_KERNEL); if (!caching_array) { pr_err("Unable to allocate table for new pages\n"); diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index 90ddbdca93bd..bc824c8e089f 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c @@ -442,8 +442,9 @@ static unsigned ttm_dma_page_pool_free(struct dma_pool *pool, unsigned nr_free, if (use_static) pages_to_free = static_buf; else - pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), - GFP_KERNEL); + pages_to_free = kmalloc_array(npages_to_free, + sizeof(struct page *), + GFP_KERNEL); if (!pages_to_free) { pr_err("%s: Failed to allocate memory for pool free operation\n", @@ -729,7 +730,8 @@ static int ttm_dma_pool_alloc_new_pages(struct dma_pool *pool, (unsigned)(PAGE_SIZE/sizeof(struct page *))); /* allocate array for page caching change */ - caching_array = kmalloc(max_cpages*sizeof(struct page *), GFP_KERNEL); + caching_array = kmalloc_array(max_cpages, sizeof(struct page *), + GFP_KERNEL); if (!caching_array) { pr_err("%s: Unable to allocate table for new pages\n", diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 6277a3f2d5d1..01966db9eb34 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -241,7 +241,7 @@ static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val) { if (vc4_state->dlist_count == vc4_state->dlist_size) { u32 new_size = max(4u, vc4_state->dlist_count * 2); - u32 *new_dlist = kmalloc(new_size * 4, GFP_KERNEL); + u32 *new_dlist = kmalloc_array(new_size, 4, GFP_KERNEL); if (!new_dlist) return; diff --git a/drivers/gpu/drm/via/via_dmablit.c b/drivers/gpu/drm/via/via_dmablit.c index 98aae9809249..3133a449b3d8 100644 --- a/drivers/gpu/drm/via/via_dmablit.c +++ b/drivers/gpu/drm/via/via_dmablit.c @@ -235,7 +235,7 @@ via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer) vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride - 1)) - first_pfn + 1; - vsg->pages = vzalloc(sizeof(struct page *) * vsg->num_pages); + vsg->pages = vzalloc(array_size(sizeof(struct page *), vsg->num_pages)); if (NULL == vsg->pages) return -ENOMEM; ret = get_user_pages_unlocked((unsigned long)xfer->mem_addr, diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 9ec73038b8c4..1ae774892ecd 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -1190,7 +1190,6 @@ static int adreno_probe(struct platform_device *pdev) struct adreno_device *adreno_dev; int status; - place_marker("M - DRIVER GPU Init"); adreno_dev = adreno_get_dev(pdev); @@ -1319,7 +1318,6 @@ static int adreno_probe(struct platform_device *pdev) "Failed to get gpuhtw LLC slice descriptor %ld\n", PTR_ERR(adreno_dev->gpuhtw_llc_slice)); - place_marker("M - DRIVER GPU Ready"); out: if (status) { adreno_ringbuffer_close(adreno_dev); @@ -1528,7 +1526,6 @@ static int adreno_init(struct kgsl_device *device) if (test_bit(ADRENO_DEVICE_INITIALIZED, &adreno_dev->priv)) return 0; - place_marker("M - DRIVER ADRENO Init"); /* * Either the microcode read failed because the usermodehelper isn't @@ -1603,7 +1600,6 @@ static int adreno_init(struct kgsl_device *device) } - place_marker("M - DRIVER ADRENO Ready"); return 0; } @@ -1645,10 +1641,10 @@ static void _set_secvid(struct kgsl_device *device) adreno_writereg64(adreno_dev, ADRENO_REG_RBBM_SECVID_TSB_TRUSTED_BASE, ADRENO_REG_RBBM_SECVID_TSB_TRUSTED_BASE_HI, - KGSL_IOMMU_SECURE_BASE(&device->mmu)); + device->mmu.secure_base); adreno_writereg(adreno_dev, ADRENO_REG_RBBM_SECVID_TSB_TRUSTED_SIZE, - KGSL_IOMMU_SECURE_SIZE); + device->mmu.secure_size); if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_SECVID_SET_ONCE)) set = true; } diff --git a/drivers/gpu/msm/adreno_cp_parser.c b/drivers/gpu/msm/adreno_cp_parser.c index 3f484b98577d..58064925e6a5 100644 --- a/drivers/gpu/msm/adreno_cp_parser.c +++ b/drivers/gpu/msm/adreno_cp_parser.c @@ -1019,8 +1019,7 @@ int adreno_ib_create_object_list(struct kgsl_device *device, if (!ib_obj_list) return -ENOMEM; - ib_obj_list->obj_list = vmalloc(MAX_IB_OBJS * - sizeof(struct adreno_ib_object)); + ib_obj_list->obj_list = vmalloc(array_size(MAX_IB_OBJS, sizeof(struct adreno_ib_object))); if (!ib_obj_list->obj_list) { kfree(ib_obj_list); diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c index df8e8acecb4c..aa945a4bd302 100644 --- a/drivers/gpu/msm/adreno_drawctxt.c +++ b/drivers/gpu/msm/adreno_drawctxt.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -487,11 +487,12 @@ void adreno_drawctxt_detach(struct kgsl_context *context) drawctxt = ADRENO_CONTEXT(context); rb = drawctxt->rb; + spin_lock(&drawctxt->lock); + spin_lock(&adreno_dev->active_list_lock); list_del_init(&drawctxt->active_node); spin_unlock(&adreno_dev->active_list_lock); - spin_lock(&drawctxt->lock); count = drawctxt_detach_drawobjs(drawctxt, list); spin_unlock(&drawctxt->lock); diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index f75e68e86d73..c346f4174e41 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -5116,7 +5116,6 @@ static int __init kgsl_core_init(void) int result = 0; struct sched_param param = { .sched_priority = 2 }; - place_marker("M - DRIVER KGSL Init"); /* alloc major and minor device numbers */ result = alloc_chrdev_region(&kgsl_driver.major, 0, KGSL_DEVICE_MAX, @@ -5203,7 +5202,6 @@ static int __init kgsl_core_init(void) kgsl_memfree_init(); - place_marker("M - DRIVER KGSL Ready"); return 0; diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index b338a1568476..ca65e8fc0dfd 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -189,7 +189,7 @@ int kgsl_iommu_map_global_secure_pt_entry(struct kgsl_device *device, struct kgsl_pagetable *pagetable = device->mmu.securepagetable; entry->pagetable = pagetable; - entry->gpuaddr = KGSL_IOMMU_SECURE_BASE(&device->mmu) + + entry->gpuaddr = device->mmu.secure_base + secure_global_size; ret = kgsl_mmu_map(pagetable, entry); @@ -1097,13 +1097,13 @@ static void setup_64bit_pagetable(struct kgsl_mmu *mmu, struct kgsl_iommu_pt *pt) { if (mmu->secured && pagetable->name == KGSL_MMU_SECURE_PT) { - pt->compat_va_start = KGSL_IOMMU_SECURE_BASE(mmu); + pt->compat_va_start = mmu->secure_base; pt->compat_va_end = KGSL_IOMMU_SECURE_END(mmu); - pt->va_start = KGSL_IOMMU_SECURE_BASE(mmu); + pt->va_start = mmu->secure_base; pt->va_end = KGSL_IOMMU_SECURE_END(mmu); } else { pt->compat_va_start = mmu->svm_base32; - pt->compat_va_end = KGSL_IOMMU_SECURE_BASE(mmu); + pt->compat_va_end = mmu->secure_base; pt->va_start = KGSL_IOMMU_VA_BASE64; pt->va_end = KGSL_IOMMU_VA_END64; } @@ -1112,7 +1112,7 @@ static void setup_64bit_pagetable(struct kgsl_mmu *mmu, pagetable->name != KGSL_MMU_SECURE_PT) { if (kgsl_is_compat_task()) { pt->svm_start = mmu->svm_base32; - pt->svm_end = KGSL_IOMMU_SECURE_BASE(mmu); + pt->svm_end = mmu->secure_base; } else { pt->svm_start = KGSL_IOMMU_SVM_BASE64; pt->svm_end = KGSL_IOMMU_SVM_END64; @@ -1126,13 +1126,13 @@ static void setup_32bit_pagetable(struct kgsl_mmu *mmu, { if (mmu->secured) { if (pagetable->name == KGSL_MMU_SECURE_PT) { - pt->compat_va_start = KGSL_IOMMU_SECURE_BASE(mmu); + pt->compat_va_start = mmu->secure_base; pt->compat_va_end = KGSL_IOMMU_SECURE_END(mmu); - pt->va_start = KGSL_IOMMU_SECURE_BASE(mmu); + pt->va_start = mmu->secure_base; pt->va_end = KGSL_IOMMU_SECURE_END(mmu); } else { pt->va_start = mmu->svm_base32; - pt->va_end = KGSL_IOMMU_SECURE_BASE(mmu); + pt->va_end = mmu->secure_base; pt->compat_va_start = pt->va_start; pt->compat_va_end = pt->va_end; } @@ -2725,6 +2725,7 @@ static int _kgsl_iommu_probe(struct kgsl_device *device, u32 reg_val[2]; int i = 0; struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device); + struct kgsl_mmu *mmu = &device->mmu; struct kgsl_pwrctrl *pwr = &device->pwrctrl; struct device_node *child; struct platform_device *pdev = of_find_device_by_node(node); @@ -2769,7 +2770,7 @@ static int _kgsl_iommu_probe(struct kgsl_device *device, for (i = 0; i < ARRAY_SIZE(kgsl_iommu_features); i++) { if (of_property_read_bool(node, kgsl_iommu_features[i].feature)) - device->mmu.features |= kgsl_iommu_features[i].bit; + mmu->features |= kgsl_iommu_features[i].bit; } /* @@ -2790,8 +2791,16 @@ static int _kgsl_iommu_probe(struct kgsl_device *device, iommu->micro_mmu_ctrl = UINT_MAX; if (of_property_read_u32(node, "qcom,secure_align_mask", - &device->mmu.secure_align_mask)) - device->mmu.secure_align_mask = 0xfff; + &mmu->secure_align_mask)) + mmu->secure_align_mask = 0xfff; + + if (of_property_read_u32(node, "qcom,secure-size", &mmu->secure_size)) + mmu->secure_size = KGSL_IOMMU_SECURE_SIZE; + else if (mmu->secure_size > + (KGSL_IOMMU_SECURE_END(mmu) - mmu->svm_base32)) + mmu->secure_size = KGSL_IOMMU_SECURE_SIZE; + + mmu->secure_base = KGSL_IOMMU_SECURE_END(mmu) - mmu->secure_size; /* Fill out the rest of the devices in the node */ of_platform_populate(node, NULL, NULL, &pdev->dev); diff --git a/drivers/gpu/msm/kgsl_iommu.h b/drivers/gpu/msm/kgsl_iommu.h index 79eee71a0cd7..4660717b99b1 100644 --- a/drivers/gpu/msm/kgsl_iommu.h +++ b/drivers/gpu/msm/kgsl_iommu.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -33,8 +33,6 @@ #define KGSL_IOMMU_SECURE_SIZE SZ_256M #define KGSL_IOMMU_SECURE_END(_mmu) KGSL_IOMMU_GLOBAL_MEM_BASE(_mmu) -#define KGSL_IOMMU_SECURE_BASE(_mmu) \ - (KGSL_IOMMU_GLOBAL_MEM_BASE(_mmu) - KGSL_IOMMU_SECURE_SIZE) #define KGSL_IOMMU_SVM_BASE32 0x300000 #define KGSL_IOMMU_SVM_END32 (0xC0000000 - SZ_16M) diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h index 06d0ae387f1c..b10d079448f8 100644 --- a/drivers/gpu/msm/kgsl_mmu.h +++ b/drivers/gpu/msm/kgsl_mmu.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -170,6 +170,8 @@ struct kgsl_mmu { unsigned int secure_align_mask; uint64_t va_padding; unsigned int svm_base32; + unsigned int secure_base; + unsigned int secure_size; union { struct kgsl_iommu iommu; } priv; diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c index 857467022cf0..118840f87ce3 100644 --- a/drivers/gpu/msm/kgsl_pwrctrl.c +++ b/drivers/gpu/msm/kgsl_pwrctrl.c @@ -2386,8 +2386,9 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) } } - pwr->bus_ib = kzalloc(bus_scale_table->num_usecases * - sizeof(*pwr->bus_ib), GFP_KERNEL); + pwr->bus_ib = kcalloc(bus_scale_table->num_usecases, + sizeof(*pwr->bus_ib), + GFP_KERNEL); if (pwr->bus_ib == NULL) { result = -ENOMEM; goto error_cleanup_pcl; diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index b8ada634c977..c790c1e0be83 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -131,8 +131,8 @@ static int open_collection(struct hid_parser *parser, unsigned type) } if (parser->device->maxcollection == parser->device->collection_size) { - collection = kmalloc(sizeof(struct hid_collection) * - parser->device->collection_size * 2, GFP_KERNEL); + collection = kmalloc(array3_size(sizeof(struct hid_collection), parser->device->collection_size, 2), + GFP_KERNEL); if (collection == NULL) { hid_err(parser->device, "failed to reallocate collection array\n"); return -ENOMEM; @@ -1360,7 +1360,7 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, __s32 max = field->logical_maximum; __s32 *value; - value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC); + value = kmalloc_array(count, sizeof(__s32), GFP_ATOMIC); if (!value) return; diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index a0bcbb633b67..b96d5f0d1524 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -681,7 +681,7 @@ void hid_dump_report(struct hid_device *hid, int type, u8 *data, char *buf; unsigned int i; - buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC); + buf = kmalloc(HID_DEBUG_BUFSIZE, GFP_ATOMIC); if (!buf) return; diff --git a/drivers/hid/hid-picolcd_fb.c b/drivers/hid/hid-picolcd_fb.c index 7f965e231433..864a084b6cba 100644 --- a/drivers/hid/hid-picolcd_fb.c +++ b/drivers/hid/hid-picolcd_fb.c @@ -394,7 +394,8 @@ static int picolcd_set_par(struct fb_info *info) return -EINVAL; o_fb = fbdata->bitmap; - tmp_fb = kmalloc(PICOLCDFB_SIZE*info->var.bits_per_pixel, GFP_KERNEL); + tmp_fb = kmalloc_array(PICOLCDFB_SIZE, info->var.bits_per_pixel, + GFP_KERNEL); if (!tmp_fb) return -ENOMEM; diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index b5bd5cb7d532..4256fdc5cd6d 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -653,7 +653,8 @@ static int sensor_hub_probe(struct hid_device *hdev, ret = -EINVAL; goto err_stop_hw; } - sd->hid_sensor_hub_client_devs = devm_kzalloc(&hdev->dev, dev_cnt * + sd->hid_sensor_hub_client_devs = devm_kcalloc(&hdev->dev, + dev_cnt, sizeof(struct mfd_cell), GFP_KERNEL); if (sd->hid_sensor_hub_client_devs == NULL) { diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 5243c4120819..ac8a3f5926d5 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -218,7 +218,7 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t goto out; } - buf = kmalloc(count * sizeof(__u8), GFP_KERNEL); + buf = kmalloc(count, GFP_KERNEL); if (!buf) { ret = -ENOMEM; goto out; diff --git a/drivers/hid/intel-ish-hid/ishtp-hid-client.c b/drivers/hid/intel-ish-hid/ishtp-hid-client.c index 157b44aacdff..295d8fdff342 100644 --- a/drivers/hid/intel-ish-hid/ishtp-hid-client.c +++ b/drivers/hid/intel-ish-hid/ishtp-hid-client.c @@ -121,9 +121,9 @@ static void process_recv(struct ishtp_cl *hid_ishtp_cl, void *recv_buf, } client_data->hid_dev_count = (unsigned int)*payload; if (!client_data->hid_devices) - client_data->hid_devices = devm_kzalloc( + client_data->hid_devices = devm_kcalloc( &client_data->cl_device->dev, - client_data->hid_dev_count * + client_data->hid_dev_count, sizeof(struct device_info), GFP_KERNEL); if (!client_data->hid_devices) { diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index bf8e727988c4..7b531f9feefd 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1267,7 +1267,7 @@ static int wacom_led_groups_alloc_and_register_one(struct device *dev, if (!devres_open_group(dev, &wacom->led.groups[group_id], GFP_KERNEL)) return -ENOMEM; - leds = devm_kzalloc(dev, sizeof(struct wacom_led) * count, GFP_KERNEL); + leds = devm_kcalloc(dev, count, sizeof(struct wacom_led), GFP_KERNEL); if (!leds) { error = -ENOMEM; goto err; @@ -1367,7 +1367,7 @@ static int wacom_led_groups_allocate(struct wacom *wacom, int count) struct wacom_group_leds *groups; int error; - groups = devm_kzalloc(dev, sizeof(struct wacom_group_leds) * count, + groups = devm_kcalloc(dev, count, sizeof(struct wacom_group_leds), GFP_KERNEL); if (!groups) return -ENOMEM; diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 23f312b4c6aa..daf1a9891f83 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -160,7 +160,7 @@ int hv_synic_alloc(void) memset(hv_cpu, 0, sizeof(*hv_cpu)); } - hv_context.hv_numa_map = kzalloc(sizeof(struct cpumask) * nr_node_ids, + hv_context.hv_numa_map = kcalloc(nr_node_ids, sizeof(struct cpumask), GFP_ATOMIC); if (hv_context.hv_numa_map == NULL) { pr_err("Unable to allocate NUMA map\n"); diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c index 74c1dfb8183b..69d6737f4fe7 100644 --- a/drivers/hv/ring_buffer.c +++ b/drivers/hv/ring_buffer.c @@ -178,7 +178,7 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, * First page holds struct hv_ring_buffer, do wraparound mapping for * the rest. */ - pages_wraparound = kzalloc(sizeof(struct page *) * (page_cnt * 2 - 1), + pages_wraparound = kcalloc(page_cnt * 2 - 1, sizeof(struct page *), GFP_KERNEL); if (!pages_wraparound) return -ENOMEM; diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c index e40d8907853b..2f40da04a944 100644 --- a/drivers/hwmon/acpi_power_meter.c +++ b/drivers/hwmon/acpi_power_meter.c @@ -575,8 +575,9 @@ static int read_domain_devices(struct acpi_power_meter_resource *resource) if (!pss->package.count) goto end; - resource->domain_devices = kzalloc(sizeof(struct acpi_device *) * - pss->package.count, GFP_KERNEL); + resource->domain_devices = kcalloc(pss->package.count, + sizeof(struct acpi_device *), + GFP_KERNEL); if (!resource->domain_devices) { res = -ENOMEM; goto end; @@ -796,7 +797,7 @@ static int read_capabilities(struct acpi_power_meter_resource *resource) goto error; } - *str = kzalloc(sizeof(u8) * (element->string.length + 1), + *str = kcalloc(element->string.length + 1, sizeof(u8), GFP_KERNEL); if (!*str) { res = -ENOMEM; diff --git a/drivers/hwmon/aspeed-pwm-tacho.c b/drivers/hwmon/aspeed-pwm-tacho.c index e4337e9dda44..f9b0342ef0c8 100644 --- a/drivers/hwmon/aspeed-pwm-tacho.c +++ b/drivers/hwmon/aspeed-pwm-tacho.c @@ -894,7 +894,7 @@ static int aspeed_create_fan(struct device *dev, count = of_property_count_u8_elems(child, "aspeed,fan-tach-ch"); if (count < 1) return -EINVAL; - fan_tach_ch = devm_kzalloc(dev, sizeof(*fan_tach_ch) * count, + fan_tach_ch = devm_kcalloc(dev, count, sizeof(*fan_tach_ch), GFP_KERNEL); if (!fan_tach_ch) return -ENOMEM; diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index a42744c7665b..8991f1babf48 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -741,7 +741,7 @@ static int __init coretemp_init(void) return -ENODEV; max_packages = topology_max_packages(); - pkg_devices = kzalloc(max_packages * sizeof(struct platform_device *), + pkg_devices = kcalloc(max_packages, sizeof(struct platform_device *), GFP_KERNEL); if (!pkg_devices) return -ENOMEM; diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index 9c355b9d31c5..bd673ccaf4e9 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c @@ -477,7 +477,7 @@ static int gpio_fan_get_of_pdata(struct device *dev, dev_err(dev, "DT properties empty / missing"); return -ENODEV; } - ctrl = devm_kzalloc(dev, pdata->num_ctrl * sizeof(unsigned), + ctrl = devm_kcalloc(dev, pdata->num_ctrl, sizeof(unsigned), GFP_KERNEL); if (!ctrl) return -ENOMEM; @@ -509,8 +509,8 @@ static int gpio_fan_get_of_pdata(struct device *dev, * Speed map is in the form * this needs splitting into pairs to create gpio_fan_speed structs */ - speed = devm_kzalloc(dev, - pdata->num_speed * sizeof(struct gpio_fan_speed), + speed = devm_kcalloc(dev, + pdata->num_speed, sizeof(struct gpio_fan_speed), GFP_KERNEL); if (!speed) return -ENOMEM; diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c index 9397d2f0e79a..4f657ce8f951 100644 --- a/drivers/hwmon/i5k_amb.c +++ b/drivers/hwmon/i5k_amb.c @@ -274,7 +274,7 @@ static int i5k_amb_hwmon_init(struct platform_device *pdev) num_ambs += hweight16(data->amb_present[i] & 0x7fff); /* Set up sysfs stuff */ - data->attrs = kzalloc(sizeof(*data->attrs) * num_ambs * KNOBS_PER_AMB, + data->attrs = kzalloc(array3_size(num_ambs, KNOBS_PER_AMB, sizeof(*data->attrs)), GFP_KERNEL); if (!data->attrs) return -ENOMEM; diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 21b9c72f16bd..ab72cabf5a95 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -387,7 +387,7 @@ static int ibmpex_find_sensors(struct ibmpex_bmc_data *data) return -ENOENT; data->num_sensors = err; - data->sensors = kzalloc(data->num_sensors * sizeof(*data->sensors), + data->sensors = kcalloc(data->num_sensors, sizeof(*data->sensors), GFP_KERNEL); if (!data->sensors) return -ENOMEM; diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c index b38f4951c94e..f15b286bf111 100644 --- a/drivers/hwmon/ibmpowernv.c +++ b/drivers/hwmon/ibmpowernv.c @@ -322,9 +322,9 @@ static int populate_attr_groups(struct platform_device *pdev) of_node_put(opal); for (type = 0; type < MAX_SENSOR_TYPE; type++) { - sensor_groups[type].group.attrs = devm_kzalloc(&pdev->dev, - sizeof(struct attribute *) * - (sensor_groups[type].attr_count + 1), + sensor_groups[type].group.attrs = devm_kcalloc(&pdev->dev, + sensor_groups[type].attr_count + 1, + sizeof(struct attribute *), GFP_KERNEL); if (!sensor_groups[type].group.attrs) return -ENOMEM; @@ -405,7 +405,8 @@ static int create_device_attrs(struct platform_device *pdev) int err = 0; opal = of_find_node_by_path("/ibm,opal/sensors"); - sdata = devm_kzalloc(&pdev->dev, pdata->sensors_count * sizeof(*sdata), + sdata = devm_kcalloc(&pdev->dev, + pdata->sensors_count, sizeof(*sdata), GFP_KERNEL); if (!sdata) { err = -ENOMEM; diff --git a/drivers/hwmon/iio_hwmon.c b/drivers/hwmon/iio_hwmon.c index f6a76679c650..2eeb52e6fe37 100644 --- a/drivers/hwmon/iio_hwmon.c +++ b/drivers/hwmon/iio_hwmon.c @@ -91,8 +91,8 @@ static int iio_hwmon_probe(struct platform_device *pdev) while (st->channels[st->num_channels].indio_dev) st->num_channels++; - st->attrs = devm_kzalloc(dev, - sizeof(*st->attrs) * (st->num_channels + 1), + st->attrs = devm_kcalloc(dev, + st->num_channels + 1, sizeof(*st->attrs), GFP_KERNEL); if (st->attrs == NULL) { ret = -ENOMEM; diff --git a/drivers/hwmon/nct6683.c b/drivers/hwmon/nct6683.c index 8b0bc4fc06e8..43aa38933d1c 100644 --- a/drivers/hwmon/nct6683.c +++ b/drivers/hwmon/nct6683.c @@ -426,12 +426,12 @@ nct6683_create_attr_group(struct device *dev, if (group == NULL) return ERR_PTR(-ENOMEM); - attrs = devm_kzalloc(dev, sizeof(*attrs) * (repeat * count + 1), + attrs = devm_kcalloc(dev, repeat * count + 1, sizeof(*attrs), GFP_KERNEL); if (attrs == NULL) return ERR_PTR(-ENOMEM); - su = devm_kzalloc(dev, sizeof(*su) * repeat * count, + su = devm_kzalloc(dev, array3_size(repeat, count, sizeof(*su)), GFP_KERNEL); if (su == NULL) return ERR_PTR(-ENOMEM); diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index 7e14143ed119..42ad3bb2c427 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c @@ -1149,12 +1149,12 @@ nct6775_create_attr_group(struct device *dev, if (group == NULL) return ERR_PTR(-ENOMEM); - attrs = devm_kzalloc(dev, sizeof(*attrs) * (repeat * count + 1), + attrs = devm_kcalloc(dev, repeat * count + 1, sizeof(*attrs), GFP_KERNEL); if (attrs == NULL) return ERR_PTR(-ENOMEM); - su = devm_kzalloc(dev, sizeof(*su) * repeat * count, + su = devm_kzalloc(dev, array3_size(repeat, count, sizeof(*su)), GFP_KERNEL); if (su == NULL) return ERR_PTR(-ENOMEM); diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index cb9064ac4977..c8982cb07768 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -1992,8 +1992,8 @@ static int pmbus_init_debugfs(struct i2c_client *client, } /* Allocate the max possible entries we need. */ - entries = devm_kzalloc(data->dev, - sizeof(*entries) * (data->info->pages * 10), + entries = devm_kcalloc(data->dev, + data->info->pages * 10, sizeof(*entries), GFP_KERNEL); if (!entries) return -ENOMEM; diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c index f981da686d7e..65de80bd63d8 100644 --- a/drivers/hwmon/pwm-fan.c +++ b/drivers/hwmon/pwm-fan.c @@ -180,7 +180,7 @@ static int pwm_fan_of_get_cooling_data(struct device *dev, } num = ret; - ctx->pwm_fan_cooling_levels = devm_kzalloc(dev, num * sizeof(u32), + ctx->pwm_fan_cooling_levels = devm_kcalloc(dev, num, sizeof(u32), GFP_KERNEL); if (!ctx->pwm_fan_cooling_levels) return -ENOMEM; diff --git a/drivers/hwtracing/coresight/coresight-cti.c b/drivers/hwtracing/coresight/coresight-cti.c index 486356e527a5..605e76a0f184 100644 --- a/drivers/hwtracing/coresight/coresight-cti.c +++ b/drivers/hwtracing/coresight/coresight-cti.c @@ -63,6 +63,7 @@ do { \ #define ITTRIGOUTACK (0xEF0) #define ITCHIN (0xEF4) #define ITTRIGIN (0xEF8) +#define DEVID (0xFC8) #define CTI_MAX_TRIGGERS (32) #define CTI_MAX_CHANNELS (4) @@ -93,6 +94,8 @@ struct cti_drvdata { struct coresight_cti cti; int refcnt; int cpu; + unsigned int trig_num_max; + unsigned int ch_num_max; bool cti_save; bool cti_hwclk; bool l2_off; @@ -1360,6 +1363,19 @@ static ssize_t cti_store_disable_gate(struct device *dev, } static DEVICE_ATTR(disable_gate, 0200, NULL, cti_store_disable_gate); +static ssize_t show_info_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); + ssize_t size = 0; + + size = scnprintf(&buf[size], PAGE_SIZE, "%d %d\n", + drvdata->trig_num_max, drvdata->ch_num_max); + + return size; +} +static DEVICE_ATTR_RO(show_info); + static struct attribute *cti_attrs[] = { &dev_attr_show_trigin.attr, &dev_attr_show_trigout.attr, @@ -1376,6 +1392,7 @@ static struct attribute *cti_attrs[] = { &dev_attr_show_gate.attr, &dev_attr_enable_gate.attr, &dev_attr_disable_gate.attr, + &dev_attr_show_info.attr, NULL, }; @@ -1416,6 +1433,7 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id) { int ret; int trig; + unsigned int ctidevid; struct device *dev = &adev->dev; struct coresight_platform_data *pdata; struct cti_drvdata *drvdata; @@ -1522,6 +1540,10 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id) cpu_pm_register_notifier(&cti_cpu_pm_notifier); registered++; } + + ctidevid = cti_readl(drvdata, DEVID); + drvdata->trig_num_max = (ctidevid & GENMASK(15, 8)) >> 8; + drvdata->ch_num_max = (ctidevid & GENMASK(21, 16)) >> 16; pm_runtime_put(&adev->dev); dev_dbg(dev, "CTI initialized\n"); return 0; diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index e1132524f4c8..38f4e49022a7 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -748,8 +748,8 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id) if (drvdata->buffer_depth & 0x80000000) return -EINVAL; - drvdata->buf = devm_kzalloc(dev, - drvdata->buffer_depth * 4, GFP_KERNEL); + drvdata->buf = devm_kcalloc(dev, + drvdata->buffer_depth, 4, GFP_KERNEL); if (!drvdata->buf) return -ENOMEM; diff --git a/drivers/hwtracing/coresight/coresight-hwevent.c b/drivers/hwtracing/coresight/coresight-hwevent.c index d06fe1d749d1..0ed6b4675bff 100644 --- a/drivers/hwtracing/coresight/coresight-hwevent.c +++ b/drivers/hwtracing/coresight/coresight-hwevent.c @@ -204,7 +204,8 @@ static int hwevent_probe(struct platform_device *pdev) drvdata->nr_hmux = 0; if (drvdata->nr_hmux > 0) { - drvdata->hmux = devm_kzalloc(dev, drvdata->nr_hmux * + drvdata->hmux = devm_kcalloc(dev, + drvdata->nr_hmux, sizeof(*drvdata->hmux), GFP_KERNEL); if (!drvdata->hmux) @@ -236,7 +237,8 @@ static int hwevent_probe(struct platform_device *pdev) "qcom,hwevent-regs"); if (drvdata->nr_hclk > 0) { - drvdata->hclk = devm_kzalloc(dev, drvdata->nr_hclk * + drvdata->hclk = devm_kcalloc(dev, + drvdata->nr_hclk, sizeof(*drvdata->hclk), GFP_KERNEL); if (!drvdata->hclk) @@ -255,7 +257,8 @@ static int hwevent_probe(struct platform_device *pdev) } } if (drvdata->nr_hreg > 0) { - drvdata->hreg = devm_kzalloc(dev, drvdata->nr_hreg * + drvdata->hreg = devm_kcalloc(dev, + drvdata->nr_hreg, sizeof(*drvdata->hreg), GFP_KERNEL); if (!drvdata->hreg) diff --git a/drivers/hwtracing/coresight/coresight-tgu.c b/drivers/hwtracing/coresight/coresight-tgu.c index 31e10b52ac1d..ca17fed4b139 100644 --- a/drivers/hwtracing/coresight/coresight-tgu.c +++ b/drivers/hwtracing/coresight/coresight-tgu.c @@ -458,34 +458,39 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id) return -EINVAL; /* Alloc memory for Grps, Conditions and Steps */ - drvdata->grp_data = devm_kzalloc(dev, MAX_GROUP_SETS * - sizeof(*drvdata->grp_data), - GFP_KERNEL); + drvdata->grp_data = devm_kcalloc(dev, + MAX_GROUP_SETS, + sizeof(*drvdata->grp_data), + GFP_KERNEL); if (!drvdata->grp_data) return -ENOMEM; - drvdata->condition_data = devm_kzalloc(dev, MAX_CONDITION_SETS * - sizeof(*drvdata->condition_data), - GFP_KERNEL); + drvdata->condition_data = devm_kcalloc(dev, + MAX_CONDITION_SETS, + sizeof(*drvdata->condition_data), + GFP_KERNEL); if (!drvdata->condition_data) return -ENOMEM; - drvdata->select_data = devm_kzalloc(dev, MAX_CONDITION_SETS * - sizeof(*drvdata->select_data), - GFP_KERNEL); + drvdata->select_data = devm_kcalloc(dev, + MAX_CONDITION_SETS, + sizeof(*drvdata->select_data), + GFP_KERNEL); if (!drvdata->select_data) return -ENOMEM; - drvdata->timer_data = devm_kzalloc(dev, MAX_TIMER_COUNTER_SETS * - sizeof(*drvdata->timer_data), - GFP_KERNEL); + drvdata->timer_data = devm_kcalloc(dev, + MAX_TIMER_COUNTER_SETS, + sizeof(*drvdata->timer_data), + GFP_KERNEL); if (!drvdata->timer_data) return -ENOMEM; - drvdata->counter_data = devm_kzalloc(dev, MAX_TIMER_COUNTER_SETS * - sizeof(*drvdata->counter_data), - GFP_KERNEL); + drvdata->counter_data = devm_kcalloc(dev, + MAX_TIMER_COUNTER_SETS, + sizeof(*drvdata->counter_data), + GFP_KERNEL); if (!drvdata->counter_data) return -ENOMEM; diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c index 18c0ce7d84fa..d14a31b00b0f 100644 --- a/drivers/hwtracing/coresight/coresight-tpdm.c +++ b/drivers/hwtracing/coresight/coresight-tpdm.c @@ -4437,7 +4437,8 @@ static int tpdm_probe(struct amba_device *adev, const struct amba_id *id) drvdata->nr_tclk = of_property_count_strings(adev->dev.of_node, "qcom,tpdm-clks"); if (drvdata->nr_tclk > 0) { - drvdata->tclk = devm_kzalloc(dev, drvdata->nr_tclk * + drvdata->tclk = devm_kcalloc(dev, + drvdata->nr_tclk, sizeof(*drvdata->tclk), GFP_KERNEL); if (!drvdata->tclk) @@ -4459,7 +4460,8 @@ static int tpdm_probe(struct amba_device *adev, const struct amba_id *id) drvdata->nr_treg = of_property_count_strings(adev->dev.of_node, "qcom,tpdm-regs"); if (drvdata->nr_treg > 0) { - drvdata->treg = devm_kzalloc(dev, drvdata->nr_treg * + drvdata->treg = devm_kcalloc(dev, + drvdata->nr_treg, sizeof(*drvdata->treg), GFP_KERNEL); if (!drvdata->treg) diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c index 3374394a4df4..d11d0c6292f6 100644 --- a/drivers/hwtracing/coresight/of_coresight.c +++ b/drivers/hwtracing/coresight/of_coresight.c @@ -85,27 +85,31 @@ static int of_coresight_alloc_memory(struct device *dev, struct coresight_platform_data *pdata) { /* List of output port on this component */ - pdata->outports = devm_kzalloc(dev, pdata->nr_outport * + pdata->outports = devm_kcalloc(dev, + pdata->nr_outport, sizeof(*pdata->outports), GFP_KERNEL); if (!pdata->outports) return -ENOMEM; - pdata->source_names = devm_kzalloc(dev, pdata->nr_outport * - sizeof(*pdata->source_names), - GFP_KERNEL); + pdata->source_names = devm_kcalloc(dev, + pdata->nr_outport, + sizeof(*pdata->source_names), + GFP_KERNEL); if (!pdata->source_names) return -ENOMEM; /* Children connected to this component via @outports */ - pdata->child_names = devm_kzalloc(dev, pdata->nr_outport * + pdata->child_names = devm_kcalloc(dev, + pdata->nr_outport, sizeof(*pdata->child_names), GFP_KERNEL); if (!pdata->child_names) return -ENOMEM; /* Port number on the child this component is connected to */ - pdata->child_ports = devm_kzalloc(dev, pdata->nr_outport * + pdata->child_ports = devm_kcalloc(dev, + pdata->nr_outport, sizeof(*pdata->child_ports), GFP_KERNEL); if (!pdata->child_ports) @@ -149,8 +153,9 @@ of_coresight_get_reg_clk(struct device *dev, const struct device_node *node) reg_clk->nr_reg = nr_reg; reg_clk->nr_clk = nr_clk; if (nr_reg > 0) { - reg_clk->reg = devm_kzalloc(dev, nr_reg * - sizeof(reg_clk->reg), GFP_KERNEL); + reg_clk->reg = devm_kcalloc(dev, + nr_reg, sizeof(reg_clk->reg), + GFP_KERNEL); if (!reg_clk->reg) return ERR_PTR(-ENOMEM); @@ -165,8 +170,9 @@ of_coresight_get_reg_clk(struct device *dev, const struct device_node *node) } } if (nr_clk > 0) { - reg_clk->clk = devm_kzalloc(dev, nr_clk * - sizeof(reg_clk->clk), GFP_KERNEL); + reg_clk->clk = devm_kcalloc(dev, + nr_clk, sizeof(reg_clk->clk), + GFP_KERNEL); if (!reg_clk->clk) return ERR_PTR(-ENOMEM); @@ -336,7 +342,8 @@ struct coresight_cti_data *of_get_coresight_cti_data( return ERR_PTR(-EINVAL); if (ctidata->nr_ctis) { - ctidata->names = devm_kzalloc(dev, ctidata->nr_ctis * + ctidata->names = devm_kcalloc(dev, + ctidata->nr_ctis, sizeof(*ctidata->names), GFP_KERNEL); if (!ctidata->names) diff --git a/drivers/i2c/busses/i2c-amd756-s4882.c b/drivers/i2c/busses/i2c-amd756-s4882.c index 65e324054970..a2f5f992af7a 100644 --- a/drivers/i2c/busses/i2c-amd756-s4882.c +++ b/drivers/i2c/busses/i2c-amd756-s4882.c @@ -169,12 +169,12 @@ static int __init amd756_s4882_init(void) printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4882\n"); /* Define the 5 virtual adapters and algorithms structures */ - if (!(s4882_adapter = kzalloc(5 * sizeof(struct i2c_adapter), + if (!(s4882_adapter = kcalloc(5, sizeof(struct i2c_adapter), GFP_KERNEL))) { error = -ENOMEM; goto ERROR1; } - if (!(s4882_algo = kzalloc(5 * sizeof(struct i2c_algorithm), + if (!(s4882_algo = kcalloc(5, sizeof(struct i2c_algorithm), GFP_KERNEL))) { error = -ENOMEM; goto ERROR2; diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index d917cefc5a19..b13605718291 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c @@ -382,10 +382,8 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id) * Check for the message size against FIFO depth and set the * 'hold bus' bit if it is greater than FIFO depth. */ - if ((id->recv_count > CDNS_I2C_FIFO_DEPTH) || id->bus_hold_flag) + if (id->recv_count > CDNS_I2C_FIFO_DEPTH) ctrl_reg |= CDNS_I2C_CR_HOLD; - else - ctrl_reg = ctrl_reg & ~CDNS_I2C_CR_HOLD; cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET); @@ -442,11 +440,8 @@ static void cdns_i2c_msend(struct cdns_i2c *id) * Check for the message size against FIFO depth and set the * 'hold bus' bit if it is greater than FIFO depth. */ - if ((id->send_count > CDNS_I2C_FIFO_DEPTH) || id->bus_hold_flag) + if (id->send_count > CDNS_I2C_FIFO_DEPTH) ctrl_reg |= CDNS_I2C_CR_HOLD; - else - ctrl_reg = ctrl_reg & ~CDNS_I2C_CR_HOLD; - cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET); /* Clear the interrupts in interrupt status register. */ diff --git a/drivers/i2c/busses/i2c-msm-v2.c b/drivers/i2c/busses/i2c-msm-v2.c index 69c4a71826c0..42ef4f0472c2 100644 --- a/drivers/i2c/busses/i2c-msm-v2.c +++ b/drivers/i2c/busses/i2c-msm-v2.c @@ -1598,11 +1598,11 @@ static int i2c_msm_clk_path_init_structs(struct i2c_msm_ctrl *ctrl) i2c_msm_dbg(ctrl, MSM_PROF, "initializes path clock voting structs\n"); - paths = devm_kzalloc(ctrl->dev, sizeof(*paths) * 2, GFP_KERNEL); + paths = devm_kcalloc(ctrl->dev, 2, sizeof(*paths), GFP_KERNEL); if (!paths) return -ENOMEM; - usecases = devm_kzalloc(ctrl->dev, sizeof(*usecases) * 2, GFP_KERNEL); + usecases = devm_kcalloc(ctrl->dev, 2, sizeof(*usecases), GFP_KERNEL); if (!usecases) goto path_init_err; diff --git a/drivers/i2c/busses/i2c-nforce2-s4985.c b/drivers/i2c/busses/i2c-nforce2-s4985.c index 88eda09e73c0..58a0fbf0e074 100644 --- a/drivers/i2c/busses/i2c-nforce2-s4985.c +++ b/drivers/i2c/busses/i2c-nforce2-s4985.c @@ -164,12 +164,12 @@ static int __init nforce2_s4985_init(void) printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4985\n"); /* Define the 5 virtual adapters and algorithms structures */ - s4985_adapter = kzalloc(5 * sizeof(struct i2c_adapter), GFP_KERNEL); + s4985_adapter = kcalloc(5, sizeof(struct i2c_adapter), GFP_KERNEL); if (!s4985_adapter) { error = -ENOMEM; goto ERROR1; } - s4985_algo = kzalloc(5 * sizeof(struct i2c_algorithm), GFP_KERNEL); + s4985_algo = kcalloc(5, sizeof(struct i2c_algorithm), GFP_KERNEL); if (!s4985_algo) { error = -ENOMEM; goto ERROR2; diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 3241bb9d6c18..f6a1272c5854 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -381,7 +381,7 @@ static int nforce2_probe(struct pci_dev *dev, const struct pci_device_id *id) int res1, res2; /* we support 2 SMBus adapters */ - smbuses = kzalloc(2 * sizeof(struct nforce2_smbus), GFP_KERNEL); + smbuses = kcalloc(2, sizeof(struct nforce2_smbus), GFP_KERNEL); if (!smbuses) return -ENOMEM; pci_set_drvdata(dev, smbuses); diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c index 768585782484..ad591c9afbf7 100644 --- a/drivers/i2c/busses/i2c-qcom-geni.c +++ b/drivers/i2c/busses/i2c-qcom-geni.c @@ -356,6 +356,7 @@ static void gi2c_ev_cb(struct dma_chan *ch, struct msm_gpi_cb const *cb_str, case MSM_GPI_QUP_MAX_EVENT: /* fall through to stall impacted channel */ case MSM_GPI_QUP_CH_ERROR: + case MSM_GPI_QUP_FW_ERROR: case MSM_GPI_QUP_PENDING_EVENT: case MSM_GPI_QUP_EOT_DESC_MISMATCH: break; @@ -373,9 +374,9 @@ static void gi2c_ev_cb(struct dma_chan *ch, struct msm_gpi_cb const *cb_str, } if (cb_str->cb_event != MSM_GPI_QUP_NOTIFY) GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, - "GSI QN err:0x%x, status:0x%x, err:%d\n", - cb_str->error_log.error_code, - m_stat, cb_str->cb_event); + "GSI QN err:0x%x, status:0x%x, err:%d\n", + cb_str->error_log.error_code, m_stat, + cb_str->cb_event); } static void gi2c_gsi_cb_err(struct msm_gpi_dma_async_tx_cb_param *cb, @@ -498,6 +499,7 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], struct msm_gpi_tre *go_t = &gi2c->go_t; struct device *rx_dev = gi2c->wrapper_dev; struct device *tx_dev = gi2c->wrapper_dev; + reinit_completion(&gi2c->xfer); gi2c->cur = &msgs[i]; qcom_geni_i2c_calc_timeout(gi2c); @@ -745,6 +747,8 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, if (!timeout) geni_abort_m_cmd(gi2c->base); } + gi2c->cur_wr = 0; + gi2c->cur_rd = 0; gi2c->cur_wr = 0; gi2c->cur_rd = 0; @@ -807,9 +811,6 @@ static int geni_i2c_probe(struct platform_device *pdev) return -ENOMEM; gi2c->dev = &pdev->dev; - snprintf(boot_marker, sizeof(boot_marker), - "M - DRIVER GENI_I2C Init"); - place_marker(boot_marker); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) @@ -950,9 +951,6 @@ static int geni_i2c_probe(struct platform_device *pdev) pm_runtime_enable(gi2c->dev); i2c_add_adapter(&gi2c->adap); - snprintf(boot_marker, sizeof(boot_marker), - "M - DRIVER GENI_I2C_%d Ready", gi2c->adap.nr); - place_marker(boot_marker); dev_dbg(gi2c->dev, "I2C probed\n"); return 0; } diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c index 8f6903ec7aec..fa5d8e0068e2 100644 --- a/drivers/i2c/busses/i2c-qup.c +++ b/drivers/i2c/busses/i2c-qup.c @@ -1459,8 +1459,8 @@ static int qup_i2c_probe(struct platform_device *pdev) goto nodma; blocks = (MX_BLOCKS << 1) + 1; - qup->btx.sg = devm_kzalloc(&pdev->dev, - sizeof(*qup->btx.sg) * blocks, + qup->btx.sg = devm_kcalloc(&pdev->dev, + blocks, sizeof(*qup->btx.sg), GFP_KERNEL); if (!qup->btx.sg) { ret = -ENOMEM; @@ -1468,8 +1468,8 @@ static int qup_i2c_probe(struct platform_device *pdev) } sg_init_table(qup->btx.sg, blocks); - qup->brx.sg = devm_kzalloc(&pdev->dev, - sizeof(*qup->brx.sg) * blocks, + qup->brx.sg = devm_kcalloc(&pdev->dev, + blocks, sizeof(*qup->brx.sg), GFP_KERNEL); if (!qup->brx.sg) { ret = -ENOMEM; diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index c4066276eb7b..dd7dd7daba63 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -262,7 +262,8 @@ static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client, if (IS_ERR(rdwr_pa)) return PTR_ERR(rdwr_pa); - data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL); + data_ptrs = kmalloc_array(rdwr_arg.nmsgs, sizeof(u8 __user *), + GFP_KERNEL); if (data_ptrs == NULL) { kfree(rdwr_pa); return -ENOMEM; diff --git a/drivers/i2c/i2c-stub.c b/drivers/i2c/i2c-stub.c index 4a9ad91c5ba3..f31ec0861979 100644 --- a/drivers/i2c/i2c-stub.c +++ b/drivers/i2c/i2c-stub.c @@ -338,8 +338,9 @@ static int __init i2c_stub_allocate_banks(int i) chip->bank_mask >>= 1; } - chip->bank_words = kzalloc(chip->bank_mask * chip->bank_size * - sizeof(u16), GFP_KERNEL); + chip->bank_words = kcalloc(chip->bank_mask * chip->bank_size, + sizeof(u16), + GFP_KERNEL); if (!chip->bank_words) return -ENOMEM; diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c index 1a9973ede443..ddc4bd4ca13b 100644 --- a/drivers/i2c/muxes/i2c-mux-gpio.c +++ b/drivers/i2c/muxes/i2c-mux-gpio.c @@ -88,8 +88,8 @@ static int i2c_mux_gpio_probe_dt(struct gpiomux *mux, mux->data.n_values = of_get_child_count(np); - values = devm_kzalloc(&pdev->dev, - sizeof(*mux->data.values) * mux->data.n_values, + values = devm_kcalloc(&pdev->dev, + mux->data.n_values, sizeof(*mux->data.values), GFP_KERNEL); if (!values) { dev_err(&pdev->dev, "Cannot allocate values array"); @@ -111,8 +111,9 @@ static int i2c_mux_gpio_probe_dt(struct gpiomux *mux, return -EINVAL; } - gpios = devm_kzalloc(&pdev->dev, - sizeof(*mux->data.gpios) * mux->data.n_gpios, GFP_KERNEL); + gpios = devm_kcalloc(&pdev->dev, + mux->data.n_gpios, sizeof(*mux->data.gpios), + GFP_KERNEL); if (!gpios) { dev_err(&pdev->dev, "Cannot allocate gpios array"); return -ENOMEM; diff --git a/drivers/i2c/muxes/i2c-mux-reg.c b/drivers/i2c/muxes/i2c-mux-reg.c index d97031804de8..92af78769600 100644 --- a/drivers/i2c/muxes/i2c-mux-reg.c +++ b/drivers/i2c/muxes/i2c-mux-reg.c @@ -127,8 +127,8 @@ static int i2c_mux_reg_probe_dt(struct regmux *mux, else mux->data.write_only = false; - values = devm_kzalloc(&pdev->dev, - sizeof(*mux->data.values) * mux->data.n_values, + values = devm_kcalloc(&pdev->dev, + mux->data.n_values, sizeof(*mux->data.values), GFP_KERNEL); if (!values) { dev_err(&pdev->dev, "Cannot allocate values array"); diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c index 4b5dc0162e67..e52c58c29d9a 100644 --- a/drivers/ide/hpt366.c +++ b/drivers/ide/hpt366.c @@ -1455,7 +1455,7 @@ static int hpt366_init_one(struct pci_dev *dev, const struct pci_device_id *id) if (info == &hpt36x || info == &hpt374) dev2 = pci_get_slot(dev->bus, dev->devfn + 1); - dyn_info = kzalloc(sizeof(*dyn_info) * (dev2 ? 2 : 1), GFP_KERNEL); + dyn_info = kcalloc(dev2 ? 2 : 1, sizeof(*dyn_info), GFP_KERNEL); if (dyn_info == NULL) { printk(KERN_ERR "%s %s: out of memory!\n", d.name, pci_name(dev)); diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index eaf39e5db08b..cb0f42102a63 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -989,8 +989,9 @@ static int hwif_init(ide_hwif_t *hwif) if (!hwif->sg_max_nents) hwif->sg_max_nents = PRD_ENTRIES; - hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents, - GFP_KERNEL); + hwif->sg_table = kmalloc_array(hwif->sg_max_nents, + sizeof(struct scatterlist), + GFP_KERNEL); if (!hwif->sg_table) { printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name); goto out; diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c index 04029d18a696..36a64c8ea575 100644 --- a/drivers/ide/it821x.c +++ b/drivers/ide/it821x.c @@ -652,7 +652,7 @@ static int it821x_init_one(struct pci_dev *dev, const struct pci_device_id *id) struct it821x_dev *itdevs; int rc; - itdevs = kzalloc(2 * sizeof(*itdevs), GFP_KERNEL); + itdevs = kcalloc(2, sizeof(*itdevs), GFP_KERNEL); if (itdevs == NULL) { printk(KERN_ERR DRV_NAME " %s: out of memory\n", pci_name(dev)); return -ENOMEM; diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 492f6c8ba735..465b7b065ac8 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -629,8 +629,8 @@ static int at91_adc_trigger_init(struct iio_dev *idev) struct at91_adc_state *st = iio_priv(idev); int i, ret; - st->trig = devm_kzalloc(&idev->dev, - st->trigger_number * sizeof(*st->trig), + st->trig = devm_kcalloc(&idev->dev, + st->trigger_number, sizeof(*st->trig), GFP_KERNEL); if (st->trig == NULL) { @@ -919,7 +919,8 @@ static int at91_adc_probe_dt(struct at91_adc_state *st, st->registers = &st->caps->registers; st->num_channels = st->caps->num_channels; st->trigger_number = of_get_child_count(node); - st->trigger_list = devm_kzalloc(&idev->dev, st->trigger_number * + st->trigger_list = devm_kcalloc(&idev->dev, + st->trigger_number, sizeof(struct at91_adc_trigger), GFP_KERNEL); if (!st->trigger_list) { diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c index 03af02769370..728230b6f127 100644 --- a/drivers/iio/adc/max1027.c +++ b/drivers/iio/adc/max1027.c @@ -424,8 +424,8 @@ static int max1027_probe(struct spi_device *spi) indio_dev->num_channels = st->info->num_channels; indio_dev->available_scan_masks = st->info->available_scan_masks; - st->buffer = devm_kmalloc(&indio_dev->dev, - indio_dev->num_channels * 2, + st->buffer = devm_kmalloc_array(&indio_dev->dev, + indio_dev->num_channels, 2, GFP_KERNEL); if (st->buffer == NULL) { dev_err(&indio_dev->dev, "Can't allocate buffer\n"); diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c index 80eada4886b3..7f255486bff0 100644 --- a/drivers/iio/adc/max1363.c +++ b/drivers/iio/adc/max1363.c @@ -1455,8 +1455,8 @@ static int max1363_alloc_scan_masks(struct iio_dev *indio_dev) int i; masks = devm_kzalloc(&indio_dev->dev, - BITS_TO_LONGS(MAX1363_MAX_CHANNELS) * sizeof(long) * - (st->chip_info->num_modes + 1), GFP_KERNEL); + array3_size(BITS_TO_LONGS(MAX1363_MAX_CHANNELS), sizeof(long), (st->chip_info->num_modes + 1)), + GFP_KERNEL); if (!masks) return -ENOMEM; diff --git a/drivers/iio/adc/qcom-spmi-adc5.c b/drivers/iio/adc/qcom-spmi-adc5.c index e584d0f18875..ce7ec35d417a 100644 --- a/drivers/iio/adc/qcom-spmi-adc5.c +++ b/drivers/iio/adc/qcom-spmi-adc5.c @@ -794,6 +794,10 @@ static const struct adc_channels adc_chans_rev2[ADC_MAX_CHANNEL] = { SCALE_HW_CALIB_THERM_100K_PULLUP) [ANA_IN] = ADC_CHAN_TEMP("drax_temp", 1, SCALE_HW_CALIB_PMIC_THERM) + [ADC_AMUX_THM1] = ADC_CHAN_VOLT("amux_thm1", 1, + SCALE_HW_CALIB_DEFAULT) + [ADC_AMUX_THM3] = ADC_CHAN_VOLT("amux_thm3", 1, + SCALE_HW_CALIB_DEFAULT) }; static int adc_get_dt_channel_data(struct device *dev, diff --git a/drivers/iio/adc/twl6030-gpadc.c b/drivers/iio/adc/twl6030-gpadc.c index bc0e60b9da45..b74a1f410ff8 100644 --- a/drivers/iio/adc/twl6030-gpadc.c +++ b/drivers/iio/adc/twl6030-gpadc.c @@ -899,9 +899,10 @@ static int twl6030_gpadc_probe(struct platform_device *pdev) gpadc = iio_priv(indio_dev); - gpadc->twl6030_cal_tbl = devm_kzalloc(dev, - sizeof(*gpadc->twl6030_cal_tbl) * - pdata->nchannels, GFP_KERNEL); + gpadc->twl6030_cal_tbl = devm_kcalloc(dev, + pdata->nchannels, + sizeof(*gpadc->twl6030_cal_tbl), + GFP_KERNEL); if (!gpadc->twl6030_cal_tbl) return -ENOMEM; diff --git a/drivers/iio/dac/ad5592r-base.c b/drivers/iio/dac/ad5592r-base.c index 69bde5909854..93c9b461c955 100644 --- a/drivers/iio/dac/ad5592r-base.c +++ b/drivers/iio/dac/ad5592r-base.c @@ -537,8 +537,9 @@ static int ad5592r_alloc_channels(struct ad5592r_state *st) st->channel_offstate[reg] = tmp; } - channels = devm_kzalloc(st->dev, - (1 + 2 * num_channels) * sizeof(*channels), GFP_KERNEL); + channels = devm_kcalloc(st->dev, + 1 + 2 * num_channels, sizeof(*channels), + GFP_KERNEL); if (!channels) return -ENOMEM; diff --git a/drivers/iio/imu/adis16400_buffer.c b/drivers/iio/imu/adis16400_buffer.c index e70a5339acb1..3fc11aec98b9 100644 --- a/drivers/iio/imu/adis16400_buffer.c +++ b/drivers/iio/imu/adis16400_buffer.c @@ -38,8 +38,11 @@ int adis16400_update_scan_mode(struct iio_dev *indio_dev, return -ENOMEM; adis->buffer = kzalloc(burst_length + sizeof(u16), GFP_KERNEL); - if (!adis->buffer) + if (!adis->buffer) { + kfree(adis->xfer); + adis->xfer = NULL; return -ENOMEM; + } tx = adis->buffer + burst_length; tx[0] = ADIS_READ_REG(ADIS16400_GLOB_CMD); diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c index 36607d52fee0..76643c5571aa 100644 --- a/drivers/iio/imu/adis_buffer.c +++ b/drivers/iio/imu/adis_buffer.c @@ -38,7 +38,7 @@ int adis_update_scan_mode(struct iio_dev *indio_dev, if (!adis->xfer) return -ENOMEM; - adis->buffer = kzalloc(indio_dev->scan_bytes * 2, GFP_KERNEL); + adis->buffer = kcalloc(indio_dev->scan_bytes, 2, GFP_KERNEL); if (!adis->buffer) return -ENOMEM; diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 85dae32e9c4e..ba1b0f40df46 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -436,7 +436,7 @@ struct iio_channel *iio_channel_get_all(struct device *dev) } /* NULL terminated array to save passing size */ - chans = kzalloc(sizeof(*chans)*(nummaps + 1), GFP_KERNEL); + chans = kcalloc(nummaps + 1, sizeof(*chans), GFP_KERNEL); if (chans == NULL) { ret = -ENOMEM; goto error_ret; diff --git a/drivers/iio/multiplexer/iio-mux.c b/drivers/iio/multiplexer/iio-mux.c index 74831fcd0313..805c66517468 100644 --- a/drivers/iio/multiplexer/iio-mux.c +++ b/drivers/iio/multiplexer/iio-mux.c @@ -282,9 +282,10 @@ static int mux_configure_channel(struct device *dev, struct mux *mux, if (!page) return -ENOMEM; } - child->ext_info_cache = devm_kzalloc(dev, - sizeof(*child->ext_info_cache) * - num_ext_info, GFP_KERNEL); + child->ext_info_cache = devm_kcalloc(dev, + num_ext_info, + sizeof(*child->ext_info_cache), + GFP_KERNEL); if (!child->ext_info_cache) return -ENOMEM; diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c index 896cfd9303b0..afbcbbe98464 100644 --- a/drivers/infiniband/core/cache.c +++ b/drivers/infiniband/core/cache.c @@ -1074,16 +1074,16 @@ static void ib_cache_update(struct ib_device *device, goto err; } - pkey_cache = kmalloc(sizeof *pkey_cache + tprops->pkey_tbl_len * - sizeof *pkey_cache->table, GFP_KERNEL); + pkey_cache = kmalloc(struct_size(pkey_cache, table, tprops->pkey_tbl_len), + GFP_KERNEL); if (!pkey_cache) goto err; pkey_cache->table_len = tprops->pkey_tbl_len; if (!use_roce_gid_table) { - gid_cache = kmalloc(sizeof(*gid_cache) + tprops->gid_tbl_len * - sizeof(*gid_cache->table), GFP_KERNEL); + gid_cache = kmalloc(struct_size(gid_cache, table, tprops->gid_tbl_len), + GFP_KERNEL); if (!gid_cache) goto err; @@ -1197,8 +1197,9 @@ int ib_cache_setup_one(struct ib_device *device) rwlock_init(&device->cache.lock); device->cache.ports = - kzalloc(sizeof(*device->cache.ports) * - (rdma_end_port(device) - rdma_start_port(device) + 1), GFP_KERNEL); + kcalloc(rdma_end_port(device) - rdma_start_port(device) + 1, + sizeof(*device->cache.ports), + GFP_KERNEL); if (!device->cache.ports) return -ENOMEM; diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 6e8af2b91492..9d1f92782936 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -1878,8 +1878,8 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id, rt = &id->route; rt->num_paths = ib_event->param.req_rcvd.alternate_path ? 2 : 1; - rt->path_rec = kmalloc(sizeof *rt->path_rec * rt->num_paths, - GFP_KERNEL); + rt->path_rec = kmalloc_array(rt->num_paths, sizeof(*rt->path_rec), + GFP_KERNEL); if (!rt->path_rec) goto err; diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 6b0d1d8609ca..848b5115def0 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -335,8 +335,8 @@ static int read_port_immutable(struct ib_device *device) * Therefore port_immutable is declared as a 1 based array with * potential empty slots at the beginning. */ - device->port_immutable = kzalloc(sizeof(*device->port_immutable) - * (end_port + 1), + device->port_immutable = kcalloc(end_port + 1, + sizeof(*device->port_immutable), GFP_KERNEL); if (!device->port_immutable) return -ENOMEM; diff --git a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c index 84d2615b5d4b..c89b7abed72f 100644 --- a/drivers/infiniband/core/fmr_pool.c +++ b/drivers/infiniband/core/fmr_pool.c @@ -235,8 +235,9 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd, if (params->cache) { pool->cache_bucket = - kmalloc(IB_FMR_HASH_SIZE * sizeof *pool->cache_bucket, - GFP_KERNEL); + kmalloc_array(IB_FMR_HASH_SIZE, + sizeof(*pool->cache_bucket), + GFP_KERNEL); if (!pool->cache_bucket) { ret = -ENOMEM; goto out_free_pool; diff --git a/drivers/infiniband/core/iwpm_util.c b/drivers/infiniband/core/iwpm_util.c index cb0fecc958b5..242d23ebba7d 100644 --- a/drivers/infiniband/core/iwpm_util.c +++ b/drivers/infiniband/core/iwpm_util.c @@ -56,14 +56,16 @@ int iwpm_init(u8 nl_client) int ret = 0; mutex_lock(&iwpm_admin_lock); if (atomic_read(&iwpm_admin.refcount) == 0) { - iwpm_hash_bucket = kzalloc(IWPM_MAPINFO_HASH_SIZE * - sizeof(struct hlist_head), GFP_KERNEL); + iwpm_hash_bucket = kcalloc(IWPM_MAPINFO_HASH_SIZE, + sizeof(struct hlist_head), + GFP_KERNEL); if (!iwpm_hash_bucket) { ret = -ENOMEM; goto init_exit; } - iwpm_reminfo_bucket = kzalloc(IWPM_REMINFO_HASH_SIZE * - sizeof(struct hlist_head), GFP_KERNEL); + iwpm_reminfo_bucket = kcalloc(IWPM_REMINFO_HASH_SIZE, + sizeof(struct hlist_head), + GFP_KERNEL); if (!iwpm_reminfo_bucket) { kfree(iwpm_hash_bucket); ret = -ENOMEM; diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c index 688ce1846911..46a84d947918 100644 --- a/drivers/infiniband/core/umem_odp.c +++ b/drivers/infiniband/core/umem_odp.c @@ -252,13 +252,13 @@ struct ib_umem *ib_alloc_odp_umem(struct ib_ucontext *context, mutex_init(&odp_data->umem_mutex); init_completion(&odp_data->notifier_completion); - odp_data->page_list = vzalloc(pages * sizeof(*odp_data->page_list)); + odp_data->page_list = vzalloc(array_size(pages, sizeof(*odp_data->page_list))); if (!odp_data->page_list) { ret = -ENOMEM; goto out_odp_data; } - odp_data->dma_list = vzalloc(pages * sizeof(*odp_data->dma_list)); + odp_data->dma_list = vzalloc(array_size(pages, sizeof(*odp_data->dma_list))); if (!odp_data->dma_list) { ret = -ENOMEM; goto out_page_list; @@ -339,15 +339,13 @@ int ib_umem_odp_get(struct ib_ucontext *context, struct ib_umem *umem, init_completion(&umem->odp_data->notifier_completion); if (ib_umem_num_pages(umem)) { - umem->odp_data->page_list = vzalloc(ib_umem_num_pages(umem) * - sizeof(*umem->odp_data->page_list)); + umem->odp_data->page_list = vzalloc(array_size(sizeof(*umem->odp_data->page_list), ib_umem_num_pages(umem))); if (!umem->odp_data->page_list) { ret_val = -ENOMEM; goto out_odp_data; } - umem->odp_data->dma_list = vzalloc(ib_umem_num_pages(umem) * - sizeof(*umem->odp_data->dma_list)); + umem->odp_data->dma_list = vzalloc(array_size(sizeof(*umem->odp_data->dma_list), ib_umem_num_pages(umem))); if (!umem->odp_data->dma_list) { ret_val = -ENOMEM; goto out_page_list; diff --git a/drivers/infiniband/core/uverbs_ioctl_merge.c b/drivers/infiniband/core/uverbs_ioctl_merge.c index 48a99dce976c..a73ae212f63d 100644 --- a/drivers/infiniband/core/uverbs_ioctl_merge.c +++ b/drivers/infiniband/core/uverbs_ioctl_merge.c @@ -297,8 +297,7 @@ static struct uverbs_method_spec *build_method_with_attrs(const struct uverbs_me if (max_attr_buckets >= 0) num_attr_buckets = max_attr_buckets + 1; - method = kzalloc(sizeof(*method) + - num_attr_buckets * sizeof(*method->attr_buckets), + method = kzalloc(struct_size(method, attr_buckets, num_attr_buckets), GFP_KERNEL); if (!method) return ERR_PTR(-ENOMEM); @@ -446,9 +445,8 @@ static struct uverbs_object_spec *build_object_with_methods(const struct uverbs_ if (max_method_buckets >= 0) num_method_buckets = max_method_buckets + 1; - object = kzalloc(sizeof(*object) + - num_method_buckets * - sizeof(*object->method_buckets), GFP_KERNEL); + object = kzalloc(struct_size(object, method_buckets, num_method_buckets), + GFP_KERNEL); if (!object) return ERR_PTR(-ENOMEM); @@ -469,8 +467,7 @@ static struct uverbs_object_spec *build_object_with_methods(const struct uverbs_ if (methods_max_bucket < 0) continue; - hash = kzalloc(sizeof(*hash) + - sizeof(*hash->methods) * (methods_max_bucket + 1), + hash = kzalloc(struct_size(hash, methods, (methods_max_bucket + 1)), GFP_KERNEL); if (!hash) { res = -ENOMEM; @@ -579,8 +576,7 @@ struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees, if (max_object_buckets >= 0) num_objects_buckets = max_object_buckets + 1; - root_spec = kzalloc(sizeof(*root_spec) + - num_objects_buckets * sizeof(*root_spec->object_buckets), + root_spec = kzalloc(struct_size(root_spec, object_buckets, num_objects_buckets), GFP_KERNEL); if (!root_spec) return ERR_PTR(-ENOMEM); @@ -603,8 +599,7 @@ struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees, if (objects_max_bucket < 0) continue; - hash = kzalloc(sizeof(*hash) + - sizeof(*hash->objects) * (objects_max_bucket + 1), + hash = kzalloc(struct_size(hash, objects, (objects_max_bucket + 1)), GFP_KERNEL); if (!hash) { res = -ENOMEM; diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c index 3eff6541bd6f..7da0d365ebd2 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c @@ -279,7 +279,7 @@ int cxio_create_qp(struct cxio_rdev *rdev_p, u32 kernel_domain, if (!wq->qpid) return -ENOMEM; - wq->rq = kzalloc(depth * sizeof(struct t3_swrq), GFP_KERNEL); + wq->rq = kcalloc(depth, sizeof(struct t3_swrq), GFP_KERNEL); if (!wq->rq) goto err1; @@ -287,7 +287,7 @@ int cxio_create_qp(struct cxio_rdev *rdev_p, u32 kernel_domain, if (!wq->rq_addr) goto err2; - wq->sq = kzalloc(depth * sizeof(struct t3_swsq), GFP_KERNEL); + wq->sq = kcalloc(depth, sizeof(struct t3_swsq), GFP_KERNEL); if (!wq->sq) goto err3; diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index 99f232e3ea93..ef64a8f5f412 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c @@ -868,8 +868,9 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev) rdev->status_page->cq_size = rdev->lldi.vr->cq.size; if (c4iw_wr_log) { - rdev->wr_log = kzalloc((1 << c4iw_wr_log_size_order) * - sizeof(*rdev->wr_log), GFP_KERNEL); + rdev->wr_log = kcalloc(1 << c4iw_wr_log_size_order, + sizeof(*rdev->wr_log), + GFP_KERNEL); if (rdev->wr_log) { rdev->wr_log_size = 1 << c4iw_wr_log_size_order; atomic_set(&rdev->wr_log_idx, 0); @@ -1458,7 +1459,7 @@ static void recover_queues(struct uld_ctx *ctx) ctx->dev->db_state = RECOVERY; idr_for_each(&ctx->dev->qpidr, count_qps, &count); - qp_list.qps = kzalloc(count * sizeof *qp_list.qps, GFP_ATOMIC); + qp_list.qps = kcalloc(count, sizeof(*qp_list.qps), GFP_ATOMIC); if (!qp_list.qps) { spin_unlock_irq(&ctx->dev->lock); return; diff --git a/drivers/infiniband/hw/cxgb4/id_table.c b/drivers/infiniband/hw/cxgb4/id_table.c index 0161ae6ad629..1304ab4ab50b 100644 --- a/drivers/infiniband/hw/cxgb4/id_table.c +++ b/drivers/infiniband/hw/cxgb4/id_table.c @@ -93,8 +93,8 @@ int c4iw_id_table_alloc(struct c4iw_id_table *alloc, u32 start, u32 num, alloc->last = 0; alloc->max = num; spin_lock_init(&alloc->lock); - alloc->table = kmalloc(BITS_TO_LONGS(num) * sizeof(long), - GFP_KERNEL); + alloc->table = kmalloc_array(BITS_TO_LONGS(num), sizeof(long), + GFP_KERNEL); if (!alloc->table) return -ENOMEM; diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 24952af51a54..96cde77717c9 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -216,15 +216,15 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, } if (!user) { - wq->sq.sw_sq = kzalloc(wq->sq.size * sizeof *wq->sq.sw_sq, - GFP_KERNEL); + wq->sq.sw_sq = kcalloc(wq->sq.size, sizeof(*wq->sq.sw_sq), + GFP_KERNEL); if (!wq->sq.sw_sq) { ret = -ENOMEM; goto free_rq_qid; } - wq->rq.sw_rq = kzalloc(wq->rq.size * sizeof *wq->rq.sw_rq, - GFP_KERNEL); + wq->rq.sw_rq = kcalloc(wq->rq.size, sizeof(*wq->rq.sw_rq), + GFP_KERNEL); if (!wq->rq.sw_rq) { ret = -ENOMEM; goto free_sw_sq; diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c index 27e7de4c4a34..c9b73c339665 100644 --- a/drivers/infiniband/hw/hfi1/init.c +++ b/drivers/infiniband/hw/hfi1/init.c @@ -174,7 +174,7 @@ int hfi1_create_kctxts(struct hfi1_devdata *dd) u16 i; int ret; - dd->rcd = kzalloc_node(dd->num_rcv_contexts * sizeof(*dd->rcd), + dd->rcd = kcalloc_node(dd->num_rcv_contexts, sizeof(*dd->rcd), GFP_KERNEL, dd->node); if (!dd->rcd) return -ENOMEM; @@ -424,15 +424,14 @@ int hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, int numa, * The resulting value will be rounded down to the closest * multiple of dd->rcv_entries.group_size. */ - rcd->egrbufs.buffers = kzalloc_node( - rcd->egrbufs.count * sizeof(*rcd->egrbufs.buffers), - GFP_KERNEL, numa); + rcd->egrbufs.buffers = kcalloc_node(rcd->egrbufs.count, + sizeof(*rcd->egrbufs.buffers), + GFP_KERNEL, numa); if (!rcd->egrbufs.buffers) goto bail; - rcd->egrbufs.rcvtids = kzalloc_node( - rcd->egrbufs.count * - sizeof(*rcd->egrbufs.rcvtids), - GFP_KERNEL, numa); + rcd->egrbufs.rcvtids = kcalloc_node(rcd->egrbufs.count, + sizeof(*rcd->egrbufs.rcvtids), + GFP_KERNEL, numa); if (!rcd->egrbufs.rcvtids) goto bail; rcd->egrbufs.size = eager_buffer_size; diff --git a/drivers/infiniband/hw/hfi1/pio.c b/drivers/infiniband/hw/hfi1/pio.c index 07bf282fd8aa..f90d0f8244d8 100644 --- a/drivers/infiniband/hw/hfi1/pio.c +++ b/drivers/infiniband/hw/hfi1/pio.c @@ -876,8 +876,9 @@ struct send_context *sc_alloc(struct hfi1_devdata *dd, int type, * so head == tail can mean empty. */ sc->sr_size = sci->credits + 1; - sc->sr = kzalloc_node(sizeof(union pio_shadow_ring) * - sc->sr_size, GFP_KERNEL, numa); + sc->sr = kcalloc_node(sc->sr_size, + sizeof(union pio_shadow_ring), + GFP_KERNEL, numa); if (!sc->sr) { sc_free(sc); return NULL; @@ -2030,9 +2031,9 @@ int init_pervl_scs(struct hfi1_devdata *dd) hfi1_init_ctxt(dd->vld[15].sc); dd->vld[15].mtu = enum_to_mtu(OPA_MTU_2048); - dd->kernel_send_context = kzalloc_node(dd->num_send_contexts * - sizeof(struct send_context *), - GFP_KERNEL, dd->node); + dd->kernel_send_context = kcalloc_node(dd->num_send_contexts, + sizeof(struct send_context *), + GFP_KERNEL, dd->node); if (!dd->kernel_send_context) goto freesc15; diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c index 741938409f8e..3ca4d228b91e 100644 --- a/drivers/infiniband/hw/hfi1/sdma.c +++ b/drivers/infiniband/hw/hfi1/sdma.c @@ -1469,9 +1469,7 @@ int sdma_init(struct hfi1_devdata *dd, u8 port) GFP_KERNEL); if (!sde->tx_ring) sde->tx_ring = - vzalloc( - sizeof(struct sdma_txreq *) * - descq_cnt); + vzalloc(array_size(descq_cnt, sizeof(struct sdma_txreq *))); if (!sde->tx_ring) goto bail; } diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c index e387360e3780..0da6cea71f87 100644 --- a/drivers/infiniband/hw/hns/hns_roce_mr.c +++ b/drivers/infiniband/hw/hns/hns_roce_mr.c @@ -142,7 +142,7 @@ static int hns_roce_buddy_init(struct hns_roce_buddy *buddy, int max_order) buddy->bits[i] = kcalloc(s, sizeof(long), GFP_KERNEL | __GFP_NOWARN); if (!buddy->bits[i]) { - buddy->bits[i] = vzalloc(s * sizeof(long)); + buddy->bits[i] = vzalloc(array_size(s, sizeof(long))); if (!buddy->bits[i]) goto err_out_free; } diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index c69158ccab82..9e30791f7dcf 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c @@ -1613,7 +1613,8 @@ static int mlx4_ib_alloc_pv_bufs(struct mlx4_ib_demux_pv_ctx *ctx, tun_qp = &ctx->qp[qp_type]; - tun_qp->ring = kzalloc(sizeof (struct mlx4_ib_buf) * MLX4_NUM_TUNNEL_BUFS, + tun_qp->ring = kcalloc(MLX4_NUM_TUNNEL_BUFS, + sizeof(struct mlx4_ib_buf), GFP_KERNEL); if (!tun_qp->ring) return -ENOMEM; diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 3f8511104c5b..859d3f576785 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -305,7 +305,8 @@ static int mlx4_ib_add_gid(struct ib_device *device, ctx->refcount++; } if (!ret && hw_update) { - gids = kmalloc(sizeof(*gids) * MLX4_MAX_PORT_GIDS, GFP_ATOMIC); + gids = kmalloc_array(MLX4_MAX_PORT_GIDS, sizeof(*gids), + GFP_ATOMIC); if (!gids) { ret = -ENOMEM; } else { @@ -360,7 +361,8 @@ static int mlx4_ib_del_gid(struct ib_device *device, if (!ret && hw_update) { int i; - gids = kmalloc(sizeof(*gids) * MLX4_MAX_PORT_GIDS, GFP_ATOMIC); + gids = kmalloc_array(MLX4_MAX_PORT_GIDS, sizeof(*gids), + GFP_ATOMIC); if (!gids) { ret = -ENOMEM; } else { @@ -2880,9 +2882,9 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) goto err_counter; ibdev->ib_uc_qpns_bitmap = - kmalloc(BITS_TO_LONGS(ibdev->steer_qpn_count) * - sizeof(long), - GFP_KERNEL); + kmalloc_array(BITS_TO_LONGS(ibdev->steer_qpn_count), + sizeof(long), + GFP_KERNEL); if (!ibdev->ib_uc_qpns_bitmap) goto err_steer_qp_release; diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index df1ecd29057f..f7261fe07d5b 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -573,8 +573,8 @@ static int alloc_proxy_bufs(struct ib_device *dev, struct mlx4_ib_qp *qp) int i; qp->sqp_proxy_rcv = - kmalloc(sizeof (struct mlx4_ib_buf) * qp->rq.wqe_cnt, - GFP_KERNEL); + kmalloc_array(qp->rq.wqe_cnt, sizeof(struct mlx4_ib_buf), + GFP_KERNEL); if (!qp->sqp_proxy_rcv) return -ENOMEM; for (i = 0; i < qp->rq.wqe_cnt; i++) { diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c index 93d67d97c279..f5de5adc9b1a 100644 --- a/drivers/infiniband/hw/mlx5/srq.c +++ b/drivers/infiniband/hw/mlx5/srq.c @@ -127,7 +127,7 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq, goto err_umem; } - in->pas = kvzalloc(sizeof(*in->pas) * ncont, GFP_KERNEL); + in->pas = kvcalloc(ncont, sizeof(*in->pas), GFP_KERNEL); if (!in->pas) { err = -ENOMEM; goto err_umem; @@ -189,7 +189,7 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq, } mlx5_ib_dbg(dev, "srq->buf.page_shift = %d\n", srq->buf.page_shift); - in->pas = kvzalloc(sizeof(*in->pas) * srq->buf.npages, GFP_KERNEL); + in->pas = kvcalloc(srq->buf.npages, sizeof(*in->pas), GFP_KERNEL); if (!in->pas) { err = -ENOMEM; goto err_buf; diff --git a/drivers/infiniband/hw/mthca/mthca_allocator.c b/drivers/infiniband/hw/mthca/mthca_allocator.c index b4e0cf4e95cd..aaf10dd5364d 100644 --- a/drivers/infiniband/hw/mthca/mthca_allocator.c +++ b/drivers/infiniband/hw/mthca/mthca_allocator.c @@ -90,8 +90,8 @@ int mthca_alloc_init(struct mthca_alloc *alloc, u32 num, u32 mask, alloc->max = num; alloc->mask = mask; spin_lock_init(&alloc->lock); - alloc->table = kmalloc(BITS_TO_LONGS(num) * sizeof (long), - GFP_KERNEL); + alloc->table = kmalloc_array(BITS_TO_LONGS(num), sizeof(long), + GFP_KERNEL); if (!alloc->table) return -ENOMEM; @@ -162,7 +162,8 @@ int mthca_array_init(struct mthca_array *array, int nent) int npage = (nent * sizeof (void *) + PAGE_SIZE - 1) / PAGE_SIZE; int i; - array->page_list = kmalloc(npage * sizeof *array->page_list, GFP_KERNEL); + array->page_list = kmalloc_array(npage, sizeof(*array->page_list), + GFP_KERNEL); if (!array->page_list) return -ENOMEM; @@ -220,7 +221,8 @@ int mthca_buf_alloc(struct mthca_dev *dev, int size, int max_direct, npages *= 2; } - dma_list = kmalloc(npages * sizeof *dma_list, GFP_KERNEL); + dma_list = kmalloc_array(npages, sizeof(*dma_list), + GFP_KERNEL); if (!dma_list) goto err_free; @@ -231,12 +233,14 @@ int mthca_buf_alloc(struct mthca_dev *dev, int size, int max_direct, npages = (size + PAGE_SIZE - 1) / PAGE_SIZE; shift = PAGE_SHIFT; - dma_list = kmalloc(npages * sizeof *dma_list, GFP_KERNEL); + dma_list = kmalloc_array(npages, sizeof(*dma_list), + GFP_KERNEL); if (!dma_list) return -ENOMEM; - buf->page_list = kmalloc(npages * sizeof *buf->page_list, - GFP_KERNEL); + buf->page_list = kmalloc_array(npages, + sizeof(*buf->page_list), + GFP_KERNEL); if (!buf->page_list) goto err_out; diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index 419a2a20c047..83aa47eb81a9 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -565,9 +565,9 @@ int mthca_cmd_use_events(struct mthca_dev *dev) { int i; - dev->cmd.context = kmalloc(dev->cmd.max_cmds * - sizeof (struct mthca_cmd_context), - GFP_KERNEL); + dev->cmd.context = kmalloc_array(dev->cmd.max_cmds, + sizeof(struct mthca_cmd_context), + GFP_KERNEL); if (!dev->cmd.context) return -ENOMEM; diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c index 690201738993..30400ea4808b 100644 --- a/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/drivers/infiniband/hw/mthca/mthca_eq.c @@ -479,15 +479,15 @@ static int mthca_create_eq(struct mthca_dev *dev, eq->nent = roundup_pow_of_two(max(nent, 2)); npages = ALIGN(eq->nent * MTHCA_EQ_ENTRY_SIZE, PAGE_SIZE) / PAGE_SIZE; - eq->page_list = kmalloc(npages * sizeof *eq->page_list, - GFP_KERNEL); + eq->page_list = kmalloc_array(npages, sizeof(*eq->page_list), + GFP_KERNEL); if (!eq->page_list) goto err_out; for (i = 0; i < npages; ++i) eq->page_list[i].buf = NULL; - dma_list = kmalloc(npages * sizeof *dma_list, GFP_KERNEL); + dma_list = kmalloc_array(npages, sizeof(*dma_list), GFP_KERNEL); if (!dma_list) goto err_out_free; diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c index c6fe89d79248..cdd045694942 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c @@ -367,7 +367,7 @@ struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev, obj_per_chunk = MTHCA_TABLE_CHUNK_SIZE / obj_size; num_icm = DIV_ROUND_UP(nobj, obj_per_chunk); - table = kmalloc(sizeof *table + num_icm * sizeof *table->icm, GFP_KERNEL); + table = kmalloc(struct_size(table, icm, num_icm), GFP_KERNEL); if (!table) return NULL; @@ -529,7 +529,7 @@ struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev) return NULL; npages = dev->uar_table.uarc_size / MTHCA_ICM_PAGE_SIZE; - db_tab = kmalloc(sizeof *db_tab + npages * sizeof *db_tab->page, GFP_KERNEL); + db_tab = kmalloc(struct_size(db_tab, page, npages), GFP_KERNEL); if (!db_tab) return ERR_PTR(-ENOMEM); @@ -713,9 +713,9 @@ int mthca_init_db_tab(struct mthca_dev *dev) dev->db_tab->max_group1 = 0; dev->db_tab->min_group2 = dev->db_tab->npages - 1; - dev->db_tab->page = kmalloc(dev->db_tab->npages * - sizeof *dev->db_tab->page, - GFP_KERNEL); + dev->db_tab->page = kmalloc_array(dev->db_tab->npages, + sizeof(*dev->db_tab->page), + GFP_KERNEL); if (!dev->db_tab->page) { kfree(dev->db_tab); return -ENOMEM; diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c index ed9a989e501b..6686042aafb4 100644 --- a/drivers/infiniband/hw/mthca/mthca_mr.c +++ b/drivers/infiniband/hw/mthca/mthca_mr.c @@ -144,7 +144,7 @@ static int mthca_buddy_init(struct mthca_buddy *buddy, int max_order) buddy->max_order = max_order; spin_lock_init(&buddy->lock); - buddy->bits = kzalloc((buddy->max_order + 1) * sizeof (long *), + buddy->bits = kcalloc(buddy->max_order + 1, sizeof(long *), GFP_KERNEL); buddy->num_free = kcalloc((buddy->max_order + 1), sizeof *buddy->num_free, GFP_KERNEL); @@ -153,7 +153,7 @@ static int mthca_buddy_init(struct mthca_buddy *buddy, int max_order) for (i = 0; i <= buddy->max_order; ++i) { s = BITS_TO_LONGS(1 << (buddy->max_order - i)); - buddy->bits[i] = kmalloc(s * sizeof (long), GFP_KERNEL); + buddy->bits[i] = kmalloc_array(s, sizeof(long), GFP_KERNEL); if (!buddy->bits[i]) goto err_out_free; bitmap_zero(buddy->bits[i], diff --git a/drivers/infiniband/hw/mthca/mthca_profile.c b/drivers/infiniband/hw/mthca/mthca_profile.c index 15d064479ef6..7ea970774839 100644 --- a/drivers/infiniband/hw/mthca/mthca_profile.c +++ b/drivers/infiniband/hw/mthca/mthca_profile.c @@ -79,7 +79,7 @@ s64 mthca_make_profile(struct mthca_dev *dev, struct mthca_resource *profile; int i, j; - profile = kzalloc(MTHCA_RES_NUM * sizeof *profile, GFP_KERNEL); + profile = kcalloc(MTHCA_RES_NUM, sizeof(*profile), GFP_KERNEL); if (!profile) return -ENOMEM; diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index d21960cd9a49..af1c49d70b89 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c @@ -1054,8 +1054,8 @@ static int mthca_alloc_wqe_buf(struct mthca_dev *dev, size = PAGE_ALIGN(qp->send_wqe_offset + (qp->sq.max << qp->sq.wqe_shift)); - qp->wrid = kmalloc((qp->rq.max + qp->sq.max) * sizeof (u64), - GFP_KERNEL); + qp->wrid = kmalloc_array(qp->rq.max + qp->sq.max, sizeof(u64), + GFP_KERNEL); if (!qp->wrid) goto err_out; diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c index d22f970480c0..f79732bc73b4 100644 --- a/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/drivers/infiniband/hw/mthca/mthca_srq.c @@ -155,7 +155,7 @@ static int mthca_alloc_srq_buf(struct mthca_dev *dev, struct mthca_pd *pd, if (pd->ibpd.uobject) return 0; - srq->wrid = kmalloc(srq->max * sizeof (u64), GFP_KERNEL); + srq->wrid = kmalloc_array(srq->max, sizeof(u64), GFP_KERNEL); if (!srq->wrid) return -ENOMEM; diff --git a/drivers/infiniband/hw/nes/nes_mgt.c b/drivers/infiniband/hw/nes/nes_mgt.c index 77226cf4ea02..d4afee7860d8 100644 --- a/drivers/infiniband/hw/nes/nes_mgt.c +++ b/drivers/infiniband/hw/nes/nes_mgt.c @@ -877,7 +877,8 @@ int nes_init_mgt_qp(struct nes_device *nesdev, struct net_device *netdev, struct int ret; /* Allocate space the all mgt QPs once */ - mgtvnic = kzalloc(NES_MGT_QP_COUNT * sizeof(struct nes_vnic_mgt), GFP_KERNEL); + mgtvnic = kcalloc(NES_MGT_QP_COUNT, sizeof(struct nes_vnic_mgt), + GFP_KERNEL); if (!mgtvnic) return -ENOMEM; diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index 5921ea3d50ae..dd98401b7226 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c @@ -904,7 +904,7 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) int i; struct netdev_hw_addr *ha; - addrs = kmalloc(ETH_ALEN * mc_count, GFP_ATOMIC); + addrs = kmalloc_array(mc_count, ETH_ALEN, GFP_ATOMIC); if (!addrs) { set_allmulti(nesdev, nic_active_bit); goto unlock; diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 442b9bdc0f03..6b6ee9b692d2 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -2255,8 +2255,9 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, ibmr = ERR_PTR(-ENOMEM); goto reg_user_mr_err; } - root_vpbl.leaf_vpbl = kzalloc(sizeof(*root_vpbl.leaf_vpbl)*1024, - GFP_KERNEL); + root_vpbl.leaf_vpbl = kcalloc(1024, + sizeof(*root_vpbl.leaf_vpbl), + GFP_KERNEL); if (!root_vpbl.leaf_vpbl) { ib_umem_release(region); pci_free_consistent(nesdev->pcidev, 8192, root_vpbl.pbl_vbase, diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c index 1ba296aeabca..cb042baaf235 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c @@ -3108,7 +3108,7 @@ static int ocrdma_create_eqs(struct ocrdma_dev *dev) if (!num_eq) return -EINVAL; - dev->eq_tbl = kzalloc(sizeof(struct ocrdma_eq) * num_eq, GFP_KERNEL); + dev->eq_tbl = kcalloc(num_eq, sizeof(struct ocrdma_eq), GFP_KERNEL); if (!dev->eq_tbl) return -ENOMEM; diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c index fbfbd9e96147..4682597fe016 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c @@ -223,19 +223,20 @@ static int ocrdma_register_device(struct ocrdma_dev *dev) static int ocrdma_alloc_resources(struct ocrdma_dev *dev) { mutex_init(&dev->dev_lock); - dev->cq_tbl = kzalloc(sizeof(struct ocrdma_cq *) * - OCRDMA_MAX_CQ, GFP_KERNEL); + dev->cq_tbl = kcalloc(OCRDMA_MAX_CQ, sizeof(struct ocrdma_cq *), + GFP_KERNEL); if (!dev->cq_tbl) goto alloc_err; if (dev->attr.max_qp) { - dev->qp_tbl = kzalloc(sizeof(struct ocrdma_qp *) * - OCRDMA_MAX_QP, GFP_KERNEL); + dev->qp_tbl = kcalloc(OCRDMA_MAX_QP, + sizeof(struct ocrdma_qp *), + GFP_KERNEL); if (!dev->qp_tbl) goto alloc_err; } - dev->stag_arr = kzalloc(sizeof(u64) * OCRDMA_MAX_STAG, GFP_KERNEL); + dev->stag_arr = kcalloc(OCRDMA_MAX_STAG, sizeof(u64), GFP_KERNEL); if (dev->stag_arr == NULL) goto alloc_err; diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index 7683d13dad3d..df195904b2e6 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c @@ -880,8 +880,8 @@ static int ocrdma_build_pbl_tbl(struct ocrdma_dev *dev, struct ocrdma_hw_mr *mr) void *va; dma_addr_t pa; - mr->pbl_table = kzalloc(sizeof(struct ocrdma_pbl) * - mr->num_pbls, GFP_KERNEL); + mr->pbl_table = kcalloc(mr->num_pbls, sizeof(struct ocrdma_pbl), + GFP_KERNEL); if (!mr->pbl_table) return -ENOMEM; @@ -1361,12 +1361,12 @@ static void ocrdma_set_qp_db(struct ocrdma_dev *dev, struct ocrdma_qp *qp, static int ocrdma_alloc_wr_id_tbl(struct ocrdma_qp *qp) { qp->wqe_wr_id_tbl = - kzalloc(sizeof(*(qp->wqe_wr_id_tbl)) * qp->sq.max_cnt, + kcalloc(qp->sq.max_cnt, sizeof(*(qp->wqe_wr_id_tbl)), GFP_KERNEL); if (qp->wqe_wr_id_tbl == NULL) return -ENOMEM; qp->rqe_wr_id_tbl = - kzalloc(sizeof(u64) * qp->rq.max_cnt, GFP_KERNEL); + kcalloc(qp->rq.max_cnt, sizeof(u64), GFP_KERNEL); if (qp->rqe_wr_id_tbl == NULL) return -ENOMEM; @@ -1903,15 +1903,16 @@ struct ib_srq *ocrdma_create_srq(struct ib_pd *ibpd, if (udata == NULL) { status = -ENOMEM; - srq->rqe_wr_id_tbl = kzalloc(sizeof(u64) * srq->rq.max_cnt, - GFP_KERNEL); + srq->rqe_wr_id_tbl = kcalloc(srq->rq.max_cnt, sizeof(u64), + GFP_KERNEL); if (srq->rqe_wr_id_tbl == NULL) goto arm_err; srq->bit_fields_len = (srq->rq.max_cnt / 32) + (srq->rq.max_cnt % 32 ? 1 : 0); srq->idx_bit_fields = - kmalloc(srq->bit_fields_len * sizeof(u32), GFP_KERNEL); + kmalloc_array(srq->bit_fields_len, sizeof(u32), + GFP_KERNEL); if (srq->idx_bit_fields == NULL) goto arm_err; memset(srq->idx_bit_fields, 0xff, diff --git a/drivers/infiniband/hw/qedr/main.c b/drivers/infiniband/hw/qedr/main.c index 3e48ed64760b..bf9875f85a1b 100644 --- a/drivers/infiniband/hw/qedr/main.c +++ b/drivers/infiniband/hw/qedr/main.c @@ -234,8 +234,8 @@ static int qedr_alloc_resources(struct qedr_dev *dev) u16 n_entries; int i, rc; - dev->sgid_tbl = kzalloc(sizeof(union ib_gid) * - QEDR_MAX_SGID, GFP_KERNEL); + dev->sgid_tbl = kcalloc(QEDR_MAX_SGID, sizeof(union ib_gid), + GFP_KERNEL); if (!dev->sgid_tbl) return -ENOMEM; diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c index 6ae72accae3d..cc8f95b038f8 100644 --- a/drivers/infiniband/hw/qedr/verbs.c +++ b/drivers/infiniband/hw/qedr/verbs.c @@ -1506,7 +1506,7 @@ static int qedr_create_kernel_qp(struct qedr_dev *dev, qp->sq.max_wr = min_t(u32, attrs->cap.max_send_wr * dev->wq_multiplier, dev->attr.max_sqe); - qp->wqe_wr_id = kzalloc(qp->sq.max_wr * sizeof(*qp->wqe_wr_id), + qp->wqe_wr_id = kcalloc(qp->sq.max_wr, sizeof(*qp->wqe_wr_id), GFP_KERNEL); if (!qp->wqe_wr_id) { DP_ERR(dev, "create qp: failed SQ shadow memory allocation\n"); @@ -1524,7 +1524,7 @@ static int qedr_create_kernel_qp(struct qedr_dev *dev, qp->rq.max_wr = (u16) max_t(u32, attrs->cap.max_recv_wr, 1); /* Allocate driver internal RQ array */ - qp->rqe_wr_id = kzalloc(qp->rq.max_wr * sizeof(*qp->rqe_wr_id), + qp->rqe_wr_id = kcalloc(qp->rq.max_wr, sizeof(*qp->rqe_wr_id), GFP_KERNEL); if (!qp->rqe_wr_id) { DP_ERR(dev, diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c index 3259a60e4f4f..39808dc50277 100644 --- a/drivers/infiniband/hw/qib/qib_iba6120.c +++ b/drivers/infiniband/hw/qib/qib_iba6120.c @@ -2523,15 +2523,16 @@ static void init_6120_cntrnames(struct qib_devdata *dd) dd->cspec->cntrnamelen = sizeof(cntr6120names) - 1; else dd->cspec->cntrnamelen = 1 + s - cntr6120names; - dd->cspec->cntrs = kmalloc(dd->cspec->ncntrs - * sizeof(u64), GFP_KERNEL); + dd->cspec->cntrs = kmalloc_array(dd->cspec->ncntrs, sizeof(u64), + GFP_KERNEL); for (i = 0, s = (char *)portcntr6120names; s; i++) s = strchr(s + 1, '\n'); dd->cspec->nportcntrs = i - 1; dd->cspec->portcntrnamelen = sizeof(portcntr6120names) - 1; - dd->cspec->portcntrs = kmalloc(dd->cspec->nportcntrs - * sizeof(u64), GFP_KERNEL); + dd->cspec->portcntrs = kmalloc_array(dd->cspec->nportcntrs, + sizeof(u64), + GFP_KERNEL); } static u32 qib_read_6120cntrs(struct qib_devdata *dd, loff_t pos, char **namep, diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c index 04bdd3d487b1..265034b7e03b 100644 --- a/drivers/infiniband/hw/qib/qib_iba7220.c +++ b/drivers/infiniband/hw/qib/qib_iba7220.c @@ -3170,15 +3170,16 @@ static void init_7220_cntrnames(struct qib_devdata *dd) dd->cspec->cntrnamelen = sizeof(cntr7220names) - 1; else dd->cspec->cntrnamelen = 1 + s - cntr7220names; - dd->cspec->cntrs = kmalloc(dd->cspec->ncntrs - * sizeof(u64), GFP_KERNEL); + dd->cspec->cntrs = kmalloc_array(dd->cspec->ncntrs, sizeof(u64), + GFP_KERNEL); for (i = 0, s = (char *)portcntr7220names; s; i++) s = strchr(s + 1, '\n'); dd->cspec->nportcntrs = i - 1; dd->cspec->portcntrnamelen = sizeof(portcntr7220names) - 1; - dd->cspec->portcntrs = kmalloc(dd->cspec->nportcntrs - * sizeof(u64), GFP_KERNEL); + dd->cspec->portcntrs = kmalloc_array(dd->cspec->nportcntrs, + sizeof(u64), + GFP_KERNEL); } static u32 qib_read_7220cntrs(struct qib_devdata *dd, loff_t pos, char **namep, diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index a45e46098914..e393585f9ef1 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c @@ -3677,8 +3677,9 @@ static int qib_do_7322_reset(struct qib_devdata *dd) if (msix_entries) { qib_7322_nomsix(dd); /* can be up to 512 bytes, too big for stack */ - msix_vecsave = kmalloc(2 * dd->cspec->num_msix_entries * - sizeof(u64), GFP_KERNEL); + msix_vecsave = kmalloc_array(2 * dd->cspec->num_msix_entries, + sizeof(u64), + GFP_KERNEL); } /* @@ -5038,16 +5039,17 @@ static void init_7322_cntrnames(struct qib_devdata *dd) dd->cspec->cntrnamelen = sizeof(cntr7322names) - 1; else dd->cspec->cntrnamelen = 1 + s - cntr7322names; - dd->cspec->cntrs = kmalloc(dd->cspec->ncntrs - * sizeof(u64), GFP_KERNEL); + dd->cspec->cntrs = kmalloc_array(dd->cspec->ncntrs, sizeof(u64), + GFP_KERNEL); for (i = 0, s = (char *)portcntr7322names; s; i++) s = strchr(s + 1, '\n'); dd->cspec->nportcntrs = i - 1; dd->cspec->portcntrnamelen = sizeof(portcntr7322names) - 1; for (i = 0; i < dd->num_pports; ++i) { - dd->pport[i].cpspec->portcntrs = kmalloc(dd->cspec->nportcntrs - * sizeof(u64), GFP_KERNEL); + dd->pport[i].cpspec->portcntrs = kmalloc_array(dd->cspec->nportcntrs, + sizeof(u64), + GFP_KERNEL); } } @@ -6445,12 +6447,15 @@ static int qib_init_7322_variables(struct qib_devdata *dd) sbufcnt = dd->piobcnt2k + dd->piobcnt4k + NUM_VL15_BUFS + BITS_PER_LONG - 1; sbufcnt /= BITS_PER_LONG; - dd->cspec->sendchkenable = kmalloc(sbufcnt * - sizeof(*dd->cspec->sendchkenable), GFP_KERNEL); - dd->cspec->sendgrhchk = kmalloc(sbufcnt * - sizeof(*dd->cspec->sendgrhchk), GFP_KERNEL); - dd->cspec->sendibchk = kmalloc(sbufcnt * - sizeof(*dd->cspec->sendibchk), GFP_KERNEL); + dd->cspec->sendchkenable = kmalloc_array(sbufcnt, + sizeof(*dd->cspec->sendchkenable), + GFP_KERNEL); + dd->cspec->sendgrhchk = kmalloc_array(sbufcnt, + sizeof(*dd->cspec->sendgrhchk), + GFP_KERNEL); + dd->cspec->sendibchk = kmalloc_array(sbufcnt, + sizeof(*dd->cspec->sendibchk), + GFP_KERNEL); if (!dd->cspec->sendchkenable || !dd->cspec->sendgrhchk || !dd->cspec->sendibchk) { ret = -ENOMEM; @@ -7325,8 +7330,9 @@ struct qib_devdata *qib_init_iba7322_funcs(struct pci_dev *pdev, actual_cnt -= dd->num_pports; tabsize = actual_cnt; - dd->cspec->msix_entries = kzalloc(tabsize * - sizeof(struct qib_msix_entry), GFP_KERNEL); + dd->cspec->msix_entries = kcalloc(tabsize, + sizeof(struct qib_msix_entry), + GFP_KERNEL); if (!dd->cspec->msix_entries) tabsize = 0; diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c index 7ba7d2122f3b..81d9ab511819 100644 --- a/drivers/infiniband/hw/qib/qib_init.c +++ b/drivers/infiniband/hw/qib/qib_init.c @@ -370,11 +370,11 @@ static void init_shadow_tids(struct qib_devdata *dd) struct page **pages; dma_addr_t *addrs; - pages = vzalloc(dd->cfgctxts * dd->rcvtidcnt * sizeof(struct page *)); + pages = vzalloc(array_size(sizeof(struct page *), (dd->cfgctxts * dd->rcvtidcnt))); if (!pages) goto bail; - addrs = vzalloc(dd->cfgctxts * dd->rcvtidcnt * sizeof(dma_addr_t)); + addrs = vzalloc(array_size(sizeof(dma_addr_t), (dd->cfgctxts * dd->rcvtidcnt))); if (!addrs) goto bail_free; @@ -1141,8 +1141,8 @@ struct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra) if (!qib_cpulist_count) { u32 count = num_online_cpus(); - qib_cpulist = kzalloc(BITS_TO_LONGS(count) * - sizeof(long), GFP_KERNEL); + qib_cpulist = kcalloc(BITS_TO_LONGS(count), sizeof(long), + GFP_KERNEL); if (qib_cpulist) qib_cpulist_count = count; } @@ -1680,15 +1680,16 @@ int qib_setup_eagerbufs(struct qib_ctxtdata *rcd) size = rcd->rcvegrbuf_size; if (!rcd->rcvegrbuf) { rcd->rcvegrbuf = - kzalloc_node(chunk * sizeof(rcd->rcvegrbuf[0]), - GFP_KERNEL, rcd->node_id); + kcalloc_node(chunk, sizeof(rcd->rcvegrbuf[0]), + GFP_KERNEL, rcd->node_id); if (!rcd->rcvegrbuf) goto bail; } if (!rcd->rcvegrbuf_phys) { rcd->rcvegrbuf_phys = - kmalloc_node(chunk * sizeof(rcd->rcvegrbuf_phys[0]), - GFP_KERNEL, rcd->node_id); + kmalloc_array_node(chunk, + sizeof(rcd->rcvegrbuf_phys[0]), + GFP_KERNEL, rcd->node_id); if (!rcd->rcvegrbuf_phys) goto bail_rcvegrbuf; } diff --git a/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c b/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c index 092d4e11a633..2e596d09074f 100644 --- a/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c +++ b/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c @@ -545,7 +545,7 @@ alloc_res_chunk_list(struct usnic_vnic *vnic, /* Do Nothing */ } - res_chunk_list = kzalloc(sizeof(*res_chunk_list)*(res_lst_sz+1), + res_chunk_list = kcalloc(res_lst_sz + 1, sizeof(*res_chunk_list), GFP_ATOMIC); if (!res_chunk_list) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/usnic/usnic_vnic.c b/drivers/infiniband/hw/usnic/usnic_vnic.c index e7b0030254da..ebe08f348453 100644 --- a/drivers/infiniband/hw/usnic/usnic_vnic.c +++ b/drivers/infiniband/hw/usnic/usnic_vnic.c @@ -312,7 +312,7 @@ static int usnic_vnic_alloc_res_chunk(struct usnic_vnic *vnic, } chunk->cnt = chunk->free_cnt = cnt; - chunk->res = kzalloc(sizeof(*(chunk->res))*cnt, GFP_KERNEL); + chunk->res = kcalloc(cnt, sizeof(*(chunk->res)), GFP_KERNEL); if (!chunk->res) return -ENOMEM; diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c index b0309876f4bb..0eef239f27d7 100644 --- a/drivers/infiniband/sw/rdmavt/qp.c +++ b/drivers/infiniband/sw/rdmavt/qp.c @@ -238,7 +238,7 @@ int rvt_driver_qp_init(struct rvt_dev_info *rdi) rdi->qp_dev->qp_table_size = rdi->dparms.qp_table_size; rdi->qp_dev->qp_table_bits = ilog2(rdi->dparms.qp_table_size); rdi->qp_dev->qp_table = - kmalloc_node(rdi->qp_dev->qp_table_size * + kmalloc_array_node(rdi->qp_dev->qp_table_size, sizeof(*rdi->qp_dev->qp_table), GFP_KERNEL, rdi->dparms.node); if (!rdi->qp_dev->qp_table) @@ -814,7 +814,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, sz = sizeof(struct rvt_sge) * init_attr->cap.max_send_sge + sizeof(struct rvt_swqe); - swq = vzalloc_node(sqsize * sz, rdi->dparms.node); + swq = vzalloc_node(array_size(sz, sqsize), rdi->dparms.node); if (!swq) return ERR_PTR(-ENOMEM); @@ -837,11 +837,10 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, RCU_INIT_POINTER(qp->next, NULL); if (init_attr->qp_type == IB_QPT_RC) { qp->s_ack_queue = - kzalloc_node( - sizeof(*qp->s_ack_queue) * - rvt_max_atomic(rdi), - GFP_KERNEL, - rdi->dparms.node); + kcalloc_node(rvt_max_atomic(rdi), + sizeof(*qp->s_ack_queue), + GFP_KERNEL, + rdi->dparms.node); if (!qp->s_ack_queue) goto bail_qp; } diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 0e85b3445c07..c3f8dbe0a7da 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -358,7 +358,7 @@ static int ipoib_cm_nonsrq_init_rx(struct net_device *dev, struct ib_cm_id *cm_i int ret; int i; - rx->rx_ring = vzalloc(ipoib_recvq_size * sizeof *rx->rx_ring); + rx->rx_ring = vzalloc(array_size(ipoib_recvq_size, sizeof(*rx->rx_ring))); if (!rx->rx_ring) return -ENOMEM; @@ -1138,7 +1138,7 @@ static int ipoib_cm_tx_init(struct ipoib_cm_tx *p, u32 qpn, int ret; noio_flag = memalloc_noio_save(); - p->tx_ring = vzalloc(ipoib_sendq_size * sizeof(*p->tx_ring)); + p->tx_ring = vzalloc(array_size(ipoib_sendq_size, sizeof(*p->tx_ring))); if (!p->tx_ring) { ret = -ENOMEM; goto err_tx; @@ -1565,7 +1565,7 @@ static void ipoib_cm_create_srq(struct net_device *dev, int max_sge) return; } - priv->cm.srq_ring = vzalloc(ipoib_recvq_size * sizeof *priv->cm.srq_ring); + priv->cm.srq_ring = vzalloc(array_size(ipoib_recvq_size, sizeof(*priv->cm.srq_ring))); if (!priv->cm.srq_ring) { ib_destroy_srq(priv->cm.srq); priv->cm.srq = NULL; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index caae4bfab950..429336093a09 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -1507,7 +1507,7 @@ static int ipoib_neigh_hash_init(struct ipoib_dev_priv *priv) return -ENOMEM; set_bit(IPOIB_STOP_NEIGH_GC, &priv->flags); size = roundup_pow_of_two(arp_tbl.gc_thresh3); - buckets = kzalloc(size * sizeof(*buckets), GFP_KERNEL); + buckets = kcalloc(size, sizeof(*buckets), GFP_KERNEL); if (!buckets) { kfree(htbl); return -ENOMEM; @@ -1669,12 +1669,13 @@ static int ipoib_dev_init_default(struct net_device *dev) netif_napi_add(dev, &priv->napi, ipoib_poll, NAPI_POLL_WEIGHT); /* Allocate RX/TX "rings" to hold queued skbs */ - priv->rx_ring = kzalloc(ipoib_recvq_size * sizeof *priv->rx_ring, - GFP_KERNEL); + priv->rx_ring = kcalloc(ipoib_recvq_size, + sizeof(*priv->rx_ring), + GFP_KERNEL); if (!priv->rx_ring) goto out; - priv->tx_ring = vzalloc(ipoib_sendq_size * sizeof *priv->tx_ring); + priv->tx_ring = vzalloc(array_size(ipoib_sendq_size, sizeof(*priv->tx_ring))); if (!priv->tx_ring) { printk(KERN_WARNING "%s: failed to allocate TX ring (%d entries)\n", priv->ca->name, ipoib_sendq_size); diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c index a126750b65a9..1f46c08efd2d 100644 --- a/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/drivers/infiniband/ulp/iser/iser_initiator.c @@ -259,8 +259,9 @@ int iser_alloc_rx_descriptors(struct iser_conn *iser_conn, goto alloc_login_buf_fail; iser_conn->num_rx_descs = session->cmds_max; - iser_conn->rx_descs = kmalloc(iser_conn->num_rx_descs * - sizeof(struct iser_rx_desc), GFP_KERNEL); + iser_conn->rx_descs = kmalloc_array(iser_conn->num_rx_descs, + sizeof(struct iser_rx_desc), + GFP_KERNEL); if (!iser_conn->rx_descs) goto rx_desc_alloc_fail; diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index ee3f630c9217..907aec3520ec 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -181,8 +181,9 @@ isert_alloc_rx_descriptors(struct isert_conn *isert_conn) u64 dma_addr; int i, j; - isert_conn->rx_descs = kzalloc(ISERT_QP_MAX_RECV_DTOS * - sizeof(struct iser_rx_desc), GFP_KERNEL); + isert_conn->rx_descs = kcalloc(ISERT_QP_MAX_RECV_DTOS, + sizeof(struct iser_rx_desc), + GFP_KERNEL); if (!isert_conn->rx_descs) return -ENOMEM; diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 9f7287f45d06..a77315f70791 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -883,16 +883,17 @@ static int srp_alloc_req_data(struct srp_rdma_ch *ch) for (i = 0; i < target->req_ring_size; ++i) { req = &ch->req_ring[i]; - mr_list = kmalloc(target->mr_per_cmd * sizeof(void *), - GFP_KERNEL); + mr_list = kmalloc_array(target->mr_per_cmd, sizeof(void *), + GFP_KERNEL); if (!mr_list) goto out; if (srp_dev->use_fast_reg) { req->fr_list = mr_list; } else { req->fmr_list = mr_list; - req->map_page = kmalloc(srp_dev->max_pages_per_mr * - sizeof(void *), GFP_KERNEL); + req->map_page = kmalloc_array(srp_dev->max_pages_per_mr, + sizeof(void *), + GFP_KERNEL); if (!req->map_page) goto out; } diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 5f1055c94d66..8ae224280421 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -657,7 +657,7 @@ static struct srpt_ioctx **srpt_alloc_ioctx_ring(struct srpt_device *sdev, WARN_ON(ioctx_size != sizeof(struct srpt_recv_ioctx) && ioctx_size != sizeof(struct srpt_send_ioctx)); - ring = kmalloc(ring_size * sizeof(ring[0]), GFP_KERNEL); + ring = kmalloc_array(ring_size, sizeof(ring[0]), GFP_KERNEL); if (!ring) goto out; for (i = 0; i < ring_size; ++i) { diff --git a/drivers/input/input-leds.c b/drivers/input/input-leds.c index 5f04b2d94635..99cc784e1264 100644 --- a/drivers/input/input-leds.c +++ b/drivers/input/input-leds.c @@ -98,8 +98,7 @@ static int input_leds_connect(struct input_handler *handler, if (!num_leds) return -ENXIO; - leds = kzalloc(sizeof(*leds) + num_leds * sizeof(*leds->leds), - GFP_KERNEL); + leds = kzalloc(struct_size(leds, leds, num_leds), GFP_KERNEL); if (!leds) return -ENOMEM; diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index a1bbec9cda8d..cf30523c6ef6 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c @@ -49,7 +49,7 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots, if (mt) return mt->num_slots != num_slots ? -EINVAL : 0; - mt = kzalloc(sizeof(*mt) + num_slots * sizeof(*mt->slots), GFP_KERNEL); + mt = kzalloc(struct_size(mt, slots, num_slots), GFP_KERNEL); if (!mt) goto err_mem; diff --git a/drivers/input/joystick/joydump.c b/drivers/input/joystick/joydump.c index d1c6e4846a4a..7f4dff9a566f 100644 --- a/drivers/input/joystick/joydump.c +++ b/drivers/input/joystick/joydump.c @@ -80,7 +80,7 @@ static int joydump_connect(struct gameport *gameport, struct gameport_driver *dr timeout = gameport_time(gameport, 10000); /* 10 ms */ - buf = kmalloc(BUF_SIZE * sizeof(struct joydump), GFP_KERNEL); + buf = kmalloc_array(BUF_SIZE, sizeof(struct joydump), GFP_KERNEL); if (!buf) { printk(KERN_INFO "joydump: no memory for testing\n"); goto jd_end; diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index 39bcbc38997f..ac1458005a02 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c @@ -201,8 +201,8 @@ static int bfin_kpad_probe(struct platform_device *pdev) platform_set_drvdata(pdev, bf54x_kpad); /* Allocate memory for keymap followed by private LUT */ - bf54x_kpad->keycode = kmalloc(pdata->keymapsize * - sizeof(unsigned short) * 2, GFP_KERNEL); + bf54x_kpad->keycode = kmalloc(array3_size(pdata->keymapsize, sizeof(unsigned short), 2), + GFP_KERNEL); if (!bf54x_kpad->keycode) { error = -ENOMEM; goto out; diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c index 87fb48143859..73686c2460ce 100644 --- a/drivers/input/keyboard/cap11xx.c +++ b/drivers/input/keyboard/cap11xx.c @@ -344,8 +344,7 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client, } priv = devm_kzalloc(dev, - sizeof(*priv) + - cap->num_channels * sizeof(priv->keycodes[0]), + struct_size(priv, keycodes, cap->num_channels), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/input/keyboard/clps711x-keypad.c b/drivers/input/keyboard/clps711x-keypad.c index 997e3e97f573..e319f745771a 100644 --- a/drivers/input/keyboard/clps711x-keypad.c +++ b/drivers/input/keyboard/clps711x-keypad.c @@ -109,8 +109,8 @@ static int clps711x_keypad_probe(struct platform_device *pdev) if (priv->row_count < 1) return -EINVAL; - priv->gpio_data = devm_kzalloc(dev, - sizeof(*priv->gpio_data) * priv->row_count, + priv->gpio_data = devm_kcalloc(dev, + priv->row_count, sizeof(*priv->gpio_data), GFP_KERNEL); if (!priv->gpio_data) return -ENOMEM; diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index c04559a232f7..3d1cb7bf5e35 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -443,9 +443,9 @@ matrix_keypad_parse_dt(struct device *dev) of_property_read_u32(np, "col-scan-delay-us", &pdata->col_scan_delay_us); - gpios = devm_kzalloc(dev, - sizeof(unsigned int) * - (pdata->num_row_gpios + pdata->num_col_gpios), + gpios = devm_kcalloc(dev, + pdata->num_row_gpios + pdata->num_col_gpios, + sizeof(unsigned int), GFP_KERNEL); if (!gpios) { dev_err(dev, "could not allocate memory for gpios\n"); diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index 616fdd94b069..840e53732753 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c @@ -339,7 +339,8 @@ static int omap4_keypad_probe(struct platform_device *pdev) keypad_data->row_shift = get_count_order(keypad_data->cols); max_keys = keypad_data->rows << keypad_data->row_shift; - keypad_data->keymap = kzalloc(max_keys * sizeof(keypad_data->keymap[0]), + keypad_data->keymap = kcalloc(max_keys, + sizeof(keypad_data->keymap[0]), GFP_KERNEL); if (!keypad_data->keymap) { dev_err(&pdev->dev, "Not enough memory for keymap\n"); diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index 316414465c77..1fe1aa2adf85 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c @@ -281,7 +281,7 @@ samsung_keypad_parse_dt(struct device *dev) key_count = of_get_child_count(np); keymap_data->keymap_size = key_count; - keymap = devm_kzalloc(dev, sizeof(uint32_t) * key_count, GFP_KERNEL); + keymap = devm_kcalloc(dev, key_count, sizeof(uint32_t), GFP_KERNEL); if (!keymap) { dev_err(dev, "could not allocate memory for keymap\n"); return ERR_PTR(-ENOMEM); diff --git a/drivers/input/matrix-keymap.c b/drivers/input/matrix-keymap.c index 8ccefc15c7a4..8b3a5758451e 100644 --- a/drivers/input/matrix-keymap.c +++ b/drivers/input/matrix-keymap.c @@ -170,8 +170,8 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, return -EINVAL; if (!keymap) { - keymap = devm_kzalloc(input_dev->dev.parent, - max_keys * sizeof(*keymap), + keymap = devm_kcalloc(input_dev->dev.parent, + max_keys, sizeof(*keymap), GFP_KERNEL); if (!keymap) { dev_err(input_dev->dev.parent, diff --git a/drivers/input/misc/gpio_input.c b/drivers/input/misc/gpio_input.c index dc266cb9f8fd..94c58e0cf5c7 100644 --- a/drivers/input/misc/gpio_input.c +++ b/drivers/input/misc/gpio_input.c @@ -287,8 +287,8 @@ int gpio_event_input_func(struct gpio_event_input_devs *input_devs, if (ktime_to_ns(di->poll_time) <= 0) di->poll_time = ktime_set(0, 20 * NSEC_PER_MSEC); - *data = ds = kzalloc(sizeof(*ds) + sizeof(ds->key_state[0]) * - di->keymap_size, GFP_KERNEL); + *data = ds = kzalloc(struct_size(ds, key_state, di->keymap_size), + GFP_KERNEL); if (ds == NULL) { ret = -ENOMEM; pr_err("gpio_event_input_func: " diff --git a/drivers/input/misc/gpio_matrix.c b/drivers/input/misc/gpio_matrix.c index 08769dd88f56..92aa6b89d71c 100644 --- a/drivers/input/misc/gpio_matrix.c +++ b/drivers/input/misc/gpio_matrix.c @@ -327,8 +327,8 @@ int gpio_event_matrix_func(struct gpio_event_input_devs *input_devs, } key_count = mi->ninputs * mi->noutputs; - *data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) * - BITS_TO_LONGS(key_count), GFP_KERNEL); + *data = kp = kzalloc(struct_size(kp, keys_pressed, BITS_TO_LONGS(key_count)), + GFP_KERNEL); if (kp == NULL) { err = -ENOMEM; pr_err("gpiomatrix: Failed to allocate private data\n"); diff --git a/drivers/input/misc/qpnp-power-on.c b/drivers/input/misc/qpnp-power-on.c index abb57ad50d9d..c3092f996fd1 100644 --- a/drivers/input/misc/qpnp-power-on.c +++ b/drivers/input/misc/qpnp-power-on.c @@ -167,6 +167,7 @@ enum pon_type { PON_RESIN = PON_POWER_ON_TYPE_RESIN, PON_CBLPWR = PON_POWER_ON_TYPE_CBLPWR, PON_KPDPWR_RESIN = PON_POWER_ON_TYPE_KPDPWR_RESIN, + PON_KEY_MAX }; struct pon_reg { @@ -224,6 +225,7 @@ struct qpnp_pon { int pon_trigger_reason; int pon_power_off_reason; u32 dbc_time_us; + u32 sw_dbc_time_us; u32 uvlo; int warm_reset_poff_type; int hard_reset_poff_type; @@ -237,12 +239,12 @@ struct qpnp_pon { bool resin_shutdown_disable; bool ps_hold_hard_reset_disable; bool ps_hold_shutdown_disable; - bool kpdpwr_dbc_enable; bool support_twm_config; bool resin_pon_reset; - ktime_t kpdpwr_last_release_time; struct notifier_block pon_nb; bool legacy_hard_reset_offset; + bool sw_dbc_enable; + ktime_t sw_dbc_last_release_time[PON_KEY_MAX]; }; static int pon_ship_mode_en; @@ -541,6 +543,19 @@ static ssize_t debounce_us_store(struct device *dev, } static DEVICE_ATTR_RW(debounce_us); +static struct qpnp_pon_config * +qpnp_get_cfg(struct qpnp_pon *pon, u32 pon_type) +{ + int i; + + for (i = 0; i < pon->num_pon_config; i++) { + if (pon_type == pon->pon_cfg[i].pon_type) + return &pon->pon_cfg[i]; + } + + return NULL; +} + #define PON_TWM_ENTRY_PBS_BIT BIT(0) static int qpnp_pon_reset_config(struct qpnp_pon *pon, enum pon_power_off_type type) @@ -548,6 +563,7 @@ static int qpnp_pon_reset_config(struct qpnp_pon *pon, int rc; bool disable = false; u16 rst_en_reg; + struct qpnp_pon_config *cfg; /* Ignore the PS_HOLD reset config if TWM ENTRY is enabled */ if (pon->support_twm_config && pon->twm_state == PMIC_TWM_ENABLE) { @@ -558,6 +574,18 @@ static int qpnp_pon_reset_config(struct qpnp_pon *pon, rc); return rc; } + + cfg = qpnp_get_cfg(pon, PON_KPDPWR); + if (cfg) { + /* configure KPDPWR_S2 to Hard reset */ + rc = qpnp_pon_masked_write(pon, cfg->s2_cntl_addr, + QPNP_PON_S2_CNTL_TYPE_MASK, + PON_POWER_OFF_HARD_RESET); + if (rc < 0) + pr_err("Unable to config KPDPWR_N S2 for hard-reset rc=%d\n", + rc); + } + pr_crit("PMIC configured for TWM entry\n"); return 0; } @@ -917,18 +945,6 @@ static int qpnp_pon_store_and_clear_warm_reset(struct qpnp_pon *pon) return 0; } -static struct qpnp_pon_config *qpnp_get_cfg(struct qpnp_pon *pon, u32 pon_type) -{ - int i; - - for (i = 0; i < pon->num_pon_config; i++) { - if (pon_type == pon->pon_cfg[i].pon_type) - return &pon->pon_cfg[i]; - } - - return NULL; -} - static int qpnp_pon_input_dispatch(struct qpnp_pon *pon, u32 pon_type) { struct qpnp_pon_config *cfg = NULL; @@ -946,10 +962,10 @@ static int qpnp_pon_input_dispatch(struct qpnp_pon *pon, u32 pon_type) if (!cfg->key_code) return 0; - if (pon->kpdpwr_dbc_enable && cfg->pon_type == PON_KPDPWR) { + if (pon->sw_dbc_enable) { elapsed_us = ktime_us_delta(ktime_get(), - pon->kpdpwr_last_release_time); - if (elapsed_us < pon->dbc_time_us) { + pon->sw_dbc_last_release_time[cfg->pon_type]); + if (elapsed_us < pon->sw_dbc_time_us) { pr_debug("Ignoring kpdpwr event; within debounce time\n"); return 0; } @@ -981,10 +997,8 @@ static int qpnp_pon_input_dispatch(struct qpnp_pon *pon, u32 pon_type) pon_rt_sts); key_status = pon_rt_sts & pon_rt_bit; - if (pon->kpdpwr_dbc_enable && cfg->pon_type == PON_KPDPWR) { - if (!key_status) - pon->kpdpwr_last_release_time = ktime_get(); - } + if (pon->sw_dbc_enable && !key_status) + pon->sw_dbc_last_release_time[cfg->pon_type] = ktime_get(); /* * Simulate a press event in case release event occurred without a press @@ -2411,8 +2425,22 @@ static int qpnp_pon_probe(struct platform_device *pdev) if (rc) return rc; - pon->kpdpwr_dbc_enable = of_property_read_bool(dev->of_node, - "qcom,kpdpwr-sw-debounce"); + pon->sw_dbc_enable = of_property_read_bool(dev->of_node, + "qcom,pon-sw-debounce"); + if (pon->sw_dbc_enable) { + rc = of_property_read_u32(dev->of_node, + "qcom,pon-sw-dbc-delay", + &pon->sw_dbc_time_us); + if (rc) { + if (rc == -EINVAL) { + pon->sw_dbc_time_us = pon->dbc_time_us; + } else { + dev_err(dev, "Unable to read software debounce delay rc: %d\n", + rc); + return rc; + } + } + } pon->store_hard_reset_reason = of_property_read_bool(dev->of_node, "qcom,store-hard-reset-reason"); diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 1588aecafff7..6d304381fc30 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c @@ -283,8 +283,8 @@ static int rotary_encoder_probe(struct platform_device *pdev) } encoder->irq = - devm_kzalloc(dev, - sizeof(*encoder->irq) * encoder->gpios->ndescs, + devm_kcalloc(dev, + encoder->gpios->ndescs, sizeof(*encoder->irq), GFP_KERNEL); if (!encoder->irq) return -ENOMEM; diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c index 30a8d816c45c..e51cf50f3b22 100644 --- a/drivers/input/rmi4/rmi_driver.c +++ b/drivers/input/rmi4/rmi_driver.c @@ -636,9 +636,10 @@ int rmi_read_register_desc(struct rmi_device *d, u16 addr, rdesc->num_registers = bitmap_weight(rdesc->presense_map, RMI_REG_DESC_PRESENSE_BITS); - rdesc->registers = devm_kzalloc(&d->dev, rdesc->num_registers * - sizeof(struct rmi_register_desc_item), - GFP_KERNEL); + rdesc->registers = devm_kcalloc(&d->dev, + rdesc->num_registers, + sizeof(struct rmi_register_desc_item), + GFP_KERNEL); if (!rdesc->registers) return -ENOMEM; @@ -1057,7 +1058,7 @@ int rmi_probe_interrupts(struct rmi_driver_data *data) data->num_of_irq_regs = (data->irq_count + 7) / 8; size = BITS_TO_LONGS(data->irq_count) * sizeof(unsigned long); - data->irq_memory = devm_kzalloc(dev, size * 4, GFP_KERNEL); + data->irq_memory = devm_kcalloc(dev, size, 4, GFP_KERNEL); if (!data->irq_memory) { dev_err(dev, "Failed to allocate memory for irq masks.\n"); return -ENOMEM; diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c index e8c3e5d1ea22..77a4a1b2dd4f 100644 --- a/drivers/input/rmi4/rmi_f11.c +++ b/drivers/input/rmi4/rmi_f11.c @@ -1190,14 +1190,15 @@ static int rmi_f11_initialize(struct rmi_function *fn) f11->sensor.attn_size += f11->sensor.nbr_fingers * 2; /* allocate the in-kernel tracking buffers */ - sensor->tracking_pos = devm_kzalloc(&fn->dev, - sizeof(struct input_mt_pos) * sensor->nbr_fingers, + sensor->tracking_pos = devm_kcalloc(&fn->dev, + sensor->nbr_fingers, sizeof(struct input_mt_pos), + GFP_KERNEL); + sensor->tracking_slots = devm_kcalloc(&fn->dev, + sensor->nbr_fingers, sizeof(int), GFP_KERNEL); + sensor->objs = devm_kcalloc(&fn->dev, + sensor->nbr_fingers, + sizeof(struct rmi_2d_sensor_abs_object), GFP_KERNEL); - sensor->tracking_slots = devm_kzalloc(&fn->dev, - sizeof(int) * sensor->nbr_fingers, GFP_KERNEL); - sensor->objs = devm_kzalloc(&fn->dev, - sizeof(struct rmi_2d_sensor_abs_object) - * sensor->nbr_fingers, GFP_KERNEL); if (!sensor->tracking_pos || !sensor->tracking_slots || !sensor->objs) return -ENOMEM; diff --git a/drivers/input/rmi4/rmi_f12.c b/drivers/input/rmi4/rmi_f12.c index 99dd2f512058..10847408e0f9 100644 --- a/drivers/input/rmi4/rmi_f12.c +++ b/drivers/input/rmi4/rmi_f12.c @@ -526,14 +526,15 @@ static int rmi_f12_probe(struct rmi_function *fn) } /* allocate the in-kernel tracking buffers */ - sensor->tracking_pos = devm_kzalloc(&fn->dev, - sizeof(struct input_mt_pos) * sensor->nbr_fingers, + sensor->tracking_pos = devm_kcalloc(&fn->dev, + sensor->nbr_fingers, sizeof(struct input_mt_pos), + GFP_KERNEL); + sensor->tracking_slots = devm_kcalloc(&fn->dev, + sensor->nbr_fingers, sizeof(int), GFP_KERNEL); + sensor->objs = devm_kcalloc(&fn->dev, + sensor->nbr_fingers, + sizeof(struct rmi_2d_sensor_abs_object), GFP_KERNEL); - sensor->tracking_slots = devm_kzalloc(&fn->dev, - sizeof(int) * sensor->nbr_fingers, GFP_KERNEL); - sensor->objs = devm_kzalloc(&fn->dev, - sizeof(struct rmi_2d_sensor_abs_object) - * sensor->nbr_fingers, GFP_KERNEL); if (!sensor->tracking_pos || !sensor->tracking_slots || !sensor->objs) return -ENOMEM; diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c index 7f1959517ec0..de036cad7274 100644 --- a/drivers/input/rmi4/rmi_f54.c +++ b/drivers/input/rmi4/rmi_f54.c @@ -685,7 +685,7 @@ static int rmi_f54_probe(struct rmi_function *fn) rx = f54->num_rx_electrodes; tx = f54->num_tx_electrodes; f54->report_data = devm_kzalloc(&fn->dev, - sizeof(u16) * tx * rx, + array3_size(tx, rx, sizeof(u16)), GFP_KERNEL); if (f54->report_data == NULL) return -ENOMEM; diff --git a/drivers/input/rmi4/rmi_spi.c b/drivers/input/rmi4/rmi_spi.c index d0c3d275bf9f..9623395d9415 100644 --- a/drivers/input/rmi4/rmi_spi.c +++ b/drivers/input/rmi4/rmi_spi.c @@ -69,7 +69,7 @@ static int rmi_spi_manage_pools(struct rmi_spi_xport *rmi_spi, int len) buf_size = RMI_SPI_XFER_SIZE_LIMIT; tmp = rmi_spi->rx_buf; - buf = devm_kzalloc(&spi->dev, buf_size * 2, + buf = devm_kcalloc(&spi->dev, buf_size, 2, GFP_KERNEL | GFP_DMA); if (!buf) return -ENOMEM; @@ -96,9 +96,10 @@ static int rmi_spi_manage_pools(struct rmi_spi_xport *rmi_spi, int len) * per byte delays. */ tmp = rmi_spi->rx_xfers; - xfer_buf = devm_kzalloc(&spi->dev, - (rmi_spi->rx_xfer_count + rmi_spi->tx_xfer_count) - * sizeof(struct spi_transfer), GFP_KERNEL); + xfer_buf = devm_kcalloc(&spi->dev, + rmi_spi->rx_xfer_count + rmi_spi->tx_xfer_count, + sizeof(struct spi_transfer), + GFP_KERNEL); if (!xfer_buf) return -ENOMEM; diff --git a/drivers/input/touchscreen/goodix_driver_gt9886/goodix_ts_core.c b/drivers/input/touchscreen/goodix_driver_gt9886/goodix_ts_core.c index e451d15451aa..7696437425f4 100644 --- a/drivers/input/touchscreen/goodix_driver_gt9886/goodix_ts_core.c +++ b/drivers/input/touchscreen/goodix_driver_gt9886/goodix_ts_core.c @@ -959,7 +959,7 @@ int goodix_ts_irq_setup(struct goodix_ts_core *core_data) r = devm_request_threaded_irq(&core_data->pdev->dev, core_data->irq, NULL, goodix_ts_threadirq_func, - ts_bdata->irq_flags | IRQF_ONESHOT, + ts_bdata->irq_flags | IRQF_ONESHOT | IRQF_PERF_CRITICAL, GOODIX_CORE_DRIVER_NAME, core_data); if (r < 0) diff --git a/drivers/input/touchscreen/hxchipset/himax_common.c b/drivers/input/touchscreen/hxchipset/himax_common.c index 1667d823ac71..f9398babb5ab 100644 --- a/drivers/input/touchscreen/hxchipset/himax_common.c +++ b/drivers/input/touchscreen/hxchipset/himax_common.c @@ -885,7 +885,9 @@ int himax_report_data_init(void) D("%s: g_hx_rawdata_size:%d, hx_touch_data->touch_info_size:%d\n", __func__, hx_touch_data->rawdata_size, hx_touch_data->touch_info_size); - hx_touch_data->hx_coord_buf = kzalloc(sizeof(uint8_t) * (hx_touch_data->touch_info_size), GFP_KERNEL); + hx_touch_data->hx_coord_buf = kcalloc(hx_touch_data->touch_info_size, + sizeof(uint8_t), + GFP_KERNEL); if (hx_touch_data->hx_coord_buf == NULL) goto mem_alloc_fail; @@ -893,29 +895,38 @@ int himax_report_data_init(void) g_target_report_data = kzalloc(sizeof(struct himax_target_report_data), GFP_KERNEL); if (g_target_report_data == NULL) goto mem_alloc_fail; - g_target_report_data->x = kzalloc(sizeof(int)*(ic_data->HX_MAX_PT), GFP_KERNEL); + g_target_report_data->x = kcalloc(ic_data->HX_MAX_PT, sizeof(int), + GFP_KERNEL); if (g_target_report_data->x == NULL) goto mem_alloc_fail; - g_target_report_data->y = kzalloc(sizeof(int)*(ic_data->HX_MAX_PT), GFP_KERNEL); + g_target_report_data->y = kcalloc(ic_data->HX_MAX_PT, sizeof(int), + GFP_KERNEL); if (g_target_report_data->y == NULL) goto mem_alloc_fail; - g_target_report_data->w = kzalloc(sizeof(int)*(ic_data->HX_MAX_PT), GFP_KERNEL); + g_target_report_data->w = kcalloc(ic_data->HX_MAX_PT, sizeof(int), + GFP_KERNEL); if (g_target_report_data->w == NULL) goto mem_alloc_fail; - g_target_report_data->finger_id = kzalloc(sizeof(int)*(ic_data->HX_MAX_PT), GFP_KERNEL); + g_target_report_data->finger_id = kcalloc(ic_data->HX_MAX_PT, + sizeof(int), + GFP_KERNEL); if (g_target_report_data->finger_id == NULL) goto mem_alloc_fail; #ifdef HX_SMART_WAKEUP g_target_report_data->SMWP_event_chk = 0; #endif - hx_touch_data->hx_rawdata_buf = kzalloc(sizeof(uint8_t) * (hx_touch_data->touch_all_size - hx_touch_data->touch_info_size), GFP_KERNEL); + hx_touch_data->hx_rawdata_buf = kcalloc(hx_touch_data->touch_all_size - hx_touch_data->touch_info_size, + sizeof(uint8_t), + GFP_KERNEL); if (hx_touch_data->hx_rawdata_buf == NULL) goto mem_alloc_fail; #if defined(HX_SMART_WAKEUP) - hx_touch_data->hx_event_buf = kzalloc(sizeof(uint8_t) * (hx_touch_data->event_size), GFP_KERNEL); + hx_touch_data->hx_event_buf = kcalloc(hx_touch_data->event_size, + sizeof(uint8_t), + GFP_KERNEL); if (hx_touch_data->hx_event_buf == NULL) goto mem_alloc_fail; diff --git a/drivers/input/touchscreen/hxchipset/himax_debug.c b/drivers/input/touchscreen/hxchipset/himax_debug.c index 9d7f5b99a4cb..a38dde9dc245 100644 --- a/drivers/input/touchscreen/hxchipset/himax_debug.c +++ b/drivers/input/touchscreen/hxchipset/himax_debug.c @@ -853,19 +853,22 @@ void setYChannel(uint8_t y) } void setMutualBuffer(void) { - diag_mutual = kzalloc(x_channel * y_channel * sizeof(int32_t), GFP_KERNEL); + diag_mutual = kcalloc(x_channel * y_channel, sizeof(int32_t), + GFP_KERNEL); if (!diag_mutual) E("%s: allocate memory failed!\n", __func__); } void setMutualNewBuffer(void) { - diag_mutual_new = kzalloc(x_channel * y_channel * sizeof(int32_t), GFP_KERNEL); + diag_mutual_new = kcalloc(x_channel * y_channel, sizeof(int32_t), + GFP_KERNEL); if (!diag_mutual_new) E("%s: allocate memory failed!\n", __func__); } void setMutualOldBuffer(void) { - diag_mutual_old = kzalloc(x_channel * y_channel * sizeof(int32_t), GFP_KERNEL); + diag_mutual_old = kcalloc(x_channel * y_channel, sizeof(int32_t), + GFP_KERNEL); if (!diag_mutual_old) E("%s: allocate memory failed!\n", __func__); } @@ -898,7 +901,8 @@ void setYChannel_2(uint8_t y) void setMutualBuffer_2(void) { - diag_mutual_2 = kzalloc(x_channel_2 * y_channel_2 * sizeof(int32_t), GFP_KERNEL); + diag_mutual_2 = kcalloc(x_channel_2 * y_channel_2, sizeof(int32_t), + GFP_KERNEL); } #endif diff --git a/drivers/input/touchscreen/st/fts.c b/drivers/input/touchscreen/st/fts.c index a10a2afbb50b..910dfed9cddd 100644 --- a/drivers/input/touchscreen/st/fts.c +++ b/drivers/input/touchscreen/st/fts.c @@ -3470,8 +3470,9 @@ static int fts_interrupt_install(struct fts_ts_info *info) { int i, error = 0; - info->event_dispatch_table = kzalloc(sizeof(event_dispatch_handler_t) - * EVENTID_LAST, GFP_KERNEL); + info->event_dispatch_table = kcalloc(EVENTID_LAST, + sizeof(event_dispatch_handler_t), + GFP_KERNEL); if (!info->event_dispatch_table) { logError(1, "%s OOM allocating event dispatch table\n", tag); diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c index 5fa4cf353b14..3194a9b23df5 100644 --- a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c +++ b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c @@ -2724,7 +2724,7 @@ static int synaptics_rmi4_f1a_alloc_mem(struct synaptics_rmi4_data *rmi4_data, f1a->max_count = f1a->button_query.max_button_count + 1; - f1a->button_control.txrx_map = kzalloc(f1a->max_count * 2, GFP_KERNEL); + f1a->button_control.txrx_map = kcalloc(f1a->max_count, 2, GFP_KERNEL); if (!f1a->button_control.txrx_map) { dev_err(rmi4_data->pdev->dev.parent, "%s: Failed to alloc mem for tx rx mapping\n", diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_gesture.c b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_gesture.c index 1820abe6ce3b..b04af90d8f7b 100644 --- a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_gesture.c +++ b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_gesture.c @@ -2011,9 +2011,9 @@ static int synaptics_rmi4_udg_init(struct synaptics_rmi4_data *rmi4_data) } #ifdef STORE_GESTURES - udg->storage_buf = kzalloc( - udg->template_data_size * udg->gestures_to_store, - GFP_KERNEL); + udg->storage_buf = kcalloc(udg->template_data_size, + udg->gestures_to_store, + GFP_KERNEL); if (!udg->storage_buf) { dev_err(rmi4_data->pdev->dev.parent, "%s: Failed to alloc mem for storage_buf\n", diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 69d62ab44f4f..b51a0e4812cb 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -4545,13 +4545,14 @@ static int arm_smmu_parse_impl_def_registers(struct arm_smmu_device *smmu) return -EINVAL; } - regs = devm_kmalloc( - dev, sizeof(*smmu->impl_def_attach_registers) * ntuples, + regs = devm_kmalloc_array( + dev, ntuples, sizeof(*smmu->impl_def_attach_registers), GFP_KERNEL); if (!regs) return -ENOMEM; - tuples = devm_kmalloc(dev, sizeof(u32) * ntuples * 2, GFP_KERNEL); + tuples = devm_kmalloc(dev, array3_size(sizeof(u32), ntuples, 2), + GFP_KERNEL); if (!tuples) return -ENOMEM; @@ -4589,8 +4590,8 @@ static int arm_smmu_init_clocks(struct arm_smmu_power_resources *pwr) return 0; } - pwr->clocks = devm_kzalloc( - dev, sizeof(*pwr->clocks) * pwr->num_clocks, + pwr->clocks = devm_kcalloc( + dev, pwr->num_clocks, sizeof(*pwr->clocks), GFP_KERNEL); if (!pwr->clocks) @@ -4635,8 +4636,8 @@ static int arm_smmu_init_regulators(struct arm_smmu_power_resources *pwr) return 0; } - pwr->gdscs = devm_kzalloc( - dev, sizeof(*pwr->gdscs) * pwr->num_gdscs, GFP_KERNEL); + pwr->gdscs = devm_kcalloc( + dev, pwr->num_gdscs, sizeof(*pwr->gdscs), GFP_KERNEL); if (!pwr->gdscs) return -ENOMEM; @@ -5146,7 +5147,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) return -ENODEV; } - smmu->irqs = devm_kzalloc(dev, sizeof(*smmu->irqs) * num_irqs, + smmu->irqs = devm_kcalloc(dev, num_irqs, sizeof(*smmu->irqs), GFP_KERNEL); if (!smmu->irqs) { dev_err(dev, "failed to allocate %d irqs\n", num_irqs); @@ -5943,7 +5944,7 @@ static int qsmmuv500_read_actlr_tbl(struct arm_smmu_device *smmu) if (len < 0) return 0; - actlrs = devm_kzalloc(dev, sizeof(*actlrs) * len, GFP_KERNEL); + actlrs = devm_kcalloc(dev, len, sizeof(*actlrs), GFP_KERNEL); if (!actlrs) return -ENOMEM; @@ -6642,7 +6643,7 @@ static int qsmmuv500_tbu_probe(struct platform_device *pdev) while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, num_irqs))) num_irqs++; - tbu->irqs = devm_kzalloc(dev, sizeof(*tbu->irqs) * num_irqs, + tbu->irqs = devm_kcalloc(dev, num_irqs, sizeof(*tbu->irqs), GFP_KERNEL); if (!tbu->irqs) return -ENOMEM; diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index 1f527ca60955..e3b3aa16cf1b 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -1464,7 +1464,7 @@ int dmar_enable_qi(struct intel_iommu *iommu) qi->desc = page_address(desc_page); - qi->desc_status = kzalloc(QI_LENGTH * sizeof(int), GFP_ATOMIC); + qi->desc_status = kcalloc(QI_LENGTH, sizeof(int), GFP_ATOMIC); if (!qi->desc_status) { free_page((unsigned long) qi->desc); kfree(qi); diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index db1b546134f5..e2bfb8795816 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -3197,7 +3197,7 @@ static int copy_translation_tables(struct intel_iommu *iommu) /* This is too big for the stack - allocate it from slab */ ctxt_table_entries = ext ? 512 : 256; ret = -ENOMEM; - ctxt_tbls = kzalloc(ctxt_table_entries * sizeof(void *), GFP_KERNEL); + ctxt_tbls = kcalloc(ctxt_table_entries, sizeof(void *), GFP_KERNEL); if (!ctxt_tbls) goto out_unmap; @@ -4086,7 +4086,7 @@ static int iommu_suspend(void) unsigned long flag; for_each_active_iommu(iommu, drhd) { - iommu->iommu_state = kzalloc(sizeof(u32) * MAX_SR_DMAR_REGS, + iommu->iommu_state = kcalloc(MAX_SR_DMAR_REGS, sizeof(u32), GFP_ATOMIC); if (!iommu->iommu_state) goto nomem; diff --git a/drivers/iommu/io-pgtable-fast.c b/drivers/iommu/io-pgtable-fast.c index 5a5d597a00a6..60977727f37f 100644 --- a/drivers/iommu/io-pgtable-fast.c +++ b/drivers/iommu/io-pgtable-fast.c @@ -438,11 +438,11 @@ av8l_fast_prepopulate_pgtables(struct av8l_fast_io_pgtable *data, dma_addr_t pud, pmd; int pmd_pg_index; - pages = kmalloc(sizeof(*pages) * NUM_PGTBL_PAGES, __GFP_NOWARN | + pages = kmalloc_array(NUM_PGTBL_PAGES, sizeof(*pages), __GFP_NOWARN | __GFP_NORETRY); if (!pages) - pages = vmalloc(sizeof(*pages) * NUM_PGTBL_PAGES); + pages = vmalloc(array_size(NUM_PGTBL_PAGES, sizeof(*pages))); if (!pages) return -ENOMEM; diff --git a/drivers/iommu/msm_dma_iommu_mapping.c b/drivers/iommu/msm_dma_iommu_mapping.c index bc64c06d2be8..3ce62c6c905c 100644 --- a/drivers/iommu/msm_dma_iommu_mapping.c +++ b/drivers/iommu/msm_dma_iommu_mapping.c @@ -1,481 +1,220 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2015-2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 Sultan Alsawaf . */ -#include -#include +#include +#include +#include #include -#include -#include -#include #include -#include - -/** - * struct msm_iommu_map - represents a mapping of an ion buffer to an iommu - * @lnode - list node to exist in the buffer's list of iommu mappings - * @dev - Device this is mapped to. Used as key - * @sgl - The scatterlist for this mapping - * @nents - Number of entries in sgl - * @dir - The direction for the map. - * @meta - Backpointer to the meta this guy belongs to. - * @ref - for reference counting this mapping - * @attrs - dma mapping attributes - * @buf_start_addr - address of start of buffer - * - * Represents a mapping of one dma_buf buffer to a particular device - * and address range. There may exist other mappings of this buffer in - * different devices. All mappings will have the same cacheability and security. - */ -struct msm_iommu_map { - struct list_head lnode; - struct rb_node node; - struct device *dev; - struct scatterlist *sgl; - unsigned int nents; - enum dma_data_direction dir; - struct msm_iommu_meta *meta; - struct kref ref; - unsigned long attrs; - dma_addr_t buf_start_addr; -}; - struct msm_iommu_meta { - struct rb_node node; - struct list_head iommu_maps; - struct kref ref; - struct mutex lock; - void *buffer; + struct msm_iommu_data *data; + struct list_head lnode; + struct list_head map_list; + int refcount; }; -static struct rb_root iommu_root; -static DEFINE_MUTEX(msm_iommu_map_mutex); +struct msm_iommu_map { + struct device *dev; + struct list_head lnode; + struct scatterlist *sgl; + enum dma_data_direction dir; + unsigned long attrs; + int nents; + int refcount; +}; -static void msm_iommu_meta_add(struct msm_iommu_meta *meta) +static LIST_HEAD(meta_list); +static DEFINE_SPINLOCK(meta_list_lock); +static DECLARE_RWSEM(unmap_all_rwsem); + +static struct msm_iommu_map *msm_iommu_map_lookup(struct msm_iommu_meta *meta, + struct device *dev) { - struct rb_root *root = &iommu_root; - struct rb_node **p = &root->rb_node; - struct rb_node *parent = NULL; - struct msm_iommu_meta *entry; + struct msm_iommu_map *map; - while (*p) { - parent = *p; - entry = rb_entry(parent, struct msm_iommu_meta, node); - - if (meta->buffer < entry->buffer) - p = &(*p)->rb_left; - else if (meta->buffer > entry->buffer) - p = &(*p)->rb_right; - else - pr_err("%s: dma_buf %p already exists\n", __func__, - entry->buffer); - } - - rb_link_node(&meta->node, parent, p); - rb_insert_color(&meta->node, root); -} - -static struct msm_iommu_meta *msm_iommu_meta_lookup(void *buffer) -{ - struct rb_root *root = &iommu_root; - struct rb_node **p = &root->rb_node; - struct rb_node *parent = NULL; - struct msm_iommu_meta *entry = NULL; - - while (*p) { - parent = *p; - entry = rb_entry(parent, struct msm_iommu_meta, node); - - if (buffer < entry->buffer) - p = &(*p)->rb_left; - else if (buffer > entry->buffer) - p = &(*p)->rb_right; - else - return entry; + list_for_each_entry(map, &meta->map_list, lnode) { + if (map->dev == dev) + return map; } return NULL; } -static void msm_iommu_add(struct msm_iommu_meta *meta, - struct msm_iommu_map *iommu) +static void msm_iommu_map_free(struct msm_iommu_meta *meta, + struct msm_iommu_map *map) { - INIT_LIST_HEAD(&iommu->lnode); - list_add(&iommu->lnode, &meta->iommu_maps); -} + struct msm_iommu_data *data = meta->data; + struct sg_table table = { + .nents = map->nents, + .orig_nents = map->nents, + .sgl = map->sgl + }; + if (--meta->refcount) { + list_del(&map->lnode); + } else { + spin_lock(&meta_list_lock); + list_del(&meta->lnode); + spin_unlock(&meta_list_lock); -static struct msm_iommu_map *msm_iommu_lookup(struct msm_iommu_meta *meta, - struct device *dev) -{ - struct msm_iommu_map *entry; - - list_for_each_entry(entry, &meta->iommu_maps, lnode) { - if (entry->dev == dev) - return entry; + data->meta = NULL; + kfree(meta); } - return NULL; + /* Skip an additional cache maintenance on the dma unmap path */ + map->attrs |= DMA_ATTR_SKIP_CPU_SYNC; + dma_unmap_sg_attrs(map->dev, map->sgl, map->nents, map->dir, + map->attrs); + sg_free_table(&table); + kfree(map); } -static struct msm_iommu_meta *msm_iommu_meta_create(struct dma_buf *dma_buf) -{ - struct msm_iommu_meta *meta; - - meta = kzalloc(sizeof(*meta), GFP_KERNEL); - - if (!meta) - return ERR_PTR(-ENOMEM); - - INIT_LIST_HEAD(&meta->iommu_maps); - meta->buffer = dma_buf->priv; - kref_init(&meta->ref); - mutex_init(&meta->lock); - msm_iommu_meta_add(meta); - - return meta; -} - -static void msm_iommu_meta_put(struct msm_iommu_meta *meta); - static struct scatterlist *clone_sgl(struct scatterlist *sg, int nents) { struct scatterlist *next, *s; - int i; struct sg_table table; + int i; - if (sg_alloc_table(&table, nents, GFP_KERNEL)) - return NULL; + sg_alloc_table(&table, nents, GFP_KERNEL | __GFP_NOFAIL); next = table.sgl; for_each_sg(sg, s, nents, i) { *next = *s; next = sg_next(next); } + return table.sgl; } -static inline int __msm_dma_map_sg(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction dir, - struct dma_buf *dma_buf, - unsigned long attrs) -{ - struct msm_iommu_map *iommu_map; - struct msm_iommu_meta *iommu_meta = NULL; - int ret = 0; - bool extra_meta_ref_taken = false; - int late_unmap = !(attrs & DMA_ATTR_NO_DELAYED_UNMAP); - - mutex_lock(&msm_iommu_map_mutex); - iommu_meta = msm_iommu_meta_lookup(dma_buf->priv); - - if (!iommu_meta) { - iommu_meta = msm_iommu_meta_create(dma_buf); - - if (IS_ERR(iommu_meta)) { - mutex_unlock(&msm_iommu_map_mutex); - ret = PTR_ERR(iommu_meta); - goto out; - } - if (late_unmap) { - kref_get(&iommu_meta->ref); - extra_meta_ref_taken = true; - } - } else { - kref_get(&iommu_meta->ref); - } - - mutex_unlock(&msm_iommu_map_mutex); - - mutex_lock(&iommu_meta->lock); - iommu_map = msm_iommu_lookup(iommu_meta, dev); - if (!iommu_map) { - iommu_map = kmalloc(sizeof(*iommu_map), GFP_KERNEL); - - if (!iommu_map) { - ret = -ENOMEM; - goto out_unlock; - } - - ret = dma_map_sg_attrs(dev, sg, nents, dir, attrs); - if (!ret) { - kfree(iommu_map); - goto out_unlock; - } - - iommu_map->sgl = clone_sgl(sg, nents); - if (!iommu_map->sgl) { - kfree(iommu_map); - ret = -ENOMEM; - goto out_unlock; - } - iommu_map->nents = nents; - iommu_map->dev = dev; - iommu_map->dir = dir; - iommu_map->attrs = attrs; - iommu_map->buf_start_addr = sg_phys(sg); - - kref_init(&iommu_map->ref); - if (late_unmap) - kref_get(&iommu_map->ref); - iommu_map->meta = iommu_meta; - msm_iommu_add(iommu_meta, iommu_map); - - } else { - if (nents == iommu_map->nents && - dir == iommu_map->dir && - (attrs & ~DMA_ATTR_SKIP_CPU_SYNC) == - (iommu_map->attrs & ~DMA_ATTR_SKIP_CPU_SYNC) && - sg_phys(sg) == iommu_map->buf_start_addr) { - struct scatterlist *sg_tmp = sg; - struct scatterlist *map_sg; - int i; - - for_each_sg(iommu_map->sgl, map_sg, nents, i) { - sg_dma_address(sg_tmp) = sg_dma_address(map_sg); - sg_dma_len(sg_tmp) = sg_dma_len(map_sg); - if (sg_dma_len(map_sg) == 0) - break; - - sg_tmp = sg_next(sg_tmp); - if (sg_tmp == NULL) - break; - } - - kref_get(&iommu_map->ref); - - if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0) - dma_sync_sg_for_device(dev, iommu_map->sgl, - iommu_map->nents, iommu_map->dir); - - if (is_device_dma_coherent(dev)) - /* - * Ensure all outstanding changes for coherent - * buffers are applied to the cache before any - * DMA occurs. - */ - dmb(ish); - ret = nents; - } else { - bool start_diff = (sg_phys(sg) != - iommu_map->buf_start_addr); - - dev_err(dev, "lazy map request differs:\n" - "req dir:%d, original dir:%d\n" - "req nents:%d, original nents:%d\n" - "req map attrs:%lu, original map attrs:%lu\n" - "req buffer start address differs:%d\n", - dir, iommu_map->dir, nents, - iommu_map->nents, attrs, iommu_map->attrs, - start_diff); - ret = -EINVAL; - } - } - mutex_unlock(&iommu_meta->lock); - return ret; - -out_unlock: - mutex_unlock(&iommu_meta->lock); -out: - if (!IS_ERR(iommu_meta)) { - if (extra_meta_ref_taken) - msm_iommu_meta_put(iommu_meta); - msm_iommu_meta_put(iommu_meta); - } - return ret; - -} - -/* - * We are not taking a reference to the dma_buf here. It is expected that - * clients hold reference to the dma_buf until they are done with mapping and - * unmapping. - */ int msm_dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, - enum dma_data_direction dir, struct dma_buf *dma_buf, - unsigned long attrs) + enum dma_data_direction dir, struct dma_buf *dma_buf, + unsigned long attrs) { + static const gfp_t gfp_flags_nofail = GFP_KERNEL | __GFP_NOFAIL; + int not_lazy = attrs & DMA_ATTR_NO_DELAYED_UNMAP; + struct msm_iommu_data *data = dma_buf->priv; + struct msm_iommu_meta *meta; + struct msm_iommu_map *map; int ret; - if (IS_ERR_OR_NULL(dev)) { - pr_err("%s: dev pointer is invalid\n", __func__); - return -EINVAL; + mutex_lock(&data->lock); + down_read(&unmap_all_rwsem); + meta = data->meta; + map = meta ? msm_iommu_map_lookup(meta, dev) : NULL; + if (map) { + struct scatterlist *sg_tmp = sg; + struct scatterlist *map_sg; + int i; + + map->refcount++; + + for_each_sg(map->sgl, map_sg, nents, i) { + sg_dma_address(sg_tmp) = sg_dma_address(map_sg); + sg_dma_len(sg_tmp) = sg_dma_len(map_sg); + if (!sg_dma_len(map_sg)) + break; + + sg_tmp = sg_next(sg_tmp); + if (!sg_tmp) + break; + } + + if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) + dma_sync_sg_for_device(dev, map->sgl, map->nents, + map->dir); + + if (is_device_dma_coherent(dev)) + dmb(ish); + } else { + ret = dma_map_sg_attrs(dev, sg, nents, dir, attrs); + if (ret) { + map = kmalloc(sizeof(*map), gfp_flags_nofail); + map->dev = dev; + map->dir = dir; + map->nents = nents; + map->attrs = attrs; + map->refcount = 2 - not_lazy; + map->sgl = clone_sgl(sg, nents); + + if (meta) { + meta->refcount++; + } else { + meta = kmalloc(sizeof(*meta), gfp_flags_nofail); + meta->data = data; + meta->refcount = 1; + INIT_LIST_HEAD(&meta->map_list); + data->meta = meta; + + spin_lock(&meta_list_lock); + list_add(&meta->lnode, &meta_list); + spin_unlock(&meta_list_lock); + } + list_add(&map->lnode, &meta->map_list); + } } + up_read(&unmap_all_rwsem); + mutex_unlock(&data->lock); - if (IS_ERR_OR_NULL(sg)) { - pr_err("%s: sg table pointer is invalid\n", __func__); - return -EINVAL; - } - - if (IS_ERR_OR_NULL(dma_buf)) { - pr_err("%s: dma_buf pointer is invalid\n", __func__); - return -EINVAL; - } - - ret = __msm_dma_map_sg(dev, sg, nents, dir, dma_buf, attrs); - - return ret; -} -EXPORT_SYMBOL(msm_dma_map_sg_attrs); - -static void msm_iommu_meta_destroy(struct kref *kref) -{ - struct msm_iommu_meta *meta = container_of(kref, struct msm_iommu_meta, - ref); - - if (!list_empty(&meta->iommu_maps)) { - WARN(1, "%s: DMA Buffer %p being destroyed with outstanding iommu mappins!\n", - __func__, meta->buffer); - } - rb_erase(&meta->node, &iommu_root); - kfree(meta); + return nents; } -static void msm_iommu_meta_put(struct msm_iommu_meta *meta) -{ - /* - * Need to lock here to prevent race against map/unmap - */ - mutex_lock(&msm_iommu_map_mutex); - kref_put(&meta->ref, msm_iommu_meta_destroy); - mutex_unlock(&msm_iommu_map_mutex); -} - -static void msm_iommu_map_release(struct kref *kref) -{ - struct msm_iommu_map *map = container_of(kref, struct msm_iommu_map, - ref); - struct sg_table table; - - table.nents = table.orig_nents = map->nents; - table.sgl = map->sgl; - list_del(&map->lnode); - - /* Skip an additional cache maintenance on the dma unmap path */ - if (!(map->attrs & DMA_ATTR_SKIP_CPU_SYNC)) - map->attrs |= DMA_ATTR_SKIP_CPU_SYNC; - dma_unmap_sg_attrs(map->dev, map->sgl, map->nents, map->dir, - map->attrs); - sg_free_table(&table); - kfree(map); -} - -void msm_dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sgl, +void msm_dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, struct dma_buf *dma_buf, unsigned long attrs) { - struct msm_iommu_map *iommu_map; + struct msm_iommu_data *data = dma_buf->priv; struct msm_iommu_meta *meta; + struct msm_iommu_map *map; - mutex_lock(&msm_iommu_map_mutex); - meta = msm_iommu_meta_lookup(dma_buf->priv); - if (!meta) { - WARN(1, "%s: (%p) was never mapped\n", __func__, dma_buf); - mutex_unlock(&msm_iommu_map_mutex); - goto out; + mutex_lock(&data->lock); + down_read(&unmap_all_rwsem); + meta = data->meta; + if (meta) { + map = msm_iommu_map_lookup(meta, dev); + if (map) { + if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) + dma_sync_sg_for_cpu(dev, map->sgl, map->nents, + dir); + if (!--map->refcount) + msm_iommu_map_free(meta, map); + } } - mutex_unlock(&msm_iommu_map_mutex); - - mutex_lock(&meta->lock); - iommu_map = msm_iommu_lookup(meta, dev); - - if (!iommu_map) { - WARN(1, "%s: (%p) was never mapped for device %p\n", __func__, - dma_buf, dev); - mutex_unlock(&meta->lock); - goto out; - } - - if (dir != iommu_map->dir) - WARN(1, "%s: (%pK) dir:%d differs from original dir:%d\n", - __func__, dma_buf, dir, iommu_map->dir); - - if (attrs && ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)) - dma_sync_sg_for_cpu(dev, iommu_map->sgl, iommu_map->nents, dir); - - iommu_map->attrs = attrs; - kref_put(&iommu_map->ref, msm_iommu_map_release); - mutex_unlock(&meta->lock); - - msm_iommu_meta_put(meta); - -out: - return; + up_read(&unmap_all_rwsem); + mutex_unlock(&data->lock); } -EXPORT_SYMBOL(msm_dma_unmap_sg_attrs); int msm_dma_unmap_all_for_dev(struct device *dev) { - int ret = 0; - struct msm_iommu_meta *meta; - struct rb_root *root; - struct rb_node *meta_node; + struct msm_iommu_meta *meta, *tmp_meta; + struct msm_iommu_map *map; - mutex_lock(&msm_iommu_map_mutex); - root = &iommu_root; - meta_node = rb_first(root); - while (meta_node) { - struct msm_iommu_map *iommu_map; - struct msm_iommu_map *iommu_map_next; - - meta = rb_entry(meta_node, struct msm_iommu_meta, node); - mutex_lock(&meta->lock); - list_for_each_entry_safe(iommu_map, iommu_map_next, - &meta->iommu_maps, lnode) - if (iommu_map->dev == dev) - if (!kref_put(&iommu_map->ref, - msm_iommu_map_release)) - ret = -EINVAL; - - mutex_unlock(&meta->lock); - meta_node = rb_next(meta_node); + down_write(&unmap_all_rwsem); + list_for_each_entry_safe(meta, tmp_meta, &meta_list, lnode) { + map = msm_iommu_map_lookup(meta, dev); + if (map) + msm_iommu_map_free(meta, map); } - mutex_unlock(&msm_iommu_map_mutex); + up_write(&unmap_all_rwsem); - return ret; + return 0; } -/* - * Only to be called by ION code when a buffer is freed - */ -void msm_dma_buf_freed(void *buffer) +void msm_dma_buf_freed(struct msm_iommu_data *data) { - struct msm_iommu_map *iommu_map; - struct msm_iommu_map *iommu_map_next; + struct msm_iommu_map *map, *tmp_map; struct msm_iommu_meta *meta; - mutex_lock(&msm_iommu_map_mutex); - meta = msm_iommu_meta_lookup(buffer); - if (!meta) { - /* Already unmapped (assuming no late unmapping) */ - mutex_unlock(&msm_iommu_map_mutex); - return; + mutex_lock(&data->lock); + down_read(&unmap_all_rwsem); + meta = data->meta; + if (meta) { + list_for_each_entry_safe(map, tmp_map, &meta->map_list, lnode) + msm_iommu_map_free(meta, map); } - mutex_unlock(&msm_iommu_map_mutex); - - mutex_lock(&meta->lock); - - list_for_each_entry_safe(iommu_map, iommu_map_next, &meta->iommu_maps, - lnode) - kref_put(&iommu_map->ref, msm_iommu_map_release); - - if (!list_empty(&meta->iommu_maps)) { - WARN(1, "%s: DMA buffer %p destroyed with outstanding iommu mappings\n", - __func__, meta->buffer); - } - - INIT_LIST_HEAD(&meta->iommu_maps); - mutex_unlock(&meta->lock); - - msm_iommu_meta_put(meta); + up_read(&unmap_all_rwsem); + mutex_unlock(&data->lock); } diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index 9d991c2d8767..3300562dfa70 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -1148,7 +1148,7 @@ static int rk_iommu_probe(struct platform_device *pdev) iommu->dev = dev; iommu->num_mmu = 0; - iommu->bases = devm_kzalloc(dev, sizeof(*iommu->bases) * num_res, + iommu->bases = devm_kcalloc(dev, num_res, sizeof(*iommu->bases), GFP_KERNEL); if (!iommu->bases) return -ENOMEM; diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c index b62f790ad1ba..708ec771a92f 100644 --- a/drivers/iommu/tegra-gart.c +++ b/drivers/iommu/tegra-gart.c @@ -454,7 +454,7 @@ static int tegra_gart_probe(struct platform_device *pdev) gart->iovmm_base = (dma_addr_t)res_remap->start; gart->page_count = (resource_size(res_remap) >> GART_PAGE_SHIFT); - gart->savedata = vmalloc(sizeof(u32) * gart->page_count); + gart->savedata = vmalloc(array_size(sizeof(u32), gart->page_count)); if (!gart->savedata) { dev_err(dev, "failed to allocate context save area\n"); return -ENOMEM; diff --git a/drivers/ipack/carriers/tpci200.c b/drivers/ipack/carriers/tpci200.c index 9b23843dcad4..a16b320739b4 100644 --- a/drivers/ipack/carriers/tpci200.c +++ b/drivers/ipack/carriers/tpci200.c @@ -457,8 +457,8 @@ static int tpci200_install(struct tpci200_board *tpci200) { int res; - tpci200->slots = kzalloc( - TPCI200_NB_SLOT * sizeof(struct tpci200_slot), GFP_KERNEL); + tpci200->slots = kcalloc(TPCI200_NB_SLOT, sizeof(struct tpci200_slot), + GFP_KERNEL); if (tpci200->slots == NULL) return -ENOMEM; diff --git a/drivers/irqchip/irq-alpine-msi.c b/drivers/irqchip/irq-alpine-msi.c index 63d980995d17..23a3b877f7f1 100644 --- a/drivers/irqchip/irq-alpine-msi.c +++ b/drivers/irqchip/irq-alpine-msi.c @@ -268,7 +268,8 @@ static int alpine_msix_init(struct device_node *node, goto err_priv; } - priv->msi_map = kzalloc(sizeof(*priv->msi_map) * BITS_TO_LONGS(priv->num_spis), + priv->msi_map = kcalloc(BITS_TO_LONGS(priv->num_spis), + sizeof(*priv->msi_map), GFP_KERNEL); if (!priv->msi_map) { ret = -ENOMEM; diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c index 993a8426a453..87bb60063f8b 100644 --- a/drivers/irqchip/irq-gic-v2m.c +++ b/drivers/irqchip/irq-gic-v2m.c @@ -363,7 +363,7 @@ static int __init gicv2m_init_one(struct fwnode_handle *fwnode, break; } - v2m->bm = kzalloc(sizeof(long) * BITS_TO_LONGS(v2m->nr_spis), + v2m->bm = kcalloc(BITS_TO_LONGS(v2m->nr_spis), sizeof(long), GFP_KERNEL); if (!v2m->bm) { ret = -ENOMEM; diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 84b23d902d5b..a2d5c4744c0b 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1153,7 +1153,7 @@ static int its_vlpi_map(struct irq_data *d, struct its_cmd_info *info) if (!its_dev->event_map.vm) { struct its_vlpi_map *maps; - maps = kzalloc(sizeof(*maps) * its_dev->event_map.nr_lpis, + maps = kcalloc(its_dev->event_map.nr_lpis, sizeof(*maps), GFP_KERNEL); if (!maps) { ret = -ENOMEM; @@ -1337,7 +1337,7 @@ static int __init its_lpi_init(u32 id_bits) { lpi_chunks = its_lpi_to_chunk(1UL << id_bits); - lpi_bitmap = kzalloc(BITS_TO_LONGS(lpi_chunks) * sizeof(long), + lpi_bitmap = kcalloc(BITS_TO_LONGS(lpi_chunks), sizeof(long), GFP_KERNEL); if (!lpi_bitmap) { lpi_chunks = 0; @@ -1371,7 +1371,8 @@ static unsigned long *its_lpi_alloc_chunks(int nr_irqs, int *base, int *nr_ids) if (!nr_chunks) goto out; - bitmap = kzalloc(BITS_TO_LONGS(nr_chunks * IRQS_PER_CHUNK) * sizeof (long), + bitmap = kcalloc(BITS_TO_LONGS(nr_chunks * IRQS_PER_CHUNK), + sizeof(long), GFP_ATOMIC); if (!bitmap) goto out; @@ -1734,7 +1735,7 @@ static int its_alloc_tables(struct its_node *its) static int its_alloc_collections(struct its_node *its) { - its->collections = kzalloc(nr_cpu_ids * sizeof(*its->collections), + its->collections = kcalloc(nr_cpu_ids, sizeof(*its->collections), GFP_KERNEL); if (!its->collections) return -ENOMEM; @@ -2044,10 +2045,10 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, if (alloc_lpis) { lpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis); if (lpi_map) - col_map = kzalloc(sizeof(*col_map) * nr_lpis, + col_map = kcalloc(nr_lpis, sizeof(*col_map), GFP_KERNEL); } else { - col_map = kzalloc(sizeof(*col_map) * nr_ites, GFP_KERNEL); + col_map = kcalloc(nr_ites, sizeof(*col_map), GFP_KERNEL); nr_lpis = 0; lpi_base = 0; } @@ -2893,7 +2894,7 @@ static int its_init_vpe_domain(void) its = list_first_entry(&its_nodes, struct its_node, entry); entries = roundup_pow_of_two(nr_cpu_ids); - vpe_proxy.vpes = kzalloc(sizeof(*vpe_proxy.vpes) * entries, + vpe_proxy.vpes = kcalloc(entries, sizeof(*vpe_proxy.vpes), GFP_KERNEL); if (!vpe_proxy.vpes) { pr_err("ITS: Can't allocate GICv4 proxy device array\n"); @@ -3213,8 +3214,8 @@ static void __init acpi_table_parse_srat_its(void) if (count <= 0) return; - its_srat_maps = kmalloc(count * sizeof(struct its_srat_map), - GFP_KERNEL); + its_srat_maps = kmalloc_array(count, sizeof(struct its_srat_map), + GFP_KERNEL); if (!its_srat_maps) { pr_warn("SRAT: Failed to allocate memory for its_srat_maps!\n"); return; diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 26938ca27a38..755418aab90b 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -1272,7 +1273,7 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node) if (!nr_parts) goto out_put_node; - parts = kzalloc(sizeof(*parts) * nr_parts, GFP_KERNEL); + parts = kcalloc(nr_parts, sizeof(*parts), GFP_KERNEL); if (WARN_ON(!parts)) goto out_put_node; @@ -1394,7 +1395,8 @@ static int __init gicv3_of_init(struct device_node *node, struct device_node *pa if (of_property_read_u32(node, "#redistributor-regions", &nr_redist_regions)) nr_redist_regions = 1; - rdist_regs = kzalloc(sizeof(*rdist_regs) * nr_redist_regions, GFP_KERNEL); + rdist_regs = kcalloc(nr_redist_regions, sizeof(*rdist_regs), + GFP_KERNEL); if (!rdist_regs) { err = -ENOMEM; goto out_unmap_dist; diff --git a/drivers/irqchip/irq-imgpdc.c b/drivers/irqchip/irq-imgpdc.c index 1f59998e03f8..b4a84ba16b39 100644 --- a/drivers/irqchip/irq-imgpdc.c +++ b/drivers/irqchip/irq-imgpdc.c @@ -354,7 +354,7 @@ static int pdc_intc_probe(struct platform_device *pdev) priv->nr_syswakes = val; /* Get peripheral IRQ numbers */ - priv->perip_irqs = devm_kzalloc(&pdev->dev, 4 * priv->nr_perips, + priv->perip_irqs = devm_kcalloc(&pdev->dev, 4, priv->nr_perips, GFP_KERNEL); if (!priv->perip_irqs) { dev_err(&pdev->dev, "cannot allocate perip IRQ list\n"); diff --git a/drivers/irqchip/irq-mvebu-gicp.c b/drivers/irqchip/irq-mvebu-gicp.c index 17a4a7b6cdbb..cb3e6ddb075b 100644 --- a/drivers/irqchip/irq-mvebu-gicp.c +++ b/drivers/irqchip/irq-mvebu-gicp.c @@ -207,8 +207,8 @@ static int mvebu_gicp_probe(struct platform_device *pdev) gicp->spi_ranges_cnt = ret / 2; gicp->spi_ranges = - devm_kzalloc(&pdev->dev, - gicp->spi_ranges_cnt * + devm_kcalloc(&pdev->dev, + gicp->spi_ranges_cnt, sizeof(struct mvebu_gicp_spi_range), GFP_KERNEL); if (!gicp->spi_ranges) @@ -226,8 +226,8 @@ static int mvebu_gicp_probe(struct platform_device *pdev) gicp->spi_cnt += gicp->spi_ranges[i].count; } - gicp->spi_bitmap = devm_kzalloc(&pdev->dev, - BITS_TO_LONGS(gicp->spi_cnt) * sizeof(long), + gicp->spi_bitmap = devm_kcalloc(&pdev->dev, + BITS_TO_LONGS(gicp->spi_cnt), sizeof(long), GFP_KERNEL); if (!gicp->spi_bitmap) return -ENOMEM; diff --git a/drivers/irqchip/irq-partition-percpu.c b/drivers/irqchip/irq-partition-percpu.c index ccd72c2cbc23..1f7cc5933cd5 100644 --- a/drivers/irqchip/irq-partition-percpu.c +++ b/drivers/irqchip/irq-partition-percpu.c @@ -229,7 +229,7 @@ struct partition_desc *partition_create_desc(struct fwnode_handle *fwnode, goto out; desc->domain = d; - desc->bitmap = kzalloc(sizeof(long) * BITS_TO_LONGS(nr_parts), + desc->bitmap = kcalloc(BITS_TO_LONGS(nr_parts), sizeof(long), GFP_KERNEL); if (WARN_ON(!desc->bitmap)) goto out; diff --git a/drivers/irqchip/irq-s3c24xx.c b/drivers/irqchip/irq-s3c24xx.c index c25ce5af091a..e1eb8eeac4b4 100644 --- a/drivers/irqchip/irq-s3c24xx.c +++ b/drivers/irqchip/irq-s3c24xx.c @@ -1261,7 +1261,7 @@ static int __init s3c_init_intc_of(struct device_node *np, return -ENOMEM; intc->domain = domain; - intc->irqs = kzalloc(sizeof(struct s3c_irq_data) * 32, + intc->irqs = kcalloc(32, sizeof(struct s3c_irq_data), GFP_KERNEL); if (!intc->irqs) { kfree(intc); diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index da45049de97e..5919baa3828a 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1268,7 +1268,7 @@ static int __init capinc_tty_init(void) if (capi_ttyminors <= 0) capi_ttyminors = CAPINC_NR_PORTS; - capiminors = kzalloc(sizeof(struct capiminor *) * capi_ttyminors, + capiminors = kcalloc(capi_ttyminors, sizeof(struct capiminor *), GFP_KERNEL); if (!capiminors) return -ENOMEM; diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c index 89dd1303a98a..982fc1e26062 100644 --- a/drivers/isdn/capi/capidrv.c +++ b/drivers/isdn/capi/capidrv.c @@ -2268,7 +2268,8 @@ static int capidrv_addcontr(u16 contr, struct capi_profile *profp) strcpy(card->name, id); card->contrnr = contr; card->nbchan = profp->nbchannel; - card->bchans = kmalloc(sizeof(capidrv_bchan) * card->nbchan, GFP_ATOMIC); + card->bchans = kmalloc_array(card->nbchan, sizeof(capidrv_bchan), + GFP_ATOMIC); if (!card->bchans) { printk(KERN_WARNING "capidrv: (%s) Could not allocate bchan-structs.\n", id); diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c index ccec7778cad2..fcf34fe704fe 100644 --- a/drivers/isdn/gigaset/capi.c +++ b/drivers/isdn/gigaset/capi.c @@ -252,7 +252,7 @@ static inline void dump_rawmsg(enum debuglevel level, const char *tag, return; if (l > 64) l = 64; /* arbitrary limit */ - dbgline = kmalloc(3 * l, GFP_ATOMIC); + dbgline = kmalloc_array(3, l, GFP_ATOMIC); if (!dbgline) return; for (i = 0; i < l; i++) { @@ -272,7 +272,7 @@ static inline void dump_rawmsg(enum debuglevel level, const char *tag, return; if (l > 64) l = 64; /* arbitrary limit */ - dbgline = kmalloc(3 * l, GFP_ATOMIC); + dbgline = kmalloc_array(3, l, GFP_ATOMIC); if (!dbgline) return; data += CAPIMSG_LEN(data); @@ -1370,7 +1370,7 @@ static void do_connect_req(struct gigaset_capi_ctr *iif, cmsg->adr.adrPLCI |= (bcs->channel + 1) << 8; /* build command table */ - commands = kzalloc(AT_NUM * (sizeof *commands), GFP_KERNEL); + commands = kcalloc(AT_NUM, sizeof(*commands), GFP_KERNEL); if (!commands) goto oom; diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 7c7814497e3e..47894afb563e 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c @@ -710,7 +710,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, cs->mode = M_UNKNOWN; cs->mstate = MS_UNINITIALIZED; - cs->bcs = kmalloc(channels * sizeof(struct bc_state), GFP_KERNEL); + cs->bcs = kmalloc_array(channels, sizeof(struct bc_state), GFP_KERNEL); cs->inbuf = kmalloc(sizeof(struct inbuf_t), GFP_KERNEL); if (!cs->bcs || !cs->inbuf) { pr_err("out of memory\n"); @@ -1090,7 +1090,7 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, drv->owner = owner; INIT_LIST_HEAD(&drv->list); - drv->cs = kmalloc(minors * sizeof *drv->cs, GFP_KERNEL); + drv->cs = kmalloc_array(minors, sizeof(*drv->cs), GFP_KERNEL); if (!drv->cs) goto error; diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c index 2d75329007f1..b5b389e95edd 100644 --- a/drivers/isdn/gigaset/i4l.c +++ b/drivers/isdn/gigaset/i4l.c @@ -243,7 +243,7 @@ static int command_from_LL(isdn_ctrl *cntrl) dev_kfree_skb(bcs->rx_skb); gigaset_new_rx_skb(bcs); - commands = kzalloc(AT_NUM * (sizeof *commands), GFP_ATOMIC); + commands = kcalloc(AT_NUM, sizeof(*commands), GFP_ATOMIC); if (!commands) { gigaset_free_channel(bcs); dev_err(cs->dev, "ISDN_CMD_DIAL: out of memory\n"); diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c index 40a099f33bfc..45985170af7c 100644 --- a/drivers/isdn/hardware/avm/b1.c +++ b/drivers/isdn/hardware/avm/b1.c @@ -72,7 +72,7 @@ avmcard *b1_alloc_card(int nr_controllers) if (!card) return NULL; - cinfo = kzalloc(sizeof(*cinfo) * nr_controllers, GFP_KERNEL); + cinfo = kcalloc(nr_controllers, sizeof(*cinfo), GFP_KERNEL); if (!cinfo) { kfree(card); return NULL; diff --git a/drivers/isdn/hisax/fsm.c b/drivers/isdn/hisax/fsm.c index d63266fa8cbd..36555e666e98 100644 --- a/drivers/isdn/hisax/fsm.c +++ b/drivers/isdn/hisax/fsm.c @@ -27,7 +27,8 @@ FsmNew(struct Fsm *fsm, struct FsmNode *fnlist, int fncount) int i; fsm->jumpmatrix = - kzalloc(sizeof(FSMFNPTR) * fsm->state_count * fsm->event_count, GFP_KERNEL); + kzalloc(array3_size(sizeof(FSMFNPTR), fsm->state_count, fsm->event_count), + GFP_KERNEL); if (!fsm->jumpmatrix) return -ENOMEM; diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c index ad8597a1a07e..a6c378f8964e 100644 --- a/drivers/isdn/hisax/hfc_2bds0.c +++ b/drivers/isdn/hisax/hfc_2bds0.c @@ -1024,7 +1024,7 @@ static unsigned int int i; unsigned *send; - if (!(send = kmalloc(cnt * sizeof(unsigned int), GFP_ATOMIC))) { + if (!(send = kmalloc_array(cnt, sizeof(unsigned int), GFP_ATOMIC))) { printk(KERN_WARNING "HiSax: No memory for hfcd.send\n"); return (NULL); diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c index 14dada42874e..3cc3a9f62538 100644 --- a/drivers/isdn/hisax/hfc_2bs0.c +++ b/drivers/isdn/hisax/hfc_2bs0.c @@ -557,7 +557,7 @@ init_send(struct BCState *bcs) { int i; - if (!(bcs->hw.hfc.send = kmalloc(32 * sizeof(unsigned int), GFP_ATOMIC))) { + if (!(bcs->hw.hfc.send = kmalloc_array(32, sizeof(unsigned int), GFP_ATOMIC))) { printk(KERN_WARNING "HiSax: No memory for hfc.send\n"); return; diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c index b7f54fa29228..579654513fec 100644 --- a/drivers/isdn/hisax/netjet.c +++ b/drivers/isdn/hisax/netjet.c @@ -912,8 +912,8 @@ setstack_tiger(struct PStack *st, struct BCState *bcs) void inittiger(struct IsdnCardState *cs) { - if (!(cs->bcs[0].hw.tiger.send = kmalloc(NETJET_DMA_TXSIZE * sizeof(unsigned int), - GFP_KERNEL | GFP_DMA))) { + if (!(cs->bcs[0].hw.tiger.send = kmalloc_array(NETJET_DMA_TXSIZE, sizeof(unsigned int), + GFP_KERNEL | GFP_DMA))) { printk(KERN_WARNING "HiSax: No memory for tiger.send\n"); return; @@ -933,8 +933,8 @@ inittiger(struct IsdnCardState *cs) cs->hw.njet.base + NETJET_DMA_READ_IRQ); outl(virt_to_bus(cs->bcs[0].hw.tiger.s_end), cs->hw.njet.base + NETJET_DMA_READ_END); - if (!(cs->bcs[0].hw.tiger.rec = kmalloc(NETJET_DMA_RXSIZE * sizeof(unsigned int), - GFP_KERNEL | GFP_DMA))) { + if (!(cs->bcs[0].hw.tiger.rec = kmalloc_array(NETJET_DMA_RXSIZE, sizeof(unsigned int), + GFP_KERNEL | GFP_DMA))) { printk(KERN_WARNING "HiSax: No memory for tiger.rec\n"); return; diff --git a/drivers/isdn/i4l/isdn_bsdcomp.c b/drivers/isdn/i4l/isdn_bsdcomp.c index 99012c047751..891e0d96c409 100644 --- a/drivers/isdn/i4l/isdn_bsdcomp.c +++ b/drivers/isdn/i4l/isdn_bsdcomp.c @@ -340,7 +340,7 @@ static void *bsd_alloc(struct isdn_ppp_comp_data *data) * Allocate space for the dictionary. This may be more than one page in * length. */ - db->dict = vmalloc(hsize * sizeof(struct bsd_dict)); + db->dict = vmalloc(array_size(hsize, sizeof(struct bsd_dict))); if (!db->dict) { bsd_free(db); return NULL; @@ -353,7 +353,7 @@ static void *bsd_alloc(struct isdn_ppp_comp_data *data) if (!decomp) db->lens = NULL; else { - db->lens = vmalloc((maxmaxcode + 1) * sizeof(db->lens[0])); + db->lens = vmalloc(array_size(sizeof(db->lens[0]), (maxmaxcode + 1))); if (!db->lens) { bsd_free(db); return (NULL); diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index 598724ffde4e..4fce7264e380 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c @@ -2064,14 +2064,14 @@ isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding) if ((adding) && (d->rcverr)) kfree(d->rcverr); - if (!(d->rcverr = kzalloc(sizeof(int) * m, GFP_ATOMIC))) { + if (!(d->rcverr = kcalloc(m, sizeof(int), GFP_ATOMIC))) { printk(KERN_WARNING "register_isdn: Could not alloc rcverr\n"); return -1; } if ((adding) && (d->rcvcount)) kfree(d->rcvcount); - if (!(d->rcvcount = kzalloc(sizeof(int) * m, GFP_ATOMIC))) { + if (!(d->rcvcount = kcalloc(m, sizeof(int), GFP_ATOMIC))) { printk(KERN_WARNING "register_isdn: Could not alloc rcvcount\n"); if (!adding) kfree(d->rcverr); @@ -2083,7 +2083,7 @@ isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding) skb_queue_purge(&d->rpqueue[j]); kfree(d->rpqueue); } - if (!(d->rpqueue = kmalloc(sizeof(struct sk_buff_head) * m, GFP_ATOMIC))) { + if (!(d->rpqueue = kmalloc_array(m, sizeof(struct sk_buff_head), GFP_ATOMIC))) { printk(KERN_WARNING "register_isdn: Could not alloc rpqueue\n"); if (!adding) { kfree(d->rcvcount); @@ -2097,7 +2097,8 @@ isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding) if ((adding) && (d->rcv_waitq)) kfree(d->rcv_waitq); - d->rcv_waitq = kmalloc(sizeof(wait_queue_head_t) * 2 * m, GFP_ATOMIC); + d->rcv_waitq = kmalloc(array3_size(sizeof(wait_queue_head_t), 2, m), + GFP_ATOMIC); if (!d->rcv_waitq) { printk(KERN_WARNING "register_isdn: Could not alloc rcv_waitq\n"); if (!adding) { diff --git a/drivers/isdn/mISDN/fsm.c b/drivers/isdn/mISDN/fsm.c index 92e6570b1143..153b7b6d2be4 100644 --- a/drivers/isdn/mISDN/fsm.c +++ b/drivers/isdn/mISDN/fsm.c @@ -32,8 +32,8 @@ mISDN_FsmNew(struct Fsm *fsm, { int i; - fsm->jumpmatrix = kzalloc(sizeof(FSMFNPTR) * fsm->state_count * - fsm->event_count, GFP_KERNEL); + fsm->jumpmatrix = kzalloc(array3_size(sizeof(FSMFNPTR), fsm->state_count, fsm->event_count), + GFP_KERNEL); if (fsm->jumpmatrix == NULL) return -ENOMEM; diff --git a/drivers/leds/leds-adp5520.c b/drivers/leds/leds-adp5520.c index 853b2d3bdb17..7ecf080f73ad 100644 --- a/drivers/leds/leds-adp5520.c +++ b/drivers/leds/leds-adp5520.c @@ -108,7 +108,7 @@ static int adp5520_led_probe(struct platform_device *pdev) return -EFAULT; } - led = devm_kzalloc(&pdev->dev, sizeof(*led) * pdata->num_leds, + led = devm_kcalloc(&pdev->dev, pdata->num_leds, sizeof(*led), GFP_KERNEL); if (!led) return -ENOMEM; diff --git a/drivers/leds/leds-da9052.c b/drivers/leds/leds-da9052.c index f8c7d82c2652..31d4c94e6fd8 100644 --- a/drivers/leds/leds-da9052.c +++ b/drivers/leds/leds-da9052.c @@ -113,8 +113,8 @@ static int da9052_led_probe(struct platform_device *pdev) goto err; } - led = devm_kzalloc(&pdev->dev, - sizeof(struct da9052_led) * pled->num_leds, + led = devm_kcalloc(&pdev->dev, + pled->num_leds, sizeof(struct da9052_led), GFP_KERNEL); if (!led) { error = -ENOMEM; diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c index 55c0517fbe03..99689b51a73d 100644 --- a/drivers/leds/leds-lp5521.c +++ b/drivers/leds/leds-lp5521.c @@ -533,8 +533,8 @@ static int lp5521_probe(struct i2c_client *client, if (!chip) return -ENOMEM; - led = devm_kzalloc(&client->dev, - sizeof(*led) * pdata->num_channels, GFP_KERNEL); + led = devm_kcalloc(&client->dev, + pdata->num_channels, sizeof(*led), GFP_KERNEL); if (!led) return -ENOMEM; diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c index 13838d72e297..5074a1b79563 100644 --- a/drivers/leds/leds-lp5523.c +++ b/drivers/leds/leds-lp5523.c @@ -900,8 +900,8 @@ static int lp5523_probe(struct i2c_client *client, if (!chip) return -ENOMEM; - led = devm_kzalloc(&client->dev, - sizeof(*led) * pdata->num_channels, GFP_KERNEL); + led = devm_kcalloc(&client->dev, + pdata->num_channels, sizeof(*led), GFP_KERNEL); if (!led) return -ENOMEM; diff --git a/drivers/leds/leds-lp5562.c b/drivers/leds/leds-lp5562.c index 9d9b673c873c..18edc8bdc9f7 100644 --- a/drivers/leds/leds-lp5562.c +++ b/drivers/leds/leds-lp5562.c @@ -538,8 +538,8 @@ static int lp5562_probe(struct i2c_client *client, if (!chip) return -ENOMEM; - led = devm_kzalloc(&client->dev, - sizeof(*led) * pdata->num_channels, GFP_KERNEL); + led = devm_kcalloc(&client->dev, + pdata->num_channels, sizeof(*led), GFP_KERNEL); if (!led) return -ENOMEM; diff --git a/drivers/leds/leds-lp55xx-common.c b/drivers/leds/leds-lp55xx-common.c index e2655953667c..723f2f17497a 100644 --- a/drivers/leds/leds-lp55xx-common.c +++ b/drivers/leds/leds-lp55xx-common.c @@ -560,7 +560,7 @@ struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device *dev, return ERR_PTR(-EINVAL); } - cfg = devm_kzalloc(dev, sizeof(*cfg) * num_channels, GFP_KERNEL); + cfg = devm_kcalloc(dev, num_channels, sizeof(*cfg), GFP_KERNEL); if (!cfg) return ERR_PTR(-ENOMEM); diff --git a/drivers/leds/leds-lp8501.c b/drivers/leds/leds-lp8501.c index 3adb113cf02e..4c800b5989a9 100644 --- a/drivers/leds/leds-lp8501.c +++ b/drivers/leds/leds-lp8501.c @@ -327,8 +327,8 @@ static int lp8501_probe(struct i2c_client *client, if (!chip) return -ENOMEM; - led = devm_kzalloc(&client->dev, - sizeof(*led) * pdata->num_channels, GFP_KERNEL); + led = devm_kcalloc(&client->dev, + pdata->num_channels, sizeof(*led), GFP_KERNEL); if (!led) return -ENOMEM; diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c index a7ff510cbdd0..5ec730a31b65 100644 --- a/drivers/leds/leds-lt3593.c +++ b/drivers/leds/leds-lt3593.c @@ -128,8 +128,8 @@ static int lt3593_led_probe(struct platform_device *pdev) if (!pdata) return -EBUSY; - leds_data = devm_kzalloc(&pdev->dev, - sizeof(struct lt3593_led_data) * pdata->num_leds, + leds_data = devm_kcalloc(&pdev->dev, + pdata->num_leds, sizeof(struct lt3593_led_data), GFP_KERNEL); if (!leds_data) return -ENOMEM; diff --git a/drivers/leds/leds-mc13783.c b/drivers/leds/leds-mc13783.c index 2421cf104991..47ad7de9553c 100644 --- a/drivers/leds/leds-mc13783.c +++ b/drivers/leds/leds-mc13783.c @@ -136,7 +136,7 @@ static struct mc13xxx_leds_platform_data __init *mc13xxx_led_probe_dt( pdata->num_leds = of_get_child_count(parent); - pdata->led = devm_kzalloc(dev, pdata->num_leds * sizeof(*pdata->led), + pdata->led = devm_kcalloc(dev, pdata->num_leds, sizeof(*pdata->led), GFP_KERNEL); if (!pdata->led) { ret = -ENOMEM; @@ -210,7 +210,7 @@ static int __init mc13xxx_led_probe(struct platform_device *pdev) return -EINVAL; } - leds->led = devm_kzalloc(dev, leds->num_leds * sizeof(*leds->led), + leds->led = devm_kcalloc(dev, leds->num_leds, sizeof(*leds->led), GFP_KERNEL); if (!leds->led) return -ENOMEM; diff --git a/drivers/leds/leds-mlxcpld.c b/drivers/leds/leds-mlxcpld.c index 281482e1d50f..f4721f8065f0 100644 --- a/drivers/leds/leds-mlxcpld.c +++ b/drivers/leds/leds-mlxcpld.c @@ -329,8 +329,10 @@ static int mlxcpld_led_config(struct device *dev, int i; int err; - cpld->pled = devm_kzalloc(dev, sizeof(struct mlxcpld_led_priv) * - cpld->num_led_instances, GFP_KERNEL); + cpld->pled = devm_kcalloc(dev, + cpld->num_led_instances, + sizeof(struct mlxcpld_led_priv), + GFP_KERNEL); if (!cpld->pled) return -ENOMEM; diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c index f48b1aed9b4e..62fa0de526ee 100644 --- a/drivers/leds/leds-netxbig.c +++ b/drivers/leds/leds-netxbig.c @@ -335,7 +335,7 @@ static int gpio_ext_get_of_pdata(struct device *dev, struct device_node *np, return ret; } num_addr = ret; - addr = devm_kzalloc(dev, num_addr * sizeof(*addr), GFP_KERNEL); + addr = devm_kcalloc(dev, num_addr, sizeof(*addr), GFP_KERNEL); if (!addr) return -ENOMEM; @@ -355,7 +355,7 @@ static int gpio_ext_get_of_pdata(struct device *dev, struct device_node *np, return ret; } num_data = ret; - data = devm_kzalloc(dev, num_data * sizeof(*data), GFP_KERNEL); + data = devm_kcalloc(dev, num_data, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; @@ -415,7 +415,7 @@ static int netxbig_leds_get_of_pdata(struct device *dev, if (ret % 3) return -EINVAL; num_timers = ret / 3; - timers = devm_kzalloc(dev, num_timers * sizeof(*timers), + timers = devm_kcalloc(dev, num_timers, sizeof(*timers), GFP_KERNEL); if (!timers) return -ENOMEM; @@ -444,7 +444,7 @@ static int netxbig_leds_get_of_pdata(struct device *dev, return -ENODEV; } - leds = devm_kzalloc(dev, num_leds * sizeof(*leds), GFP_KERNEL); + leds = devm_kcalloc(dev, num_leds, sizeof(*leds), GFP_KERNEL); if (!leds) return -ENOMEM; @@ -470,8 +470,8 @@ static int netxbig_leds_get_of_pdata(struct device *dev, goto err_node_put; mode_val = - devm_kzalloc(dev, - NETXBIG_LED_MODE_NUM * sizeof(*mode_val), + devm_kcalloc(dev, + NETXBIG_LED_MODE_NUM, sizeof(*mode_val), GFP_KERNEL); if (!mode_val) { ret = -ENOMEM; @@ -560,8 +560,8 @@ static int netxbig_led_probe(struct platform_device *pdev) return ret; } - leds_data = devm_kzalloc(&pdev->dev, - pdata->num_leds * sizeof(*leds_data), + leds_data = devm_kcalloc(&pdev->dev, + pdata->num_leds, sizeof(*leds_data), GFP_KERNEL); if (!leds_data) return -ENOMEM; diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c index 506b75b190e7..14fe5cd43232 100644 --- a/drivers/leds/leds-ns2.c +++ b/drivers/leds/leds-ns2.c @@ -264,7 +264,7 @@ ns2_leds_get_of_pdata(struct device *dev, struct ns2_led_platform_data *pdata) if (!num_leds) return -ENODEV; - leds = devm_kzalloc(dev, num_leds * sizeof(struct ns2_led), + leds = devm_kcalloc(dev, num_leds, sizeof(struct ns2_led), GFP_KERNEL); if (!leds) return -ENOMEM; @@ -298,8 +298,9 @@ ns2_leds_get_of_pdata(struct device *dev, struct ns2_led_platform_data *pdata) } num_modes = ret / 3; - modval = devm_kzalloc(dev, - num_modes * sizeof(struct ns2_led_modval), + modval = devm_kcalloc(dev, + num_modes, + sizeof(struct ns2_led_modval), GFP_KERNEL); if (!modval) return -ENOMEM; diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c index 78183f90820e..f51b356d4426 100644 --- a/drivers/leds/leds-pca955x.c +++ b/drivers/leds/leds-pca955x.c @@ -390,8 +390,8 @@ pca955x_pdata_of_init(struct i2c_client *client, struct pca955x_chipdef *chip) if (!pdata) return ERR_PTR(-ENOMEM); - pdata->leds = devm_kzalloc(&client->dev, - sizeof(struct pca955x_led) * chip->bits, + pdata->leds = devm_kcalloc(&client->dev, + chip->bits, sizeof(struct pca955x_led), GFP_KERNEL); if (!pdata->leds) return ERR_PTR(-ENOMEM); @@ -494,8 +494,8 @@ static int pca955x_probe(struct i2c_client *client, if (!pca955x) return -ENOMEM; - pca955x->leds = devm_kzalloc(&client->dev, - sizeof(*pca955x_led) * chip->bits, GFP_KERNEL); + pca955x->leds = devm_kcalloc(&client->dev, + chip->bits, sizeof(*pca955x_led), GFP_KERNEL); if (!pca955x->leds) return -ENOMEM; diff --git a/drivers/leds/leds-pca963x.c b/drivers/leds/leds-pca963x.c index 88c7313cf869..bbcde13b77f1 100644 --- a/drivers/leds/leds-pca963x.c +++ b/drivers/leds/leds-pca963x.c @@ -302,8 +302,8 @@ pca963x_dt_init(struct i2c_client *client, struct pca963x_chipdef *chip) if (!count || count > chip->n_leds) return ERR_PTR(-ENODEV); - pca963x_leds = devm_kzalloc(&client->dev, - sizeof(struct led_info) * chip->n_leds, GFP_KERNEL); + pca963x_leds = devm_kcalloc(&client->dev, + chip->n_leds, sizeof(struct led_info), GFP_KERNEL); if (!pca963x_leds) return ERR_PTR(-ENOMEM); @@ -409,7 +409,7 @@ static int pca963x_probe(struct i2c_client *client, GFP_KERNEL); if (!pca963x_chip) return -ENOMEM; - pca963x = devm_kzalloc(&client->dev, chip->n_leds * sizeof(*pca963x), + pca963x = devm_kcalloc(&client->dev, chip->n_leds, sizeof(*pca963x), GFP_KERNEL); if (!pca963x) return -ENOMEM; diff --git a/drivers/leds/leds-pca9956b.c b/drivers/leds/leds-pca9956b.c index 0b23f21e1afb..2d0373d2c19e 100644 --- a/drivers/leds/leds-pca9956b.c +++ b/drivers/leds/leds-pca9956b.c @@ -484,8 +484,9 @@ static int pca9956b_probe(struct i2c_client *client, if (!chip) return -ENOMEM; - chip->leds = devm_kzalloc(&client->dev, sizeof(*led)*PCA9956B_LED_NUM, - GFP_KERNEL); + chip->leds = devm_kcalloc(&client->dev, + PCA9956B_LED_NUM, sizeof(*led), + GFP_KERNEL); if (!chip->leds) { devm_kfree(&client->dev, chip); return -ENOMEM; diff --git a/drivers/leds/leds-tca6507.c b/drivers/leds/leds-tca6507.c index 45222a7f4f75..6aae71362d4b 100644 --- a/drivers/leds/leds-tca6507.c +++ b/drivers/leds/leds-tca6507.c @@ -697,8 +697,8 @@ tca6507_led_dt_init(struct i2c_client *client) if (!count || count > NUM_LEDS) return ERR_PTR(-ENODEV); - tca_leds = devm_kzalloc(&client->dev, - sizeof(struct led_info) * NUM_LEDS, GFP_KERNEL); + tca_leds = devm_kcalloc(&client->dev, + NUM_LEDS, sizeof(struct led_info), GFP_KERNEL); if (!tca_leds) return ERR_PTR(-ENOMEM); diff --git a/drivers/lightnvm/pblk-gc.c b/drivers/lightnvm/pblk-gc.c index d6bae085e1d2..2814788265c8 100644 --- a/drivers/lightnvm/pblk-gc.c +++ b/drivers/lightnvm/pblk-gc.c @@ -72,7 +72,7 @@ static int pblk_gc_move_valid_secs(struct pblk *pblk, struct pblk_gc_rq *gc_rq) unsigned int secs_to_gc; int ret = 0; - data = vmalloc(gc_rq->nr_secs * geo->sec_size); + data = vmalloc(array_size(gc_rq->nr_secs, geo->sec_size)); if (!data) { ret = -ENOMEM; goto out; diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c index 1b75675ee67b..6dcab44b49f2 100644 --- a/drivers/lightnvm/pblk-init.c +++ b/drivers/lightnvm/pblk-init.c @@ -90,7 +90,7 @@ static int pblk_l2p_init(struct pblk *pblk) if (pblk->ppaf_bitsize < 32) entry_size = 4; - pblk->trans_map = vmalloc(entry_size * pblk->rl.nr_secs); + pblk->trans_map = vmalloc(array_size(entry_size, pblk->rl.nr_secs)); if (!pblk->trans_map) return -ENOMEM; @@ -121,7 +121,7 @@ static int pblk_rwb_init(struct pblk *pblk) nr_entries = pblk_rb_calculate_size(pblk->pgs_in_buffer); - entries = vzalloc(nr_entries * sizeof(struct pblk_rb_entry)); + entries = vzalloc(array_size(nr_entries, sizeof(struct pblk_rb_entry))); if (!entries) return -ENOMEM; diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c index 5d0912bf9eab..81be0be821c9 100644 --- a/drivers/lightnvm/pblk-recovery.c +++ b/drivers/lightnvm/pblk-recovery.c @@ -376,7 +376,7 @@ static int pblk_recov_pad_oob(struct pblk *pblk, struct pblk_line *line, if (!pad_rq) return -ENOMEM; - data = vzalloc(pblk->max_write_pgs * geo->sec_size); + data = vzalloc(array_size(pblk->max_write_pgs, geo->sec_size)); if (!data) { ret = -ENOMEM; goto free_rq; diff --git a/drivers/lightnvm/rrpc.c b/drivers/lightnvm/rrpc.c index 267f01ae87e4..42e8bc44dc23 100644 --- a/drivers/lightnvm/rrpc.c +++ b/drivers/lightnvm/rrpc.c @@ -1140,12 +1140,11 @@ static int rrpc_map_init(struct rrpc *rrpc) sector_t i; int ret; - rrpc->trans_map = vzalloc(sizeof(struct rrpc_addr) * rrpc->nr_sects); + rrpc->trans_map = vzalloc(array_size(sizeof(struct rrpc_addr), rrpc->nr_sects)); if (!rrpc->trans_map) return -ENOMEM; - rrpc->rev_trans_map = vmalloc(sizeof(struct rrpc_rev_addr) - * rrpc->nr_sects); + rrpc->rev_trans_map = vmalloc(array_size(sizeof(struct rrpc_rev_addr), rrpc->nr_sects)); if (!rrpc->rev_trans_map) return -ENOMEM; @@ -1316,8 +1315,7 @@ static int rrpc_luns_init(struct rrpc *rrpc, struct ppa_addr *luns) rlun = &rrpc->luns[i]; rlun->id = i; rrpc_set_lun_ppa(rlun, luns[i]); - rlun->blocks = vzalloc(sizeof(struct rrpc_block) * - geo->blks_per_lun); + rlun->blocks = vzalloc(array_size(sizeof(struct rrpc_block), geo->blks_per_lun)); if (!rlun->blocks) { ret = -ENOMEM; goto err; diff --git a/drivers/mailbox/hi6220-mailbox.c b/drivers/mailbox/hi6220-mailbox.c index 519376d3534c..4fa9803cd204 100644 --- a/drivers/mailbox/hi6220-mailbox.c +++ b/drivers/mailbox/hi6220-mailbox.c @@ -282,13 +282,13 @@ static int hi6220_mbox_probe(struct platform_device *pdev) mbox->dev = dev; mbox->chan_num = MBOX_CHAN_MAX; - mbox->mchan = devm_kzalloc(dev, - mbox->chan_num * sizeof(*mbox->mchan), GFP_KERNEL); + mbox->mchan = devm_kcalloc(dev, + mbox->chan_num, sizeof(*mbox->mchan), GFP_KERNEL); if (!mbox->mchan) return -ENOMEM; - mbox->chan = devm_kzalloc(dev, - mbox->chan_num * sizeof(*mbox->chan), GFP_KERNEL); + mbox->chan = devm_kcalloc(dev, + mbox->chan_num, sizeof(*mbox->chan), GFP_KERNEL); if (!mbox->chan) return -ENOMEM; diff --git a/drivers/mailbox/mailbox-sti.c b/drivers/mailbox/mailbox-sti.c index 41bcd339b68a..779d41262ef0 100644 --- a/drivers/mailbox/mailbox-sti.c +++ b/drivers/mailbox/mailbox-sti.c @@ -442,8 +442,8 @@ static int sti_mbox_probe(struct platform_device *pdev) if (!mbox) return -ENOMEM; - chans = devm_kzalloc(&pdev->dev, - sizeof(*chans) * STI_MBOX_CHAN_MAX, GFP_KERNEL); + chans = devm_kcalloc(&pdev->dev, + STI_MBOX_CHAN_MAX, sizeof(*chans), GFP_KERNEL); if (!chans) return -ENOMEM; diff --git a/drivers/mailbox/msm_qmp.c b/drivers/mailbox/msm_qmp.c index 226d1d7f84ff..9ecae6c3cb00 100644 --- a/drivers/mailbox/msm_qmp.c +++ b/drivers/mailbox/msm_qmp.c @@ -831,7 +831,8 @@ static int qmp_mbox_init(struct device_node *n, struct qmp_device *mdev) mbox->desc = mdev->msgram + desc_of; num_chans = get_mbox_num_chans(n); mbox->rx_disabled = (num_chans > 1) ? true : false; - chans = devm_kzalloc(mdev->dev, sizeof(*chans) * num_chans, GFP_KERNEL); + chans = devm_kcalloc(mdev->dev, num_chans, sizeof(*chans), + GFP_KERNEL); if (!chans) return -ENOMEM; diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c index c5e8b9cb170d..b943619a79e9 100644 --- a/drivers/mailbox/omap-mailbox.c +++ b/drivers/mailbox/omap-mailbox.c @@ -729,7 +729,7 @@ static int omap_mbox_probe(struct platform_device *pdev) return -ENODEV; } - finfoblk = devm_kzalloc(&pdev->dev, info_count * sizeof(*finfoblk), + finfoblk = devm_kcalloc(&pdev->dev, info_count, sizeof(*finfoblk), GFP_KERNEL); if (!finfoblk) return -ENOMEM; @@ -773,23 +773,23 @@ static int omap_mbox_probe(struct platform_device *pdev) if (IS_ERR(mdev->mbox_base)) return PTR_ERR(mdev->mbox_base); - mdev->irq_ctx = devm_kzalloc(&pdev->dev, num_users * sizeof(u32), + mdev->irq_ctx = devm_kcalloc(&pdev->dev, num_users, sizeof(u32), GFP_KERNEL); if (!mdev->irq_ctx) return -ENOMEM; /* allocate one extra for marking end of list */ - list = devm_kzalloc(&pdev->dev, (info_count + 1) * sizeof(*list), + list = devm_kcalloc(&pdev->dev, info_count + 1, sizeof(*list), GFP_KERNEL); if (!list) return -ENOMEM; - chnls = devm_kzalloc(&pdev->dev, (info_count + 1) * sizeof(*chnls), + chnls = devm_kcalloc(&pdev->dev, info_count + 1, sizeof(*chnls), GFP_KERNEL); if (!chnls) return -ENOMEM; - mboxblk = devm_kzalloc(&pdev->dev, info_count * sizeof(*mbox), + mboxblk = devm_kcalloc(&pdev->dev, info_count, sizeof(*mbox), GFP_KERNEL); if (!mboxblk) return -ENOMEM; diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c index 27c2294be51a..ae965af5b0e6 100644 --- a/drivers/mailbox/pcc.c +++ b/drivers/mailbox/pcc.c @@ -477,8 +477,8 @@ static int __init acpi_pcc_probe(void) return -EINVAL; } - pcc_mbox_channels = kzalloc(sizeof(struct mbox_chan) * - sum, GFP_KERNEL); + pcc_mbox_channels = kcalloc(sum, sizeof(struct mbox_chan), + GFP_KERNEL); if (!pcc_mbox_channels) { pr_err("Could not allocate space for PCC mbox channels\n"); return -ENOMEM; diff --git a/drivers/mailbox/qcom-rpmh-mailbox.c b/drivers/mailbox/qcom-rpmh-mailbox.c index 45d2887aaaa5..a62c296f5f06 100644 --- a/drivers/mailbox/qcom-rpmh-mailbox.c +++ b/drivers/mailbox/qcom-rpmh-mailbox.c @@ -1224,8 +1224,9 @@ static int rsc_drv_probe(struct platform_device *pdev) tcs->tcs_offset = st; st += tcs->num_tcs; - tcs->cmd_addr = devm_kzalloc(&pdev->dev, sizeof(u32) * - tcs->num_tcs * tcs->ncpt, GFP_KERNEL); + tcs->cmd_addr = devm_kzalloc(&pdev->dev, + array3_size(sizeof(u32), tcs->num_tcs, tcs->ncpt), + GFP_KERNEL); if (!tcs->cmd_addr) return -ENOMEM; @@ -1253,7 +1254,7 @@ static int rsc_drv_probe(struct platform_device *pdev) return -ENODEV; } - chans = devm_kzalloc(&pdev->dev, num_chans * sizeof(*chans), + chans = devm_kcalloc(&pdev->dev, num_chans, sizeof(*chans), GFP_KERNEL); if (!chans) return -ENOMEM; diff --git a/drivers/mailbox/ti-msgmgr.c b/drivers/mailbox/ti-msgmgr.c index 54b9e4cb4cfa..ae050f79a27b 100644 --- a/drivers/mailbox/ti-msgmgr.c +++ b/drivers/mailbox/ti-msgmgr.c @@ -576,12 +576,12 @@ static int ti_msgmgr_probe(struct platform_device *pdev) } inst->num_valid_queues = queue_count; - qinst = devm_kzalloc(dev, sizeof(*qinst) * queue_count, GFP_KERNEL); + qinst = devm_kcalloc(dev, queue_count, sizeof(*qinst), GFP_KERNEL); if (!qinst) return -ENOMEM; inst->qinsts = qinst; - chans = devm_kzalloc(dev, sizeof(*chans) * queue_count, GFP_KERNEL); + chans = devm_kcalloc(dev, queue_count, sizeof(*chans), GFP_KERNEL); if (!chans) return -ENOMEM; inst->chans = chans; diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index 294be8b1d07c..c805d628d04d 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig @@ -302,7 +302,7 @@ config DM_DEFAULT_KEY To compile this code as a module, choose M here: the module will be called dm-default-key. - If unsure, say N. ======= + If unsure, say N. config DM_SNAPSHOT tristate "Snapshot target" diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 690aeb09bbf5..f4d20deaec1b 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -1534,7 +1534,7 @@ struct cache_set *bch_cache_set_alloc(struct cache_sb *sb) iter_size = (sb->bucket_size / sb->block_size + 1) * sizeof(struct btree_iter_set); - if (!(c->devices = kzalloc(c->nr_uuids * sizeof(void *), GFP_KERNEL)) || + if (!(c->devices = kcalloc(c->nr_uuids, sizeof(void *), GFP_KERNEL)) || !(c->bio_meta = mempool_create_kmalloc_pool(2, sizeof(struct bbio) + sizeof(struct bio_vec) * bucket_pages(c))) || @@ -1866,10 +1866,8 @@ static int cache_alloc(struct cache *ca) !init_fifo(&ca->free[RESERVE_NONE], free, GFP_KERNEL) || !init_fifo(&ca->free_inc, free << 2, GFP_KERNEL) || !init_heap(&ca->heap, free << 3, GFP_KERNEL) || - !(ca->buckets = vzalloc(sizeof(struct bucket) * - ca->sb.nbuckets)) || - !(ca->prio_buckets = kzalloc(sizeof(uint64_t) * prio_buckets(ca) * - 2, GFP_KERNEL)) || + !(ca->buckets = vzalloc(array_size(sizeof(struct bucket), ca->sb.nbuckets))) || + !(ca->prio_buckets = kzalloc(array3_size(sizeof(uint64_t), prio_buckets(ca), 2), GFP_KERNEL)) || !(ca->disk_buckets = alloc_bucket_pages(GFP_KERNEL, ca))) return -ENOMEM; diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 7eb76a1a2505..2ae26d42576d 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -785,8 +785,8 @@ static int bitmap_storage_alloc(struct bitmap_storage *store, num_pages = DIV_ROUND_UP(bytes, PAGE_SIZE); offset = slot_number * num_pages; - store->filemap = kmalloc(sizeof(struct page *) - * num_pages, GFP_KERNEL); + store->filemap = kmalloc_array(num_pages, sizeof(struct page *), + GFP_KERNEL); if (!store->filemap) return -ENOMEM; @@ -2113,7 +2113,7 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks, pages = DIV_ROUND_UP(chunks, PAGE_COUNTER_RATIO); - new_bp = kzalloc(pages * sizeof(*new_bp), GFP_KERNEL); + new_bp = kcalloc(pages, sizeof(*new_bp), GFP_KERNEL); ret = -ENOMEM; if (!new_bp) { bitmap_file_unmap(&store); diff --git a/drivers/md/dm-android-verity.c b/drivers/md/dm-android-verity.c index 20e05936551f..dd10e58155ac 100644 --- a/drivers/md/dm-android-verity.c +++ b/drivers/md/dm-android-verity.c @@ -141,8 +141,9 @@ static int read_block_dev(struct bio_read *payload, struct block_device *bdev, bio->bi_iter.bi_sector = offset; bio_set_op_attrs(bio, REQ_OP_READ, 0); - payload->page_io = kzalloc(sizeof(struct page *) * - payload->number_of_pages, GFP_KERNEL); + payload->page_io = kcalloc(payload->number_of_pages, + sizeof(struct page *), + GFP_KERNEL); if (!payload->page_io) { DMERR("page_io array alloc failed"); err = -ENOMEM; diff --git a/drivers/md/dm-cache-policy-smq.c b/drivers/md/dm-cache-policy-smq.c index e5eb9c9b4bc8..786bc064f24b 100644 --- a/drivers/md/dm-cache-policy-smq.c +++ b/drivers/md/dm-cache-policy-smq.c @@ -69,7 +69,7 @@ static int space_init(struct entry_space *es, unsigned nr_entries) return 0; } - es->begin = vzalloc(sizeof(struct entry) * nr_entries); + es->begin = vzalloc(array_size(nr_entries, sizeof(struct entry))); if (!es->begin) return -ENOMEM; @@ -575,7 +575,7 @@ static int h_init(struct smq_hash_table *ht, struct entry_space *es, unsigned nr nr_buckets = roundup_pow_of_two(max(nr_entries / 4u, 16u)); ht->hash_bits = __ffs(nr_buckets); - ht->buckets = vmalloc(sizeof(*ht->buckets) * nr_buckets); + ht->buckets = vmalloc(array_size(nr_buckets, sizeof(*ht->buckets))); if (!ht->buckets) return -ENOMEM; diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 87e8a2b0b999..a8db67fc9787 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -1886,8 +1886,9 @@ static int crypt_alloc_tfms_skcipher(struct crypt_config *cc, char *ciphermode) unsigned i; int err; - cc->cipher_tfm.tfms = kzalloc(cc->tfms_count * - sizeof(struct crypto_skcipher *), GFP_KERNEL); + cc->cipher_tfm.tfms = kcalloc(cc->tfms_count, + sizeof(struct crypto_skcipher *), + GFP_KERNEL); if (!cc->cipher_tfm.tfms) return -ENOMEM; diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index b6ca5b1100db..fcb0c33fc629 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -2448,7 +2448,9 @@ static struct scatterlist **dm_integrity_alloc_journal_scatterlist(struct dm_int struct scatterlist **sl; unsigned i; - sl = kvmalloc(ic->journal_sections * sizeof(struct scatterlist *), GFP_KERNEL | __GFP_ZERO); + sl = kvmalloc_array(ic->journal_sections, + sizeof(struct scatterlist *), + GFP_KERNEL | __GFP_ZERO); if (!sl) return NULL; @@ -2464,7 +2466,8 @@ static struct scatterlist **dm_integrity_alloc_journal_scatterlist(struct dm_int n_pages = (end_index - start_index + 1); - s = kvmalloc(n_pages * sizeof(struct scatterlist), GFP_KERNEL); + s = kvmalloc_array(n_pages, sizeof(struct scatterlist), + GFP_KERNEL); if (!s) { dm_integrity_free_journal_scatterlist(ic, sl); return NULL; @@ -2643,7 +2646,9 @@ static int create_journal(struct dm_integrity_c *ic, char **error) goto bad; } - sg = kvmalloc((ic->journal_pages + 1) * sizeof(struct scatterlist), GFP_KERNEL); + sg = kvmalloc_array(ic->journal_pages + 1, + sizeof(struct scatterlist), + GFP_KERNEL); if (!sg) { *error = "Unable to allocate sg list"; r = -ENOMEM; @@ -2709,7 +2714,9 @@ static int create_journal(struct dm_integrity_c *ic, char **error) r = -ENOMEM; goto bad; } - ic->sk_requests = kvmalloc(ic->journal_sections * sizeof(struct skcipher_request *), GFP_KERNEL | __GFP_ZERO); + ic->sk_requests = kvmalloc_array(ic->journal_sections, + sizeof(struct skcipher_request *), + GFP_KERNEL | __GFP_ZERO); if (!ic->sk_requests) { *error = "Unable to allocate sk requests"; r = -ENOMEM; @@ -2743,7 +2750,8 @@ static int create_journal(struct dm_integrity_c *ic, char **error) r = -ENOMEM; goto bad; } - section_req->iv = kmalloc(ivsize * 2, GFP_KERNEL); + section_req->iv = kmalloc_array(ivsize, 2, + GFP_KERNEL); if (!section_req->iv) { skcipher_request_free(section_req); *error = "Unable to allocate iv"; diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 33d6011ac461..787afba77b2e 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -6,7 +6,6 @@ */ #include "dm-core.h" -#include "dm-ioctrl.h" #include #include @@ -2057,37 +2056,3 @@ out: return r; } - -int __init dm_ioctrl(uint cmd, struct dm_ioctl *param) -{ - int r = 0; - int ioctl_flags; - ioctl_fn fn = NULL; - size_t input_param_size; - - /* - * Nothing more to do for the version command. - */ - if (cmd == DM_VERSION_CMD) - return 0; - - DMDEBUG("dm_ctl_ioctl: command 0x%x", cmd); - - fn = lookup_ioctl(cmd, &ioctl_flags); - if (!fn) { - DMWARN("dm_ctl_ioctl: unknown command 0x%x", cmd); - return -ENOTTY; - } - - input_param_size = param->data_size; - param->data_size = sizeof(*param); - - r = fn(NULL, param, input_param_size); - - if (unlikely(param->flags & DM_BUFFER_FULL_FLAG) && - unlikely(ioctl_flags & IOCTL_FLAGS_NO_PARAMS)) - DMERR("ioctl %d but has IOCTL_FLAGS_NO_PARAMS set", cmd); - - return r; -} -EXPORT_SYMBOL(dm_ioctrl); diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 2c5912e75514..5f63bd1ac14b 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -740,7 +740,7 @@ static struct raid_set *raid_set_alloc(struct dm_target *ti, struct raid_type *r return ERR_PTR(-EINVAL); } - rs = kzalloc(sizeof(*rs) + raid_devs * sizeof(rs->dev[0]), GFP_KERNEL); + rs = kzalloc(struct_size(rs, dev, raid_devs), GFP_KERNEL); if (!rs) { ti->error = "Cannot allocate raid context"; return ERR_PTR(-ENOMEM); diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c index 91c6f6d72eee..fb5582c7087e 100644 --- a/drivers/md/dm-region-hash.c +++ b/drivers/md/dm-region-hash.c @@ -201,7 +201,7 @@ struct dm_region_hash *dm_region_hash_create( rh->shift = RH_HASH_SHIFT; rh->prime = RH_HASH_MULT; - rh->buckets = vmalloc(nr_buckets * sizeof(*rh->buckets)); + rh->buckets = vmalloc(array_size(nr_buckets, sizeof(*rh->buckets))); if (!rh->buckets) { DMERR("unable to allocate region hash bucket memory"); kfree(rh); diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 2170f6c118b8..c835ed4d08a2 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -342,8 +342,8 @@ static int init_origin_hash(void) { int i; - _origins = kmalloc(ORIGIN_HASH_SIZE * sizeof(struct list_head), - GFP_KERNEL); + _origins = kmalloc_array(ORIGIN_HASH_SIZE, sizeof(struct list_head), + GFP_KERNEL); if (!_origins) { DMERR("unable to allocate memory for _origins"); return -ENOMEM; @@ -351,8 +351,9 @@ static int init_origin_hash(void) for (i = 0; i < ORIGIN_HASH_SIZE; i++) INIT_LIST_HEAD(_origins + i); - _dm_origins = kmalloc(ORIGIN_HASH_SIZE * sizeof(struct list_head), - GFP_KERNEL); + _dm_origins = kmalloc_array(ORIGIN_HASH_SIZE, + sizeof(struct list_head), + GFP_KERNEL); if (!_dm_origins) { DMERR("unable to allocate memory for _dm_origins"); kfree(_origins); diff --git a/drivers/md/dm-stats.c b/drivers/md/dm-stats.c index a7868503d135..935c2fc9274b 100644 --- a/drivers/md/dm-stats.c +++ b/drivers/md/dm-stats.c @@ -914,7 +914,9 @@ static int parse_histogram(const char *h, unsigned *n_histogram_entries, if (*q == ',') (*n_histogram_entries)++; - *histogram_boundaries = kmalloc(*n_histogram_entries * sizeof(unsigned long long), GFP_KERNEL); + *histogram_boundaries = kmalloc_array(*n_histogram_entries, + sizeof(unsigned long long), + GFP_KERNEL); if (!*histogram_boundaries) return -ENOMEM; diff --git a/drivers/md/dm-switch.c b/drivers/md/dm-switch.c index 4c8de1ff78ca..56ff981570b0 100644 --- a/drivers/md/dm-switch.c +++ b/drivers/md/dm-switch.c @@ -114,7 +114,7 @@ static int alloc_region_table(struct dm_target *ti, unsigned nr_paths) return -EINVAL; } - sctx->region_table = vmalloc(nr_slots * sizeof(region_table_slot_t)); + sctx->region_table = vmalloc(array_size(nr_slots, sizeof(region_table_slot_t))); if (!sctx->region_table) { ti->error = "Cannot allocate region table"; return -ENOMEM; diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 0f9a8087e1a0..1a25e7185628 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -561,7 +561,7 @@ static char **realloc_argv(unsigned *size, char **old_argv) new_size = 8; gfp = GFP_NOIO; } - argv = kmalloc(new_size * sizeof(*argv), gfp); + argv = kmalloc_array(new_size, sizeof(*argv), gfp); if (argv) { memcpy(argv, old_argv, *size * sizeof(*argv)); *size = new_size; diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 0ee5eae71690..7a8ec9bceeda 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -3041,7 +3041,7 @@ static struct pool *pool_create(struct mapped_device *pool_md, goto bad_mapping_pool; } - pool->cell_sort_array = vmalloc(sizeof(*pool->cell_sort_array) * CELL_SORT_ARRAY_SIZE); + pool->cell_sort_array = vmalloc(array_size(CELL_SORT_ARRAY_SIZE, sizeof(*pool->cell_sort_array))); if (!pool->cell_sort_array) { *error = "Error allocating cell sort array"; err_p = ERR_PTR(-ENOMEM); diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index 23399c7131ee..d29d5012b0a4 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -865,8 +865,9 @@ static int verity_alloc_most_once(struct dm_verity *v) return -E2BIG; } - v->validated_blocks = kvzalloc(BITS_TO_LONGS(v->data_blocks) * - sizeof(unsigned long), GFP_KERNEL); + v->validated_blocks = kvcalloc(BITS_TO_LONGS(v->data_blocks), + sizeof(unsigned long), + GFP_KERNEL); if (!v->validated_blocks) { ti->error = "failed to allocate bitset for check_at_most_once"; return -ENOMEM; diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index 10057ac85476..a9e7f23a739a 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -1381,9 +1381,9 @@ static int lock_all_bitmaps(struct mddev *mddev) char str[64]; struct md_cluster_info *cinfo = mddev->cluster_info; - cinfo->other_bitmap_lockres = kzalloc((mddev->bitmap_info.nodes - 1) * - sizeof(struct dlm_lock_resource *), - GFP_KERNEL); + cinfo->other_bitmap_lockres = kcalloc(mddev->bitmap_info.nodes - 1, + sizeof(struct dlm_lock_resource *), + GFP_KERNEL); if (!cinfo->other_bitmap_lockres) { pr_err("md: can't alloc mem for other bitmap locks\n"); return 0; diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index b68e0666b9b0..23a6bf8bad90 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -400,7 +400,8 @@ static int multipath_run (struct mddev *mddev) if (!conf) goto out; - conf->multipaths = kzalloc(sizeof(struct multipath_info)*mddev->raid_disks, + conf->multipaths = kcalloc(mddev->raid_disks, + sizeof(struct multipath_info), GFP_KERNEL); if (!conf->multipaths) goto out_free_conf; diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index e179c121c030..4814b45631c8 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -178,12 +178,12 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) } err = -ENOMEM; - conf->strip_zone = kzalloc(sizeof(struct strip_zone)* - conf->nr_strip_zones, GFP_KERNEL); + conf->strip_zone = kcalloc(conf->nr_strip_zones, + sizeof(struct strip_zone), + GFP_KERNEL); if (!conf->strip_zone) goto abort; - conf->devlist = kzalloc(sizeof(struct md_rdev*)* - conf->nr_strip_zones*mddev->raid_disks, + conf->devlist = kzalloc(array3_size(sizeof(struct md_rdev *), conf->nr_strip_zones, mddev->raid_disks), GFP_KERNEL); if (!conf->devlist) goto abort; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 0a9d623b13c2..57506ba2c335 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -127,8 +127,8 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data) if (!r1_bio) return NULL; - rps = kmalloc(sizeof(struct resync_pages) * pi->raid_disks, - gfp_flags); + rps = kmalloc_array(pi->raid_disks, sizeof(struct resync_pages), + gfp_flags); if (!rps) goto out_free_r1bio; @@ -2936,8 +2936,7 @@ static struct r1conf *setup_conf(struct mddev *mddev) if (!conf->barrier) goto abort; - conf->mirrors = kzalloc(sizeof(struct raid1_info) - * mddev->raid_disks * 2, + conf->mirrors = kzalloc(array3_size(sizeof(struct raid1_info), mddev->raid_disks, 2), GFP_KERNEL); if (!conf->mirrors) goto abort; @@ -3251,7 +3250,7 @@ static int raid1_reshape(struct mddev *mddev) kfree(newpoolinfo); return -ENOMEM; } - newmirrors = kzalloc(sizeof(struct raid1_info) * raid_disks * 2, + newmirrors = kzalloc(array3_size(sizeof(struct raid1_info), raid_disks, 2), GFP_KERNEL); if (!newmirrors) { kfree(newpoolinfo); diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index d08d77b9674f..02518d022bdf 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -172,7 +172,7 @@ static void * r10buf_pool_alloc(gfp_t gfp_flags, void *data) nalloc_rp = nalloc; else nalloc_rp = nalloc * 2; - rps = kmalloc(sizeof(struct resync_pages) * nalloc_rp, gfp_flags); + rps = kmalloc_array(nalloc_rp, sizeof(struct resync_pages), gfp_flags); if (!rps) goto out_free_r10bio; @@ -3566,8 +3566,8 @@ static struct r10conf *setup_conf(struct mddev *mddev) goto out; /* FIXME calc properly */ - conf->mirrors = kzalloc(sizeof(struct raid10_info)*(mddev->raid_disks + - max(0,-mddev->delta_disks)), + conf->mirrors = kcalloc(mddev->raid_disks + max(0, -mddev->delta_disks), + sizeof(struct raid10_info), GFP_KERNEL); if (!conf->mirrors) goto out; @@ -4005,11 +4005,9 @@ static int raid10_check_reshape(struct mddev *mddev) conf->mirrors_new = NULL; if (mddev->delta_disks > 0) { /* allocate new 'mirrors' list */ - conf->mirrors_new = kzalloc( - sizeof(struct raid10_info) - *(mddev->raid_disks + - mddev->delta_disks), - GFP_KERNEL); + conf->mirrors_new = kcalloc(mddev->raid_disks + mddev->delta_disks, + sizeof(struct raid10_info), + GFP_KERNEL); if (!conf->mirrors_new) return -ENOMEM; } diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index d5c14d56a714..5791066dd511 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -2392,7 +2392,7 @@ static int resize_stripes(struct r5conf *conf, int newsize) * is completely stalled, so now is a good time to resize * conf->disks and the scribble region */ - ndisks = kzalloc(newsize * sizeof(struct disk_info), GFP_NOIO); + ndisks = kcalloc(newsize, sizeof(struct disk_info), GFP_NOIO); if (ndisks) { for (i = 0; i < conf->pool_size; i++) ndisks[i] = conf->disks[i]; @@ -6663,9 +6663,9 @@ static int alloc_thread_groups(struct r5conf *conf, int cnt, } *group_cnt = num_possible_nodes(); size = sizeof(struct r5worker) * cnt; - workers = kzalloc(size * *group_cnt, GFP_NOIO); - *worker_groups = kzalloc(sizeof(struct r5worker_group) * - *group_cnt, GFP_NOIO); + workers = kcalloc(size, *group_cnt, GFP_NOIO); + *worker_groups = kcalloc(*group_cnt, sizeof(struct r5worker_group), + GFP_NOIO); if (!*worker_groups || !workers) { kfree(workers); kfree(*worker_groups); @@ -6895,8 +6895,9 @@ static struct r5conf *setup_conf(struct mddev *mddev) goto abort; INIT_LIST_HEAD(&conf->free_list); INIT_LIST_HEAD(&conf->pending_list); - conf->pending_data = kzalloc(sizeof(struct r5pending_data) * - PENDING_IO_MAX, GFP_KERNEL); + conf->pending_data = kcalloc(PENDING_IO_MAX, + sizeof(struct r5pending_data), + GFP_KERNEL); if (!conf->pending_data) goto abort; for (i = 0; i < PENDING_IO_MAX; i++) @@ -6945,7 +6946,7 @@ static struct r5conf *setup_conf(struct mddev *mddev) conf->previous_raid_disks = mddev->raid_disks - mddev->delta_disks; max_disks = max(conf->raid_disks, conf->previous_raid_disks); - conf->disks = kzalloc(max_disks * sizeof(struct disk_info), + conf->disks = kcalloc(max_disks, sizeof(struct disk_info), GFP_KERNEL); if (!conf->disks) diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c index 664c4b8b1a6d..fae2c5230570 100644 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c @@ -131,12 +131,12 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w) for (plane = 0; plane < TPG_MAX_PLANES; plane++) { unsigned pixelsz = plane ? 2 : 4; - tpg->lines[pat][plane] = vzalloc(max_w * 2 * pixelsz); + tpg->lines[pat][plane] = vzalloc(array3_size(max_w, 2, pixelsz)); if (!tpg->lines[pat][plane]) return -ENOMEM; if (plane == 0) continue; - tpg->downsampled_lines[pat][plane] = vzalloc(max_w * 2 * pixelsz); + tpg->downsampled_lines[pat][plane] = vzalloc(array3_size(max_w, 2, pixelsz)); if (!tpg->downsampled_lines[pat][plane]) return -ENOMEM; } @@ -144,13 +144,13 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w) for (plane = 0; plane < TPG_MAX_PLANES; plane++) { unsigned pixelsz = plane ? 2 : 4; - tpg->contrast_line[plane] = vzalloc(max_w * pixelsz); + tpg->contrast_line[plane] = vzalloc(array_size(pixelsz, max_w)); if (!tpg->contrast_line[plane]) return -ENOMEM; - tpg->black_line[plane] = vzalloc(max_w * pixelsz); + tpg->black_line[plane] = vzalloc(array_size(pixelsz, max_w)); if (!tpg->black_line[plane]) return -ENOMEM; - tpg->random_line[plane] = vzalloc(max_w * 2 * pixelsz); + tpg->random_line[plane] = vzalloc(array3_size(max_w, 2, pixelsz)); if (!tpg->random_line[plane]) return -ENOMEM; } diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index ff6a5cf93eb8..436ecd3992ba 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -4848,7 +4848,7 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) if (dmxdev->demux->open(dmxdev->demux) < 0) return -EUSERS; - dmxdev->filter = vmalloc(dmxdev->filternum * sizeof(struct dmxdev_filter)); + dmxdev->filter = vmalloc(array_size(sizeof(struct dmxdev_filter), dmxdev->filternum)); if (!dmxdev->filter) return -ENOMEM; diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c index 99f47ab4064e..5a2ed4ac572b 100644 --- a/drivers/media/dvb-core/dvb_demux.c +++ b/drivers/media/dvb-core/dvb_demux.c @@ -3298,20 +3298,19 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux) dvbdemux->cnt_storage = NULL; dvbdemux->users = 0; - dvbdemux->filter = vmalloc(dvbdemux->filternum * sizeof(struct dvb_demux_filter)); + dvbdemux->filter = vmalloc(array_size(sizeof(struct dvb_demux_filter), dvbdemux->filternum)); if (!dvbdemux->filter) return -ENOMEM; - dvbdemux->feed = vmalloc(dvbdemux->feednum * sizeof(struct dvb_demux_feed)); + dvbdemux->feed = vmalloc(array_size(sizeof(struct dvb_demux_feed), dvbdemux->feednum)); if (!dvbdemux->feed) { vfree(dvbdemux->filter); dvbdemux->filter = NULL; return -ENOMEM; } - dvbdemux->rec_info_pool = vmalloc(dvbdemux->feednum * - sizeof(struct dvb_demux_rec_info)); + dvbdemux->rec_info_pool = vmalloc(array_size(sizeof(struct dvb_demux_rec_info), dvbdemux->feednum)); if (!dvbdemux->rec_info_pool) { vfree(dvbdemux->feed); vfree(dvbdemux->filter); diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c index 0fbaabe43682..e52d839bc9ae 100644 --- a/drivers/media/dvb-frontends/dib7000p.c +++ b/drivers/media/dvb-frontends/dib7000p.c @@ -2018,10 +2018,10 @@ static int dib7000pc_detection(struct i2c_adapter *i2c_adap) }; int ret = 0; - tx = kzalloc(2*sizeof(u8), GFP_KERNEL); + tx = kzalloc(2, GFP_KERNEL); if (!tx) return -ENOMEM; - rx = kzalloc(2*sizeof(u8), GFP_KERNEL); + rx = kzalloc(2, GFP_KERNEL); if (!rx) { ret = -ENOMEM; goto rx_memory_error; diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c index 5d9381509b07..83ca74f9d5d3 100644 --- a/drivers/media/dvb-frontends/dib8000.c +++ b/drivers/media/dvb-frontends/dib8000.c @@ -4271,12 +4271,12 @@ static int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 new_addr = 0; struct i2c_device client = {.adap = host }; - client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL); + client.i2c_write_buffer = kzalloc(4, GFP_KERNEL); if (!client.i2c_write_buffer) { dprintk("%s: not enough memory\n", __func__); return -ENOMEM; } - client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL); + client.i2c_read_buffer = kzalloc(4, GFP_KERNEL); if (!client.i2c_read_buffer) { dprintk("%s: not enough memory\n", __func__); ret = -ENOMEM; diff --git a/drivers/media/dvb-frontends/dib9000.c b/drivers/media/dvb-frontends/dib9000.c index 1b7a4331af05..03b047fdc14c 100644 --- a/drivers/media/dvb-frontends/dib9000.c +++ b/drivers/media/dvb-frontends/dib9000.c @@ -2381,12 +2381,12 @@ int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defaul u8 new_addr = 0; struct i2c_device client = {.i2c_adap = i2c }; - client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL); + client.i2c_write_buffer = kzalloc(4, GFP_KERNEL); if (!client.i2c_write_buffer) { dprintk("%s: not enough memory\n", __func__); return -ENOMEM; } - client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL); + client.i2c_read_buffer = kzalloc(4, GFP_KERNEL); if (!client.i2c_read_buffer) { dprintk("%s: not enough memory\n", __func__); ret = -ENOMEM; diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index ff46d2c96cea..5007c9659342 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -373,7 +373,7 @@ static int s5k5baf_fw_parse(struct device *dev, struct s5k5baf_fw **fw, data += S5K5BAG_FW_TAG_LEN; count -= S5K5BAG_FW_TAG_LEN; - d = devm_kzalloc(dev, count * sizeof(u16), GFP_KERNEL); + d = devm_kcalloc(dev, count, sizeof(u16), GFP_KERNEL); if (!d) return -ENOMEM; diff --git a/drivers/media/pci/bt8xx/bttv-risc.c b/drivers/media/pci/bt8xx/bttv-risc.c index 3859dde98be2..39c941b29ed6 100644 --- a/drivers/media/pci/bt8xx/bttv-risc.c +++ b/drivers/media/pci/bt8xx/bttv-risc.c @@ -255,7 +255,7 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, u32 addr; /* skip list for window clipping */ - if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL))) + if (NULL == (skips = kmalloc_array(ov->nclips, sizeof(*skips),GFP_KERNEL))) return -ENOMEM; /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions diff --git a/drivers/media/pci/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c index d8c3637e492e..11e1cdf5633f 100644 --- a/drivers/media/pci/cx23885/cx23885-alsa.c +++ b/drivers/media/pci/cx23885/cx23885-alsa.c @@ -96,7 +96,7 @@ static int cx23885_alsa_dma_init(struct cx23885_audio_dev *chip, int nr_pages) memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT); buf->nr_pages = nr_pages; - buf->sglist = vzalloc(buf->nr_pages * sizeof(*buf->sglist)); + buf->sglist = vzalloc(array_size(sizeof(*buf->sglist), buf->nr_pages)); if (NULL == buf->sglist) goto vzalloc_err; diff --git a/drivers/media/pci/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c index 040323b0f945..f63a7e6f272c 100644 --- a/drivers/media/pci/cx23885/cx23888-ir.c +++ b/drivers/media/pci/cx23885/cx23888-ir.c @@ -1178,8 +1178,11 @@ int cx23888_ir_probe(struct cx23885_dev *dev) return -ENOMEM; spin_lock_init(&state->rx_kfifo_lock); - if (kfifo_alloc(&state->rx_kfifo, CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL)) + if (kfifo_alloc(&state->rx_kfifo, CX23888_IR_RX_KFIFO_SIZE, + GFP_KERNEL)) { + kfree(state); return -ENOMEM; + } state->dev = dev; sd = &state->sd; diff --git a/drivers/media/pci/cx25821/cx25821-alsa.c b/drivers/media/pci/cx25821/cx25821-alsa.c index 2b34990e86f2..c16a81cecb82 100644 --- a/drivers/media/pci/cx25821/cx25821-alsa.c +++ b/drivers/media/pci/cx25821/cx25821-alsa.c @@ -159,7 +159,7 @@ static int cx25821_alsa_dma_init(struct cx25821_audio_dev *chip, int nr_pages) memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT); buf->nr_pages = nr_pages; - buf->sglist = vzalloc(buf->nr_pages * sizeof(*buf->sglist)); + buf->sglist = vzalloc(array_size(sizeof(*buf->sglist), buf->nr_pages)); if (NULL == buf->sglist) goto vzalloc_err; diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c index 9740326bc93f..7ac3c2b357da 100644 --- a/drivers/media/pci/cx88/cx88-alsa.c +++ b/drivers/media/pci/cx88/cx88-alsa.c @@ -298,7 +298,7 @@ static int cx88_alsa_dma_init(struct cx88_audio_dev *chip, int nr_pages) memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT); buf->nr_pages = nr_pages; - buf->sglist = vzalloc(buf->nr_pages * sizeof(*buf->sglist)); + buf->sglist = vzalloc(array_size(sizeof(*buf->sglist), buf->nr_pages)); if (!buf->sglist) goto vzalloc_err; diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c index 621b2f613d81..9b8abebefeed 100644 --- a/drivers/media/pci/ivtv/ivtvfb.c +++ b/drivers/media/pci/ivtv/ivtvfb.c @@ -1079,7 +1079,7 @@ static int ivtvfb_init_vidmode(struct ivtv *itv) /* Allocate the pseudo palette */ oi->ivtvfb_info.pseudo_palette = - kmalloc(sizeof(u32) * 16, GFP_KERNEL|__GFP_NOWARN); + kmalloc_array(16, sizeof(u32), GFP_KERNEL|__GFP_NOWARN); if (!oi->ivtvfb_info.pseudo_palette) { IVTVFB_ERR("abort, unable to alloc pseudo palette\n"); diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c index 926707c997ac..dc0335e74d31 100644 --- a/drivers/media/pci/meye/meye.c +++ b/drivers/media/pci/meye/meye.c @@ -1625,7 +1625,7 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) ret = -ENOMEM; meye.mchip_dev = pcidev; - meye.grab_temp = vmalloc(MCHIP_NB_PAGES_MJPEG * PAGE_SIZE); + meye.grab_temp = vmalloc(array_size(PAGE_SIZE, MCHIP_NB_PAGES_MJPEG)); if (!meye.grab_temp) { v4l2_err(v4l2_dev, "grab buffer allocation failed\n"); goto outvmalloc; diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c index b6b1a8d20d86..b9c25fd2ccf1 100644 --- a/drivers/media/pci/pt1/pt1.c +++ b/drivers/media/pci/pt1/pt1.c @@ -443,7 +443,7 @@ static int pt1_init_tables(struct pt1 *pt1) int i, ret; u32 first_pfn, pfn; - tables = vmalloc(sizeof(struct pt1_table) * pt1_nr_tables); + tables = vmalloc(array_size(pt1_nr_tables, sizeof(struct pt1_table))); if (tables == NULL) return -ENOMEM; diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c index c59b69f1af9d..5510cfbd0049 100644 --- a/drivers/media/pci/saa7134/saa7134-alsa.c +++ b/drivers/media/pci/saa7134/saa7134-alsa.c @@ -280,7 +280,7 @@ static int saa7134_alsa_dma_init(struct saa7134_dev *dev, int nr_pages) memset(dma->vaddr, 0, nr_pages << PAGE_SHIFT); dma->nr_pages = nr_pages; - dma->sglist = vzalloc(dma->nr_pages * sizeof(*dma->sglist)); + dma->sglist = vzalloc(array_size(sizeof(*dma->sglist), dma->nr_pages)); if (NULL == dma->sglist) goto vzalloc_err; diff --git a/drivers/media/pci/ttpci/av7110_ipack.c b/drivers/media/pci/ttpci/av7110_ipack.c index 5aff26574fe1..ec528fae7333 100644 --- a/drivers/media/pci/ttpci/av7110_ipack.c +++ b/drivers/media/pci/ttpci/av7110_ipack.c @@ -24,7 +24,7 @@ void av7110_ipack_reset(struct ipack *p) int av7110_ipack_init(struct ipack *p, int size, void (*func)(u8 *buf, int size, void *priv)) { - if (!(p->buf = vmalloc(size*sizeof(u8)))) { + if (!(p->buf = vmalloc(size))) { printk(KERN_WARNING "Couldn't allocate memory for ipack\n"); return -ENOMEM; } diff --git a/drivers/media/pci/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c index a11cb501c550..ffb689e9dcfb 100644 --- a/drivers/media/pci/zoran/zoran_driver.c +++ b/drivers/media/pci/zoran/zoran_driver.c @@ -941,7 +941,7 @@ static int zoran_open(struct file *file) /* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows * on norm-change! */ fh->overlay_mask = - kmalloc(((768 + 31) / 32) * 576 * 4, GFP_KERNEL); + kmalloc(array3_size((768 + 31) / 32, 576, 4), GFP_KERNEL); if (!fh->overlay_mask) { dprintk(1, KERN_ERR @@ -1220,7 +1220,7 @@ static int setup_window(struct zoran_fh *fh, } } else if (clipcount) { /* write our own bitmap from the clips */ - vcp = vmalloc(sizeof(struct v4l2_clip) * (clipcount + 4)); + vcp = vmalloc(array_size(sizeof(struct v4l2_clip), (clipcount + 4))); if (vcp == NULL) { dprintk(1, KERN_ERR diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c index e92c5b56be42..643a728e2257 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.c +++ b/drivers/media/platform/am437x/am437x-vpfe.c @@ -2585,8 +2585,10 @@ static int vpfe_probe(struct platform_device *pdev) pm_runtime_put_sync(&pdev->dev); - vpfe->sd = devm_kzalloc(&pdev->dev, sizeof(struct v4l2_subdev *) * - ARRAY_SIZE(vpfe->cfg->asd), GFP_KERNEL); + vpfe->sd = devm_kcalloc(&pdev->dev, + ARRAY_SIZE(vpfe->cfg->asd), + sizeof(struct v4l2_subdev *), + GFP_KERNEL); if (!vpfe->sd) { ret = -ENOMEM; goto probe_out_v4l2_unregister; diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index dc8fc2120b63..ace58725c087 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -1523,8 +1523,10 @@ vpif_capture_get_pdata(struct platform_device *pdev) if (!pdata) return NULL; pdata->subdev_info = - devm_kzalloc(&pdev->dev, sizeof(*pdata->subdev_info) * - VPIF_CAPTURE_NUM_CHANNELS, GFP_KERNEL); + devm_kcalloc(&pdev->dev, + VPIF_CAPTURE_NUM_CHANNELS, + sizeof(*pdata->subdev_info), + GFP_KERNEL); if (!pdata->subdev_info) return NULL; @@ -1541,9 +1543,9 @@ vpif_capture_get_pdata(struct platform_device *pdev) sdinfo = &pdata->subdev_info[i]; chan = &pdata->chan_config[i]; - chan->inputs = devm_kzalloc(&pdev->dev, - sizeof(*chan->inputs) * + chan->inputs = devm_kcalloc(&pdev->dev, VPIF_CAPTURE_NUM_CHANNELS, + sizeof(*chan->inputs), GFP_KERNEL); if (!chan->inputs) return NULL; diff --git a/drivers/media/platform/msm/ais/ais_isp/Makefile b/drivers/media/platform/msm/ais/ais_isp/Makefile index 96ff9c02a624..277eb8275180 100644 --- a/drivers/media/platform/msm/ais/ais_isp/Makefile +++ b/drivers/media/platform/msm/ais/ais_isp/Makefile @@ -8,5 +8,6 @@ ccflags-y += -Idrivers/media/platform/msm/ais/cam_cdm/ obj-$(CONFIG_MSM_AIS) += csid_hw/ obj-$(CONFIG_MSM_AIS) += vfe_hw/ +obj-$(CONFIG_MSM_AIS) += utils/ obj-$(CONFIG_MSM_AIS) += ais_ife_dev.o diff --git a/drivers/media/platform/msm/ais/ais_isp/csid_hw/ais_ife_csid_core.c b/drivers/media/platform/msm/ais/ais_isp/csid_hw/ais_ife_csid_core.c index 73bf53ae1f2d..284ff888ca5e 100644 --- a/drivers/media/platform/msm/ais/ais_isp/csid_hw/ais_ife_csid_core.c +++ b/drivers/media/platform/msm/ais/ais_isp/csid_hw/ais_ife_csid_core.c @@ -577,24 +577,6 @@ static int ais_ife_csid_config_rdi_path( else path_cfg->pix_enable = true; - /* - * RDI path config and enable the time stamp capture - * Enable the measurement blocks - */ - cfg0 = (path_cfg->vc << csid_reg->cmn_reg->vc_shift_val) | - (path_cfg->dt << csid_reg->cmn_reg->dt_shift_val) | - (path_cfg->cid << csid_reg->cmn_reg->dt_id_shift_val) | - (path_cfg->decode_fmt << csid_reg->cmn_reg->fmt_shift_val) | - (path_cfg->plain_fmt << csid_reg->cmn_reg->plain_fmt_shit_val) | - (path_cfg->crop_enable << - csid_reg->cmn_reg->crop_h_en_shift_val) | - (path_cfg->crop_enable << - csid_reg->cmn_reg->crop_v_en_shift_val) | - (1 << 2) | 3; - - cam_io_w_mb(cfg0, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr); - /* select the post irq sub sample strobe for time stamp capture */ cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base + csid_reg->rdi_reg[id]->csid_rdi_cfg1_addr); @@ -701,8 +683,18 @@ static int ais_ife_csid_config_rdi_path( } } - /* Enable the path */ - cfg0 |= (1 << csid_reg->cmn_reg->path_en_shift_val); + /* RDI path config and enable*/ + cfg0 = (path_cfg->vc << csid_reg->cmn_reg->vc_shift_val) | + (path_cfg->dt << csid_reg->cmn_reg->dt_shift_val) | + (path_cfg->cid << csid_reg->cmn_reg->dt_id_shift_val) | + (path_cfg->decode_fmt << csid_reg->cmn_reg->fmt_shift_val) | + (path_cfg->plain_fmt << csid_reg->cmn_reg->plain_fmt_shit_val) | + (path_cfg->crop_enable << + csid_reg->cmn_reg->crop_h_en_shift_val) | + (path_cfg->crop_enable << + csid_reg->cmn_reg->crop_v_en_shift_val) | + (1 << csid_reg->cmn_reg->path_en_shift_val) | + (1 << 2) | 3; cam_io_w_mb(cfg0, soc_info->reg_map[0].mem_base + csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr); diff --git a/drivers/media/platform/msm/ais/ais_isp/utils/Makefile b/drivers/media/platform/msm/ais/ais_isp/utils/Makefile new file mode 100644 index 000000000000..bada56e9bf98 --- /dev/null +++ b/drivers/media/platform/msm/ais/ais_isp/utils/Makefile @@ -0,0 +1,9 @@ +ccflags-y += -Idrivers/media/platform/msm/ais/cam_core +ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/include +ccflags-y += -Idrivers/media/platform/msm/ais/cam_req_mgr +ccflags-y += -Idrivers/media/platform/msm/ais/cam_smmu/ +ccflags-y += -Idrivers/media/platform/msm/ais/cam_sync +ccflags-y += -Idrivers/media/platform/msm/ais/cam_utils +ccflags-y += -Idrivers/media/platform/msm/ais/cam_cdm/ + +obj-$(CONFIG_MSM_AIS) += ais_isp_trace.o diff --git a/drivers/md/dm-ioctrl.h b/drivers/media/platform/msm/ais/ais_isp/utils/ais_isp_trace.c similarity index 68% rename from drivers/md/dm-ioctrl.h rename to drivers/media/platform/msm/ais/ais_isp/utils/ais_isp_trace.c index d331fcd83df4..659acf4b1186 100644 --- a/drivers/md/dm-ioctrl.h +++ b/drivers/media/platform/msm/ais/ais_isp/utils/ais_isp_trace.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -8,13 +8,9 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. + * */ -#ifndef DM_IOCTRL_INTERNAL_H -#define DM_IOCTRL_INTERNAL_H - -#include - -int dm_ioctrl(uint cmd, struct dm_ioctl *param); - -#endif +/* Instantiate tracepoints */ +#define CREATE_TRACE_POINTS +#include "ais_isp_trace.h" diff --git a/drivers/media/platform/msm/ais/ais_isp/utils/ais_isp_trace.h b/drivers/media/platform/msm/ais/ais_isp/utils/ais_isp_trace.h new file mode 100644 index 000000000000..e2ff0184306e --- /dev/null +++ b/drivers/media/platform/msm/ais/ais_isp/utils/ais_isp_trace.h @@ -0,0 +1,229 @@ +/* Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#if !defined(_AIS_ISP_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _AIS_ISP_TRACE_H + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM camera +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE ais_isp_trace + +#include +#include +#include "ais_isp_hw.h" + +TRACE_EVENT(ais_isp_vfe_irq_activated, + TP_PROTO(uint8_t id, uint32_t status0, uint32_t status1), + TP_ARGS(id, status0, status1), + TP_STRUCT__entry( + __field(uint8_t, id) + __field(uint32_t, status0) + __field(uint32_t, status1) + ), + TP_fast_assign( + __entry->id = id; + __entry->status0 = status0; + __entry->status1 = status1; + ), + TP_printk( + "vfe%d: irq 0x%08x 0x%08x", + __entry->id, + __entry->status0, __entry->status1 + ) +); + +TRACE_EVENT(ais_isp_irq_process, + TP_PROTO(uint8_t id, uint8_t evt, uint8_t state), + TP_ARGS(id, evt, state), + TP_STRUCT__entry( + __field(uint8_t, id) + __field(uint8_t, evt) + __field(uint8_t, state) + ), + TP_fast_assign( + __entry->id = id; + __entry->evt = evt; + __entry->state = state; + ), + TP_printk( + "vfe%d: irq event %d (%d)", + __entry->id, __entry->evt, __entry->state + ) +); + +TRACE_EVENT(ais_isp_vfe_state, + TP_PROTO(uint8_t id, uint8_t path, uint8_t state), + TP_ARGS(id, path, state), + TP_STRUCT__entry( + __field(uint8_t, id) + __field(uint8_t, path) + __field(uint8_t, state) + ), + TP_fast_assign( + __entry->id = id; + __entry->path = path; + __entry->state = state; + ), + TP_printk( + "vfe%d:%d: state %d", + __entry->id, __entry->path, __entry->state + ) +); + +TRACE_EVENT(ais_isp_vfe_sof, + TP_PROTO(uint8_t id, uint8_t path, struct ais_ife_rdi_timestamps *ts, + uint32_t fifo, uint32_t miss), + TP_ARGS(id, path, ts, fifo, miss), + TP_STRUCT__entry( + __field(uint8_t, id) + __field(uint8_t, path) + __field(uint32_t, fifo) + __field(uint32_t, miss) + __field(uint64_t, ts_cur) + __field(uint64_t, ts_prev) + ), + TP_fast_assign( + __entry->id = id; + __entry->path = path; + __entry->fifo = fifo; + __entry->miss = miss; + __entry->ts_cur = ts->cur_sof_ts; + __entry->ts_prev = ts->prev_sof_ts; + ), + TP_printk( + "vfe%d:%d: sof %llu %llu fifo %u miss %u", + __entry->id, __entry->path, __entry->ts_cur, __entry->ts_prev, + __entry->fifo, __entry->miss + ) +); + +TRACE_EVENT(ais_isp_vfe_q_sof, + TP_PROTO(uint8_t id, uint8_t path, uint32_t frame, uint64_t ts), + TP_ARGS(id, path, frame, ts), + TP_STRUCT__entry( + __field(uint8_t, id) + __field(uint8_t, path) + __field(uint32_t, frame) + __field(uint64_t, ts) + ), + TP_fast_assign( + __entry->id = id; + __entry->path = path; + __entry->frame = frame; + __entry->ts = ts; + ), + TP_printk( + "vfe%d:%d: sof %d %llu", + __entry->id, __entry->path, __entry->frame, __entry->ts + ) +); + +TRACE_EVENT(ais_isp_vfe_buf_done, + TP_PROTO(uint8_t id, uint8_t path, uint8_t idx, uint32_t frame, + uint8_t fifo, uint8_t match), + TP_ARGS(id, path, idx, frame, fifo, match), + TP_STRUCT__entry( + __field(uint8_t, id) + __field(uint8_t, path) + __field(uint8_t, idx) + __field(uint32_t, frame) + __field(uint8_t, fifo) + __field(uint8_t, match) + ), + TP_fast_assign( + __entry->id = id; + __entry->path = path; + __entry->idx = idx; + __entry->frame = frame; + __entry->fifo = fifo; + __entry->match = match; + ), + TP_printk( + "vfe%d:%d: buf_done %d (%d fifo %d match %d)", + __entry->id, __entry->path, __entry->idx, __entry->frame, + __entry->fifo, __entry->match + ) +); + +TRACE_EVENT(ais_isp_vfe_enq_buf_hw, + TP_PROTO(uint8_t id, uint8_t path, uint8_t idx, + uint8_t fifo, uint8_t full), + TP_ARGS(id, path, idx, fifo, full), + TP_STRUCT__entry( + __field(uint8_t, id) + __field(uint8_t, path) + __field(uint8_t, idx) + __field(uint8_t, fifo) + __field(uint8_t, full) + ), + TP_fast_assign( + __entry->id = id; + __entry->path = path; + __entry->idx = idx; + __entry->fifo = fifo; + __entry->full = full; + ), + TP_printk( + "vfe%d:%d: enq buf hw %d fifo %d full %d", + __entry->id, __entry->path, __entry->idx, + __entry->fifo, __entry->full + ) +); + +TRACE_EVENT(ais_isp_vfe_enq_req, + TP_PROTO(uint8_t id, uint8_t path, uint8_t idx), + TP_ARGS(id, path, idx), + TP_STRUCT__entry( + __field(uint8_t, id) + __field(uint8_t, path) + __field(uint8_t, idx) + ), + TP_fast_assign( + __entry->id = id; + __entry->path = path; + __entry->idx = idx; + ), + TP_printk( + "vfe%d:%d: enq req %d", + __entry->id, __entry->path, __entry->idx + ) +); + +TRACE_EVENT(ais_isp_vfe_error, + TP_PROTO(uint8_t id, uint8_t path, uint8_t err, uint8_t payload), + TP_ARGS(id, path, err, payload), + TP_STRUCT__entry( + __field(uint8_t, id) + __field(uint8_t, path) + __field(uint8_t, err) + __field(uint8_t, payload) + ), + TP_fast_assign( + __entry->id = id; + __entry->path = path; + __entry->err = err; + __entry->payload = payload; + ), + TP_printk( + "vfe%d:%d: error %d %d", + __entry->id, __entry->path, __entry->err, __entry->payload + ) +); + +#endif /* _AIS_ISP_TRACE_H */ + +/* This part must be outside protection */ +#include diff --git a/drivers/media/platform/msm/ais/ais_isp/vfe_hw/Makefile b/drivers/media/platform/msm/ais/ais_isp/vfe_hw/Makefile index 45f022014a74..81e5b8b88dcd 100644 --- a/drivers/media/platform/msm/ais/ais_isp/vfe_hw/Makefile +++ b/drivers/media/platform/msm/ais/ais_isp/vfe_hw/Makefile @@ -5,6 +5,7 @@ ccflags-y += -Idrivers/media/platform/msm/ais/cam_smmu/ ccflags-y += -Idrivers/media/platform/msm/ais/cam_req_mgr/ ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/include +ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/utils ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/vfe_hw/include ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/vfe_hw/vfe_bus/include ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/vfe_hw/vfe_bus diff --git a/drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.c b/drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.c index 1321d7dddbd3..00219b70667a 100644 --- a/drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.c +++ b/drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.c @@ -20,6 +20,7 @@ #include "ais_vfe_soc.h" #include "ais_vfe_core.h" #include "cam_debug_util.h" +#include "ais_isp_trace.h" /*VFE TOP DEFINITIONS*/ #define AIS_VFE_HW_RESET_HW_AND_REG_VAL 0x00003F9F @@ -715,6 +716,9 @@ static void ais_vfe_q_bufs_to_hw(struct ais_vfe_hw_core_info *core_info, fifo_status = cam_io_r_mb(core_info->mem_base + bus_hw_info->common_reg.addr_fifo_status); is_full = fifo_status & (1 << path); + + trace_ais_isp_vfe_enq_buf_hw(core_info->vfe_idx, path, + vfe_buf->bufIdx, rdi_path->num_buffer_hw_q, is_full); } if (rdi_path->num_buffer_hw_q > MAX_NUM_BUF_SW_FIFOQ_ERR) @@ -791,6 +795,10 @@ static int ais_vfe_cmd_enq_buf(struct ais_vfe_hw_core_info *core_info, vfe_buf->iova_addr += enq_buf->buffer.offset; spin_lock(&rdi_path->buffer_lock); + + trace_ais_isp_vfe_enq_req(core_info->vfe_idx, enq_buf->path, + enq_buf->buffer.idx); + list_add_tail(&vfe_buf->list, &rdi_path->buffer_q); if (rdi_path->state < AIS_ISP_RESOURCE_STATE_STREAMING) @@ -884,15 +892,17 @@ static int ais_vfe_q_sof(struct ais_vfe_hw_core_info *core_info, list_add_tail(&p_sof_info->list, &p_rdi->sof_info_q); p_rdi->num_sof_info_q++; + trace_ais_isp_vfe_q_sof(core_info->vfe_idx, path, + p_sof->frame_cnt, p_sof->cur_sof_hw_ts); CAM_DBG(CAM_ISP, "I%d|R%d|F%llu: sof %llu", - core_info->vfe_idx, path, p_rdi->frame_cnt, + core_info->vfe_idx, path, p_sof->frame_cnt, p_sof_info->cur_sof_hw_ts); } else { rc = -1; CAM_ERR(CAM_ISP, "I%d|R%d|F%llu: free timestamp empty (%d)", - core_info->vfe_idx, path, p_rdi->frame_cnt, + core_info->vfe_idx, path, p_sof->frame_cnt, p_rdi->num_buffer_hw_q); } @@ -936,6 +946,10 @@ static void ais_vfe_handle_sof_rdi(struct ais_vfe_hw_core_info *core_info, } } + trace_ais_isp_vfe_sof(core_info->vfe_idx, path, + &work_data->ts_hw[path], + p_rdi->num_buffer_hw_q, miss_sof); + if (p_rdi->frame_cnt == 1 && prev_sof_hw_ts != 0) { //enq missed first frame sof.sof_ts = work_data->ts; @@ -977,6 +991,10 @@ static void ais_vfe_handle_sof_rdi(struct ais_vfe_hw_core_info *core_info, ais_vfe_q_sof(core_info, path, &sof); } else { + trace_ais_isp_vfe_sof(core_info->vfe_idx, path, + &work_data->ts_hw[path], + p_rdi->num_buffer_hw_q, 0); + CAM_DBG(CAM_ISP, "I%d R%d Flush SOF (%d) HW Q empty", core_info->vfe_idx, path, p_rdi->num_sof_info_q); @@ -995,6 +1013,8 @@ static void ais_vfe_handle_sof_rdi(struct ais_vfe_hw_core_info *core_info, p_rdi->num_sof_info_q = 0; } + trace_ais_isp_vfe_error(core_info->vfe_idx, + path, 1, 0); //send warning core_info->event.type = AIS_IFE_MSG_OUTPUT_WARNING; @@ -1030,7 +1050,7 @@ static int ais_vfe_handle_sof( CAM_DBG(CAM_ISP, "IFE%d SOF RDIs 0x%x", core_info->vfe_idx, work_data->path); - for (path = 0; path <= AIS_IFE_PATH_MAX; path++) { + for (path = 0; path < AIS_IFE_PATH_MAX; path++) { if (!(work_data->path & (1 << path))) continue; @@ -1065,11 +1085,14 @@ static int ais_vfe_handle_error( CAM_ERR(CAM_ISP, "IFE%d ERROR on RDIs 0x%x", core_info->vfe_idx, work_data->path); + trace_ais_isp_vfe_error(core_info->vfe_idx, + work_data->path, 0, 0); + top_hw_info = core_info->vfe_hw_info->top_hw_info; bus_hw_info = core_info->vfe_hw_info->bus_hw_info; bus_hw_irq_regs = bus_hw_info->common_reg.irq_reg_info.irq_reg_set; - for (path = 0; path <= AIS_IFE_PATH_MAX; path++) { + for (path = 0; path < AIS_IFE_PATH_MAX; path++) { if (!(work_data->path & (1 << path))) continue; @@ -1112,7 +1135,7 @@ static void ais_vfe_bus_handle_client_frame_done( struct ais_vfe_rdi_output *rdi_path = NULL; struct ais_vfe_buffer_t *vfe_buf = NULL; struct ais_vfe_bus_ver2_hw_info *bus_hw_info = NULL; - uint64_t frame_cnt; + uint64_t frame_cnt = 0; uint64_t sof_ts; uint64_t cur_sof_hw_ts; bool last_addr_match = false; @@ -1146,6 +1169,12 @@ static void ais_vfe_bus_handle_client_frame_done( list_del_init(&vfe_buf->list); --rdi_path->num_buffer_hw_q; + if (last_addr == vfe_buf->iova_addr) + last_addr_match = true; + else + CAM_WARN(CAM_ISP, "IFE%d buf %d did not match addr", + core_info->vfe_idx, vfe_buf->bufIdx); + CAM_DBG(CAM_ISP, "I%d|R%d BUF DQ %d (0x%x) FIFO:%d|0x%x", core_info->vfe_idx, path, vfe_buf->bufIdx, vfe_buf->iova_addr, @@ -1175,6 +1204,12 @@ static void ais_vfe_bus_handle_client_frame_done( cur_sof_hw_ts); + trace_ais_isp_vfe_buf_done(core_info->vfe_idx, path, + vfe_buf->bufIdx, + frame_cnt, + rdi_path->num_buffer_hw_q, + last_addr_match); + core_info->event.u.frame_msg.frame_id = frame_cnt; core_info->event.u.frame_msg.buf_idx = vfe_buf->bufIdx; core_info->event.u.frame_msg.ts = sof_ts; @@ -1183,11 +1218,7 @@ static void ais_vfe_bus_handle_client_frame_done( core_info->event_cb(core_info->event_cb_priv, &core_info->event); - if (last_addr == vfe_buf->iova_addr) - last_addr_match = true; - else - CAM_WARN(CAM_ISP, "IFE%d buf %d did not match addr", - core_info->vfe_idx, vfe_buf->bufIdx); + list_add_tail(&vfe_buf->list, &rdi_path->free_buffer_list); } @@ -1195,6 +1226,8 @@ static void ais_vfe_bus_handle_client_frame_done( CAM_ERR(CAM_ISP, "IFE%d BUF| RDI%d NO MATCH addr 0x%x", core_info->vfe_idx, path, last_addr); + trace_ais_isp_vfe_error(core_info->vfe_idx, path, 1, 1); + //send warning core_info->event.type = AIS_IFE_MSG_OUTPUT_WARNING; core_info->event.path = path; @@ -1222,6 +1255,8 @@ static void ais_vfe_bus_handle_client_frame_done( rdi_path->num_sof_info_q = 0; + trace_ais_isp_vfe_error(core_info->vfe_idx, path, 1, 0); + //send warning core_info->event.type = AIS_IFE_MSG_OUTPUT_WARNING; core_info->event.path = path; @@ -1371,6 +1406,8 @@ static int ais_vfe_process_irq_bh(void *priv, void *data) } work_data = (struct ais_vfe_hw_work_data *)data; + + trace_ais_isp_irq_process(core_info->vfe_idx, work_data->evt_type, 1); CAM_DBG(CAM_ISP, "VFE[%d] event %d", core_info->vfe_idx, work_data->evt_type); @@ -1393,6 +1430,8 @@ static int ais_vfe_process_irq_bh(void *priv, void *data) break; } + trace_ais_isp_irq_process(core_info->vfe_idx, work_data->evt_type, 2); + return rc; } @@ -1417,6 +1456,8 @@ static int ais_vfe_dispatch_irq(struct cam_hw_info *vfe_hw, work_data = (struct ais_vfe_hw_work_data *)task->payload; *work_data = *p_work; + trace_ais_isp_irq_process(core_info->vfe_idx, p_work->evt_type, 0); + task->process_cb = ais_vfe_process_irq_bh; rc = cam_req_mgr_workq_enqueue_task(task, vfe_hw, CRM_TASK_PRIORITY_0); @@ -1444,6 +1485,8 @@ irqreturn_t ais_vfe_irq(int irq_num, void *data) cam_io_w_mb(ife_status[1], core_info->mem_base + AIS_VFE_IRQ_CLEAR1); cam_io_w_mb(0x1, core_info->mem_base + AIS_VFE_IRQ_CMD); + trace_ais_isp_vfe_irq_activated(core_info->vfe_idx, + ife_status[0], ife_status[1]); CAM_DBG(CAM_ISP, "VFE%d irq status 0x%x 0x%x", core_info->vfe_idx, ife_status[0], ife_status[1]); diff --git a/drivers/media/platform/msm/ais/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/ais/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index c6f0b746729c..f7db88c15a04 100644 --- a/drivers/media/platform/msm/ais/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/media/platform/msm/ais/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -5071,8 +5071,9 @@ static int cam_icp_mgr_alloc_devs(struct device_node *of_node) goto num_a5_failed; } - icp_hw_mgr.devices[CAM_ICP_DEV_A5] = kzalloc( - sizeof(struct cam_hw_intf *) * num_dev, GFP_KERNEL); + icp_hw_mgr.devices[CAM_ICP_DEV_A5] = kcalloc(num_dev, + sizeof(struct cam_hw_intf *), + GFP_KERNEL); if (!icp_hw_mgr.devices[CAM_ICP_DEV_A5]) { rc = -ENOMEM; goto num_a5_failed; @@ -5227,20 +5228,20 @@ static int cam_icp_mgr_create_wq(void) } icp_hw_mgr.cmd_work_data = (struct hfi_cmd_work_data *) - kzalloc(sizeof(struct hfi_cmd_work_data) * ICP_WORKQ_NUM_TASK, - GFP_KERNEL); + kcalloc(ICP_WORKQ_NUM_TASK, sizeof(struct hfi_cmd_work_data), + GFP_KERNEL); if (!icp_hw_mgr.cmd_work_data) goto cmd_work_data_failed; icp_hw_mgr.msg_work_data = (struct hfi_msg_work_data *) - kzalloc(sizeof(struct hfi_msg_work_data) * ICP_WORKQ_NUM_TASK, - GFP_KERNEL); + kcalloc(ICP_WORKQ_NUM_TASK, sizeof(struct hfi_msg_work_data), + GFP_KERNEL); if (!icp_hw_mgr.msg_work_data) goto msg_work_data_failed; icp_hw_mgr.timer_work_data = (struct hfi_msg_work_data *) - kzalloc(sizeof(struct hfi_msg_work_data) * ICP_WORKQ_NUM_TASK, - GFP_KERNEL); + kcalloc(ICP_WORKQ_NUM_TASK, sizeof(struct hfi_msg_work_data), + GFP_KERNEL); if (!icp_hw_mgr.timer_work_data) goto timer_work_data_failed; diff --git a/drivers/media/platform/msm/ais/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/ais/cam_isp/cam_isp_context.c index 6cfbf7b89a30..699829135ec5 100644 --- a/drivers/media/platform/msm/ais/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/ais/cam_isp/cam_isp_context.c @@ -3431,8 +3431,7 @@ static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx, goto end; } - isp_res = kzalloc( - sizeof(*isp_res)*cmd->num_resources, GFP_KERNEL); + isp_res = kcalloc(cmd->num_resources, sizeof(*isp_res), GFP_KERNEL); if (!isp_res) { rc = -ENOMEM; goto end; diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c index 02344d790423..8b0e61e77ad7 100644 --- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c +++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c @@ -152,16 +152,18 @@ int cam_irq_controller_init(const char *name, return -ENOMEM; } - controller->irq_register_arr = kzalloc(register_info->num_registers * - sizeof(struct cam_irq_register_obj), GFP_KERNEL); + controller->irq_register_arr = kcalloc(register_info->num_registers, + sizeof(struct cam_irq_register_obj), + GFP_KERNEL); if (!controller->irq_register_arr) { CAM_DBG(CAM_IRQ_CTRL, "Failed to allocate IRQ register Arr"); rc = -ENOMEM; goto reg_alloc_error; } - controller->irq_status_arr = kzalloc(register_info->num_registers * - sizeof(uint32_t), GFP_KERNEL); + controller->irq_status_arr = kcalloc(register_info->num_registers, + sizeof(uint32_t), + GFP_KERNEL); if (!controller->irq_status_arr) { CAM_DBG(CAM_IRQ_CTRL, "Failed to allocate IRQ status Arr"); rc = -ENOMEM; @@ -169,8 +171,8 @@ int cam_irq_controller_init(const char *name, } controller->th_payload.evt_status_arr = - kzalloc(register_info->num_registers * sizeof(uint32_t), - GFP_KERNEL); + kcalloc(register_info->num_registers, sizeof(uint32_t), + GFP_KERNEL); if (!controller->th_payload.evt_status_arr) { CAM_DBG(CAM_IRQ_CTRL, "Failed to allocate BH payload bit mask Arr"); @@ -293,8 +295,9 @@ int cam_irq_controller_subscribe_irq(void *irq_controller, return -ENOMEM; } - evt_handler->evt_bit_mask_arr = kzalloc(sizeof(uint32_t) * - controller->num_registers, GFP_KERNEL); + evt_handler->evt_bit_mask_arr = kcalloc(controller->num_registers, + sizeof(uint32_t), + GFP_KERNEL); if (!evt_handler->evt_bit_mask_arr) { CAM_DBG(CAM_IRQ_CTRL, "Error allocating hlist_node"); rc = -ENOMEM; diff --git a/drivers/media/platform/msm/ais/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/ais/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c index 1a995646a947..8f2de3ce498b 100644 --- a/drivers/media/platform/msm/ais/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c +++ b/drivers/media/platform/msm/ais/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c @@ -1443,8 +1443,9 @@ static int cam_jpeg_setup_workqs(void) g_jpeg_hw_mgr.process_frame_work_data = (struct cam_jpeg_process_frame_work_data_t *) - kzalloc(sizeof(struct cam_jpeg_process_frame_work_data_t) * - CAM_JPEG_WORKQ_NUM_TASK, GFP_KERNEL); + kcalloc(CAM_JPEG_WORKQ_NUM_TASK, + sizeof(struct cam_jpeg_process_frame_work_data_t), + GFP_KERNEL); if (!g_jpeg_hw_mgr.process_frame_work_data) { rc = -ENOMEM; goto work_process_frame_data_failed; @@ -1452,8 +1453,9 @@ static int cam_jpeg_setup_workqs(void) g_jpeg_hw_mgr.process_irq_cb_work_data = (struct cam_jpeg_process_irq_work_data_t *) - kzalloc(sizeof(struct cam_jpeg_process_irq_work_data_t) * - CAM_JPEG_WORKQ_NUM_TASK, GFP_KERNEL); + kcalloc(CAM_JPEG_WORKQ_NUM_TASK, + sizeof(struct cam_jpeg_process_irq_work_data_t), + GFP_KERNEL); if (!g_jpeg_hw_mgr.process_irq_cb_work_data) { rc = -ENOMEM; goto work_process_irq_cb_data_failed; @@ -1522,8 +1524,9 @@ static int cam_jpeg_init_devices(struct device_node *of_node, CAM_ERR(CAM_JPEG, "read num enc devices failed %d", rc); goto num_enc_failed; } - g_jpeg_hw_mgr.devices[CAM_JPEG_DEV_ENC] = kzalloc( - sizeof(struct cam_hw_intf *) * num_dev, GFP_KERNEL); + g_jpeg_hw_mgr.devices[CAM_JPEG_DEV_ENC] = kcalloc(num_dev, + sizeof(struct cam_hw_intf *), + GFP_KERNEL); if (!g_jpeg_hw_mgr.devices[CAM_JPEG_DEV_ENC]) { rc = -ENOMEM; CAM_ERR(CAM_JPEG, "getting number of dma dev nodes failed"); @@ -1536,8 +1539,9 @@ static int cam_jpeg_init_devices(struct device_node *of_node, goto num_dma_failed; } - g_jpeg_hw_mgr.devices[CAM_JPEG_DEV_DMA] = kzalloc( - sizeof(struct cam_hw_intf *) * num_dma_dev, GFP_KERNEL); + g_jpeg_hw_mgr.devices[CAM_JPEG_DEV_DMA] = kcalloc(num_dma_dev, + sizeof(struct cam_hw_intf *), + GFP_KERNEL); if (!g_jpeg_hw_mgr.devices[CAM_JPEG_DEV_DMA]) { rc = -ENOMEM; goto num_dma_failed; diff --git a/drivers/media/platform/msm/ais/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/ais/cam_req_mgr/cam_req_mgr_core.c index c3c9428924ce..5fe4a1314cef 100644 --- a/drivers/media/platform/msm/ais/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/media/platform/msm/ais/cam_req_mgr/cam_req_mgr_core.c @@ -1594,8 +1594,8 @@ static int __cam_req_mgr_create_subdevs( { int rc = 0; *l_dev = (struct cam_req_mgr_connected_device *) - kzalloc(sizeof(struct cam_req_mgr_connected_device) * num_dev, - GFP_KERNEL); + kcalloc(num_dev, sizeof(struct cam_req_mgr_connected_device), + GFP_KERNEL); if (!*l_dev) rc = -ENOMEM; diff --git a/drivers/media/platform/msm/ais/cam_sensor_module/cam_actuator/cam_actuator_dev.c b/drivers/media/platform/msm/ais/cam_sensor_module/cam_actuator/cam_actuator_dev.c index 228ccb8a39b3..756688699bcf 100644 --- a/drivers/media/platform/msm/ais/cam_sensor_module/cam_actuator/cam_actuator_dev.c +++ b/drivers/media/platform/msm/ais/cam_sensor_module/cam_actuator/cam_actuator_dev.c @@ -196,8 +196,9 @@ static int32_t cam_actuator_driver_i2c_probe(struct i2c_client *client, a_ctrl->i2c_data.per_frame = (struct i2c_settings_array *) - kzalloc(sizeof(struct i2c_settings_array) * - MAX_PER_FRAME_ARRAY, GFP_KERNEL); + kcalloc(MAX_PER_FRAME_ARRAY, + sizeof(struct i2c_settings_array), + GFP_KERNEL); if (a_ctrl->i2c_data.per_frame == NULL) { rc = -ENOMEM; goto unreg_subdev; @@ -342,8 +343,9 @@ static int32_t cam_actuator_driver_platform_probe( a_ctrl->i2c_data.per_frame = (struct i2c_settings_array *) - kzalloc(sizeof(struct i2c_settings_array) * - MAX_PER_FRAME_ARRAY, GFP_KERNEL); + kcalloc(MAX_PER_FRAME_ARRAY, + sizeof(struct i2c_settings_array), + GFP_KERNEL); if (a_ctrl->i2c_data.per_frame == NULL) { rc = -ENOMEM; goto free_soc; diff --git a/drivers/media/platform/msm/ais/cam_sensor_module/cam_cci/cam_cci_core.c b/drivers/media/platform/msm/ais/cam_sensor_module/cam_cci/cam_cci_core.c index 45eb1f449d35..d2096599a158 100755 --- a/drivers/media/platform/msm/ais/cam_sensor_module/cam_cci/cam_cci_core.c +++ b/drivers/media/platform/msm/ais/cam_sensor_module/cam_cci/cam_cci_core.c @@ -1797,8 +1797,9 @@ static int32_t cam_cci_i2c_write_async(struct v4l2_subdev *sd, } cci_i2c_write_cfg_w->reg_setting = - kzalloc(sizeof(struct cam_sensor_i2c_reg_array)* - cci_i2c_write_cfg->size, GFP_KERNEL); + kcalloc(cci_i2c_write_cfg->size, + sizeof(struct cam_sensor_i2c_reg_array), + GFP_KERNEL); if (!cci_i2c_write_cfg_w->reg_setting) { CAM_ERR(CAM_CCI, "Couldn't allocate memory"); kfree(write_async); diff --git a/drivers/media/platform/msm/ais/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/ais/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index 1134189eead5..36ee4ecf0e02 100644 --- a/drivers/media/platform/msm/ais/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/ais/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -580,9 +580,7 @@ static int32_t cam_eeprom_init_pkt_parser(struct cam_eeprom_ctrl_t *e_ctrl, (struct cam_eeprom_soc_private *)e_ctrl->soc_info.soc_private; struct cam_sensor_power_ctrl_t *power_info = &soc_private->power_info; - e_ctrl->cal_data.map = vzalloc((MSM_EEPROM_MEMORY_MAP_MAX_SIZE * - MSM_EEPROM_MAX_MEM_MAP_CNT) * - (sizeof(struct cam_eeprom_memory_map_t))); + e_ctrl->cal_data.map = vzalloc(array_size(sizeof(struct cam_eeprom_memory_map_t), (MSM_EEPROM_MEMORY_MAP_MAX_SIZE * MSM_EEPROM_MAX_MEM_MAP_CNT))); if (!e_ctrl->cal_data.map) { rc = -ENOMEM; CAM_ERR(CAM_EEPROM, "failed"); diff --git a/drivers/media/platform/msm/ais/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/media/platform/msm/ais/cam_sensor_module/cam_flash/cam_flash_dev.c index f4c9d254df7c..12407e305102 100644 --- a/drivers/media/platform/msm/ais/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/drivers/media/platform/msm/ais/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -456,8 +456,9 @@ static int32_t cam_flash_platform_probe(struct platform_device *pdev) } fctrl->i2c_data.per_frame = (struct i2c_settings_array *) - kzalloc(sizeof(struct i2c_settings_array) * - MAX_PER_FRAME_ARRAY, GFP_KERNEL); + kcalloc(MAX_PER_FRAME_ARRAY, + sizeof(struct i2c_settings_array), + GFP_KERNEL); if (fctrl->i2c_data.per_frame == NULL) { CAM_ERR(CAM_FLASH, "No Memory"); rc = -ENOMEM; @@ -560,8 +561,9 @@ static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client, fctrl->i2c_data.per_frame = (struct i2c_settings_array *) - kzalloc(sizeof(struct i2c_settings_array) * - MAX_PER_FRAME_ARRAY, GFP_KERNEL); + kcalloc(MAX_PER_FRAME_ARRAY, + sizeof(struct i2c_settings_array), + GFP_KERNEL); if (fctrl->i2c_data.per_frame == NULL) { rc = -ENOMEM; goto unreg_subdev; diff --git a/drivers/media/platform/msm/ais/cam_sensor_module/cam_sensor/cam_sensor_dev.c b/drivers/media/platform/msm/ais/cam_sensor_module/cam_sensor/cam_sensor_dev.c index d29a58f65a47..ff051f857ddd 100644 --- a/drivers/media/platform/msm/ais/cam_sensor_module/cam_sensor/cam_sensor_dev.c +++ b/drivers/media/platform/msm/ais/cam_sensor_module/cam_sensor/cam_sensor_dev.c @@ -193,8 +193,9 @@ static int32_t cam_sensor_driver_i2c_probe(struct i2c_client *client, s_ctrl->i2c_data.per_frame = (struct i2c_settings_array *) - kzalloc(sizeof(struct i2c_settings_array) * - MAX_PER_FRAME_ARRAY, GFP_KERNEL); + kcalloc(MAX_PER_FRAME_ARRAY, + sizeof(struct i2c_settings_array), + GFP_KERNEL); if (s_ctrl->i2c_data.per_frame == NULL) { rc = -ENOMEM; goto unreg_subdev; @@ -329,8 +330,9 @@ static int32_t cam_sensor_driver_platform_probe( s_ctrl->i2c_data.per_frame = (struct i2c_settings_array *) - kzalloc(sizeof(struct i2c_settings_array) * - MAX_PER_FRAME_ARRAY, GFP_KERNEL); + kcalloc(MAX_PER_FRAME_ARRAY, + sizeof(struct i2c_settings_array), + GFP_KERNEL); if (s_ctrl->i2c_data.per_frame == NULL) { rc = -ENOMEM; goto unreg_subdev; diff --git a/drivers/media/platform/msm/ais/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c b/drivers/media/platform/msm/ais/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c index b3a74d6c80bf..74e26a87283a 100644 --- a/drivers/media/platform/msm/ais/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c +++ b/drivers/media/platform/msm/ais/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c @@ -37,7 +37,7 @@ static struct i2c_settings_list* return NULL; tmp->i2c_settings.reg_setting = (struct cam_sensor_i2c_reg_array *) - vzalloc(size * sizeof(struct cam_sensor_i2c_reg_array)); + vzalloc(array_size(size, sizeof(struct cam_sensor_i2c_reg_array))); if (tmp->i2c_settings.reg_setting == NULL) { list_del(&(tmp->list)); kfree(tmp); @@ -944,16 +944,18 @@ int32_t cam_sensor_update_power_settings(void *cmd_buf, power_info->power_setting_size = 0; power_info->power_setting = (struct cam_sensor_power_setting *) - kzalloc(sizeof(struct cam_sensor_power_setting) * - MAX_POWER_CONFIG, GFP_KERNEL); + kcalloc(MAX_POWER_CONFIG, + sizeof(struct cam_sensor_power_setting), + GFP_KERNEL); if (!power_info->power_setting) return -ENOMEM; power_info->power_down_setting_size = 0; power_info->power_down_setting = (struct cam_sensor_power_setting *) - kzalloc(sizeof(struct cam_sensor_power_setting) * - MAX_POWER_CONFIG, GFP_KERNEL); + kcalloc(MAX_POWER_CONFIG, + sizeof(struct cam_sensor_power_setting), + GFP_KERNEL); if (!power_info->power_down_setting) { kfree(power_info->power_setting); power_info->power_setting = NULL; diff --git a/drivers/media/platform/msm/ais/cam_smmu/cam_smmu_api.c b/drivers/media/platform/msm/ais/cam_smmu/cam_smmu_api.c index e00b1f4ec0a7..1bc5a8ec640e 100644 --- a/drivers/media/platform/msm/ais/cam_smmu/cam_smmu_api.c +++ b/drivers/media/platform/msm/ais/cam_smmu/cam_smmu_api.c @@ -3312,8 +3312,8 @@ static int cam_alloc_smmu_context_banks(struct device *dev) } /* allocate memory for the context banks */ - iommu_cb_set.cb_info = devm_kzalloc(dev, - iommu_cb_set.cb_num * sizeof(struct cam_context_bank_info), + iommu_cb_set.cb_info = devm_kcalloc(dev, + iommu_cb_set.cb_num, sizeof(struct cam_context_bank_info), GFP_KERNEL); if (!iommu_cb_set.cb_info) { diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c index 3c61d883d457..60e11681b604 100644 --- a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c +++ b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c @@ -1053,8 +1053,8 @@ static int cam_context_dump_context(struct cam_context *ctx, struct cam_context_dump_header *hdr; char *dst; uint64_t *addr, *start; - uintptr_t cpu_addr; - size_t buf_len; + uintptr_t cpu_addr = 0; + size_t buf_len = 0; uint32_t min_len, remain_len; struct cam_ctx_request *req; int i; diff --git a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c index 91a1b141e659..2caf6d0a844d 100644 --- a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1579,6 +1579,7 @@ hw_dump: frame_req->submit_timestamp.tv_usec, cur_time.tv_sec, cur_time.tv_usec); + memset(&fd_dump_args, 0, sizeof(fd_dump_args)); rc = cam_mem_get_cpu_buf(dump_args->buf_handle, &fd_dump_args.cpu_addr, &fd_dump_args.buf_len); if (!fd_dump_args.cpu_addr || !fd_dump_args.buf_len || rc) { diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index 532348032d7d..aedbc1a42470 100644 --- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -4626,6 +4626,7 @@ hw_dump: frm_process->submit_timestamp[i].tv_usec, cur_time.tv_sec, cur_time.tv_usec); + memset(&icp_dump_args, 0, sizeof(icp_dump_args)); rc = cam_mem_get_cpu_buf(dump_args->buf_handle, &icp_dump_args.cpu_addr, &icp_dump_args.buf_len); if (!icp_dump_args.cpu_addr || !icp_dump_args.buf_len || rc) { @@ -5212,8 +5213,9 @@ static int cam_icp_mgr_alloc_devs(struct device_node *of_node) goto num_a5_failed; } - icp_hw_mgr.devices[CAM_ICP_DEV_A5] = kzalloc( - sizeof(struct cam_hw_intf *) * num_dev, GFP_KERNEL); + icp_hw_mgr.devices[CAM_ICP_DEV_A5] = kcalloc(num_dev, + sizeof(struct cam_hw_intf *), + GFP_KERNEL); if (!icp_hw_mgr.devices[CAM_ICP_DEV_A5]) { rc = -ENOMEM; goto num_a5_failed; @@ -5368,20 +5370,20 @@ static int cam_icp_mgr_create_wq(void) } icp_hw_mgr.cmd_work_data = (struct hfi_cmd_work_data *) - kzalloc(sizeof(struct hfi_cmd_work_data) * ICP_WORKQ_NUM_TASK, - GFP_KERNEL); + kcalloc(ICP_WORKQ_NUM_TASK, sizeof(struct hfi_cmd_work_data), + GFP_KERNEL); if (!icp_hw_mgr.cmd_work_data) goto cmd_work_data_failed; icp_hw_mgr.msg_work_data = (struct hfi_msg_work_data *) - kzalloc(sizeof(struct hfi_msg_work_data) * ICP_WORKQ_NUM_TASK, - GFP_KERNEL); + kcalloc(ICP_WORKQ_NUM_TASK, sizeof(struct hfi_msg_work_data), + GFP_KERNEL); if (!icp_hw_mgr.msg_work_data) goto msg_work_data_failed; icp_hw_mgr.timer_work_data = (struct hfi_msg_work_data *) - kzalloc(sizeof(struct hfi_msg_work_data) * ICP_WORKQ_NUM_TASK, - GFP_KERNEL); + kcalloc(ICP_WORKQ_NUM_TASK, sizeof(struct hfi_msg_work_data), + GFP_KERNEL); if (!icp_hw_mgr.timer_work_data) goto timer_work_data_failed; diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c index 6821a9524484..6bc114c5949b 100644 --- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c @@ -929,7 +929,7 @@ static int __cam_isp_ctx_reg_upd_in_activated_state( list_del_init(&req->list); req_isp = (struct cam_isp_ctx_req *) req->req_priv; - if (req_isp->num_fence_map_out != 0) { + if (req_isp && req_isp->num_fence_map_out != 0) { list_add_tail(&req->list, &ctx->active_req_list); ctx_isp->active_req_cnt++; CAM_DBG(CAM_REQ, @@ -1909,7 +1909,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state( list_del_init(&req->list); req_isp = (struct cam_isp_ctx_req *) req->req_priv; - if (req_isp->num_fence_map_out != 0) { + if (req_isp && req_isp->num_fence_map_out != 0) { list_add_tail(&req->list, &ctx->active_req_list); ctx_isp->active_req_cnt++; CAM_DBG(CAM_REQ, "move request %lld to active list(cnt = %d)", @@ -1927,7 +1927,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state( * state so change substate here. */ ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH; - if (req_isp->num_fence_map_out != 1) + if (req_isp && req_isp->num_fence_map_out != 1) goto end; if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger && @@ -2367,6 +2367,7 @@ hw_dump: is_dump_only_event_record = true; } ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; + memset(&cpu_addr, 0, sizeof(cpu_addr)); rc = cam_mem_get_cpu_buf(dump_info->buf_handle, &cpu_addr, &buf_len); if (!cpu_addr || !buf_len || rc) { @@ -3386,7 +3387,7 @@ static int __cam_isp_ctx_config_dev_in_top_state( CAM_INFO(CAM_ISP, "request %lld has been flushed, reject packet", packet->header.request_id); - rc = -EINVAL; + rc = -EBADR; goto free_cpu_buf; } @@ -3545,8 +3546,7 @@ static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx, goto end; } - isp_res = kzalloc( - sizeof(*isp_res)*cmd->num_resources, GFP_KERNEL); + isp_res = kcalloc(cmd->num_resources, sizeof(*isp_res), GFP_KERNEL); if (!isp_res) { rc = -ENOMEM; goto end; diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index cb39d176a375..fe2bc05f3016 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -4664,6 +4664,7 @@ static int cam_ife_mgr_dump(void *hw_mgr_priv, void *args) int i; int rc = 0; + memset(&isp_hw_dump_args, 0, sizeof(isp_hw_dump_args)); rc = cam_mem_get_cpu_buf(dump_args->buf_handle, &isp_hw_dump_args.cpu_addr, &isp_hw_dump_args.buf_len); diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c index e6a0e015963c..b91fae3cabf7 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c @@ -152,16 +152,18 @@ int cam_irq_controller_init(const char *name, return -ENOMEM; } - controller->irq_register_arr = kzalloc(register_info->num_registers * - sizeof(struct cam_irq_register_obj), GFP_KERNEL); + controller->irq_register_arr = kcalloc(register_info->num_registers, + sizeof(struct cam_irq_register_obj), + GFP_KERNEL); if (!controller->irq_register_arr) { CAM_DBG(CAM_IRQ_CTRL, "Failed to allocate IRQ register Arr"); rc = -ENOMEM; goto reg_alloc_error; } - controller->irq_status_arr = kzalloc(register_info->num_registers * - sizeof(uint32_t), GFP_KERNEL); + controller->irq_status_arr = kcalloc(register_info->num_registers, + sizeof(uint32_t), + GFP_KERNEL); if (!controller->irq_status_arr) { CAM_DBG(CAM_IRQ_CTRL, "Failed to allocate IRQ status Arr"); rc = -ENOMEM; @@ -169,8 +171,8 @@ int cam_irq_controller_init(const char *name, } controller->th_payload.evt_status_arr = - kzalloc(register_info->num_registers * sizeof(uint32_t), - GFP_KERNEL); + kcalloc(register_info->num_registers, sizeof(uint32_t), + GFP_KERNEL); if (!controller->th_payload.evt_status_arr) { CAM_DBG(CAM_IRQ_CTRL, "Failed to allocate BH payload bit mask Arr"); @@ -293,8 +295,9 @@ int cam_irq_controller_subscribe_irq(void *irq_controller, return -ENOMEM; } - evt_handler->evt_bit_mask_arr = kzalloc(sizeof(uint32_t) * - controller->num_registers, GFP_KERNEL); + evt_handler->evt_bit_mask_arr = kcalloc(controller->num_registers, + sizeof(uint32_t), + GFP_KERNEL); if (!evt_handler->evt_bit_mask_arr) { CAM_DBG(CAM_IRQ_CTRL, "Error allocating hlist_node"); rc = -ENOMEM; diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c index 3b8fef965fd0..b100a14a83b9 100644 --- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -46,6 +46,112 @@ static struct cam_jpeg_hw_mgr g_jpeg_hw_mgr; static int32_t cam_jpeg_hw_mgr_cb(uint32_t irq_status, int32_t result_size, void *data); static int cam_jpeg_mgr_process_cmd(void *priv, void *data); +static int cam_jpeg_insert_cdm_change_base( + struct cam_hw_config_args *config_args, + struct cam_jpeg_hw_ctx_data *ctx_data, + struct cam_jpeg_hw_mgr *hw_mgr); + +static int cam_jpeg_process_next_hw_update(void *priv, void *data) +{ + int rc; + int i = 0; + struct cam_jpeg_hw_mgr *hw_mgr = priv; + struct cam_hw_update_entry *cmd; + struct cam_cdm_bl_request *cdm_cmd; + struct cam_hw_config_args *config_args = NULL; + struct cam_jpeg_hw_ctx_data *ctx_data = NULL; + uint32_t dev_type; + struct cam_jpeg_hw_cfg_req *p_cfg_req = NULL; + uint32_t cdm_cfg_to_insert = 0; + + if (!data || !priv) { + CAM_ERR(CAM_JPEG, "Invalid data"); + return -EINVAL; + } + + ctx_data = (struct cam_jpeg_hw_ctx_data *)data; + dev_type = ctx_data->jpeg_dev_acquire_info.dev_type; + p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0]; + config_args = (struct cam_hw_config_args *)&p_cfg_req->hw_cfg_args; + + if (!hw_mgr->devices[dev_type][0]->hw_ops.reset) { + CAM_ERR(CAM_JPEG, "op reset null "); + rc = -EFAULT; + goto end_error; + } + rc = hw_mgr->devices[dev_type][0]->hw_ops.reset( + hw_mgr->devices[dev_type][0]->hw_priv, + NULL, 0); + if (rc) { + CAM_ERR(CAM_JPEG, "jpeg hw reset failed %d", rc); + goto end_error; + } + + cdm_cmd = ctx_data->cdm_cmd; + cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE; + cdm_cmd->flag = false; + cdm_cmd->userdata = NULL; + cdm_cmd->cookie = 0; + cdm_cmd->cmd_arrary_count = 0; + + /* insert cdm chage base cmd */ + rc = cam_jpeg_insert_cdm_change_base(config_args, + ctx_data, hw_mgr); + if (rc) { + CAM_ERR(CAM_JPEG, "insert change base failed %d", rc); + goto end_error; + } + + /* insert next cdm payload at index */ + /* for enc or dma 1st pass at index 1 */ + /* for dma 2nd pass at index 2, for 3rd at 4 */ + if (p_cfg_req->num_hw_entry_processed == 0) + cdm_cfg_to_insert = CAM_JPEG_CFG; + else + cdm_cfg_to_insert = p_cfg_req->num_hw_entry_processed + 2; + + CAM_DBG(CAM_JPEG, "processed %d total %d using cfg entry %d for %pK", + p_cfg_req->num_hw_entry_processed, + config_args->num_hw_update_entries, + cdm_cfg_to_insert, + p_cfg_req); + + cmd = (config_args->hw_update_entries + cdm_cfg_to_insert); + cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].bl_addr.mem_handle = + cmd->handle; + cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].offset = + cmd->offset; + cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].len = + cmd->len; + CAM_DBG(CAM_JPEG, "i %d entry h %d o %d l %d", + i, cmd->handle, cmd->offset, cmd->len); + cdm_cmd->cmd_arrary_count++; + + rc = cam_cdm_submit_bls( + hw_mgr->cdm_info[dev_type][0].cdm_handle, + cdm_cmd); + if (rc) { + CAM_ERR(CAM_JPEG, "Failed to apply the configs %d", rc); + goto end_error; + } + + if (!hw_mgr->devices[dev_type][0]->hw_ops.start) { + CAM_ERR(CAM_JPEG, "op start null "); + rc = -EINVAL; + goto end_error; + } + rc = hw_mgr->devices[dev_type][0]->hw_ops.start( + hw_mgr->devices[dev_type][0]->hw_priv, NULL, 0); + if (rc) { + CAM_ERR(CAM_JPEG, "Failed to apply the configs %d", + rc); + goto end_error; + } + + return 0; +end_error: + return rc; +} static int cam_jpeg_mgr_process_irq(void *priv, void *data) { @@ -93,6 +199,21 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data) return -EINVAL; } + p_cfg_req->num_hw_entry_processed++; + CAM_DBG(CAM_JPEG, "hw entry processed %d", + p_cfg_req->num_hw_entry_processed); + + if ((task_data->result_size > 0) && + (p_cfg_req->num_hw_entry_processed < + p_cfg_req->hw_cfg_args.num_hw_update_entries - 2)) { + /* start processing next entry before marking device free */ + rc = cam_jpeg_process_next_hw_update(priv, ctx_data); + if (!rc) { + mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex); + return 0; + } + } + irq_cb.jpeg_hw_mgr_cb = cam_jpeg_hw_mgr_cb; irq_cb.data = NULL; irq_cb.b_set_cb = false; @@ -159,7 +280,9 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data) if ((p_cfg_req->hw_cfg_args.hw_update_entries[CAM_JPEG_PARAM].offset / sizeof(uint32_t)) >= cmd_buf_len) { - CAM_ERR(CAM_JPEG, "Not enough buf"); + CAM_ERR(CAM_JPEG, "Invalid offset: %u cmd buf len: %zu", + p_cfg_req->hw_cfg_args.hw_update_entries[ + CAM_JPEG_PARAM].offset, cmd_buf_len); return -EINVAL; } @@ -288,7 +411,9 @@ static int cam_jpeg_insert_cdm_change_base( if (config_args->hw_update_entries[CAM_JPEG_CHBASE].offset >= ch_base_len) { - CAM_ERR(CAM_JPEG, "Not enough buf"); + CAM_ERR(CAM_JPEG, "Not enough buf offset %d len %d", + config_args->hw_update_entries[CAM_JPEG_CHBASE].offset, + ch_base_len); return -EINVAL; } CAM_DBG(CAM_JPEG, "iova %pK len %zu offset %d", @@ -327,8 +452,6 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data) int rc; int i = 0; struct cam_jpeg_hw_mgr *hw_mgr = priv; - struct cam_hw_update_entry *cmd; - struct cam_cdm_bl_request *cdm_cmd; struct cam_hw_config_args *config_args = NULL; struct cam_jpeg_hw_ctx_data *ctx_data = NULL; uintptr_t request_id = 0; @@ -430,68 +553,14 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data) goto end_callcb; } - if (!hw_mgr->devices[dev_type][0]->hw_ops.reset) { - CAM_ERR(CAM_JPEG, "op reset null "); - rc = -EFAULT; - goto end_callcb; - } - rc = hw_mgr->devices[dev_type][0]->hw_ops.reset( - hw_mgr->devices[dev_type][0]->hw_priv, - NULL, 0); + /* insert one of the cdm payloads */ + rc = cam_jpeg_process_next_hw_update(priv, ctx_data); if (rc) { - CAM_ERR(CAM_JPEG, "jpeg hw reset failed %d", rc); + CAM_ERR(CAM_JPEG, "next hw update failed %d", rc); goto end_callcb; } - cdm_cmd = ctx_data->cdm_cmd; - cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE; - cdm_cmd->flag = false; - cdm_cmd->userdata = NULL; - cdm_cmd->cookie = 0; - cdm_cmd->cmd_arrary_count = 0; - rc = cam_jpeg_insert_cdm_change_base(config_args, - ctx_data, hw_mgr); - if (rc) { - CAM_ERR(CAM_JPEG, "insert change base failed %d", rc); - goto end_callcb; - } - - CAM_DBG(CAM_JPEG, "num hw up %d", config_args->num_hw_update_entries); - for (i = CAM_JPEG_CFG; i < (config_args->num_hw_update_entries - 1); - i++) { - cmd = (config_args->hw_update_entries + i); - cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].bl_addr.mem_handle - = cmd->handle; - cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].offset = - cmd->offset; - cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].len = - cmd->len; - CAM_DBG(CAM_JPEG, "i %d entry h %d o %d l %d", - i, cmd->handle, cmd->offset, cmd->len); - cdm_cmd->cmd_arrary_count++; - } - - rc = cam_cdm_submit_bls( - hw_mgr->cdm_info[dev_type][0].cdm_handle, cdm_cmd); - if (rc) { - CAM_ERR(CAM_JPEG, "Failed to apply the configs %d", rc); - goto rel_cpu_buf; - } - - if (!hw_mgr->devices[dev_type][0]->hw_ops.start) { - CAM_ERR(CAM_JPEG, "op start null "); - rc = -EINVAL; - goto rel_cpu_buf; - } - rc = hw_mgr->devices[dev_type][0]->hw_ops.start( - hw_mgr->devices[dev_type][0]->hw_priv, - NULL, 0); - if (rc) { - CAM_ERR(CAM_JPEG, "Failed to start hw %d", - rc); - goto rel_cpu_buf; - } cam_common_util_get_curr_timestamp(&p_cfg_req->submit_timestamp); if (cam_mem_put_cpu_buf( config_args->hw_update_entries[CAM_JPEG_CHBASE].handle)) @@ -501,11 +570,6 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data) mutex_unlock(&hw_mgr->hw_mgr_mutex); return rc; -rel_cpu_buf: - if (cam_mem_put_cpu_buf( - config_args->hw_update_entries[CAM_JPEG_CHBASE].handle)) - CAM_WARN(CAM_JPEG, "unable to put info for cmd buf: 0x%x", - config_args->hw_update_entries[CAM_JPEG_CHBASE].handle); end_callcb: mutex_unlock(&hw_mgr->hw_mgr_mutex); if (p_cfg_req) { @@ -578,6 +642,7 @@ static int cam_jpeg_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args) request_id = (uintptr_t)config_args->priv; p_cfg_req->req_id = request_id; + p_cfg_req->num_hw_entry_processed = 0; hw_update_entries = config_args->hw_update_entries; CAM_DBG(CAM_JPEG, "ctx_data = %pK req_id = %lld %zd", ctx_data, request_id, (uintptr_t)config_args->priv); @@ -797,6 +862,7 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv, i, io_cfg_ptr[i].direction, io_cfg_ptr[i].fence); } + CAM_DBG(CAM_JPEG, "received num cmd buf %d", packet->num_cmd_buf); j = prepare_args->num_hw_update_entries; rc = cam_packet_util_get_kmd_buffer(packet, &kmd_buf); @@ -1103,6 +1169,7 @@ hw_dump: p_cfg_req->submit_timestamp.tv_usec, cur_time.tv_sec, cur_time.tv_usec); + memset(&jpeg_dump_args, 0, sizeof(jpeg_dump_args)); rc = cam_mem_get_cpu_buf(dump_args->buf_handle, &jpeg_dump_args.cpu_addr, &jpeg_dump_args.buf_len); if (!jpeg_dump_args.cpu_addr || !jpeg_dump_args.buf_len || rc) { @@ -1443,8 +1510,9 @@ static int cam_jpeg_setup_workqs(void) g_jpeg_hw_mgr.process_frame_work_data = (struct cam_jpeg_process_frame_work_data_t *) - kzalloc(sizeof(struct cam_jpeg_process_frame_work_data_t) * - CAM_JPEG_WORKQ_NUM_TASK, GFP_KERNEL); + kcalloc(CAM_JPEG_WORKQ_NUM_TASK, + sizeof(struct cam_jpeg_process_frame_work_data_t), + GFP_KERNEL); if (!g_jpeg_hw_mgr.process_frame_work_data) { rc = -ENOMEM; goto work_process_frame_data_failed; @@ -1452,8 +1520,9 @@ static int cam_jpeg_setup_workqs(void) g_jpeg_hw_mgr.process_irq_cb_work_data = (struct cam_jpeg_process_irq_work_data_t *) - kzalloc(sizeof(struct cam_jpeg_process_irq_work_data_t) * - CAM_JPEG_WORKQ_NUM_TASK, GFP_KERNEL); + kcalloc(CAM_JPEG_WORKQ_NUM_TASK, + sizeof(struct cam_jpeg_process_irq_work_data_t), + GFP_KERNEL); if (!g_jpeg_hw_mgr.process_irq_cb_work_data) { rc = -ENOMEM; goto work_process_irq_cb_data_failed; @@ -1522,8 +1591,9 @@ static int cam_jpeg_init_devices(struct device_node *of_node, CAM_ERR(CAM_JPEG, "read num enc devices failed %d", rc); goto num_enc_failed; } - g_jpeg_hw_mgr.devices[CAM_JPEG_DEV_ENC] = kzalloc( - sizeof(struct cam_hw_intf *) * num_dev, GFP_KERNEL); + g_jpeg_hw_mgr.devices[CAM_JPEG_DEV_ENC] = kcalloc(num_dev, + sizeof(struct cam_hw_intf *), + GFP_KERNEL); if (!g_jpeg_hw_mgr.devices[CAM_JPEG_DEV_ENC]) { rc = -ENOMEM; CAM_ERR(CAM_JPEG, "getting number of dma dev nodes failed"); @@ -1536,8 +1606,9 @@ static int cam_jpeg_init_devices(struct device_node *of_node, goto num_dma_failed; } - g_jpeg_hw_mgr.devices[CAM_JPEG_DEV_DMA] = kzalloc( - sizeof(struct cam_hw_intf *) * num_dma_dev, GFP_KERNEL); + g_jpeg_hw_mgr.devices[CAM_JPEG_DEV_DMA] = kcalloc(num_dma_dev, + sizeof(struct cam_hw_intf *), + GFP_KERNEL); if (!g_jpeg_hw_mgr.devices[CAM_JPEG_DEV_DMA]) { rc = -ENOMEM; goto num_dma_failed; diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h index 2dc11dfa0746..3f317524611f 100644 --- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h +++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -83,6 +83,7 @@ struct cam_jpeg_hw_cdm_info_t { * @dev_type: Dev type for cfg request * @req_id: Request Id * @submit_timestamp: Timestamp of submitting request + * @num_hw_entry_processed: Cdm payloads already processed */ struct cam_jpeg_hw_cfg_req { struct list_head list; @@ -90,6 +91,7 @@ struct cam_jpeg_hw_cfg_req { uint32_t dev_type; uintptr_t req_id; struct timeval submit_timestamp; + uint32_t num_hw_entry_processed; }; /** diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/cam_jpeg_dma_hw_info_ver_4_2_0.h b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/cam_jpeg_dma_hw_info_ver_4_2_0.h new file mode 100644 index 000000000000..ff8997bd4615 --- /dev/null +++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/cam_jpeg_dma_hw_info_ver_4_2_0.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef CAM_JPEG_DMA_HW_INFO_VER_4_2_0_H +#define CAM_JPEG_DMA_HW_INFO_VER_4_2_0_H + +#define CAM_JPEGDMA_HW_IRQ_STATUS_SESSION_DONE (1 << 0) +#define CAM_JPEGDMA_HW_IRQ_STATUS_RD_BUF_DONE (1 << 1) +#define CAM_JPEGDMA_HW_IRQ_STATUS_WR_BUF_DONE (1 << 5) +#define CAM_JPEGDMA_HW_IRQ_STATUS_AXI_HALT (1 << 9) +#define CAM_JPEGDMA_HW_IRQ_STATUS_RST_DONE (1 << 10) + +#define CAM_JPEGDMA_HW_MASK_COMP_FRAMEDONE \ + CAM_JPEGDMA_HW_IRQ_STATUS_SESSION_DONE +#define CAM_JPEGDMA_HW_MASK_COMP_RESET_ACK \ + CAM_JPEGDMA_HW_IRQ_STATUS_RST_DONE + +static struct cam_jpeg_dma_device_hw_info cam_jpeg_dma_hw_info = { + .reg_offset = { + .hw_version = 0x0, + .int_clr = 0x14, + .int_status = 0x10, + .int_mask = 0x0C, + .hw_cmd = 0x1C, + .reset_cmd = 0x08, + .encode_size = 0x180, + }, + .reg_val = { + .int_clr_clearall = 0xFFFFFFFF, + .int_mask_disable_all = 0x00000000, + .int_mask_enable_all = 0xFFFFFFFF, + .hw_cmd_start = 0x00000001, + .reset_cmd = 0x32083, + .hw_cmd_stop = 0x00000004, + }, + .int_status = { + .framedone = CAM_JPEGDMA_HW_MASK_COMP_FRAMEDONE, + .resetdone = CAM_JPEGDMA_HW_MASK_COMP_RESET_ACK, + .iserror = 0x0, + .stopdone = CAM_JPEGDMA_HW_IRQ_STATUS_AXI_HALT, + } +}; + +#endif /* CAM_JPEG_DMA_HW_INFO_VER_4_2_0_H */ diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c index 037a39e5eb12..169a027d95ff 100644 --- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c +++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -31,6 +31,15 @@ #include "cam_cpas_api.h" #include "cam_debug_util.h" +#define CAM_JPEG_HW_IRQ_IS_FRAME_DONE(jpeg_irq_status, hi) \ + ((jpeg_irq_status) & (hi)->int_status.framedone) +#define CAM_JPEG_HW_IRQ_IS_RESET_ACK(jpeg_irq_status, hi) \ + ((jpeg_irq_status) & (hi)->int_status.resetdone) +#define CAM_JPEG_HW_IRQ_IS_STOP_DONE(jpeg_irq_status, hi) \ + ((jpeg_irq_status) & (hi)->int_status.stopdone) + +#define CAM_JPEG_DMA_RESET_TIMEOUT msecs_to_jiffies(500) + int cam_jpeg_dma_init_hw(void *device_priv, void *init_hw_args, uint32_t arg_size) { @@ -131,7 +140,7 @@ int cam_jpeg_dma_deinit_hw(void *device_priv, rc = cam_jpeg_dma_disable_soc_resources(soc_info); if (rc) - CAM_ERR(CAM_JPEG, "soc enable failed %d", rc); + CAM_ERR(CAM_JPEG, "soc disable failed %d", rc); rc = cam_cpas_stop(core_info->cpas_handle); if (rc) @@ -142,6 +151,226 @@ int cam_jpeg_dma_deinit_hw(void *device_priv, return 0; } +irqreturn_t cam_jpeg_dma_irq(int irq_num, void *data) +{ + struct cam_hw_info *jpeg_dma_dev = data; + struct cam_jpeg_dma_device_core_info *core_info = NULL; + uint32_t irq_status = 0; + struct cam_hw_soc_info *soc_info = NULL; + struct cam_jpeg_dma_device_hw_info *hw_info = NULL; + void __iomem *mem_base; + + if (!jpeg_dma_dev) { + CAM_ERR(CAM_JPEG, "Invalid args"); + return IRQ_HANDLED; + } + soc_info = &jpeg_dma_dev->soc_info; + core_info = (struct cam_jpeg_dma_device_core_info *) + jpeg_dma_dev->core_info; + hw_info = core_info->jpeg_dma_hw_info; + mem_base = soc_info->reg_map[0].mem_base; + + irq_status = cam_io_r_mb(mem_base + + core_info->jpeg_dma_hw_info->reg_offset.int_status); + cam_io_w_mb(irq_status, + soc_info->reg_map[0].mem_base + + core_info->jpeg_dma_hw_info->reg_offset.int_clr); + CAM_DBG(CAM_JPEG, "irq_num %d irq_status = %x , core_state %d", + irq_num, irq_status, core_info->core_state); + if (CAM_JPEG_HW_IRQ_IS_FRAME_DONE(irq_status, hw_info)) { + spin_lock(&jpeg_dma_dev->hw_lock); + if (core_info->core_state == CAM_JPEG_DMA_CORE_READY) { + core_info->result_size = 1; + CAM_DBG(CAM_JPEG, "result_size %d", + core_info->result_size); + core_info->core_state = + CAM_JPEG_DMA_CORE_RESETTING_ON_DONE; + cam_io_w_mb(hw_info->reg_val.reset_cmd, + mem_base + hw_info->reg_offset.reset_cmd); + } else { + CAM_WARN(CAM_JPEG, "unexpected frame done "); + core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY; + } + spin_unlock(&jpeg_dma_dev->hw_lock); + } + + if (CAM_JPEG_HW_IRQ_IS_RESET_ACK(irq_status, hw_info)) { + spin_lock(&jpeg_dma_dev->hw_lock); + if (core_info->core_state == CAM_JPEG_DMA_CORE_RESETTING) { + core_info->core_state = CAM_JPEG_DMA_CORE_READY; + core_info->result_size = -1; + complete(&jpeg_dma_dev->hw_complete); + } else if (core_info->core_state == + CAM_JPEG_DMA_CORE_RESETTING_ON_DONE) { + if (core_info->irq_cb.jpeg_hw_mgr_cb) { + core_info->irq_cb.jpeg_hw_mgr_cb(irq_status, + core_info->result_size, + core_info->irq_cb.data); + } else { + CAM_WARN(CAM_JPEG, "unexpected frame done"); + } + core_info->result_size = -1; + core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY; + } else { + CAM_ERR(CAM_JPEG, "unexpected reset irq"); + } + spin_unlock(&jpeg_dma_dev->hw_lock); + } + if (CAM_JPEG_HW_IRQ_IS_STOP_DONE(irq_status, hw_info)) { + spin_lock(&jpeg_dma_dev->hw_lock); + if (core_info->core_state == CAM_JPEG_DMA_CORE_ABORTING) { + core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY; + complete(&jpeg_dma_dev->hw_complete); + if (core_info->irq_cb.jpeg_hw_mgr_cb) { + core_info->irq_cb.jpeg_hw_mgr_cb(irq_status, + -1, + core_info->irq_cb.data); + } + } else { + CAM_ERR(CAM_JPEG, "unexpected abort irq"); + } + spin_unlock(&jpeg_dma_dev->hw_lock); + } + + return IRQ_HANDLED; +} + +int cam_jpeg_dma_reset_hw(void *data, + void *start_args, uint32_t arg_size) +{ + struct cam_hw_info *jpeg_dma_dev = data; + struct cam_jpeg_dma_device_core_info *core_info = NULL; + struct cam_hw_soc_info *soc_info = NULL; + struct cam_jpeg_dma_device_hw_info *hw_info = NULL; + void __iomem *mem_base; + unsigned long rem_jiffies; + + if (!jpeg_dma_dev) { + CAM_ERR(CAM_JPEG, "Invalid args"); + return -EINVAL; + } + /* maskdisable.clrirq.maskenable.resetcmd */ + soc_info = &jpeg_dma_dev->soc_info; + core_info = (struct cam_jpeg_dma_device_core_info *) + jpeg_dma_dev->core_info; + hw_info = core_info->jpeg_dma_hw_info; + mem_base = soc_info->reg_map[0].mem_base; + + mutex_lock(&core_info->core_mutex); + spin_lock(&jpeg_dma_dev->hw_lock); + if (core_info->core_state == CAM_JPEG_DMA_CORE_RESETTING) { + CAM_ERR(CAM_JPEG, "dma alrady resetting"); + spin_unlock(&jpeg_dma_dev->hw_lock); + mutex_unlock(&core_info->core_mutex); + return 0; + } + + reinit_completion(&jpeg_dma_dev->hw_complete); + + core_info->core_state = CAM_JPEG_DMA_CORE_RESETTING; + spin_unlock(&jpeg_dma_dev->hw_lock); + + cam_io_w_mb(hw_info->reg_val.int_mask_disable_all, + mem_base + hw_info->reg_offset.int_mask); + cam_io_w_mb(hw_info->reg_val.int_clr_clearall, + mem_base + hw_info->reg_offset.int_clr); + cam_io_w_mb(hw_info->reg_val.int_mask_enable_all, + mem_base + hw_info->reg_offset.int_mask); + cam_io_w_mb(hw_info->reg_val.reset_cmd, + mem_base + hw_info->reg_offset.reset_cmd); + + rem_jiffies = wait_for_completion_timeout(&jpeg_dma_dev->hw_complete, + CAM_JPEG_DMA_RESET_TIMEOUT); + if (!rem_jiffies) { + CAM_ERR(CAM_JPEG, "dma error Reset Timeout"); + core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY; + } + + mutex_unlock(&core_info->core_mutex); + return 0; +} + +int cam_jpeg_dma_start_hw(void *data, + void *start_args, uint32_t arg_size) +{ + struct cam_hw_info *jpeg_dma_dev = data; + struct cam_jpeg_dma_device_core_info *core_info = NULL; + struct cam_hw_soc_info *soc_info = NULL; + struct cam_jpeg_dma_device_hw_info *hw_info = NULL; + void __iomem *mem_base; + + if (!jpeg_dma_dev) { + CAM_ERR(CAM_JPEG, "Invalid args"); + return -EINVAL; + } + + soc_info = &jpeg_dma_dev->soc_info; + core_info = (struct cam_jpeg_dma_device_core_info *) + jpeg_dma_dev->core_info; + hw_info = core_info->jpeg_dma_hw_info; + mem_base = soc_info->reg_map[0].mem_base; + + if (core_info->core_state != CAM_JPEG_DMA_CORE_READY) { + CAM_ERR(CAM_JPEG, "Error not ready"); + return -EINVAL; + } + + CAM_DBG(CAM_JPEG, "Starting DMA"); + cam_io_w_mb(0x00000601, + mem_base + hw_info->reg_offset.int_mask); + cam_io_w_mb(hw_info->reg_val.hw_cmd_start, + mem_base + hw_info->reg_offset.hw_cmd); + + return 0; +} + +int cam_jpeg_dma_stop_hw(void *data, + void *stop_args, uint32_t arg_size) +{ + struct cam_hw_info *jpeg_dma_dev = data; + struct cam_jpeg_dma_device_core_info *core_info = NULL; + struct cam_hw_soc_info *soc_info = NULL; + struct cam_jpeg_dma_device_hw_info *hw_info = NULL; + void __iomem *mem_base; + unsigned long rem_jiffies; + + if (!jpeg_dma_dev) { + CAM_ERR(CAM_JPEG, "Invalid args"); + return -EINVAL; + } + soc_info = &jpeg_dma_dev->soc_info; + core_info = (struct cam_jpeg_dma_device_core_info *) + jpeg_dma_dev->core_info; + hw_info = core_info->jpeg_dma_hw_info; + mem_base = soc_info->reg_map[0].mem_base; + + mutex_lock(&core_info->core_mutex); + spin_lock(&jpeg_dma_dev->hw_lock); + if (core_info->core_state == CAM_JPEG_DMA_CORE_ABORTING) { + CAM_ERR(CAM_JPEG, "alrady stopping"); + spin_unlock(&jpeg_dma_dev->hw_lock); + mutex_unlock(&core_info->core_mutex); + return 0; + } + + reinit_completion(&jpeg_dma_dev->hw_complete); + core_info->core_state = CAM_JPEG_DMA_CORE_ABORTING; + spin_unlock(&jpeg_dma_dev->hw_lock); + + cam_io_w_mb(hw_info->reg_val.hw_cmd_stop, + mem_base + hw_info->reg_offset.hw_cmd); + + rem_jiffies = wait_for_completion_timeout(&jpeg_dma_dev->hw_complete, + CAM_JPEG_DMA_RESET_TIMEOUT); + if (!rem_jiffies) { + CAM_ERR(CAM_JPEG, "error Reset Timeout"); + core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY; + } + + mutex_unlock(&core_info->core_mutex); + return 0; +} + int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type, void *cmd_args, uint32_t arg_size) { @@ -186,12 +415,7 @@ int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type, rc = -EINVAL; break; } - + if (rc) + CAM_ERR(CAM_JPEG, "error cmdtype %d rc = %d", cmd_type, rc); return rc; } - -irqreturn_t cam_jpeg_dma_irq(int irq_num, void *data) -{ - return IRQ_HANDLED; -} - diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.h b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.h index 8f5fd58698d2..737c2f217feb 100644 --- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.h +++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018,2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -21,14 +21,44 @@ #include "cam_jpeg_hw_intf.h" +struct cam_jpeg_dma_reg_offsets { + uint32_t hw_version; + uint32_t int_status; + uint32_t int_clr; + uint32_t int_mask; + uint32_t hw_cmd; + uint32_t reset_cmd; + uint32_t encode_size; +}; + +struct cam_jpeg_dma_regval { + uint32_t int_clr_clearall; + uint32_t int_mask_disable_all; + uint32_t int_mask_enable_all; + uint32_t hw_cmd_start; + uint32_t reset_cmd; + uint32_t hw_cmd_stop; +}; + +struct cam_jpeg_dma_int_status { + uint32_t framedone; + uint32_t resetdone; + uint32_t iserror; + uint32_t stopdone; +}; + struct cam_jpeg_dma_device_hw_info { - uint32_t reserved; + struct cam_jpeg_dma_reg_offsets reg_offset; + struct cam_jpeg_dma_regval reg_val; + struct cam_jpeg_dma_int_status int_status; }; enum cam_jpeg_dma_core_state { CAM_JPEG_DMA_CORE_NOT_READY, CAM_JPEG_DMA_CORE_READY, CAM_JPEG_DMA_CORE_RESETTING, + CAM_JPEG_DMA_CORE_ABORTING, + CAM_JPEG_DMA_CORE_RESETTING_ON_DONE, CAM_JPEG_DMA_CORE_STATE_MAX, }; @@ -39,12 +69,19 @@ struct cam_jpeg_dma_device_core_info { struct cam_jpeg_set_irq_cb irq_cb; int32_t ref_count; struct mutex core_mutex; + int32_t result_size; }; int cam_jpeg_dma_init_hw(void *device_priv, void *init_hw_args, uint32_t arg_size); int cam_jpeg_dma_deinit_hw(void *device_priv, void *init_hw_args, uint32_t arg_size); +int cam_jpeg_dma_start_hw(void *device_priv, + void *start_hw_args, uint32_t arg_size); +int cam_jpeg_dma_stop_hw(void *device_priv, + void *stop_hw_args, uint32_t arg_size); +int cam_jpeg_dma_reset_hw(void *device_priv, + void *reset_hw_args, uint32_t arg_size); int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type, void *cmd_args, uint32_t arg_size); irqreturn_t cam_jpeg_dma_irq(int irq_num, void *data); diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c index fd4fdab19fa7..f91eee863352 100644 --- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c +++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018,2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -25,11 +25,7 @@ #include "cam_jpeg_hw_mgr_intf.h" #include "cam_cpas_api.h" #include "cam_debug_util.h" - -static struct cam_jpeg_dma_device_hw_info cam_jpeg_dma_hw_info = { - .reserved = 0, -}; -EXPORT_SYMBOL(cam_jpeg_dma_hw_info); +#include "cam_jpeg_dma_hw_info_ver_4_2_0.h" static int cam_jpeg_dma_register_cpas(struct cam_hw_soc_info *soc_info, struct cam_jpeg_dma_device_core_info *core_info, @@ -142,6 +138,9 @@ static int cam_jpeg_dma_probe(struct platform_device *pdev) jpeg_dma_dev_intf->hw_priv = jpeg_dma_dev; jpeg_dma_dev_intf->hw_ops.init = cam_jpeg_dma_init_hw; jpeg_dma_dev_intf->hw_ops.deinit = cam_jpeg_dma_deinit_hw; + jpeg_dma_dev_intf->hw_ops.start = cam_jpeg_dma_start_hw; + jpeg_dma_dev_intf->hw_ops.stop = cam_jpeg_dma_stop_hw; + jpeg_dma_dev_intf->hw_ops.reset = cam_jpeg_dma_reset_hw; jpeg_dma_dev_intf->hw_ops.process_cmd = cam_jpeg_dma_process_cmd; jpeg_dma_dev_intf->hw_type = CAM_JPEG_DEV_DMA; @@ -186,13 +185,11 @@ static int cam_jpeg_dma_probe(struct platform_device *pdev) mutex_init(&jpeg_dma_dev->hw_mutex); spin_lock_init(&jpeg_dma_dev->hw_lock); init_completion(&jpeg_dma_dev->hw_complete); - - CAM_DBG(CAM_JPEG, " hwidx %d", jpeg_dma_dev_intf->hw_idx); - + CAM_DBG(CAM_JPEG, "JPEG-DMA component bound successfully"); return rc; error_reg_cpas: - rc = cam_soc_util_release_platform_resource(&jpeg_dma_dev->soc_info); + cam_soc_util_release_platform_resource(&jpeg_dma_dev->soc_info); error_init_soc: mutex_destroy(&core_info->core_mutex); error_match_dev: diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c index 54dd62c44f67..196742d06448 100644 --- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c +++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -350,7 +350,7 @@ int cam_jpeg_enc_start_hw(void *data, return -EINVAL; } spin_unlock(&jpeg_enc_dev->hw_lock); - + CAM_DBG(CAM_JPEG, "Starting JPEG ENC"); cam_io_w_mb(hw_info->reg_val.hw_cmd_start, mem_base + hw_info->reg_offset.hw_cmd); diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c index d4daa6dde308..be703d6c3055 100644 --- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c +++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018,2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -185,7 +185,7 @@ static int cam_jpeg_enc_probe(struct platform_device *pdev) mutex_init(&jpeg_enc_dev->hw_mutex); spin_lock_init(&jpeg_enc_dev->hw_lock); init_completion(&jpeg_enc_dev->hw_complete); - + CAM_DBG(CAM_JPEG, "JPEG-Encoder component bound successfully"); return rc; error_reg_cpas: diff --git a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c index f6fa30c7c646..cb03a57acd36 100644 --- a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c @@ -695,6 +695,7 @@ static int cam_lrme_mgr_hw_dump(void *hw_mgr_priv, void *hw_dump_args) CAM_ERR(CAM_LRME, "Failed to get hw device"); return rc; } + memset(&lrme_dump_args, 0, sizeof(lrme_dump_args)); rc = cam_mem_get_cpu_buf(dump_args->buf_handle, &lrme_dump_args.cpu_addr, &lrme_dump_args.buf_len); diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c index f1ba6b0e79e3..1ffa918d50c1 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c @@ -696,13 +696,19 @@ static int32_t __cam_req_mgr_find_slot_for_req( */ static int __cam_req_mgr_check_sync_for_mslave( struct cam_req_mgr_core_link *link, - struct cam_req_mgr_slot *slot) + struct cam_req_mgr_slot *slot, + uint64_t request_id) { struct cam_req_mgr_core_link *sync_link = NULL; struct cam_req_mgr_slot *sync_slot = NULL; + struct cam_req_mgr_slot *sync_rd_slot = NULL; int sync_slot_idx = 0, prev_idx, next_idx, rd_idx, sync_rd_idx, rc = 0; int64_t req_id = 0, sync_req_id = 0; int32_t sync_num_slots = 0; + uint64_t sync_frame_duration = 0; + int32_t sync_req_status = 0; + uint64_t sof_timestamp_delta = 0; + int sync_link_idx = 0; if (!link->sync_link) { CAM_ERR(CAM_CRM, "Sync link null"); @@ -713,6 +719,12 @@ static int __cam_req_mgr_check_sync_for_mslave( req_id = slot->req_id; sync_num_slots = sync_link->req.in_q->num_slots; sync_rd_idx = sync_link->req.in_q->rd_idx; + sync_rd_slot = &sync_link->req.in_q->slot[sync_rd_idx]; + + sof_timestamp_delta = + link->sof_timestamp >= sync_link->sof_timestamp + ? link->sof_timestamp - sync_link->sof_timestamp + : sync_link->sof_timestamp - link->sof_timestamp; CAM_DBG(CAM_CRM, "link_hdl %x req %lld frame_skip_flag %d open_req_cnt:%d initial_sync_req [%lld,%lld] is_master:%d", @@ -742,6 +754,10 @@ static int __cam_req_mgr_check_sync_for_mslave( return -EINVAL; } + if (sync_link->prev_sof_timestamp) + sync_frame_duration = sync_link->sof_timestamp - + sync_link->prev_sof_timestamp; + if (link->is_master) { rc = __cam_req_mgr_inject_delay(link->req.l_tbl, slot->idx); if (rc) { @@ -763,7 +779,6 @@ static int __cam_req_mgr_check_sync_for_mslave( CAM_DBG(CAM_CRM, "Req: %lld [master] not ready on link: %x, rc=%d", req_id, link->link_hdl, rc); - link->sync_link_sof_skip = true; return rc; } @@ -835,10 +850,34 @@ static int __cam_req_mgr_check_sync_for_mslave( CAM_DBG(CAM_CRM, "Req: %lld [slave] not ready on link: %x, rc=%d", req_id, link->link_hdl, rc); - link->sync_link_sof_skip = true; return rc; } + sync_link_idx = __cam_req_mgr_find_slot_for_req( + sync_link->req.in_q, request_id); + if (sync_link_idx != -1) { + sync_req_status = + sync_link->req.in_q->slot[sync_link_idx].status; + if (sync_req_status != CRM_SLOT_STATUS_REQ_APPLIED) { + CAM_DBG(CAM_CRM, + "Skipping initial sync req %lld id %d as master not applied", + request_id, sync_link_idx); + return -EINVAL; + } + } else + sync_req_status = 0; + + if ((sync_link->initial_sync_req == req_id) && + (sync_req_status == CRM_SLOT_STATUS_REQ_APPLIED) && + (sof_timestamp_delta < (sync_frame_duration / 2)) && + (((sync_link_idx - sync_rd_idx + sync_num_slots) % + sync_num_slots) <= 1) && + (sync_rd_slot->status != + CRM_SLOT_STATUS_REQ_APPLIED)) { + CAM_DBG(CAM_CRM, "Skipping initial sync req for slave"); + return -EINVAL; + } + next_idx = link->req.in_q->rd_idx; rd_idx = sync_link->req.in_q->rd_idx; __cam_req_mgr_inc_idx(&next_idx, @@ -1220,7 +1259,7 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, } rc = __cam_req_mgr_check_sync_for_mslave( - link, slot); + link, slot, trigger_data->req_id); } else { rc = __cam_req_mgr_check_sync_req_is_ready( link, slot); @@ -1601,8 +1640,8 @@ static int __cam_req_mgr_create_subdevs( { int rc = 0; *l_dev = (struct cam_req_mgr_connected_device *) - kzalloc(sizeof(struct cam_req_mgr_connected_device) * num_dev, - GFP_KERNEL); + kcalloc(num_dev, sizeof(struct cam_req_mgr_connected_device), + GFP_KERNEL); if (!*l_dev) rc = -ENOMEM; @@ -2223,6 +2262,42 @@ end: return rc; } +static void cam_req_mgr_process_reset_for_dual_link( + struct cam_req_mgr_core_link *link, + struct cam_req_mgr_trigger_notify *trigger_data) +{ + int32_t idx = -1; + int32_t sync_idx = -1; + struct cam_req_mgr_req_queue *in_q = NULL; + struct cam_req_mgr_req_queue *sync_in_q = NULL; + + in_q = link->req.in_q; + sync_in_q = link->sync_link->req.in_q; + + sync_idx = __cam_req_mgr_find_slot_for_req(sync_in_q, + trigger_data->req_id); + if (link->is_master) + __cam_req_mgr_dec_idx(&sync_idx, + (link->max_delay - link->sync_link->max_delay), + sync_in_q->num_slots); + else + __cam_req_mgr_inc_idx(&sync_idx, + (link->sync_link->max_delay - link->max_delay), + sync_in_q->num_slots); + if (sync_idx != -1 && + (sync_in_q->slot[sync_in_q->rd_idx].status == + CRM_SLOT_STATUS_REQ_APPLIED)) { + idx = __cam_req_mgr_find_slot_for_req(in_q, + trigger_data->req_id); + CAM_DBG(CAM_CRM, "Reset req: %lld idx: %d link_hdl: %x", + trigger_data->req_id, idx, + link->link_hdl); + if (idx == in_q->last_applied_idx) + in_q->last_applied_idx = -1; + __cam_req_mgr_reset_req_slot(link, idx); + } +} + /** * cam_req_mgr_process_trigger() * @@ -2261,12 +2336,18 @@ static int cam_req_mgr_process_trigger(void *priv, void *data) mutex_lock(&link->req.lock); if (trigger_data->trigger == CAM_TRIGGER_POINT_SOF) { - idx = __cam_req_mgr_find_slot_for_req(in_q, - trigger_data->req_id); - if (idx >= 0) { - if (idx == in_q->last_applied_idx) - in_q->last_applied_idx = -1; - __cam_req_mgr_reset_req_slot(link, idx); + if (link->sync_link && + (link->is_master || link->sync_link->is_master)) { + cam_req_mgr_process_reset_for_dual_link(link, + trigger_data); + } else { + idx = __cam_req_mgr_find_slot_for_req(in_q, + trigger_data->req_id); + if (idx >= 0) { + if (idx == in_q->last_applied_idx) + in_q->last_applied_idx = -1; + __cam_req_mgr_reset_req_slot(link, idx); + } } } @@ -2300,6 +2381,8 @@ static int cam_req_mgr_process_trigger(void *priv, void *data) CAM_DBG(CAM_REQ, "No pending req to apply to lower pd devices"); rc = 0; + __cam_req_mgr_inc_idx(&in_q->rd_idx, + 1, in_q->num_slots); goto release_lock; } __cam_req_mgr_inc_idx(&in_q->rd_idx, 1, in_q->num_slots); @@ -3190,7 +3273,7 @@ int cam_req_mgr_schedule_request( CAM_INFO(CAM_CRM, "request %lld is flushed, last_flush_id to flush %u", sched_req->req_id, link->last_flush_id); - rc = -EINVAL; + rc = -EBADR; goto end; } @@ -3429,6 +3512,8 @@ int cam_req_mgr_link_control(struct cam_req_mgr_link_control *control) struct cam_req_mgr_connected_device *dev = NULL; struct cam_req_mgr_link_evt_data evt_data; + struct cam_req_mgr_req_queue *in_q = NULL; + struct cam_req_mgr_slot *slot = NULL; if (!control) { CAM_ERR(CAM_CRM, "Control command is NULL"); @@ -3492,6 +3577,18 @@ int cam_req_mgr_link_control(struct cam_req_mgr_link_control *control) if (dev->ops && dev->ops->process_evt) dev->ops->process_evt(&evt_data); } + in_q = link->req.in_q; + /* reset all slots */ + for (j = 0; j < in_q->num_slots; j++) { + slot = &in_q->slot[j]; + slot->req_id = -1; + slot->sync_mode = + CAM_REQ_MGR_SYNC_MODE_NO_SYNC; + slot->skip_idx = 1; + slot->status = CRM_SLOT_STATUS_NO_REQ; + } + in_q->wr_idx = 0; + in_q->rd_idx = 0; } else { CAM_ERR(CAM_CRM, "Invalid link control command"); rc = -EINVAL; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_dev.c index 2c66491a944b..8c80c5e4e9e9 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_dev.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_dev.c @@ -196,8 +196,9 @@ static int32_t cam_actuator_driver_i2c_probe(struct i2c_client *client, a_ctrl->i2c_data.per_frame = (struct i2c_settings_array *) - kzalloc(sizeof(struct i2c_settings_array) * - MAX_PER_FRAME_ARRAY, GFP_KERNEL); + kcalloc(MAX_PER_FRAME_ARRAY, + sizeof(struct i2c_settings_array), + GFP_KERNEL); if (a_ctrl->i2c_data.per_frame == NULL) { rc = -ENOMEM; goto unreg_subdev; @@ -342,8 +343,9 @@ static int32_t cam_actuator_driver_platform_probe( a_ctrl->i2c_data.per_frame = (struct i2c_settings_array *) - kzalloc(sizeof(struct i2c_settings_array) * - MAX_PER_FRAME_ARRAY, GFP_KERNEL); + kcalloc(MAX_PER_FRAME_ARRAY, + sizeof(struct i2c_settings_array), + GFP_KERNEL); if (a_ctrl->i2c_data.per_frame == NULL) { rc = -ENOMEM; goto free_soc; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c index 9ab01270750d..62f9ec35874f 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c @@ -1486,8 +1486,9 @@ static int32_t cam_cci_i2c_write_async(struct v4l2_subdev *sd, } cci_i2c_write_cfg_w->reg_setting = - kzalloc(sizeof(struct cam_sensor_i2c_reg_array)* - cci_i2c_write_cfg->size, GFP_KERNEL); + kcalloc(cci_i2c_write_cfg->size, + sizeof(struct cam_sensor_i2c_reg_array), + GFP_KERNEL); if (!cci_i2c_write_cfg_w->reg_setting) { CAM_ERR(CAM_CCI, "Couldn't allocate memory"); kfree(write_async); diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c index 69b5af002610..9f8ee883355a 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -404,7 +404,7 @@ static int cam_cci_platform_probe(struct platform_device *pdev) new_cci_dev->v4l2_dev_str.name = new_cci_dev->device_name; new_cci_dev->v4l2_dev_str.sd_flags = - (V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS); + V4L2_SUBDEV_FL_HAS_EVENTS; new_cci_dev->v4l2_dev_str.ent_function = CAM_CCI_DEVICE_TYPE; new_cci_dev->v4l2_dev_str.token = diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h index accbb1cdb0a1..8d1db70a6c9e 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -317,6 +317,6 @@ static inline struct v4l2_subdev *cam_cci_get_subdev(int cci_dev_index) #endif #define VIDIOC_MSM_CCI_CFG \ - _IOWR('V', BASE_VIDIOC_PRIVATE + 23, struct cam_cci_ctrl *) + _IOWR('V', BASE_VIDIOC_PRIVATE + 23, struct cam_cci_ctrl) #endif /* _CAM_CCI_DEV_H_ */ diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_2_hwreg.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_2_hwreg.h index 51ffc1872af4..0aa91d58767a 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_2_hwreg.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_2_hwreg.h @@ -19,10 +19,10 @@ struct csiphy_reg_parms_t csiphy_v1_2_2 = { .mipi_csiphy_interrupt_status0_addr = 0x8B0, .mipi_csiphy_interrupt_clear0_addr = 0x858, .mipi_csiphy_glbl_irq_cmd_addr = 0x828, - .csiphy_common_array_size = 7, + .csiphy_common_array_size = 6, .csiphy_reset_array_size = 5, - .csiphy_2ph_config_array_size = 22, - .csiphy_3ph_config_array_size = 38, + .csiphy_2ph_config_array_size = 23, + .csiphy_3ph_config_array_size = 30, .csiphy_2ph_clock_lane = 0x1, .csiphy_2ph_combo_ck_ln = 0x10, }; @@ -30,8 +30,7 @@ struct csiphy_reg_parms_t csiphy_v1_2_2 = { struct csiphy_reg_t csiphy_common_reg_1_2_2[] = { {0x0814, 0xd5, 0x00, CSIPHY_LANE_ENABLE}, {0x0818, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x081C, 0x02, 0x00, CSIPHY_2PH_REGS}, - {0x081C, 0x52, 0x00, CSIPHY_3PH_REGS}, + {0x081C, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x03, 0x01, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x02, 0x00, CSIPHY_2PH_REGS}, {0x0800, 0x0E, 0x00, CSIPHY_3PH_REGS}, @@ -65,34 +64,34 @@ csiphy_reg_t csiphy_2ph_v1_2_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x0030, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0904, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0910, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0900, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0908, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0900, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0908, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0904, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x00C4, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x002C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0034, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0010, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x001C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0014, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0028, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0028, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x003C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0000, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0008, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, - {0x000c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x005C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0060, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { {0x0730, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0C84, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0C90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0C80, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0C88, 0x14, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0C88, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0C84, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x07C4, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x072C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0734, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0710, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -108,78 +107,83 @@ csiphy_reg_t csiphy_2ph_v1_2_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { {0x0230, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A04, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A10, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A00, 0x0B, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A08, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A00, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A08, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A04, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x02C4, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x022C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0234, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0210, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x021C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0214, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0228, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0228, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x023C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0200, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0204, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0220, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0208, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, - {0x020c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x025C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0260, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { {0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B04, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B10, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0B00, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0B08, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B00, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B08, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B04, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x04C4, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x042C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0434, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0410, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x041C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0414, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0428, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0428, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x043C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0400, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0404, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0420, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0408, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, - {0x040c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x045C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0460, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { {0x0630, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0C04, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0C10, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0C00, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0C08, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0C00, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0C08, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0C04, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x06C4, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x062C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0634, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0610, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x061C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0614, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0628, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0628, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x063C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0600, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0604, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0620, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0608, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, - {0x060c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x065C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0660, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, }; @@ -189,34 +193,34 @@ struct csiphy_reg_t {0x0030, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0904, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0910, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0900, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0908, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0900, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0908, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0904, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x00C4, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x002C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0034, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0010, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x001C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0014, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0028, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x003C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0000, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0008, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, - {0x000c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x005C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0060, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { {0x0730, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0C84, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0C90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0C80, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0C88, 0x14, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0C88, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0C84, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x07C4, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x072C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0734, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0710, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -231,40 +235,42 @@ struct csiphy_reg_t {0x070c, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x075C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0760, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { {0x0230, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A04, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A10, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A00, 0x0B, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A08, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A00, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A08, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A04, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x02C4, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x022C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0234, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0210, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x021C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0214, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0228, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x023C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0200, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0204, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0220, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0208, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, - {0x020c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x025C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0260, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { {0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B04, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B10, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0B00, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0B08, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B00, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B08, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B04, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x04C4, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x042C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0434, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0410, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -276,19 +282,20 @@ struct csiphy_reg_t {0x0404, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0420, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0408, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, - {0x040c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x045C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0460, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0000, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { {0x0630, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0C04, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0C10, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0C00, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0C08, 0x14, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0C00, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0C08, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0C04, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x06C4, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x062C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0634, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0610, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -296,14 +303,16 @@ struct csiphy_reg_t {0x0614, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0628, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x063C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0600, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0600, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0604, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0620, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0608, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x060c, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x065C, 0xC0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0660, 0x0D, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, }, }; @@ -311,9 +320,6 @@ struct csiphy_reg_t csiphy_3ph_v1_2_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { { {0x015C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0990, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0994, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0998, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0990, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0994, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0998, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -339,25 +345,17 @@ csiphy_reg_t csiphy_3ph_v1_2_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x01CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0164, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x01DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x09C0, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x09C4, 0x7D, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x09C8, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0984, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0988, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0980, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x09B0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x09B4, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { {0x035C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A90, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A94, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A98, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A8C, 0xBF, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A98, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A8C, 0xAF, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0368, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x036C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0304, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -379,21 +377,13 @@ csiphy_reg_t csiphy_3ph_v1_2_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x03CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0364, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x03DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0AC0, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0AC4, 0x7D, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0AC8, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0A84, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0AB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0AB4, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { {0x055C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0B90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0B94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0B98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B90, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B94, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B98, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -419,12 +409,7 @@ csiphy_reg_t csiphy_3ph_v1_2_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x05CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0564, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x05DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0BC0, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0BC4, 0x7D, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0BC8, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0B84, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0B88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0B80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0BB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0BB4, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0800, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -437,7 +422,7 @@ struct data_rate_settings_t data_rate_delta_table_1_2_2 = { { /* (2.5 * 10**3 * 2.28) rounded value*/ .bandwidth = 5700000000, - .data_rate_reg_array_size = 8, + .data_rate_reg_array_size = 6, .csiphy_data_rate_regs = { {0x144, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x344, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -445,14 +430,12 @@ struct data_rate_settings_t data_rate_delta_table_1_2_2 = { {0x984, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, {0xA84, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, {0xB84, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A98, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A8C, 0xBF, 0x00, CSIPHY_DEFAULT_PARAMS}, } }, { /* (3.5 * 10**3 * 2.28) rounded value */ .bandwidth = 7980000000, - .data_rate_reg_array_size = 8, + .data_rate_reg_array_size = 12, .csiphy_data_rate_regs = { {0x144, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x344, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -460,14 +443,18 @@ struct data_rate_settings_t data_rate_delta_table_1_2_2 = { {0x984, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, {0xA84, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, {0xB84, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A98, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A8C, 0xAF, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0988, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0980, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, }, }, { /* (4.5 * 10**3 * 2.28) rounded value */ .bandwidth = 10260000000, - .data_rate_reg_array_size = 8, + .data_rate_reg_array_size = 12, .csiphy_data_rate_regs = { {0x144, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x344, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -475,8 +462,13 @@ struct data_rate_settings_t data_rate_delta_table_1_2_2 = { {0x984, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, {0xA84, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, {0xB84, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A98, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0A8C, 0xAF, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0988, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0980, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + }, } } diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index 61aca24179f3..da47bf319e66 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -580,9 +580,7 @@ static int32_t cam_eeprom_init_pkt_parser(struct cam_eeprom_ctrl_t *e_ctrl, (struct cam_eeprom_soc_private *)e_ctrl->soc_info.soc_private; struct cam_sensor_power_ctrl_t *power_info = &soc_private->power_info; - e_ctrl->cal_data.map = vzalloc((MSM_EEPROM_MEMORY_MAP_MAX_SIZE * - MSM_EEPROM_MAX_MEM_MAP_CNT) * - (sizeof(struct cam_eeprom_memory_map_t))); + e_ctrl->cal_data.map = vzalloc(array_size(sizeof(struct cam_eeprom_memory_map_t), (MSM_EEPROM_MEMORY_MAP_MAX_SIZE * MSM_EEPROM_MAX_MEM_MAP_CNT))); if (!e_ctrl->cal_data.map) { rc = -ENOMEM; CAM_ERR(CAM_EEPROM, "failed"); diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c index f4c9d254df7c..12407e305102 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -456,8 +456,9 @@ static int32_t cam_flash_platform_probe(struct platform_device *pdev) } fctrl->i2c_data.per_frame = (struct i2c_settings_array *) - kzalloc(sizeof(struct i2c_settings_array) * - MAX_PER_FRAME_ARRAY, GFP_KERNEL); + kcalloc(MAX_PER_FRAME_ARRAY, + sizeof(struct i2c_settings_array), + GFP_KERNEL); if (fctrl->i2c_data.per_frame == NULL) { CAM_ERR(CAM_FLASH, "No Memory"); rc = -ENOMEM; @@ -560,8 +561,9 @@ static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client, fctrl->i2c_data.per_frame = (struct i2c_settings_array *) - kzalloc(sizeof(struct i2c_settings_array) * - MAX_PER_FRAME_ARRAY, GFP_KERNEL); + kcalloc(MAX_PER_FRAME_ARRAY, + sizeof(struct i2c_settings_array), + GFP_KERNEL); if (fctrl->i2c_data.per_frame == NULL) { rc = -ENOMEM; goto unreg_subdev; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_dev.c index 5207eee15f05..a170fa9e4724 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_dev.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_dev.c @@ -176,8 +176,9 @@ static int32_t cam_sensor_driver_i2c_probe(struct i2c_client *client, s_ctrl->i2c_data.per_frame = (struct i2c_settings_array *) - kzalloc(sizeof(struct i2c_settings_array) * - MAX_PER_FRAME_ARRAY, GFP_KERNEL); + kcalloc(MAX_PER_FRAME_ARRAY, + sizeof(struct i2c_settings_array), + GFP_KERNEL); if (s_ctrl->i2c_data.per_frame == NULL) { rc = -ENOMEM; goto unreg_subdev; @@ -312,8 +313,9 @@ static int32_t cam_sensor_driver_platform_probe( s_ctrl->i2c_data.per_frame = (struct i2c_settings_array *) - kzalloc(sizeof(struct i2c_settings_array) * - MAX_PER_FRAME_ARRAY, GFP_KERNEL); + kcalloc(MAX_PER_FRAME_ARRAY, + sizeof(struct i2c_settings_array), + GFP_KERNEL); if (s_ctrl->i2c_data.per_frame == NULL) { rc = -ENOMEM; goto unreg_subdev; diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c index 5f503d8dc78a..f57c636797c3 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c @@ -36,12 +36,25 @@ static struct i2c_settings_list* else return NULL; - tmp->i2c_settings.reg_setting = (struct cam_sensor_i2c_reg_array *) - vzalloc(size * sizeof(struct cam_sensor_i2c_reg_array)); - if (tmp->i2c_settings.reg_setting == NULL) { - list_del(&(tmp->list)); - kvfree(tmp); - return NULL; + if ((sizeof(struct cam_sensor_i2c_reg_array) * size) < PAGE_SIZE) { + tmp->i2c_settings.reg_setting = + (struct cam_sensor_i2c_reg_array *) + kcalloc(size, sizeof(struct cam_sensor_i2c_reg_array), + GFP_KERNEL); + if (tmp->i2c_settings.reg_setting == NULL) { + list_del(&(tmp->list)); + kfree(tmp); + return NULL; + } + } else { + tmp->i2c_settings.reg_setting = + (struct cam_sensor_i2c_reg_array *) + vzalloc(array_size(size, sizeof(struct cam_sensor_i2c_reg_array))); + if (tmp->i2c_settings.reg_setting == NULL) { + list_del(&(tmp->list)); + kfree(tmp); + return NULL; + } } tmp->i2c_settings.size = size; @@ -878,16 +891,18 @@ int32_t cam_sensor_update_power_settings(void *cmd_buf, power_info->power_setting_size = 0; power_info->power_setting = (struct cam_sensor_power_setting *) - kzalloc(sizeof(struct cam_sensor_power_setting) * - MAX_POWER_CONFIG, GFP_KERNEL); + kcalloc(MAX_POWER_CONFIG, + sizeof(struct cam_sensor_power_setting), + GFP_KERNEL); if (!power_info->power_setting) return -ENOMEM; power_info->power_down_setting_size = 0; power_info->power_down_setting = (struct cam_sensor_power_setting *) - kzalloc(sizeof(struct cam_sensor_power_setting) * - MAX_POWER_CONFIG, GFP_KERNEL); + kcalloc(MAX_POWER_CONFIG, + sizeof(struct cam_sensor_power_setting), + GFP_KERNEL); if (!power_info->power_down_setting) { kfree(power_info->power_setting); power_info->power_setting = NULL; diff --git a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c index 6964f641188a..5dabde4184d9 100644 --- a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c +++ b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c @@ -3315,8 +3315,8 @@ static int cam_alloc_smmu_context_banks(struct device *dev) } /* allocate memory for the context banks */ - iommu_cb_set.cb_info = devm_kzalloc(dev, - iommu_cb_set.cb_num * sizeof(struct cam_context_bank_info), + iommu_cb_set.cb_info = devm_kcalloc(dev, + iommu_cb_set.cb_num, sizeof(struct cam_context_bank_info), GFP_KERNEL); if (!iommu_cb_set.cb_info) { diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c index 1d0b92ad9d8d..4b6295d1d5ce 100644 --- a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c +++ b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -177,7 +177,7 @@ int cam_packet_util_process_patches(struct cam_packet *packet, uint32_t temp; uint32_t *dst_cpu_addr; uint32_t *src_buf_iova_addr; - size_t dst_buf_len; + size_t dst_buf_len = 0; size_t src_buf_size; int i; int rc = 0; diff --git a/drivers/media/platform/msm/camera_v2/common/cam_hw_ops.c b/drivers/media/platform/msm/camera_v2/common/cam_hw_ops.c index a3b41d02963f..4ceb38eb3eaf 100644 --- a/drivers/media/platform/msm/camera_v2/common/cam_hw_ops.c +++ b/drivers/media/platform/msm/camera_v2/common/cam_hw_ops.c @@ -94,8 +94,8 @@ int cam_ahb_clk_init(struct platform_device *pdev) CDBG("number of bus vectors: %d\n", data.cnt); - data.vectors = devm_kzalloc(&pdev->dev, - sizeof(struct cam_bus_vector) * cnt, + data.vectors = devm_kcalloc(&pdev->dev, + cnt, sizeof(struct cam_bus_vector), GFP_KERNEL); if (!data.vectors) return -ENOMEM; @@ -111,16 +111,16 @@ int cam_ahb_clk_init(struct platform_device *pdev) } } - data.paths = devm_kzalloc(&pdev->dev, - sizeof(struct msm_bus_vectors) * cnt, + data.paths = devm_kcalloc(&pdev->dev, + cnt, sizeof(struct msm_bus_vectors), GFP_KERNEL); if (!data.paths) { rc = -ENOMEM; goto err1; } - data.usecases = devm_kzalloc(&pdev->dev, - sizeof(struct msm_bus_paths) * cnt, + data.usecases = devm_kcalloc(&pdev->dev, + cnt, sizeof(struct msm_bus_paths), GFP_KERNEL); if (!data.usecases) { rc = -ENOMEM; @@ -135,8 +135,8 @@ int cam_ahb_clk_init(struct platform_device *pdev) goto err3; } - data.votes = devm_kzalloc(&pdev->dev, sizeof(u32) * cnt, - GFP_KERNEL); + data.votes = devm_kcalloc(&pdev->dev, cnt, sizeof(u32), + GFP_KERNEL); if (!data.votes) { rc = -ENOMEM; goto err4; diff --git a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c index 7bdf389e1c96..6cd1ec986668 100644 --- a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c +++ b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c @@ -820,7 +820,7 @@ static int cam_smmu_send_syscall_pix_intf(int vmid, int idx) uint32_t *sid_info = NULL; struct cam_context_bank_info *cb = &iommu_cb_set.cb_info[idx]; - sid_info = kzalloc(sizeof(uint32_t) * 2, GFP_KERNEL); + sid_info = kcalloc(2, sizeof(uint32_t), GFP_KERNEL); if (!sid_info) return -ENOMEM; @@ -2151,8 +2151,8 @@ static int cam_alloc_smmu_context_banks(struct device *dev) } /* allocate memory for the context banks */ - iommu_cb_set.cb_info = devm_kzalloc(dev, - iommu_cb_set.cb_num * sizeof(struct cam_context_bank_info), + iommu_cb_set.cb_info = devm_kcalloc(dev, + iommu_cb_set.cb_num, sizeof(struct cam_context_bank_info), GFP_KERNEL); if (!iommu_cb_set.cb_info) { diff --git a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c index 6d96a0032f01..37ab9d680bfb 100644 --- a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c +++ b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c @@ -445,7 +445,7 @@ static int msm_fd_open(struct file *file) } ctx->mem_pool.fd_device = ctx->fd_device; - ctx->stats = vzalloc(sizeof(*ctx->stats) * MSM_FD_MAX_RESULT_BUFS); + ctx->stats = vzalloc(array_size(MSM_FD_MAX_RESULT_BUFS, sizeof(*ctx->stats))); if (!ctx->stats) { dev_err(device->dev, "No memory for face statistics\n"); ret = -ENOMEM; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c index d53c81016e1c..b885b24da88d 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c @@ -1075,8 +1075,9 @@ static int msm_isp_request_bufq(struct msm_isp_buf_mgr *buf_mgr, return -EINVAL; } - bufq->bufs = kzalloc(sizeof(struct msm_isp_buffer) * - buf_request->num_buf, GFP_KERNEL); + bufq->bufs = kcalloc(buf_request->num_buf, + sizeof(struct msm_isp_buffer), + GFP_KERNEL); if (!bufq->bufs) { msm_isp_free_bufq_handle(buf_mgr, buf_request->handle); return -ENOMEM; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util_32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util_32.c index 41a293660be8..6036c51e5c11 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util_32.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util_32.c @@ -1223,8 +1223,9 @@ int msm_isp_proc_cmd(struct vfe_device *vfe_dev, void *arg) return -EINVAL; } - reg_cfg_cmd = kzalloc(sizeof(struct msm_vfe_reg_cfg_cmd)* - proc_cmd->num_cfg, GFP_KERNEL); + reg_cfg_cmd = kcalloc(proc_cmd->num_cfg, + sizeof(struct msm_vfe_reg_cfg_cmd), + GFP_KERNEL); if (!reg_cfg_cmd) { rc = -ENOMEM; goto reg_cfg_failed; diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c index fd10eb974b31..2698a08e94c5 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c +++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c @@ -626,9 +626,9 @@ static int32_t msm_actuator_move_focus( return -EFAULT; } /*Allocate memory for damping parameters of all regions*/ - ringing_params_kernel = kmalloc( - sizeof(struct damping_params_t)*(a_ctrl->region_size), - GFP_KERNEL); + ringing_params_kernel = kmalloc_array(a_ctrl->region_size, + sizeof(struct damping_params_t), + GFP_KERNEL); if (!ringing_params_kernel) { pr_err("kmalloc for damping parameters failed\n"); return -EFAULT; @@ -752,9 +752,9 @@ static int32_t msm_actuator_bivcm_move_focus( return -EFAULT; } /*Allocate memory for damping parameters of all regions*/ - ringing_params_kernel = kmalloc( - sizeof(struct damping_params_t)*(a_ctrl->region_size), - GFP_KERNEL); + ringing_params_kernel = kmalloc_array(a_ctrl->region_size, + sizeof(struct damping_params_t), + GFP_KERNEL); if (!ringing_params_kernel) { pr_err("kmalloc for damping parameters failed\n"); return -EFAULT; @@ -923,8 +923,9 @@ static int32_t msm_actuator_bivcm_init_step_table( } /* Fill step position table */ a_ctrl->step_position_table = - kmalloc(sizeof(uint16_t) * - (set_info->af_tuning_params.total_steps + 1), GFP_KERNEL); + kmalloc_array(set_info->af_tuning_params.total_steps + 1, + sizeof(uint16_t), + GFP_KERNEL); if (a_ctrl->step_position_table == NULL) return -ENOMEM; @@ -1011,8 +1012,9 @@ static int32_t msm_actuator_init_step_table(struct msm_actuator_ctrl_t *a_ctrl, } /* Fill step position table */ a_ctrl->step_position_table = - kmalloc(sizeof(uint16_t) * - (set_info->af_tuning_params.total_steps + 1), GFP_KERNEL); + kmalloc_array(set_info->af_tuning_params.total_steps + 1, + sizeof(uint16_t), + GFP_KERNEL); if (a_ctrl->step_position_table == NULL) return -ENOMEM; @@ -1349,8 +1351,9 @@ static int32_t msm_actuator_set_param(struct msm_actuator_ctrl_t *a_ctrl, } a_ctrl->i2c_reg_tbl = NULL; a_ctrl->i2c_reg_tbl = - kmalloc(sizeof(struct msm_camera_i2c_reg_array) * - (set_info->af_tuning_params.total_steps + 1), GFP_KERNEL); + kmalloc_array(set_info->af_tuning_params.total_steps + 1, + sizeof(struct msm_camera_i2c_reg_array), + GFP_KERNEL); if (!a_ctrl->i2c_reg_tbl) { pr_err("kmalloc fail\n"); return -ENOMEM; @@ -1370,9 +1373,9 @@ static int32_t msm_actuator_set_param(struct msm_actuator_ctrl_t *a_ctrl, set_info->actuator_params.init_setting_size <= MAX_ACTUATOR_INIT_SET) { if (a_ctrl->func_tbl->actuator_init_focus) { - init_settings = kmalloc(sizeof(struct reg_settings_t) * - (set_info->actuator_params.init_setting_size), - GFP_KERNEL); + init_settings = kmalloc_array(set_info->actuator_params.init_setting_size, + sizeof(struct reg_settings_t), + GFP_KERNEL); if (init_settings == NULL) { kfree(a_ctrl->i2c_reg_tbl); a_ctrl->i2c_reg_tbl = NULL; diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c index fe15782812d2..e4dd91768ea8 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c +++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c @@ -1174,8 +1174,9 @@ static int32_t msm_cci_i2c_write_async(struct v4l2_subdev *sd, } cci_i2c_write_cfg_w->reg_setting = - kzalloc(sizeof(struct msm_camera_i2c_reg_array)* - cci_i2c_write_cfg->size, GFP_KERNEL); + kcalloc(cci_i2c_write_cfg->size, + sizeof(struct msm_camera_i2c_reg_array), + GFP_KERNEL); if (!cci_i2c_write_cfg_w->reg_setting) { pr_err("%s: %d Couldn't allocate memory\n", __func__, __LINE__); kfree(write_async); @@ -1904,7 +1905,7 @@ static int32_t msm_cci_init_gpio_params(struct cci_device *cci_dev) } gpio_tbl = cci_dev->cci_gpio_tbl = - kzalloc(sizeof(struct gpio) * tbl_size, GFP_KERNEL); + kcalloc(tbl_size, sizeof(struct gpio), GFP_KERNEL); if (!gpio_tbl) { pr_err("%s failed %d\n", __func__, __LINE__); return 0; diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c index fa875cbb80a0..b1c7a3f1d6d4 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c +++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c @@ -256,8 +256,9 @@ static int32_t msm_flash_i2c_init( } flash_ctrl->power_setting_array.power_setting = - kzalloc(sizeof(struct msm_sensor_power_setting)* - flash_ctrl->power_setting_array.size, GFP_KERNEL); + kcalloc(flash_ctrl->power_setting_array.size, + sizeof(struct msm_sensor_power_setting), + GFP_KERNEL); if (!flash_ctrl->power_setting_array.power_setting) { kfree(power_setting_array32); return -ENOMEM; diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c index ae75ca981dda..d0aad5835bcd 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c @@ -160,8 +160,9 @@ int32_t msm_camera_cci_i2c_write_seq(struct msm_camera_i2c_client *client, S_I2C_DBG("%s reg addr = 0x%x num bytes: %d\n", __func__, addr, num_byte); - reg_conf_tbl = kzalloc(num_byte * - (sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL); + reg_conf_tbl = kcalloc(num_byte, + sizeof(struct msm_camera_i2c_reg_array), + GFP_KERNEL); if (!reg_conf_tbl) return -ENOMEM; diff --git a/drivers/media/platform/msm/camera_v2/sensor/laser_led/msm_laser_led.c b/drivers/media/platform/msm/camera_v2/sensor/laser_led/msm_laser_led.c index fb8a11685693..c5d986cead50 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/laser_led/msm_laser_led.c +++ b/drivers/media/platform/msm/camera_v2/sensor/laser_led/msm_laser_led.c @@ -212,8 +212,9 @@ static int32_t msm_laser_led_control32( return -EFAULT; } - conf_array.reg_setting = kzalloc(conf_array.size * - (sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL); + conf_array.reg_setting = kcalloc(conf_array.size, + sizeof(struct msm_camera_i2c_reg_array), + GFP_KERNEL); if (!conf_array.reg_setting) return -ENOMEM; @@ -226,8 +227,9 @@ static int32_t msm_laser_led_control32( return -EFAULT; } if (laser_led_data.debug_reg_size <= sizeof(uint32_t)) { - debug_reg = kzalloc(laser_led_data.debug_reg_size * - (sizeof(uint32_t)), GFP_KERNEL); + debug_reg = kcalloc(laser_led_data.debug_reg_size, + sizeof(uint32_t), + GFP_KERNEL); if (!debug_reg) { kfree(conf_array.reg_setting); return -ENOMEM; @@ -350,8 +352,9 @@ static int32_t msm_laser_led_control( return -EFAULT; } - conf_array.reg_setting = kzalloc(conf_array.size * - (sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL); + conf_array.reg_setting = kcalloc(conf_array.size, + sizeof(struct msm_camera_i2c_reg_array), + GFP_KERNEL); if (!conf_array.reg_setting) return -ENOMEM; @@ -364,8 +367,9 @@ static int32_t msm_laser_led_control( return -EFAULT; } if (laser_led_data.debug_reg_size <= sizeof(uint32_t)) { - debug_reg = kzalloc(laser_led_data.debug_reg_size * - (sizeof(uint32_t)), GFP_KERNEL); + debug_reg = kcalloc(laser_led_data.debug_reg_size, + sizeof(uint32_t), + GFP_KERNEL); if (!debug_reg) { kfree(conf_array.reg_setting); return -ENOMEM; diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c index 349e2b08e45c..ec983f451085 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c +++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c @@ -492,8 +492,9 @@ static int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl, break; } - reg_setting = kzalloc(conf_array.size * - (sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL); + reg_setting = kcalloc(conf_array.size, + sizeof(struct msm_camera_i2c_reg_array), + GFP_KERNEL); if (!reg_setting) { rc = -ENOMEM; break; @@ -653,8 +654,9 @@ static int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl, break; } - reg_setting = kzalloc(write_config.conf_array.size * - (sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL); + reg_setting = kcalloc(write_config.conf_array.size, + sizeof(struct msm_camera_i2c_reg_array), + GFP_KERNEL); if (!reg_setting) { rc = -ENOMEM; break; @@ -751,9 +753,9 @@ static int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl, break; } - reg_setting = kzalloc(conf_array.size * - (sizeof(struct msm_camera_i2c_seq_reg_array)), - GFP_KERNEL); + reg_setting = kcalloc(conf_array.size, + sizeof(struct msm_camera_i2c_seq_reg_array), + GFP_KERNEL); if (!reg_setting) { pr_err("%s:%d failed\n", __func__, __LINE__); rc = -ENOMEM; @@ -862,9 +864,9 @@ static int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl, } if (stop_setting->size <= sizeof(struct msm_camera_i2c_reg_array)) { - stop_setting->reg_setting = kzalloc(stop_setting->size * - (sizeof(struct msm_camera_i2c_reg_array)), - GFP_KERNEL); + stop_setting->reg_setting = kcalloc(stop_setting->size, + sizeof(struct msm_camera_i2c_reg_array), + GFP_KERNEL); if (!stop_setting->reg_setting) { rc = -ENOMEM; break; @@ -1023,8 +1025,9 @@ int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void *argp) break; } - reg_setting = kzalloc(conf_array.size * - (sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL); + reg_setting = kcalloc(conf_array.size, + sizeof(struct msm_camera_i2c_reg_array), + GFP_KERNEL); if (!reg_setting) { rc = -ENOMEM; break; @@ -1163,8 +1166,9 @@ int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void *argp) break; } - reg_setting = kzalloc(write_config.conf_array.size * - (sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL); + reg_setting = kcalloc(write_config.conf_array.size, + sizeof(struct msm_camera_i2c_reg_array), + GFP_KERNEL); if (!reg_setting) { rc = -ENOMEM; break; @@ -1250,9 +1254,9 @@ int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void *argp) break; } - reg_setting = kzalloc(conf_array.size * - (sizeof(struct msm_camera_i2c_seq_reg_array)), - GFP_KERNEL); + reg_setting = kcalloc(conf_array.size, + sizeof(struct msm_camera_i2c_seq_reg_array), + GFP_KERNEL); if (!reg_setting) { pr_err("%s:%d failed\n", __func__, __LINE__); rc = -ENOMEM; @@ -1359,9 +1363,9 @@ int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void *argp) } if (stop_setting->size <= sizeof(struct msm_camera_i2c_reg_array)) { - stop_setting->reg_setting = kzalloc(stop_setting->size * - (sizeof(struct msm_camera_i2c_reg_array)), - GFP_KERNEL); + stop_setting->reg_setting = kcalloc(stop_setting->size, + sizeof(struct msm_camera_i2c_reg_array), + GFP_KERNEL); if (!stop_setting->reg_setting) { rc = -ENOMEM; break; diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c index 7d7b5cde2f66..0c0e011451ae 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c +++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c @@ -483,7 +483,7 @@ static int32_t msm_sensor_get_pw_settings_compat( { int32_t rc = 0, i = 0; struct msm_sensor_power_setting32 *ps32 = - kzalloc(sizeof(*ps32) * size, GFP_KERNEL); + kcalloc(size, sizeof(*ps32), GFP_KERNEL); if (!ps32) { pr_err("failed: no memory ps32"); @@ -832,9 +832,8 @@ int32_t msm_sensor_driver_probe(void *setting, } else { id_info = &(slave_info->sensor_id_info); reg_setting = - kzalloc(id_info->setting.size * - (sizeof - (struct msm_camera_i2c_reg_array)), + kcalloc(id_info->setting.size, + sizeof(struct msm_camera_i2c_reg_array), GFP_KERNEL); if (!reg_setting) { kfree(slave_info32); @@ -901,9 +900,8 @@ int32_t msm_sensor_driver_probe(void *setting, } else { id_info = &(slave_info->sensor_id_info); reg_setting = - kzalloc(id_info->setting.size * - (sizeof - (struct msm_camera_i2c_reg_array)), + kcalloc(id_info->setting.size, + sizeof(struct msm_camera_i2c_reg_array), GFP_KERNEL); if (!reg_setting) { rc = -ENOMEM; diff --git a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c index 4371a88cc2a3..335f6e54318a 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c +++ b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c @@ -438,10 +438,9 @@ static int32_t msm_ois_control(struct msm_ois_ctrl_t *o_ctrl, if (set_info->ois_params.setting_size > 0 && set_info->ois_params.setting_size < MAX_OIS_REG_SETTINGS) { - settings = kmalloc( - sizeof(struct reg_settings_ois_t) * - (set_info->ois_params.setting_size), - GFP_KERNEL); + settings = kmalloc_array(set_info->ois_params.setting_size, + sizeof(struct reg_settings_ois_t), + GFP_KERNEL); if (settings == NULL) { pr_err("Error allocating memory\n"); return -EFAULT; @@ -545,9 +544,9 @@ static int32_t msm_ois_config(struct msm_ois_ctrl_t *o_ctrl, rc = -EFAULT; break; } - reg_setting = kzalloc(conf_array.size * - (sizeof(struct msm_camera_i2c_seq_reg_array)), - GFP_KERNEL); + reg_setting = kcalloc(conf_array.size, + sizeof(struct msm_camera_i2c_seq_reg_array), + GFP_KERNEL); if (!reg_setting) { pr_err("%s:%d failed\n", __func__, __LINE__); rc = -ENOMEM; diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c index 4cc9623b1b9a..358a3e9017b0 100644 --- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c +++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c @@ -831,7 +831,7 @@ int mpq_dmx_plugin_init(mpq_dmx_init dmx_init_func, /* Allocate memory for all MPQ devices */ mpq_dmx_info.devices = - vzalloc(mpq_demux_device_num*sizeof(struct mpq_demux)); + vzalloc(array_size(mpq_demux_device_num, sizeof(struct mpq_demux))); if (!mpq_dmx_info.devices) { result = -ENOMEM; @@ -3723,8 +3723,7 @@ static int mpq_sdmx_filter_setup(struct mpq_demux *mpq_demux, MPQ_DVB_DBG_PRINT("%s: SDMX_PES_FILTER\n", __func__); } - data_buff_desc = vmalloc( - sizeof(*data_buff_desc)*DMX_MAX_DECODER_BUFFER_NUM); + data_buff_desc = vmalloc(array_size(DMX_MAX_DECODER_BUFFER_NUM, sizeof(*data_buff_desc))); if (!data_buff_desc) { MPQ_DVB_ERR_PRINT( "%s: failed to allocate memory for data buffer\n", diff --git a/drivers/media/platform/msm/npu/npu_mgr.c b/drivers/media/platform/msm/npu/npu_mgr.c index 6a22540d88c1..d36836402781 100644 --- a/drivers/media/platform/msm/npu/npu_mgr.c +++ b/drivers/media/platform/msm/npu/npu_mgr.c @@ -1013,7 +1013,7 @@ static void host_session_msg_hdlr(struct npu_device *npu_dev) uint32_t *msg; struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; - msg = kzalloc(sizeof(uint32_t) * NPU_IPC_BUF_LENGTH, GFP_KERNEL); + msg = kcalloc(NPU_IPC_BUF_LENGTH, sizeof(uint32_t), GFP_KERNEL); if (!msg) return; @@ -1059,7 +1059,7 @@ static void host_session_log_hdlr(struct npu_device *npu_dev) uint32_t *msg; struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; - msg = kzalloc(sizeof(uint32_t) * NPU_IPC_BUF_LENGTH, GFP_KERNEL); + msg = kcalloc(NPU_IPC_BUF_LENGTH, sizeof(uint32_t), GFP_KERNEL); if (!msg) return; diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c index e3ab6643c313..087ef77e0439 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c @@ -2294,8 +2294,8 @@ static int sde_rotator_open_session(struct sde_rot_mgr *mgr, if (!perf) return -ENOMEM; - perf->work_distribution = devm_kzalloc(&mgr->pdev->dev, - sizeof(u32) * mgr->queue_count, GFP_KERNEL); + perf->work_distribution = devm_kcalloc(&mgr->pdev->dev, + mgr->queue_count, sizeof(u32), GFP_KERNEL); if (!perf->work_distribution) { ret = -ENOMEM; goto alloc_err; @@ -2865,8 +2865,9 @@ static int sde_rotator_get_dt_vreg_data(struct device *dev, return 0; } mp->num_vreg = dt_vreg_total; - mp->vreg_config = devm_kzalloc(dev, sizeof(struct sde_vreg) * - dt_vreg_total, GFP_KERNEL); + mp->vreg_config = devm_kcalloc(dev, + dt_vreg_total, sizeof(struct sde_vreg), + GFP_KERNEL); if (!mp->vreg_config) return -ENOMEM; @@ -2989,8 +2990,8 @@ static int sde_rotator_parse_dt_clk(struct platform_device *pdev, } mgr->num_rot_clk = SDE_ROTATOR_CLK_MAX; - mgr->rot_clk = devm_kzalloc(&pdev->dev, - sizeof(struct sde_rot_clk) * mgr->num_rot_clk, + mgr->rot_clk = devm_kcalloc(&pdev->dev, + mgr->num_rot_clk, sizeof(struct sde_rot_clk), GFP_KERNEL); if (!mgr->rot_clk) { rc = -ENOMEM; diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c index 4658f2918898..4a169ae589f5 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c @@ -117,8 +117,8 @@ static int sde_smmu_util_parse_dt_clock(struct platform_device *pdev, } mp->num_clk = num_clk; - mp->clk_config = devm_kzalloc(&pdev->dev, - sizeof(struct sde_clk) * mp->num_clk, GFP_KERNEL); + mp->clk_config = devm_kcalloc(&pdev->dev, + mp->num_clk, sizeof(struct sde_clk), GFP_KERNEL); if (num_clk && !mp->clk_config) { rc = -ENOMEM; mp->num_clk = 0; diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c index c8306b70ddf4..8c601e3d8779 100644 --- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c @@ -534,7 +534,6 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) struct device *dev; int nr = BASE_DEVICE_NUMBER; - place_marker("M - DRIVER Video Start"); if (!vidc_driver) { dprintk(VIDC_ERR, "Invalid vidc driver\n"); @@ -642,7 +641,6 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) goto err_fail_sub_device_probe; } - place_marker("M - DRIVER Video Ready"); return rc; err_fail_sub_device_probe: @@ -785,7 +783,6 @@ static int msm_vidc_pm_suspend(struct device *dev) static int msm_vidc_pm_resume(struct device *dev) { - place_marker("vidc resumed"); dprintk(VIDC_INFO, "%s\n", __func__); return 0; } @@ -855,11 +852,9 @@ static int msm_vidc_pm_freeze(struct device *dev) return 0; if (of_device_is_compatible(dev->of_node, "qcom,msm-vidc")) { - place_marker("vidc hibernation start"); rc = msm_vidc_freeze_core(core); - place_marker("vidc hibernation end"); } dprintk(VIDC_INFO, "%s: done\n", __func__); diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c index d2e5861cba70..a863f222e23c 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_vidc.c @@ -526,6 +526,15 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) return -EINVAL; } + q = msm_comm_get_vb2q(inst, b->type); + if (!q) { + dprintk(VIDC_ERR, + "Failed to find buffer queue for type = %d\n", b->type); + return -EINVAL; + } + mutex_lock(&q->lock); + + for (i = 0; i < b->length; i++) { b->m.planes[i].m.fd = b->m.planes[i].reserved[0]; b->m.planes[i].data_offset = b->m.planes[i].reserved[1]; @@ -550,19 +559,11 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) tag_data.output_tag = b->m.planes[0].reserved[6]; msm_comm_store_tags(inst, &tag_data); - q = msm_comm_get_vb2q(inst, b->type); - if (!q) { - dprintk(VIDC_ERR, - "Failed to find buffer queue for type = %d\n", b->type); - return -EINVAL; - } - - mutex_lock(&q->lock); rc = vb2_qbuf(&q->vb2_bufq, b); - mutex_unlock(&q->lock); if (rc) dprintk(VIDC_ERR, "Failed to qbuf, %d\n", rc); + mutex_unlock(&q->lock); return rc; } EXPORT_SYMBOL(msm_vidc_qbuf); @@ -1884,7 +1885,6 @@ void *msm_vidc_open(int core_id, int session_type) mutex_init(&inst->bufq[CAPTURE_PORT].lock); mutex_init(&inst->bufq[OUTPUT_PORT].lock); mutex_init(&inst->lock); - mutex_init(&inst->flush_lock); INIT_MSM_VIDC_LIST(&inst->scratchbufs); INIT_MSM_VIDC_LIST(&inst->freqs); @@ -2008,7 +2008,6 @@ fail_bufq_capture: mutex_destroy(&inst->bufq[CAPTURE_PORT].lock); mutex_destroy(&inst->bufq[OUTPUT_PORT].lock); mutex_destroy(&inst->lock); - mutex_destroy(&inst->flush_lock); DEINIT_MSM_VIDC_LIST(&inst->scratchbufs); DEINIT_MSM_VIDC_LIST(&inst->persistbufs); @@ -2162,7 +2161,6 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) mutex_destroy(&inst->bufq[CAPTURE_PORT].lock); mutex_destroy(&inst->bufq[OUTPUT_PORT].lock); mutex_destroy(&inst->lock); - mutex_destroy(&inst->flush_lock); msm_vidc_debugfs_deinit_inst(inst); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index 75a7370a002d..10da4bdaaf50 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -98,8 +98,9 @@ static struct v4l2_ctrl **get_super_cluster(struct msm_vidc_inst *inst, int num_ctrls) { int c = 0; - struct v4l2_ctrl **cluster = kmalloc(sizeof(struct v4l2_ctrl *) * - num_ctrls, GFP_KERNEL); + struct v4l2_ctrl **cluster = kmalloc_array(num_ctrls, + sizeof(struct v4l2_ctrl *), + GFP_KERNEL); if (!cluster || !inst) { kfree(cluster); @@ -2086,7 +2087,11 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) return; } - mutex_lock(&inst->flush_lock); + if (response->data.flush_type & HAL_FLUSH_INPUT) + mutex_lock(&inst->bufq[OUTPUT_PORT].lock); + if (response->data.flush_type & HAL_FLUSH_OUTPUT) + mutex_lock(&inst->bufq[CAPTURE_PORT].lock); + if (msm_comm_get_stream_output_mode(inst) == HAL_VIDEO_DECODER_SECONDARY) { @@ -2129,7 +2134,11 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) v4l2_event_queue_fh(&inst->event_handler, &flush_event); exit: - mutex_unlock(&inst->flush_lock); + if (response->data.flush_type & HAL_FLUSH_OUTPUT) + mutex_unlock(&inst->bufq[CAPTURE_PORT].lock); + if (response->data.flush_type & HAL_FLUSH_INPUT) + mutex_unlock(&inst->bufq[OUTPUT_PORT].lock); + put_inst(inst); } @@ -2338,7 +2347,7 @@ struct vb2_buffer *msm_comm_get_vb_using_vidc_buffer( return NULL; } - mutex_lock(&inst->bufq[port].lock); + WARN_ON(!mutex_is_locked(&inst->bufq[port].lock)); found = false; q = &inst->bufq[port].vb2_bufq; if (!q->streaming) { @@ -2354,7 +2363,6 @@ struct vb2_buffer *msm_comm_get_vb_using_vidc_buffer( } } unlock: - mutex_unlock(&inst->bufq[port].lock); if (!found) { print_vidc_buffer(VIDC_ERR, "vb2 not found for", inst, mbuf); return NULL; @@ -2369,6 +2377,7 @@ int msm_comm_vb2_buffer_done(struct msm_vidc_inst *inst, struct vb2_buffer *vb2; struct vb2_v4l2_buffer *vbuf; u32 i, port; + int rc = 0; if (!inst || !mbuf) { dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", @@ -2385,16 +2394,20 @@ int msm_comm_vb2_buffer_done(struct msm_vidc_inst *inst, else return -EINVAL; - vb2 = msm_comm_get_vb_using_vidc_buffer(inst, mbuf); - if (!vb2) - return -EINVAL; - /* * access vb2 buffer under q->lock and if streaming only to * ensure the buffer was not free'd by vb2 framework while * we are accessing it here. */ mutex_lock(&inst->bufq[port].lock); + vb2 = msm_comm_get_vb_using_vidc_buffer(inst, mbuf); + if (!vb2) { + rc = -EINVAL; + dprintk(VIDC_ERR, "%s:port %d buffer not found\n", + __func__, port); + goto unlock; + } + if (inst->bufq[port].vb2_bufq.streaming) { vbuf = to_vb2_v4l2_buffer(vb2); vbuf->flags = mbuf->vvb.flags; @@ -2410,9 +2423,9 @@ int msm_comm_vb2_buffer_done(struct msm_vidc_inst *inst, dprintk(VIDC_ERR, "%s: port %d is not streaming\n", __func__, port); } +unlock: mutex_unlock(&inst->bufq[port].lock); - - return 0; + return rc; } bool heic_encode_session_supported(struct msm_vidc_inst *inst) @@ -5323,7 +5336,11 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) return 0; } - mutex_lock(&inst->flush_lock); + if (ip_flush) + mutex_lock(&inst->bufq[OUTPUT_PORT].lock); + if (op_flush) + mutex_lock(&inst->bufq[CAPTURE_PORT].lock); + /* enable in flush */ inst->in_flush = true; @@ -5377,7 +5394,12 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) rc = call_hfi_op(hdev, session_flush, inst->session, HAL_FLUSH_OUTPUT); } - mutex_unlock(&inst->flush_lock); + + if (op_flush) + mutex_unlock(&inst->bufq[CAPTURE_PORT].lock); + if (ip_flush) + mutex_unlock(&inst->bufq[OUTPUT_PORT].lock); + if (rc) { dprintk(VIDC_ERR, "Sending flush to firmware failed, flush out all buffers\n"); @@ -6469,7 +6491,6 @@ int msm_comm_flush_vidc_buffer(struct msm_vidc_inst *inst, else return -EINVAL; - mutex_lock(&inst->bufq[port].lock); if (inst->bufq[port].vb2_bufq.streaming) { vb->planes[0].bytesused = 0; vb2_buffer_done(vb, VB2_BUF_STATE_DONE); @@ -6477,7 +6498,6 @@ int msm_comm_flush_vidc_buffer(struct msm_vidc_inst *inst, dprintk(VIDC_ERR, "%s: port %d is not streaming\n", __func__, port); } - mutex_unlock(&inst->bufq[port].lock); return 0; } @@ -6831,7 +6851,7 @@ void handle_release_buffer_reference(struct msm_vidc_inst *inst, int i = 0; u32 planes[VIDEO_MAX_PLANES] = {0}; - mutex_lock(&inst->flush_lock); + mutex_lock(&inst->bufq[CAPTURE_PORT].lock); mutex_lock(&inst->registeredbufs.lock); found = false; /* check if mbuf was not removed by any chance */ @@ -6920,7 +6940,7 @@ unlock: print_vidc_buffer(VIDC_ERR, "rbr qbuf failed", inst, mbuf); } - mutex_unlock(&inst->flush_lock); + mutex_unlock(&inst->bufq[CAPTURE_PORT].lock); } int msm_comm_unmap_vidc_buffer(struct msm_vidc_inst *inst, diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h index 8718371dd12f..9d1f00cb67ca 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h +++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -442,7 +442,7 @@ struct msm_vidc_core { struct msm_vidc_inst { struct list_head list; - struct mutex sync_lock, lock, flush_lock; + struct mutex sync_lock, lock; struct msm_vidc_core *core; enum session_type session_type; void *session; diff --git a/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c b/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c index cf2e849b4b98..8ca1edfdc27b 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c @@ -169,8 +169,10 @@ static int msm_vidc_load_reg_table(struct msm_vidc_platform_resources *res) return rc; } - reg_set->reg_tbl = devm_kzalloc(&pdev->dev, reg_set->count * - sizeof(*(reg_set->reg_tbl)), GFP_KERNEL); + reg_set->reg_tbl = devm_kcalloc(&pdev->dev, + reg_set->count, + sizeof(*(reg_set->reg_tbl)), + GFP_KERNEL); if (!reg_set->reg_tbl) { dprintk(VIDC_ERR, "%s Failed to alloc register table\n", __func__); @@ -218,8 +220,9 @@ static int msm_vidc_load_qdss_table(struct msm_vidc_platform_resources *res) return rc; } - qdss_addr_set->addr_tbl = devm_kzalloc(&pdev->dev, - qdss_addr_set->count * sizeof(*qdss_addr_set->addr_tbl), + qdss_addr_set->addr_tbl = devm_kcalloc(&pdev->dev, + qdss_addr_set->count, + sizeof(*qdss_addr_set->addr_tbl), GFP_KERNEL); if (!qdss_addr_set->addr_tbl) { dprintk(VIDC_ERR, "%s Failed to alloc register table\n", @@ -259,8 +262,8 @@ static int msm_vidc_load_subcache_info(struct msm_vidc_platform_resources *res) goto err_load_subcache_table_fail; } - subcaches->subcache_tbl = devm_kzalloc(&pdev->dev, - sizeof(*subcaches->subcache_tbl) * num_subcaches, GFP_KERNEL); + subcaches->subcache_tbl = devm_kcalloc(&pdev->dev, + num_subcaches, sizeof(*subcaches->subcache_tbl), GFP_KERNEL); if (!subcaches->subcache_tbl) { dprintk(VIDC_ERR, "Failed to allocate memory for subcache tbl\n"); @@ -326,7 +329,7 @@ int msm_vidc_load_u32_table(struct platform_device *pdev, } num_elemts /= struct_size / sizeof(u32); - ptbl = devm_kzalloc(&pdev->dev, num_elemts * struct_size, GFP_KERNEL); + ptbl = devm_kcalloc(&pdev->dev, struct_size, num_elemts, GFP_KERNEL); if (!ptbl) { dprintk(VIDC_ERR, "Failed to alloc table %s\n", table_name); return -ENOMEM; @@ -498,8 +501,8 @@ static int msm_vidc_load_buffer_usage_table( return 0; } - buffer_usage_set->buffer_usage_tbl = devm_kzalloc(&pdev->dev, - buffer_usage_set->count * + buffer_usage_set->buffer_usage_tbl = devm_kcalloc(&pdev->dev, + buffer_usage_set->count, sizeof(*buffer_usage_set->buffer_usage_tbl), GFP_KERNEL); if (!buffer_usage_set->buffer_usage_tbl) { @@ -554,9 +557,9 @@ static int msm_vidc_load_regulator_table( reg_count++; } - regulators->regulator_tbl = devm_kzalloc(&pdev->dev, - sizeof(*regulators->regulator_tbl) * - reg_count, GFP_KERNEL); + regulators->regulator_tbl = devm_kcalloc(&pdev->dev, + reg_count, sizeof(*regulators->regulator_tbl), + GFP_KERNEL); if (!regulators->regulator_tbl) { rc = -ENOMEM; @@ -638,8 +641,9 @@ static int msm_vidc_load_clock_table( goto err_load_clk_table_fail; } - clock_props = devm_kzalloc(&pdev->dev, num_clocks * - sizeof(*clock_props), GFP_KERNEL); + clock_props = devm_kcalloc(&pdev->dev, + num_clocks, sizeof(*clock_props), + GFP_KERNEL); if (!clock_props) { dprintk(VIDC_ERR, "No memory to read clock properties\n"); rc = -ENOMEM; @@ -654,8 +658,10 @@ static int msm_vidc_load_clock_table( goto err_load_clk_prop_fail; } - clocks->clock_tbl = devm_kzalloc(&pdev->dev, sizeof(*clocks->clock_tbl) - * num_clocks, GFP_KERNEL); + clocks->clock_tbl = devm_kcalloc(&pdev->dev, + num_clocks, + sizeof(*clocks->clock_tbl), + GFP_KERNEL); if (!clocks->clock_tbl) { dprintk(VIDC_ERR, "Failed to allocate memory for clock tbl\n"); rc = -ENOMEM; diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c index 341d2d92af9f..4deed7f6b8ed 100644 --- a/drivers/media/platform/msm/vidc/venus_hfi.c +++ b/drivers/media/platform/msm/vidc/venus_hfi.c @@ -4303,8 +4303,8 @@ static int __init_resources(struct venus_hfi_device *device, dprintk(VIDC_WARN, "Failed to init subcaches: %d\n", rc); device->sys_init_capabilities = - kzalloc(sizeof(struct msm_vidc_capability) - * VIDC_MAX_SESSIONS, GFP_KERNEL); + kcalloc(VIDC_MAX_SESSIONS, sizeof(struct msm_vidc_capability), + GFP_KERNEL); return rc; diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h index 8fe9afeaf625..fa533afa842b 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h @@ -996,10 +996,9 @@ struct hal_fw_info { }; enum hal_flush { - HAL_FLUSH_INPUT, - HAL_FLUSH_OUTPUT, - HAL_FLUSH_ALL, - HAL_UNUSED_FLUSH = 0x10000000, + HAL_FLUSH_INPUT = BIT(0), + HAL_FLUSH_OUTPUT = BIT(1), + HAL_FLUSH_ALL = HAL_FLUSH_INPUT | HAL_FLUSH_OUTPUT, }; enum hal_event_type { diff --git a/drivers/media/platform/qcom/camss-8x16/camss-csid.c b/drivers/media/platform/qcom/camss-8x16/camss-csid.c index 4882ee25bd75..2bf65805f2c1 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-csid.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-csid.c @@ -851,7 +851,7 @@ int msm_csid_subdev_init(struct csid_device *csid, while (res->clock[csid->nclocks]) csid->nclocks++; - csid->clock = devm_kzalloc(dev, csid->nclocks * sizeof(*csid->clock), + csid->clock = devm_kcalloc(dev, csid->nclocks, sizeof(*csid->clock), GFP_KERNEL); if (!csid->clock) return -ENOMEM; @@ -874,8 +874,10 @@ int msm_csid_subdev_init(struct csid_device *csid, continue; } - clock->freq = devm_kzalloc(dev, clock->nfreqs * - sizeof(*clock->freq), GFP_KERNEL); + clock->freq = devm_kcalloc(dev, + clock->nfreqs, + sizeof(*clock->freq), + GFP_KERNEL); if (!clock->freq) return -ENOMEM; diff --git a/drivers/media/platform/qcom/camss-8x16/camss-csiphy.c b/drivers/media/platform/qcom/camss-8x16/camss-csiphy.c index 072c6cf053f6..7e61caba6a2d 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-csiphy.c @@ -732,8 +732,9 @@ int msm_csiphy_subdev_init(struct csiphy_device *csiphy, while (res->clock[csiphy->nclocks]) csiphy->nclocks++; - csiphy->clock = devm_kzalloc(dev, csiphy->nclocks * - sizeof(*csiphy->clock), GFP_KERNEL); + csiphy->clock = devm_kcalloc(dev, + csiphy->nclocks, sizeof(*csiphy->clock), + GFP_KERNEL); if (!csiphy->clock) return -ENOMEM; @@ -755,8 +756,10 @@ int msm_csiphy_subdev_init(struct csiphy_device *csiphy, continue; } - clock->freq = devm_kzalloc(dev, clock->nfreqs * - sizeof(*clock->freq), GFP_KERNEL); + clock->freq = devm_kcalloc(dev, + clock->nfreqs, + sizeof(*clock->freq), + GFP_KERNEL); if (!clock->freq) return -ENOMEM; diff --git a/drivers/media/platform/qcom/camss-8x16/camss-ispif.c b/drivers/media/platform/qcom/camss-8x16/camss-ispif.c index 24da529397b5..9d1af9353c1d 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-ispif.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-ispif.c @@ -948,7 +948,8 @@ int msm_ispif_subdev_init(struct ispif_device *ispif, while (res->clock[ispif->nclocks]) ispif->nclocks++; - ispif->clock = devm_kzalloc(dev, ispif->nclocks * sizeof(*ispif->clock), + ispif->clock = devm_kcalloc(dev, + ispif->nclocks, sizeof(*ispif->clock), GFP_KERNEL); if (!ispif->clock) return -ENOMEM; @@ -968,8 +969,10 @@ int msm_ispif_subdev_init(struct ispif_device *ispif, while (res->clock_for_reset[ispif->nclocks_for_reset]) ispif->nclocks_for_reset++; - ispif->clock_for_reset = devm_kzalloc(dev, ispif->nclocks_for_reset * - sizeof(*ispif->clock_for_reset), GFP_KERNEL); + ispif->clock_for_reset = devm_kcalloc(dev, + ispif->nclocks_for_reset, + sizeof(*ispif->clock_for_reset), + GFP_KERNEL); if (!ispif->clock_for_reset) return -ENOMEM; diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c index 55232a912950..a6329a8a7c4a 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c @@ -2794,7 +2794,7 @@ int msm_vfe_subdev_init(struct vfe_device *vfe, const struct resources *res) while (res->clock[vfe->nclocks]) vfe->nclocks++; - vfe->clock = devm_kzalloc(dev, vfe->nclocks * sizeof(*vfe->clock), + vfe->clock = devm_kcalloc(dev, vfe->nclocks, sizeof(*vfe->clock), GFP_KERNEL); if (!vfe->clock) return -ENOMEM; @@ -2817,8 +2817,10 @@ int msm_vfe_subdev_init(struct vfe_device *vfe, const struct resources *res) continue; } - clock->freq = devm_kzalloc(dev, clock->nfreqs * - sizeof(*clock->freq), GFP_KERNEL); + clock->freq = devm_kcalloc(dev, + clock->nfreqs, + sizeof(*clock->freq), + GFP_KERNEL); if (!clock->freq) return -ENOMEM; diff --git a/drivers/media/platform/qcom/camss-8x16/camss.c b/drivers/media/platform/qcom/camss-8x16/camss.c index a3760b5dd1d1..adcef956cbec 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss.c +++ b/drivers/media/platform/qcom/camss-8x16/camss.c @@ -271,7 +271,8 @@ static int camss_of_parse_endpoint_node(struct device *dev, lncfg->clk.pol = mipi_csi2->lane_polarities[0]; lncfg->num_data = mipi_csi2->num_data_lanes; - lncfg->data = devm_kzalloc(dev, lncfg->num_data * sizeof(*lncfg->data), + lncfg->data = devm_kcalloc(dev, + lncfg->num_data, sizeof(*lncfg->data), GFP_KERNEL); if (!lncfg->data) return -ENOMEM; diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 1f3c450c7a69..d76477806d2d 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -481,7 +481,7 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd) return -ENXIO; icd->user_formats = - vmalloc(fmts * sizeof(struct soc_camera_format_xlate)); + vmalloc(array_size(fmts, sizeof(struct soc_camera_format_xlate))); if (!icd->user_formats) return -ENOMEM; diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c index 5f316a5e38db..0231f42b53fb 100644 --- a/drivers/media/platform/vivid/vivid-core.c +++ b/drivers/media/platform/vivid/vivid-core.c @@ -856,10 +856,10 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) tpg_init(&dev->tpg, 640, 360); if (tpg_alloc(&dev->tpg, MAX_ZOOM * MAX_WIDTH)) goto free_dev; - dev->scaled_line = vzalloc(MAX_ZOOM * MAX_WIDTH); + dev->scaled_line = vzalloc(array_size(MAX_WIDTH, MAX_ZOOM)); if (!dev->scaled_line) goto free_dev; - dev->blended_line = vzalloc(MAX_ZOOM * MAX_WIDTH); + dev->blended_line = vzalloc(array_size(MAX_WIDTH, MAX_ZOOM)); if (!dev->blended_line) goto free_dev; @@ -871,8 +871,9 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) /* create a string array containing the names of all the preset timings */ while (v4l2_dv_timings_presets[dev->query_dv_timings_size].bt.width) dev->query_dv_timings_size++; - dev->query_dv_timings_qmenu = kmalloc(dev->query_dv_timings_size * - (sizeof(void *) + 32), GFP_KERNEL); + dev->query_dv_timings_qmenu = kmalloc_array(dev->query_dv_timings_size, + (sizeof(void *) + 32), + GFP_KERNEL); if (dev->query_dv_timings_qmenu == NULL) goto free_dev; for (i = 0; i < dev->query_dv_timings_size; i++) { diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c index 54de15095709..51ff3d8f39f3 100644 --- a/drivers/media/platform/vsp1/vsp1_entity.c +++ b/drivers/media/platform/vsp1/vsp1_entity.c @@ -511,7 +511,8 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity, entity->source_pad = num_pads - 1; /* Allocate and initialize pads. */ - entity->pads = devm_kzalloc(vsp1->dev, num_pads * sizeof(*entity->pads), + entity->pads = devm_kcalloc(vsp1->dev, + num_pads, sizeof(*entity->pads), GFP_KERNEL); if (entity->pads == NULL) return -ENOMEM; diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c index ebfdf334d99c..3bd3d640de59 100644 --- a/drivers/media/platform/xilinx/xilinx-vipp.c +++ b/drivers/media/platform/xilinx/xilinx-vipp.c @@ -535,7 +535,7 @@ static int xvip_graph_init(struct xvip_composite_device *xdev) /* Register the subdevices notifier. */ num_subdevs = xdev->num_subdevs; - subdevs = devm_kzalloc(xdev->dev, sizeof(*subdevs) * num_subdevs, + subdevs = devm_kcalloc(xdev->dev, num_subdevs, sizeof(*subdevs), GFP_KERNEL); if (subdevs == NULL) { ret = -ENOMEM; diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 067f46c4f61a..8c0acec48e5e 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -217,14 +217,14 @@ static int au0828_init_isoc(struct au0828_dev *dev, int max_packets, dev->isoc_ctl.isoc_copy = isoc_copy; dev->isoc_ctl.num_bufs = num_bufs; - dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); + dev->isoc_ctl.urb = kcalloc(num_bufs, sizeof(void *), GFP_KERNEL); if (!dev->isoc_ctl.urb) { au0828_isocdbg("cannot alloc memory for usb buffers\n"); return -ENOMEM; } - dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, - GFP_KERNEL); + dev->isoc_ctl.transfer_buffer = kcalloc(num_bufs, sizeof(void *), + GFP_KERNEL); if (!dev->isoc_ctl.transfer_buffer) { au0828_isocdbg("cannot allocate memory for usb transfer\n"); kfree(dev->isoc_ctl.urb); diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c index 91b9eaa9b2ad..f23c2fa324ac 100644 --- a/drivers/media/usb/cpia2/cpia2_usb.c +++ b/drivers/media/usb/cpia2/cpia2_usb.c @@ -663,7 +663,8 @@ static int submit_urbs(struct camera_data *cam) if (cam->sbuf[i].data) continue; cam->sbuf[i].data = - kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL); + kmalloc_array(FRAME_SIZE_PER_DESC, FRAMES_PER_DESC, + GFP_KERNEL); if (!cam->sbuf[i].data) { while (--i >= 0) { kfree(cam->sbuf[i].data); diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c index 06f10d7fc4b0..06d9a672faa6 100644 --- a/drivers/media/usb/cx231xx/cx231xx-audio.c +++ b/drivers/media/usb/cx231xx/cx231xx-audio.c @@ -710,7 +710,7 @@ static int cx231xx_audio_init(struct cx231xx *dev) dev_info(dev->dev, "audio EndPoint Addr 0x%x, Alternate settings: %i\n", adev->end_point_addr, adev->num_alt); - adev->alt_max_pkt_size = kmalloc(32 * adev->num_alt, GFP_KERNEL); + adev->alt_max_pkt_size = kmalloc_array(32, adev->num_alt, GFP_KERNEL); if (!adev->alt_max_pkt_size) { err = -ENOMEM; goto err_free_card; diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index f372ad3917a8..d10c2c5367d8 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -1034,7 +1034,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, dma_q->partial_buf[i] = 0; dev->video_mode.isoc_ctl.urb = - kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); + kcalloc(num_bufs, sizeof(void *), GFP_KERNEL); if (!dev->video_mode.isoc_ctl.urb) { dev_err(dev->dev, "cannot alloc memory for usb buffers\n"); @@ -1042,7 +1042,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, } dev->video_mode.isoc_ctl.transfer_buffer = - kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); + kcalloc(num_bufs, sizeof(void *), GFP_KERNEL); if (!dev->video_mode.isoc_ctl.transfer_buffer) { dev_err(dev->dev, "cannot allocate memory for usbtransfer\n"); @@ -1169,7 +1169,7 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, dma_q->partial_buf[i] = 0; dev->video_mode.bulk_ctl.urb = - kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); + kcalloc(num_bufs, sizeof(void *), GFP_KERNEL); if (!dev->video_mode.bulk_ctl.urb) { dev_err(dev->dev, "cannot alloc memory for usb buffers\n"); @@ -1177,7 +1177,7 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, } dev->video_mode.bulk_ctl.transfer_buffer = - kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); + kcalloc(num_bufs, sizeof(void *), GFP_KERNEL); if (!dev->video_mode.bulk_ctl.transfer_buffer) { dev_err(dev->dev, "cannot allocate memory for usbtransfer\n"); diff --git a/drivers/media/usb/cx231xx/cx231xx-vbi.c b/drivers/media/usb/cx231xx/cx231xx-vbi.c index 76e901920f6f..ccc42b693064 100644 --- a/drivers/media/usb/cx231xx/cx231xx-vbi.c +++ b/drivers/media/usb/cx231xx/cx231xx-vbi.c @@ -415,7 +415,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, for (i = 0; i < 8; i++) dma_q->partial_buf[i] = 0; - dev->vbi_mode.bulk_ctl.urb = kzalloc(sizeof(void *) * num_bufs, + dev->vbi_mode.bulk_ctl.urb = kcalloc(num_bufs, sizeof(void *), GFP_KERNEL); if (!dev->vbi_mode.bulk_ctl.urb) { dev_err(dev->dev, @@ -424,7 +424,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, } dev->vbi_mode.bulk_ctl.transfer_buffer = - kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); + kcalloc(num_bufs, sizeof(void *), GFP_KERNEL); if (!dev->vbi_mode.bulk_ctl.transfer_buffer) { dev_err(dev->dev, "cannot allocate memory for usbtransfer\n"); diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 9747e23aad27..f00f95d035bd 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -3500,8 +3500,9 @@ static int em28xx_usb_probe(struct usb_interface *interface, /* compute alternate max packet sizes */ dev->alt_max_pkt_size_isoc = - kmalloc(sizeof(dev->alt_max_pkt_size_isoc[0]) * - interface->num_altsetting, GFP_KERNEL); + kmalloc_array(interface->num_altsetting, + sizeof(dev->alt_max_pkt_size_isoc[0]), + GFP_KERNEL); if (dev->alt_max_pkt_size_isoc == NULL) { kfree(dev); retval = -ENOMEM; diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 1d0d8cc06103..476666ffab96 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -912,11 +912,11 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, usb_bufs->num_bufs = num_bufs; - usb_bufs->urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); + usb_bufs->urb = kcalloc(num_bufs, sizeof(void *), GFP_KERNEL); if (!usb_bufs->urb) return -ENOMEM; - usb_bufs->transfer_buffer = kzalloc(sizeof(void *)*num_bufs, + usb_bufs->transfer_buffer = kcalloc(num_bufs, sizeof(void *), GFP_KERNEL); if (!usb_bufs->transfer_buffer) { kfree(usb_bufs->urb); diff --git a/drivers/media/usb/go7007/go7007-fw.c b/drivers/media/usb/go7007/go7007-fw.c index a5efcd4f7b4f..e4b318fe8fc8 100644 --- a/drivers/media/usb/go7007/go7007-fw.c +++ b/drivers/media/usb/go7007/go7007-fw.c @@ -1576,7 +1576,7 @@ int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen) GO7007_FW_NAME); return -1; } - code = kzalloc(codespace * 2, GFP_KERNEL); + code = kcalloc(codespace, 2, GFP_KERNEL); if (code == NULL) goto fw_failed; diff --git a/drivers/media/usb/go7007/go7007-usb.c b/drivers/media/usb/go7007/go7007-usb.c index ed9bcaf08d5e..19c6a0354ce0 100644 --- a/drivers/media/usb/go7007/go7007-usb.c +++ b/drivers/media/usb/go7007/go7007-usb.c @@ -1143,7 +1143,8 @@ static int go7007_usb_probe(struct usb_interface *intf, usb->intr_urb = usb_alloc_urb(0, GFP_KERNEL); if (usb->intr_urb == NULL) goto allocfail; - usb->intr_urb->transfer_buffer = kmalloc(2*sizeof(u16), GFP_KERNEL); + usb->intr_urb->transfer_buffer = kmalloc_array(2, sizeof(u16), + GFP_KERNEL); if (usb->intr_urb->transfer_buffer == NULL) goto allocfail; diff --git a/drivers/media/usb/gspca/t613.c b/drivers/media/usb/gspca/t613.c index 46fb76349000..ce5c6464220f 100644 --- a/drivers/media/usb/gspca/t613.c +++ b/drivers/media/usb/gspca/t613.c @@ -363,7 +363,7 @@ static void reg_w_ixbuf(struct gspca_dev *gspca_dev, if (len * 2 <= USB_BUF_SZ) { p = tmpbuf = gspca_dev->usb_buf; } else { - p = tmpbuf = kmalloc(len * 2, GFP_KERNEL); + p = tmpbuf = kmalloc_array(len, 2, GFP_KERNEL); if (!tmpbuf) { pr_err("Out of memory\n"); return; diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index 18db7aaafcd6..38bf44edafc4 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @@ -2417,7 +2417,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, hdw->control_cnt = CTRLDEF_COUNT; hdw->control_cnt += MPEGDEF_COUNT; - hdw->controls = kzalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt, + hdw->controls = kcalloc(hdw->control_cnt, sizeof(struct pvr2_ctrl), GFP_KERNEL); if (!hdw->controls) goto fail; hdw->hdw_desc = hdw_desc; diff --git a/drivers/media/usb/pvrusb2/pvrusb2-std.c b/drivers/media/usb/pvrusb2/pvrusb2-std.c index 243e2704ce3a..37dc299a1ca2 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-std.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-std.c @@ -361,7 +361,7 @@ struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr, std_cnt); if (!std_cnt) return NULL; // paranoia - stddefs = kzalloc(sizeof(struct v4l2_standard) * std_cnt, + stddefs = kcalloc(std_cnt, sizeof(struct v4l2_standard), GFP_KERNEL); if (!stddefs) return NULL; diff --git a/drivers/media/usb/stk1160/stk1160-core.c b/drivers/media/usb/stk1160/stk1160-core.c index bea8bbbb84fb..e5acd2a4fc19 100644 --- a/drivers/media/usb/stk1160/stk1160-core.c +++ b/drivers/media/usb/stk1160/stk1160-core.c @@ -288,8 +288,9 @@ static int stk1160_probe(struct usb_interface *interface, return -ENODEV; /* Alloc an array for all possible max_pkt_size */ - alt_max_pkt_size = kmalloc(sizeof(alt_max_pkt_size[0]) * - interface->num_altsetting, GFP_KERNEL); + alt_max_pkt_size = kmalloc_array(interface->num_altsetting, + sizeof(alt_max_pkt_size[0]), + GFP_KERNEL); if (alt_max_pkt_size == NULL) return -ENOMEM; diff --git a/drivers/media/usb/stk1160/stk1160-video.c b/drivers/media/usb/stk1160/stk1160-video.c index ce8ebbe395a6..0c8378739593 100644 --- a/drivers/media/usb/stk1160/stk1160-video.c +++ b/drivers/media/usb/stk1160/stk1160-video.c @@ -439,14 +439,14 @@ int stk1160_alloc_isoc(struct stk1160 *dev) dev->isoc_ctl.buf = NULL; dev->isoc_ctl.max_pkt_size = dev->max_pkt_size; - dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); + dev->isoc_ctl.urb = kcalloc(num_bufs, sizeof(void *), GFP_KERNEL); if (!dev->isoc_ctl.urb) { stk1160_err("out of memory for urb array\n"); return -ENOMEM; } - dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, - GFP_KERNEL); + dev->isoc_ctl.transfer_buffer = kcalloc(num_bufs, sizeof(void *), + GFP_KERNEL); if (!dev->isoc_ctl.transfer_buffer) { stk1160_err("out of memory for usb transfers\n"); kfree(dev->isoc_ctl.urb); diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index 6992e84f8a8b..c4238f5ffc29 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -571,8 +571,9 @@ static int stk_prepare_sio_buffers(struct stk_camera *dev, unsigned n_sbufs) if (dev->sio_bufs != NULL) pr_err("sio_bufs already allocated\n"); else { - dev->sio_bufs = kzalloc(n_sbufs * sizeof(struct stk_sio_buffer), - GFP_KERNEL); + dev->sio_bufs = kcalloc(n_sbufs, + sizeof(struct stk_sio_buffer), + GFP_KERNEL); if (dev->sio_bufs == NULL) return -ENOMEM; for (i = 0; i < n_sbufs; i++) { diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c index ec8c4d2534dc..e3b2470ce61a 100644 --- a/drivers/media/usb/tm6000/tm6000-video.c +++ b/drivers/media/usb/tm6000/tm6000-video.c @@ -473,13 +473,14 @@ static int tm6000_alloc_urb_buffers(struct tm6000_core *dev) if (dev->urb_buffer != NULL) return 0; - dev->urb_buffer = kmalloc(sizeof(void *)*num_bufs, GFP_KERNEL); + dev->urb_buffer = kmalloc_array(num_bufs, sizeof(void *), GFP_KERNEL); if (!dev->urb_buffer) { tm6000_err("cannot allocate memory for urb buffers\n"); return -ENOMEM; } - dev->urb_dma = kmalloc(sizeof(dma_addr_t *)*num_bufs, GFP_KERNEL); + dev->urb_dma = kmalloc_array(num_bufs, sizeof(dma_addr_t *), + GFP_KERNEL); if (!dev->urb_dma) { tm6000_err("cannot allocate memory for urb dma pointers\n"); return -ENOMEM; @@ -597,14 +598,16 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev) dev->isoc_ctl.num_bufs = num_bufs; - dev->isoc_ctl.urb = kmalloc(sizeof(void *)*num_bufs, GFP_KERNEL); + dev->isoc_ctl.urb = kmalloc_array(num_bufs, sizeof(void *), + GFP_KERNEL); if (!dev->isoc_ctl.urb) { tm6000_err("cannot alloc memory for usb buffers\n"); return -ENOMEM; } - dev->isoc_ctl.transfer_buffer = kmalloc(sizeof(void *)*num_bufs, - GFP_KERNEL); + dev->isoc_ctl.transfer_buffer = kmalloc_array(num_bufs, + sizeof(void *), + GFP_KERNEL); if (!dev->isoc_ctl.transfer_buffer) { tm6000_err("cannot allocate memory for usbtransfer\n"); kfree(dev->isoc_ctl.urb); diff --git a/drivers/media/usb/usbtv/usbtv-video.c b/drivers/media/usb/usbtv/usbtv-video.c index 7c23d82313a8..3c5960c24f1b 100644 --- a/drivers/media/usb/usbtv/usbtv-video.c +++ b/drivers/media/usb/usbtv/usbtv-video.c @@ -424,7 +424,7 @@ static struct urb *usbtv_setup_iso_transfer(struct usbtv *usbtv) ip->pipe = usb_rcvisocpipe(usbtv->udev, USBTV_VIDEO_ENDP); ip->interval = 1; ip->transfer_flags = URB_ISO_ASAP; - ip->transfer_buffer = kzalloc(size * USBTV_ISOC_PACKETS, + ip->transfer_buffer = kcalloc(USBTV_ISOC_PACKETS, size, GFP_KERNEL); if (!ip->transfer_buffer) { usb_free_urb(ip); diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c index 4c39c502d616..dc4a2c7d153d 100644 --- a/drivers/media/usb/usbvision/usbvision-video.c +++ b/drivers/media/usb/usbvision/usbvision-video.c @@ -1506,7 +1506,8 @@ static int usbvision_probe(struct usb_interface *intf, usbvision->num_alt = uif->num_altsetting; PDEBUG(DBG_PROBE, "Alternate settings: %i", usbvision->num_alt); - usbvision->alt_max_pkt_size = kmalloc(32 * usbvision->num_alt, GFP_KERNEL); + usbvision->alt_max_pkt_size = kmalloc_array(32, usbvision->num_alt, + GFP_KERNEL); if (!usbvision->alt_max_pkt_size) { ret = -ENOMEM; goto err_pkt; diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 591ca125bd96..25df6e76fa5f 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -268,7 +268,7 @@ void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator, uint32_t x, y, r; unsigned int i, n; - an = kmalloc(n_terms * sizeof *an, GFP_KERNEL); + an = kmalloc_array(n_terms, sizeof(*an), GFP_KERNEL); if (an == NULL) return; diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index 393371916381..929a445bdeab 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -513,8 +513,8 @@ static int uvc_video_clock_init(struct uvc_streaming *stream) spin_lock_init(&clock->lock); clock->size = 32; - clock->samples = kmalloc(clock->size * sizeof(*clock->samples), - GFP_KERNEL); + clock->samples = kmalloc_array(clock->size, sizeof(*clock->samples), + GFP_KERNEL); if (clock->samples == NULL) return -ENOMEM; diff --git a/drivers/media/v4l2-core/v4l2-event.c b/drivers/media/v4l2-core/v4l2-event.c index 011907eff660..481e3c65cf97 100644 --- a/drivers/media/v4l2-core/v4l2-event.c +++ b/drivers/media/v4l2-core/v4l2-event.c @@ -224,8 +224,7 @@ int v4l2_event_subscribe(struct v4l2_fh *fh, if (elems < 1) elems = 1; - sev = kvzalloc(sizeof(*sev) + sizeof(struct v4l2_kevent) * elems, - GFP_KERNEL); + sev = kvzalloc(struct_size(sev, events, elems), GFP_KERNEL); if (!sev) return -ENOMEM; for (i = 0; i < elems; i++) diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c index 4ceef217de83..215b4804ada2 100644 --- a/drivers/media/v4l2-core/v4l2-flash-led-class.c +++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c @@ -412,9 +412,10 @@ static int v4l2_flash_init_controls(struct v4l2_flash *v4l2_flash, struct v4l2_ctrl_config *ctrl_cfg; int i, ret, num_ctrls = 0; - v4l2_flash->ctrls = devm_kzalloc(v4l2_flash->sd.dev, - sizeof(*v4l2_flash->ctrls) * - (STROBE_SOURCE + 1), GFP_KERNEL); + v4l2_flash->ctrls = devm_kcalloc(v4l2_flash->sd.dev, + STROBE_SOURCE + 1, + sizeof(*v4l2_flash->ctrls), + GFP_KERNEL); if (!v4l2_flash->ctrls) return -ENOMEM; diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c index c55e607f5631..fe44715fc84f 100644 --- a/drivers/media/v4l2-core/videobuf-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf-dma-sg.c @@ -69,7 +69,7 @@ static struct scatterlist *videobuf_vmalloc_to_sg(unsigned char *virt, struct page *pg; int i; - sglist = vzalloc(nr_pages * sizeof(*sglist)); + sglist = vzalloc(array_size(nr_pages, sizeof(*sglist))); if (NULL == sglist) return NULL; sg_init_table(sglist, nr_pages); @@ -100,7 +100,7 @@ static struct scatterlist *videobuf_pages_to_sg(struct page **pages, if (NULL == pages[0]) return NULL; - sglist = vmalloc(nr_pages * sizeof(*sglist)); + sglist = vmalloc(array_size(nr_pages, sizeof(*sglist))); if (NULL == sglist) return NULL; sg_init_table(sglist, nr_pages); @@ -175,7 +175,8 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, dma->offset = data & ~PAGE_MASK; dma->size = size; dma->nr_pages = last-first+1; - dma->pages = kmalloc(dma->nr_pages * sizeof(struct page *), GFP_KERNEL); + dma->pages = kmalloc_array(dma->nr_pages, sizeof(struct page *), + GFP_KERNEL); if (NULL == dma->pages) return -ENOMEM; diff --git a/drivers/memory/of_memory.c b/drivers/memory/of_memory.c index 568f05ed961a..2f5ed7366eec 100644 --- a/drivers/memory/of_memory.c +++ b/drivers/memory/of_memory.c @@ -126,8 +126,8 @@ const struct lpddr2_timings *of_get_ddr_timings(struct device_node *np_ddr, arr_sz++; if (arr_sz) - timings = devm_kzalloc(dev, sizeof(*timings) * arr_sz, - GFP_KERNEL); + timings = devm_kcalloc(dev, arr_sz, sizeof(*timings), + GFP_KERNEL); if (!timings) goto default_timings; diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c index 22de7f5ed032..072fc73d8fe9 100644 --- a/drivers/memstick/core/ms_block.c +++ b/drivers/memstick/core/ms_block.c @@ -1201,7 +1201,8 @@ static int msb_read_boot_blocks(struct msb_data *msb) dbg_verbose("Start of a scan for the boot blocks"); if (!msb->boot_page) { - page = kmalloc(sizeof(struct ms_boot_page)*2, GFP_KERNEL); + page = kmalloc_array(2, sizeof(struct ms_boot_page), + GFP_KERNEL); if (!page) return -ENOMEM; @@ -1341,7 +1342,8 @@ static int msb_ftl_initialize(struct msb_data *msb) msb->used_blocks_bitmap = kzalloc(msb->block_count / 8, GFP_KERNEL); msb->erased_blocks_bitmap = kzalloc(msb->block_count / 8, GFP_KERNEL); msb->lba_to_pba_table = - kmalloc(msb->logical_block_count * sizeof(u16), GFP_KERNEL); + kmalloc_array(msb->logical_block_count, sizeof(u16), + GFP_KERNEL); if (!msb->used_blocks_bitmap || !msb->lba_to_pba_table || !msb->erased_blocks_bitmap) { diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index 55dd71bbdc2a..e8b96383e253 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c @@ -394,7 +394,8 @@ mpt_lan_open(struct net_device *dev) "a moment.\n"); } - priv->mpt_txfidx = kmalloc(priv->tx_max_out * sizeof(int), GFP_KERNEL); + priv->mpt_txfidx = kmalloc_array(priv->tx_max_out, sizeof(int), + GFP_KERNEL); if (priv->mpt_txfidx == NULL) goto out; priv->mpt_txfidx_tail = -1; @@ -408,8 +409,8 @@ mpt_lan_open(struct net_device *dev) dlprintk((KERN_INFO MYNAM "@lo: Finished initializing SendCtl\n")); - priv->mpt_rxfidx = kmalloc(priv->max_buckets_out * sizeof(int), - GFP_KERNEL); + priv->mpt_rxfidx = kmalloc_array(priv->max_buckets_out, sizeof(int), + GFP_KERNEL); if (priv->mpt_rxfidx == NULL) goto out_SendCtl; priv->mpt_rxfidx_tail = -1; diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 28c3ee38b081..eba2a4488823 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -2952,18 +2952,18 @@ static int ab8500_debug_probe(struct platform_device *plf) ab8500 = dev_get_drvdata(plf->dev.parent); num_irqs = ab8500->mask_size; - irq_count = devm_kzalloc(&plf->dev, - sizeof(*irq_count)*num_irqs, GFP_KERNEL); + irq_count = devm_kcalloc(&plf->dev, + num_irqs, sizeof(*irq_count), GFP_KERNEL); if (!irq_count) return -ENOMEM; - dev_attr = devm_kzalloc(&plf->dev, - sizeof(*dev_attr)*num_irqs, GFP_KERNEL); + dev_attr = devm_kcalloc(&plf->dev, + num_irqs, sizeof(*dev_attr), GFP_KERNEL); if (!dev_attr) return -ENOMEM; - event_name = devm_kzalloc(&plf->dev, - sizeof(*event_name)*num_irqs, GFP_KERNEL); + event_name = devm_kcalloc(&plf->dev, + num_irqs, sizeof(*event_name), GFP_KERNEL); if (!event_name) return -ENOMEM; diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c index 3f9eee5f8fb9..9428326608ed 100644 --- a/drivers/mfd/htc-i2cpld.c +++ b/drivers/mfd/htc-i2cpld.c @@ -477,7 +477,9 @@ static int htcpld_setup_chips(struct platform_device *pdev) /* Setup each chip's output GPIOs */ htcpld->nchips = pdata->num_chip; - htcpld->chip = devm_kzalloc(dev, sizeof(struct htcpld_chip) * htcpld->nchips, + htcpld->chip = devm_kcalloc(dev, + htcpld->nchips, + sizeof(struct htcpld_chip), GFP_KERNEL); if (!htcpld->chip) { dev_warn(dev, "Unable to allocate memory for chips\n"); diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 5c8ed2150c8b..182973df1aed 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -158,7 +158,7 @@ static int mfd_add_device(struct device *parent, int id, if (!pdev) goto fail_alloc; - res = kzalloc(sizeof(*res) * cell->num_resources, GFP_KERNEL); + res = kcalloc(cell->num_resources, sizeof(*res), GFP_KERNEL); if (!res) goto fail_device; diff --git a/drivers/mfd/motorola-cpcap.c b/drivers/mfd/motorola-cpcap.c index d2cc1eabac05..8198c9c25a9e 100644 --- a/drivers/mfd/motorola-cpcap.c +++ b/drivers/mfd/motorola-cpcap.c @@ -173,9 +173,7 @@ static int cpcap_init_irq(struct cpcap_ddata *cpcap) int ret; cpcap->irqs = devm_kzalloc(&cpcap->spi->dev, - sizeof(*cpcap->irqs) * - CPCAP_NR_IRQ_REG_BANKS * - cpcap->regmap_conf->val_bits, + array3_size(sizeof(*cpcap->irqs), CPCAP_NR_IRQ_REG_BANKS, cpcap->regmap_conf->val_bits), GFP_KERNEL); if (!cpcap->irqs) return -ENOMEM; diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c index 44a5d66314c6..f40fc8d59f13 100644 --- a/drivers/mfd/omap-usb-tll.c +++ b/drivers/mfd/omap-usb-tll.c @@ -254,7 +254,7 @@ static int usbtll_omap_probe(struct platform_device *pdev) break; } - tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk *) * tll->nch, + tll->ch_clk = devm_kcalloc(dev, tll->nch, sizeof(struct clk *), GFP_KERNEL); if (!tll->ch_clk) { ret = -ENOMEM; diff --git a/drivers/mfd/qcom-pm8xxx.c b/drivers/mfd/qcom-pm8xxx.c index f08758f6b418..e6e8d81c15fd 100644 --- a/drivers/mfd/qcom-pm8xxx.c +++ b/drivers/mfd/qcom-pm8xxx.c @@ -563,8 +563,8 @@ static int pm8xxx_probe(struct platform_device *pdev) pr_info("PMIC revision 2: %02X\n", val); rev |= val << BITS_PER_BYTE; - chip = devm_kzalloc(&pdev->dev, sizeof(*chip) + - sizeof(chip->config[0]) * data->num_irqs, + chip = devm_kzalloc(&pdev->dev, + struct_size(chip, config, data->num_irqs), GFP_KERNEL); if (!chip) return -ENOMEM; diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c index cd4a6d7d6750..07579fc0d93c 100644 --- a/drivers/mfd/timberdale.c +++ b/drivers/mfd/timberdale.c @@ -707,8 +707,8 @@ static int timb_probe(struct pci_dev *dev, goto err_config; } - msix_entries = kzalloc(TIMBERDALE_NR_IRQS * sizeof(*msix_entries), - GFP_KERNEL); + msix_entries = kcalloc(TIMBERDALE_NR_IRQS, sizeof(*msix_entries), + GFP_KERNEL); if (!msix_entries) goto err_config; diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 8f993272901d..13315039e0a4 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -1139,8 +1139,9 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) } num_slaves = twl_get_num_slaves(); - twl_priv->twl_modules = devm_kzalloc(&client->dev, - sizeof(struct twl_client) * num_slaves, + twl_priv->twl_modules = devm_kcalloc(&client->dev, + num_slaves, + sizeof(struct twl_client), GFP_KERNEL); if (!twl_priv->twl_modules) { status = -ENOMEM; diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index 3259fb82d3c4..56a4c7c65c44 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c @@ -368,9 +368,10 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) goto err; } - wm8994->supplies = devm_kzalloc(wm8994->dev, - sizeof(struct regulator_bulk_data) * - wm8994->num_supplies, GFP_KERNEL); + wm8994->supplies = devm_kcalloc(wm8994->dev, + wm8994->num_supplies, + sizeof(struct regulator_bulk_data), + GFP_KERNEL); if (!wm8994->supplies) { ret = -ENOMEM; goto err; diff --git a/drivers/misc/altera-stapl/altera.c b/drivers/misc/altera-stapl/altera.c index b7ee8043a133..94bde09d9323 100644 --- a/drivers/misc/altera-stapl/altera.c +++ b/drivers/misc/altera-stapl/altera.c @@ -304,13 +304,13 @@ static int altera_execute(struct altera_state *astate, if (sym_count <= 0) goto exit_done; - vars = kzalloc(sym_count * sizeof(long), GFP_KERNEL); + vars = kcalloc(sym_count, sizeof(long), GFP_KERNEL); if (vars == NULL) status = -ENOMEM; if (status == 0) { - var_size = kzalloc(sym_count * sizeof(s32), GFP_KERNEL); + var_size = kcalloc(sym_count, sizeof(s32), GFP_KERNEL); if (var_size == NULL) status = -ENOMEM; @@ -1136,7 +1136,7 @@ exit_done: /* Allocate a writable buffer for this array */ count = var_size[variable_id]; long_tmp = vars[variable_id]; - longptr_tmp = kzalloc(count * sizeof(long), + longptr_tmp = kcalloc(count, sizeof(long), GFP_KERNEL); vars[variable_id] = (long)longptr_tmp; diff --git a/drivers/misc/cb710/core.c b/drivers/misc/cb710/core.c index fb397e7d1cce..4d4acf763b65 100644 --- a/drivers/misc/cb710/core.c +++ b/drivers/misc/cb710/core.c @@ -232,8 +232,8 @@ static int cb710_probe(struct pci_dev *pdev, if (val & CB710_SLOT_SM) ++n; - chip = devm_kzalloc(&pdev->dev, - sizeof(*chip) + n * sizeof(*chip->slot), GFP_KERNEL); + chip = devm_kzalloc(&pdev->dev, struct_size(chip, slot, n), + GFP_KERNEL); if (!chip) return -ENOMEM; diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c index de2ce5539545..73cbd1544a7b 100644 --- a/drivers/misc/cxl/guest.c +++ b/drivers/misc/cxl/guest.c @@ -89,7 +89,7 @@ static ssize_t guest_collect_vpd(struct cxl *adapter, struct cxl_afu *afu, mod = 0; } - vpd_buf = kzalloc(entries * sizeof(unsigned long *), GFP_KERNEL); + vpd_buf = kcalloc(entries, sizeof(unsigned long *), GFP_KERNEL); if (!vpd_buf) return -ENOMEM; diff --git a/drivers/misc/cxl/of.c b/drivers/misc/cxl/of.c index ec175ea5dfba..aff181cd0bf2 100644 --- a/drivers/misc/cxl/of.c +++ b/drivers/misc/cxl/of.c @@ -302,7 +302,7 @@ static int read_adapter_irq_config(struct cxl *adapter, struct device_node *np) if (nranges == 0 || (nranges * 2 * sizeof(int)) != len) return -EINVAL; - adapter->guest->irq_avail = kzalloc(nranges * sizeof(struct irq_avail), + adapter->guest->irq_avail = kcalloc(nranges, sizeof(struct irq_avail), GFP_KERNEL); if (adapter->guest->irq_avail == NULL) return -ENOMEM; diff --git a/drivers/misc/eeprom/idt_89hpesx.c b/drivers/misc/eeprom/idt_89hpesx.c index 34a5a41578d7..59dc24bb70ec 100644 --- a/drivers/misc/eeprom/idt_89hpesx.c +++ b/drivers/misc/eeprom/idt_89hpesx.c @@ -964,7 +964,7 @@ static ssize_t idt_dbgfs_csr_write(struct file *filep, const char __user *ubuf, if (colon_ch != NULL) { csraddr_len = colon_ch - buf; csraddr_str = - kmalloc(sizeof(char)*(csraddr_len + 1), GFP_KERNEL); + kmalloc(csraddr_len + 1, GFP_KERNEL); if (csraddr_str == NULL) { ret = -ENOMEM; goto free_buf; diff --git a/drivers/misc/genwqe/card_ddcb.c b/drivers/misc/genwqe/card_ddcb.c index ddfeefe39540..9af976db90a0 100644 --- a/drivers/misc/genwqe/card_ddcb.c +++ b/drivers/misc/genwqe/card_ddcb.c @@ -1048,15 +1048,16 @@ static int setup_ddcb_queue(struct genwqe_dev *cd, struct ddcb_queue *queue) "[%s] **err: could not allocate DDCB **\n", __func__); return -ENOMEM; } - queue->ddcb_req = kzalloc(sizeof(struct ddcb_requ *) * - queue->ddcb_max, GFP_KERNEL); + queue->ddcb_req = kcalloc(queue->ddcb_max, sizeof(struct ddcb_requ *), + GFP_KERNEL); if (!queue->ddcb_req) { rc = -ENOMEM; goto free_ddcbs; } - queue->ddcb_waitqs = kzalloc(sizeof(wait_queue_head_t) * - queue->ddcb_max, GFP_KERNEL); + queue->ddcb_waitqs = kcalloc(queue->ddcb_max, + sizeof(wait_queue_head_t), + GFP_KERNEL); if (!queue->ddcb_waitqs) { rc = -ENOMEM; goto free_requs; diff --git a/drivers/misc/memory_state_time.c b/drivers/misc/memory_state_time.c index ba94dcf09169..ab8d5c11eaed 100644 --- a/drivers/misc/memory_state_time.c +++ b/drivers/misc/memory_state_time.c @@ -301,13 +301,13 @@ static int get_bw_buckets(struct device *dev) return -ENODATA; } - bandwidths = devm_kzalloc(dev, - sizeof(*bandwidths) * num_sources, GFP_KERNEL); + bandwidths = devm_kcalloc(dev, + num_sources, sizeof(*bandwidths), GFP_KERNEL); if (!bandwidths) return -ENOMEM; lenb /= sizeof(*bw_buckets); - bw_buckets = devm_kzalloc(dev, lenb * sizeof(*bw_buckets), - GFP_KERNEL); + bw_buckets = devm_kcalloc(dev, lenb, sizeof(*bw_buckets), + GFP_KERNEL); if (!bw_buckets) { devm_kfree(dev, bandwidths); return -ENOMEM; @@ -342,8 +342,8 @@ static int freq_buckets_init(struct device *dev) } lenf /= sizeof(*freq_buckets); - freq_buckets = devm_kzalloc(dev, lenf * sizeof(*freq_buckets), - GFP_KERNEL); + freq_buckets = devm_kcalloc(dev, lenf, sizeof(*freq_buckets), + GFP_KERNEL); if (!freq_buckets) return -ENOMEM; pr_debug("freqs found len %d\n", lenf); @@ -364,8 +364,9 @@ static int freq_buckets_init(struct device *dev) GFP_KERNEL); if (!freq_entry) return -ENOMEM; - freq_entry->buckets = devm_kzalloc(dev, sizeof(u64)*num_buckets, - GFP_KERNEL); + freq_entry->buckets = devm_kcalloc(dev, + num_buckets, sizeof(u64), + GFP_KERNEL); if (!freq_entry->buckets) { devm_kfree(dev, freq_entry); return -ENOMEM; diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c index 7f327121e6d7..f1bce8335575 100644 --- a/drivers/misc/sgi-xp/xpc_main.c +++ b/drivers/misc/sgi-xp/xpc_main.c @@ -417,7 +417,8 @@ xpc_setup_ch_structures(struct xpc_partition *part) * memory. */ DBUG_ON(part->channels != NULL); - part->channels = kzalloc(sizeof(struct xpc_channel) * XPC_MAX_NCHANNELS, + part->channels = kcalloc(XPC_MAX_NCHANNELS, + sizeof(struct xpc_channel), GFP_KERNEL); if (part->channels == NULL) { dev_err(xpc_chan, "can't get memory for channels\n"); @@ -906,8 +907,9 @@ xpc_setup_partitions(void) short partid; struct xpc_partition *part; - xpc_partitions = kzalloc(sizeof(struct xpc_partition) * - xp_max_npartitions, GFP_KERNEL); + xpc_partitions = kcalloc(xp_max_npartitions, + sizeof(struct xpc_partition), + GFP_KERNEL); if (xpc_partitions == NULL) { dev_err(xpc_part, "can't get memory for partition structure\n"); return -ENOMEM; diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c index ca5f0102daef..b6da4fe6c7bf 100644 --- a/drivers/misc/sgi-xp/xpc_partition.c +++ b/drivers/misc/sgi-xp/xpc_partition.c @@ -425,7 +425,7 @@ xpc_discovery(void) if (remote_rp == NULL) return; - discovered_nasids = kzalloc(sizeof(long) * xpc_nasid_mask_nlongs, + discovered_nasids = kcalloc(xpc_nasid_mask_nlongs, sizeof(long), GFP_KERNEL); if (discovered_nasids == NULL) { kfree(remote_rp_base); diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c index 0c26eaf5f62b..1704fd426ad7 100644 --- a/drivers/misc/sgi-xp/xpnet.c +++ b/drivers/misc/sgi-xp/xpnet.c @@ -520,8 +520,9 @@ xpnet_init(void) dev_info(xpnet, "registering network device %s\n", XPNET_DEVICE_NAME); - xpnet_broadcast_partitions = kzalloc(BITS_TO_LONGS(xp_max_npartitions) * - sizeof(long), GFP_KERNEL); + xpnet_broadcast_partitions = kcalloc(BITS_TO_LONGS(xp_max_npartitions), + sizeof(long), + GFP_KERNEL); if (xpnet_broadcast_partitions == NULL) return -ENOMEM; diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index 8daefb81ba29..74b183baf044 100644 --- a/drivers/misc/sram.c +++ b/drivers/misc/sram.c @@ -185,7 +185,7 @@ static int sram_reserve_regions(struct sram_dev *sram, struct resource *res) * after the reserved blocks from the dt are processed. */ nblocks = (np) ? of_get_available_child_count(np) + 1 : 1; - rblocks = kzalloc((nblocks) * sizeof(*rblocks), GFP_KERNEL); + rblocks = kcalloc(nblocks, sizeof(*rblocks), GFP_KERNEL); if (!rblocks) return -ENOMEM; @@ -264,8 +264,8 @@ static int sram_reserve_regions(struct sram_dev *sram, struct resource *res) list_sort(NULL, &reserve_list, sram_reserve_cmp); if (exports) { - sram->partition = devm_kzalloc(sram->dev, - exports * sizeof(*sram->partition), + sram->partition = devm_kcalloc(sram->dev, + exports, sizeof(*sram->partition), GFP_KERNEL); if (!sram->partition) { ret = -ENOMEM; diff --git a/drivers/misc/vexpress-syscfg.c b/drivers/misc/vexpress-syscfg.c index 9b4eba41ee5d..9c56f73532e7 100644 --- a/drivers/misc/vexpress-syscfg.c +++ b/drivers/misc/vexpress-syscfg.c @@ -182,8 +182,7 @@ static struct regmap *vexpress_syscfg_regmap_init(struct device *dev, val = energy_quirk; } - func = kzalloc(sizeof(*func) + sizeof(*func->template) * num, - GFP_KERNEL); + func = kzalloc(struct_size(func, template, num), GFP_KERNEL); if (!func) return ERR_PTR(-ENOMEM); diff --git a/drivers/misc/vmw_vmci/vmci_queue_pair.c b/drivers/misc/vmw_vmci/vmci_queue_pair.c index b4570d5c1fe7..c2e88ff022ef 100644 --- a/drivers/misc/vmw_vmci/vmci_queue_pair.c +++ b/drivers/misc/vmw_vmci/vmci_queue_pair.c @@ -490,12 +490,14 @@ static int qp_alloc_ppn_set(void *prod_q, return VMCI_ERROR_ALREADY_EXISTS; produce_ppns = - kmalloc(num_produce_pages * sizeof(*produce_ppns), GFP_KERNEL); + kmalloc_array(num_produce_pages, sizeof(*produce_ppns), + GFP_KERNEL); if (!produce_ppns) return VMCI_ERROR_NO_MEM; consume_ppns = - kmalloc(num_consume_pages * sizeof(*consume_ppns), GFP_KERNEL); + kmalloc_array(num_consume_pages, sizeof(*consume_ppns), + GFP_KERNEL); if (!consume_ppns) { kfree(produce_ppns); return VMCI_ERROR_NO_MEM; diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 4ef30120be4d..d57942521149 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -678,10 +678,9 @@ out: * freq_table in clk_scaling is un32. Here allocates an individual * memory space for it and release it when exit clock scaling. */ - clk_scaling->devfreq_profile.freq_table = kzalloc( - clk_scaling->freq_table_sz * - sizeof(*(clk_scaling->devfreq_profile.freq_table)), - GFP_KERNEL); + clk_scaling->devfreq_profile.freq_table = kcalloc(clk_scaling->freq_table_sz, + sizeof(*(clk_scaling->devfreq_profile.freq_table)), + GFP_KERNEL); if (!clk_scaling->devfreq_profile.freq_table) return -ENOMEM; clk_scaling->devfreq_profile.max_state = clk_scaling->freq_table_sz; diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 45945ccdf77f..c0e4e027759f 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -1560,7 +1560,7 @@ static int sdhci_msm_dt_get_array(struct device *dev, const char *prop_name, goto out; } - arr = devm_kzalloc(dev, sz * sizeof(*arr), GFP_KERNEL); + arr = devm_kcalloc(dev, sz, sizeof(*arr), GFP_KERNEL); if (!arr) { ret = -ENOMEM; goto out; @@ -1745,8 +1745,10 @@ static int sdhci_msm_dt_parse_gpio_info(struct device *dev, goto out; } pin_data->gpio_data->size = cnt; - pin_data->gpio_data->gpio = devm_kzalloc(dev, cnt * - sizeof(struct sdhci_msm_gpio), GFP_KERNEL); + pin_data->gpio_data->gpio = devm_kcalloc(dev, + cnt, + sizeof(struct sdhci_msm_gpio), + GFP_KERNEL); if (!pin_data->gpio_data->gpio) { ret = -ENOMEM; @@ -1956,7 +1958,6 @@ static int sdhci_msm_dt_parse_hsr_info(struct device *dev, int dll_hsr_table_len, dll_hsr_reg_count; int ret = 0; -<<<<<<< HEAD if (sdhci_msm_dt_get_array(dev, "qcom,dll-hsr-list", &dll_hsr_table, &dll_hsr_table_len, 0)) goto skip_hsr; @@ -4707,18 +4708,6 @@ static bool sdhci_msm_is_bootdevice(struct device *dev) */ return true; } -======= -static const struct sdhci_pltfm_data sdhci_msm_pdata = { - .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | - SDHCI_QUIRK_NO_CARD_NO_RESET | - SDHCI_QUIRK_SINGLE_POWER_WRITE | - SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | - SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, - - .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, - .ops = &sdhci_msm_ops, -}; ->>>>>>> 539a88827e7b9e4b8f0c6b7b24a2324ad2bc9367 static int sdhci_msm_probe(struct platform_device *pdev) { diff --git a/drivers/mtd/ar7part.c b/drivers/mtd/ar7part.c index 90575deff0ae..fc15ec58230a 100644 --- a/drivers/mtd/ar7part.c +++ b/drivers/mtd/ar7part.c @@ -55,7 +55,7 @@ static int create_mtd_partitions(struct mtd_info *master, int retries = 10; struct mtd_partition *ar7_parts; - ar7_parts = kzalloc(sizeof(*ar7_parts) * AR7_PARTS, GFP_KERNEL); + ar7_parts = kcalloc(AR7_PARTS, sizeof(*ar7_parts), GFP_KERNEL); if (!ar7_parts) return -ENOMEM; ar7_parts[0].name = "loader"; diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index fe2581d9d882..2848514b1e70 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c @@ -110,7 +110,7 @@ static int bcm47xxpart_parse(struct mtd_info *master, blocksize = 0x1000; /* Alloc */ - parts = kzalloc(sizeof(struct mtd_partition) * BCM47XXPART_MAX_PARTS, + parts = kcalloc(BCM47XXPART_MAX_PARTS, sizeof(struct mtd_partition), GFP_KERNEL); if (!parts) return -ENOMEM; diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index e1b603ca0170..2f194a8cfb8e 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -608,8 +608,9 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd) mtd->size = devsize * cfi->numchips; mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; - mtd->eraseregions = kzalloc(sizeof(struct mtd_erase_region_info) - * mtd->numeraseregions, GFP_KERNEL); + mtd->eraseregions = kcalloc(mtd->numeraseregions, + sizeof(struct mtd_erase_region_info), + GFP_KERNEL); if (!mtd->eraseregions) goto setup_err; @@ -758,7 +759,9 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd, newcfi = kmalloc(sizeof(struct cfi_private) + numvirtchips * sizeof(struct flchip), GFP_KERNEL); if (!newcfi) return -ENOMEM; - shared = kmalloc(sizeof(struct flchip_shared) * cfi->numchips, GFP_KERNEL); + shared = kmalloc_array(cfi->numchips, + sizeof(struct flchip_shared), + GFP_KERNEL); if (!shared) { kfree(newcfi); return -ENOMEM; diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 1f0d83086cb0..287e5d1d021e 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -692,8 +692,9 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd) mtd->size = devsize * cfi->numchips; mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; - mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) - * mtd->numeraseregions, GFP_KERNEL); + mtd->eraseregions = kmalloc_array(mtd->numeraseregions, + sizeof(struct mtd_erase_region_info), + GFP_KERNEL); if (!mtd->eraseregions) goto setup_err; @@ -2668,7 +2669,7 @@ static int __maybe_unused cfi_ppb_unlock(struct mtd_info *mtd, loff_t ofs, * first check the locking status of all sectors and save * it for future use. */ - sect = kzalloc(MAX_SECTORS * sizeof(struct ppb_lock), GFP_KERNEL); + sect = kcalloc(MAX_SECTORS, sizeof(struct ppb_lock), GFP_KERNEL); if (!sect) return -ENOMEM; diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c index 7d342965f392..a0edda085f97 100644 --- a/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/drivers/mtd/chips/cfi_cmdset_0020.c @@ -184,8 +184,9 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map) mtd->size = devsize * cfi->numchips; mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; - mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) - * mtd->numeraseregions, GFP_KERNEL); + mtd->eraseregions = kmalloc_array(mtd->numeraseregions, + sizeof(struct mtd_erase_region_info), + GFP_KERNEL); if (!mtd->eraseregions) { kfree(cfi->cmdset_priv); kfree(mtd); diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index 0806f72102c0..f4a071734685 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -1910,7 +1910,7 @@ doc_probe_device(struct docg3_cascade *cascade, int floor, struct device *dev) mtd->dev.parent = dev; bbt_nbpages = DIV_ROUND_UP(docg3->max_block + 1, 8 * DOC_LAYOUT_PAGE_SIZE); - docg3->bbt = kzalloc(bbt_nbpages * DOC_LAYOUT_PAGE_SIZE, GFP_KERNEL); + docg3->bbt = kcalloc(DOC_LAYOUT_PAGE_SIZE, bbt_nbpages, GFP_KERNEL); if (!docg3->bbt) goto nomem3; @@ -2076,7 +2076,7 @@ static int __init docg3_probe(struct platform_device *pdev) base = devm_ioremap(dev, ress->start, DOC_IOSPACE_SIZE); ret = -ENOMEM; - cascade = devm_kzalloc(dev, sizeof(*cascade) * DOC_MAX_NBFLOORS, + cascade = devm_kcalloc(dev, DOC_MAX_NBFLOORS, sizeof(*cascade), GFP_KERNEL); if (!cascade) return ret; diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c index 664d206a4cbe..cccdbc02c85a 100644 --- a/drivers/mtd/ftl.c +++ b/drivers/mtd/ftl.c @@ -207,15 +207,16 @@ static int build_maps(partition_t *part) /* Set up erase unit maps */ part->DataUnits = le16_to_cpu(part->header.NumEraseUnits) - part->header.NumTransferUnits; - part->EUNInfo = kmalloc(part->DataUnits * sizeof(struct eun_info_t), - GFP_KERNEL); + part->EUNInfo = kmalloc_array(part->DataUnits, sizeof(struct eun_info_t), + GFP_KERNEL); if (!part->EUNInfo) goto out; for (i = 0; i < part->DataUnits; i++) part->EUNInfo[i].Offset = 0xffffffff; part->XferInfo = - kmalloc(part->header.NumTransferUnits * sizeof(struct xfer_info_t), - GFP_KERNEL); + kmalloc_array(part->header.NumTransferUnits, + sizeof(struct xfer_info_t), + GFP_KERNEL); if (!part->XferInfo) goto out_EUNInfo; @@ -268,15 +269,15 @@ static int build_maps(partition_t *part) /* Set up virtual page map */ blocks = le32_to_cpu(header.FormattedSize) >> header.BlockSize; - part->VirtualBlockMap = vmalloc(blocks * sizeof(uint32_t)); + part->VirtualBlockMap = vmalloc(array_size(blocks, sizeof(uint32_t))); if (!part->VirtualBlockMap) goto out_XferInfo; memset(part->VirtualBlockMap, 0xff, blocks * sizeof(uint32_t)); part->BlocksPerUnit = (1 << header.EraseUnitSize) >> header.BlockSize; - part->bam_cache = kmalloc(part->BlocksPerUnit * sizeof(uint32_t), - GFP_KERNEL); + part->bam_cache = kmalloc_array(part->BlocksPerUnit, sizeof(uint32_t), + GFP_KERNEL); if (!part->bam_cache) goto out_VirtualBlockMap; diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c index 8d6bb189ea8e..99c2975a3c52 100644 --- a/drivers/mtd/inftlmount.c +++ b/drivers/mtd/inftlmount.c @@ -272,7 +272,8 @@ static int find_boot_record(struct INFTLrecord *inftl) inftl->nb_blocks = ip->lastUnit + 1; /* Memory alloc */ - inftl->PUtable = kmalloc(inftl->nb_blocks * sizeof(u16), GFP_KERNEL); + inftl->PUtable = kmalloc_array(inftl->nb_blocks, sizeof(u16), + GFP_KERNEL); if (!inftl->PUtable) { printk(KERN_WARNING "INFTL: allocation of PUtable " "failed (%zd bytes)\n", @@ -280,7 +281,8 @@ static int find_boot_record(struct INFTLrecord *inftl) return -ENOMEM; } - inftl->VUtable = kmalloc(inftl->nb_blocks * sizeof(u16), GFP_KERNEL); + inftl->VUtable = kmalloc_array(inftl->nb_blocks, sizeof(u16), + GFP_KERNEL); if (!inftl->VUtable) { kfree(inftl->PUtable); printk(KERN_WARNING "INFTL: allocation of VUtable " diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c index e1c283ccbbde..889e40f7c463 100644 --- a/drivers/mtd/lpddr/lpddr_cmds.c +++ b/drivers/mtd/lpddr/lpddr_cmds.c @@ -78,7 +78,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map) mtd->erasesize = 1 << lpddr->qinfo->UniformBlockSizeShift; mtd->writesize = 1 << lpddr->qinfo->BufSizeShift; - shared = kmalloc(sizeof(struct flchip_shared) * lpddr->numchips, + shared = kmalloc_array(lpddr->numchips, sizeof(struct flchip_shared), GFP_KERNEL); if (!shared) { kfree(mtd); diff --git a/drivers/mtd/maps/physmap_of_core.c b/drivers/mtd/maps/physmap_of_core.c index 5d8399742c75..65663e86ff00 100644 --- a/drivers/mtd/maps/physmap_of_core.c +++ b/drivers/mtd/maps/physmap_of_core.c @@ -114,7 +114,7 @@ static const char * const *of_get_probes(struct device_node *dp) if (count < 0) return part_probe_types_def; - res = kzalloc((count + 1) * sizeof(*res), GFP_KERNEL); + res = kcalloc(count + 1, sizeof(*res), GFP_KERNEL); if (!res) return NULL; @@ -187,7 +187,7 @@ static int of_flash_probe(struct platform_device *dev) dev_set_drvdata(&dev->dev, info); - mtd_list = kzalloc(sizeof(*mtd_list) * count, GFP_KERNEL); + mtd_list = kcalloc(count, sizeof(*mtd_list), GFP_KERNEL); if (!mtd_list) goto err_flash_remove; diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c index 6b223cfe92b7..c5d4b6589488 100644 --- a/drivers/mtd/maps/vmu-flash.c +++ b/drivers/mtd/maps/vmu-flash.c @@ -629,15 +629,15 @@ static int vmu_connect(struct maple_device *mdev) * Not sure there are actually any multi-partition devices in the * real world, but the hardware supports them, so, so will we */ - card->parts = kmalloc(sizeof(struct vmupart) * card->partitions, - GFP_KERNEL); + card->parts = kmalloc_array(card->partitions, sizeof(struct vmupart), + GFP_KERNEL); if (!card->parts) { error = -ENOMEM; goto fail_partitions; } - card->mtd = kmalloc(sizeof(struct mtd_info) * card->partitions, - GFP_KERNEL); + card->mtd = kmalloc_array(card->partitions, sizeof(struct mtd_info), + GFP_KERNEL); if (!card->mtd) { error = -ENOMEM; goto fail_mtd_info; diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c index d573606b91c2..a3d1e0f51d38 100644 --- a/drivers/mtd/mtdconcat.c +++ b/drivers/mtd/mtdconcat.c @@ -849,8 +849,9 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c concat->mtd.erasesize = max_erasesize; concat->mtd.numeraseregions = num_erase_region; concat->mtd.eraseregions = erase_region_p = - kmalloc(num_erase_region * - sizeof (struct mtd_erase_region_info), GFP_KERNEL); + kmalloc_array(num_erase_region, + sizeof(struct mtd_erase_region_info), + GFP_KERNEL); if (!erase_region_p) { kfree(concat); printk diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index 97bb8f6304d4..4bdeb598b02b 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -350,8 +350,7 @@ static void mtdoops_notify_add(struct mtd_info *mtd) } /* oops_page_used is a bit field */ - cxt->oops_page_used = vmalloc(DIV_ROUND_UP(mtdoops_pages, - BITS_PER_LONG) * sizeof(unsigned long)); + cxt->oops_page_used = vmalloc(array_size(sizeof(unsigned long), DIV_ROUND_UP(mtdoops_pages, BITS_PER_LONG))); if (!cxt->oops_page_used) { printk(KERN_ERR "mtdoops: could not allocate page array\n"); return; diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c index 7d9080e33865..dde9168feae2 100644 --- a/drivers/mtd/mtdswap.c +++ b/drivers/mtd/mtdswap.c @@ -1350,11 +1350,11 @@ static int mtdswap_init(struct mtdswap_dev *d, unsigned int eblocks, for (i = 0; i < MTDSWAP_TREE_CNT; i++) d->trees[i].root = RB_ROOT; - d->page_data = vmalloc(sizeof(int)*pages); + d->page_data = vmalloc(array_size(pages, sizeof(int))); if (!d->page_data) goto page_data_fail; - d->revmap = vmalloc(sizeof(int)*blocks); + d->revmap = vmalloc(array_size(blocks, sizeof(int))); if (!d->revmap) goto revmap_fail; @@ -1373,7 +1373,7 @@ static int mtdswap_init(struct mtdswap_dev *d, unsigned int eblocks, if (!d->page_buf) goto page_buf_fail; - d->oob_buf = kmalloc(2 * mtd->oobavail, GFP_KERNEL); + d->oob_buf = kmalloc_array(2, mtd->oobavail, GFP_KERNEL); if (!d->oob_buf) goto oob_buf_fail; diff --git a/drivers/mtd/nand/nand_bch.c b/drivers/mtd/nand/nand_bch.c index 505441c9373b..3ab49f103591 100644 --- a/drivers/mtd/nand/nand_bch.c +++ b/drivers/mtd/nand/nand_bch.c @@ -186,7 +186,7 @@ struct nand_bch_control *nand_bch_init(struct mtd_info *mtd) } nbc->eccmask = kmalloc(eccbytes, GFP_KERNEL); - nbc->errloc = kmalloc(t*sizeof(*nbc->errloc), GFP_KERNEL); + nbc->errloc = kmalloc_array(t, sizeof(*nbc->errloc), GFP_KERNEL); if (!nbc->eccmask || !nbc->errloc) goto fail; /* diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index dbb0e47f5197..67a143051ed3 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -566,8 +566,7 @@ static int __init alloc_device(struct nandsim *ns) err = -EINVAL; goto err_close; } - ns->pages_written = vzalloc(BITS_TO_LONGS(ns->geom.pgnum) * - sizeof(unsigned long)); + ns->pages_written = vzalloc(array_size(sizeof(unsigned long), BITS_TO_LONGS(ns->geom.pgnum))); if (!ns->pages_written) { NS_ERR("alloc_device: unable to allocate pages written array\n"); err = -ENOMEM; @@ -583,7 +582,7 @@ static int __init alloc_device(struct nandsim *ns) return 0; } - ns->pages = vmalloc(ns->geom.pgnum * sizeof(union ns_mem)); + ns->pages = vmalloc(array_size(sizeof(union ns_mem), ns->geom.pgnum)); if (!ns->pages) { NS_ERR("alloc_device: unable to allocate page array\n"); return -ENOMEM; diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c index 65d1be2c3049..20ad11626f86 100644 --- a/drivers/mtd/nand/qcom_nandc.c +++ b/drivers/mtd/nand/qcom_nandc.c @@ -2414,8 +2414,8 @@ static int qcom_nandc_alloc(struct qcom_nand_controller *nandc) if (!nandc->regs) return -ENOMEM; - nandc->reg_read_buf = devm_kzalloc(nandc->dev, - MAX_REG_RD * sizeof(*nandc->reg_read_buf), + nandc->reg_read_buf = devm_kcalloc(nandc->dev, + MAX_REG_RD, sizeof(*nandc->reg_read_buf), GFP_KERNEL); if (!nandc->reg_read_buf) return -ENOMEM; diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index f60de68bfabc..87f78b6a5c16 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -1041,7 +1041,7 @@ static int s3c24xx_nand_probe_dt(struct platform_device *pdev) if (!pdata->nr_sets) return 0; - sets = devm_kzalloc(&pdev->dev, sizeof(*sets) * pdata->nr_sets, + sets = devm_kcalloc(&pdev->dev, pdata->nr_sets, sizeof(*sets), GFP_KERNEL); if (!sets) return -ENOMEM; diff --git a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c index 184c8fbfe465..6688f4e3a90b 100644 --- a/drivers/mtd/nftlmount.c +++ b/drivers/mtd/nftlmount.c @@ -200,13 +200,16 @@ device is already correct. nftl->lastEUN = nftl->nb_blocks - 1; /* memory alloc */ - nftl->EUNtable = kmalloc(nftl->nb_blocks * sizeof(u16), GFP_KERNEL); + nftl->EUNtable = kmalloc_array(nftl->nb_blocks, sizeof(u16), + GFP_KERNEL); if (!nftl->EUNtable) { printk(KERN_NOTICE "NFTL: allocation of EUNtable failed\n"); return -ENOMEM; } - nftl->ReplUnitTable = kmalloc(nftl->nb_blocks * sizeof(u16), GFP_KERNEL); + nftl->ReplUnitTable = kmalloc_array(nftl->nb_blocks, + sizeof(u16), + GFP_KERNEL); if (!nftl->ReplUnitTable) { kfree(nftl->EUNtable); printk(KERN_NOTICE "NFTL: allocation of ReplUnitTable failed\n"); diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index 6bdf4e525677..9441a86f03ab 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c @@ -71,7 +71,7 @@ static int parse_ofpart_partitions(struct mtd_info *master, if (nr_parts == 0) return 0; - parts = kzalloc(nr_parts * sizeof(*parts), GFP_KERNEL); + parts = kcalloc(nr_parts, sizeof(*parts), GFP_KERNEL); if (!parts) return -ENOMEM; @@ -170,7 +170,7 @@ static int parse_ofoldpart_partitions(struct mtd_info *master, nr_parts = plen / sizeof(part[0]); - parts = kzalloc(nr_parts * sizeof(*parts), GFP_KERNEL); + parts = kcalloc(nr_parts, sizeof(*parts), GFP_KERNEL); if (!parts) return -ENOMEM; diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 1a6d0e367b89..2e6ef0fc80b5 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -3819,8 +3819,9 @@ static int onenand_probe(struct mtd_info *mtd) this->dies = ONENAND_IS_DDP(this) ? 2 : 1; /* Maximum possible erase regions */ mtd->numeraseregions = this->dies << 1; - mtd->eraseregions = kzalloc(sizeof(struct mtd_erase_region_info) - * (this->dies << 1), GFP_KERNEL); + mtd->eraseregions = kcalloc(this->dies << 1, + sizeof(struct mtd_erase_region_info), + GFP_KERNEL); if (!mtd->eraseregions) return -ENOMEM; } diff --git a/drivers/mtd/parsers/parser_trx.c b/drivers/mtd/parsers/parser_trx.c index df360a75e1eb..17ac33599783 100644 --- a/drivers/mtd/parsers/parser_trx.c +++ b/drivers/mtd/parsers/parser_trx.c @@ -62,7 +62,7 @@ static int parser_trx_parse(struct mtd_info *mtd, uint8_t curr_part = 0, i = 0; int err; - parts = kzalloc(sizeof(struct mtd_partition) * TRX_PARSER_MAX_PARTS, + parts = kcalloc(TRX_PARSER_MAX_PARTS, sizeof(struct mtd_partition), GFP_KERNEL); if (!parts) return -ENOMEM; diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c index d1cbf26db2c0..f2c788bec94f 100644 --- a/drivers/mtd/rfd_ftl.c +++ b/drivers/mtd/rfd_ftl.c @@ -189,7 +189,7 @@ static int scan_header(struct partition *part) if (!part->blocks) goto err; - part->sector_map = vmalloc(part->sector_count * sizeof(u_long)); + part->sector_map = vmalloc(array_size(sizeof(u_long), part->sector_count)); if (!part->sector_map) { printk(KERN_ERR PREFIX "'%s': unable to allocate memory for " "sector map", part->mbd.mtd->name); diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c index 3692dd547879..5122a0075bad 100644 --- a/drivers/mtd/sm_ftl.c +++ b/drivers/mtd/sm_ftl.c @@ -82,7 +82,7 @@ static struct attribute_group *sm_create_sysfs_attributes(struct sm_ftl *ftl) /* Create array of pointers to the attributes */ - attributes = kzalloc(sizeof(struct attribute *) * (NUM_ATTRIBUTES + 1), + attributes = kcalloc(NUM_ATTRIBUTES + 1, sizeof(struct attribute *), GFP_KERNEL); if (!attributes) goto error3; @@ -768,7 +768,7 @@ static int sm_init_zone(struct sm_ftl *ftl, int zone_num) dbg("initializing zone %d", zone_num); /* Allocate memory for FTL table */ - zone->lba_to_phys_table = kmalloc(ftl->max_lba * 2, GFP_KERNEL); + zone->lba_to_phys_table = kmalloc_array(ftl->max_lba, 2, GFP_KERNEL); if (!zone->lba_to_phys_table) return -ENOMEM; @@ -1156,7 +1156,7 @@ static void sm_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) goto error2; /* Allocate zone array, it will be initialized on demand */ - ftl->zones = kzalloc(sizeof(struct ftl_zone) * ftl->zone_count, + ftl->zones = kcalloc(ftl->zone_count, sizeof(struct ftl_zone), GFP_KERNEL); if (!ftl->zones) goto error3; diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c index 8d3cbe27efb6..95e54468cf7d 100644 --- a/drivers/mtd/spi-nor/aspeed-smc.c +++ b/drivers/mtd/spi-nor/aspeed-smc.c @@ -861,8 +861,9 @@ static int aspeed_smc_probe(struct platform_device *pdev) return -ENODEV; info = match->data; - controller = devm_kzalloc(&pdev->dev, sizeof(*controller) + - info->nce * sizeof(controller->chips[0]), GFP_KERNEL); + controller = devm_kzalloc(&pdev->dev, + struct_size(controller, chips, info->nce), + GFP_KERNEL); if (!controller) return -ENOMEM; controller->info = info; diff --git a/drivers/mtd/ssfdc.c b/drivers/mtd/ssfdc.c index 95f0bf95f095..d746d983ad8e 100644 --- a/drivers/mtd/ssfdc.c +++ b/drivers/mtd/ssfdc.c @@ -332,8 +332,9 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) (long)ssfdc->sectors; /* Allocate logical block map */ - ssfdc->logic_block_map = kmalloc(sizeof(ssfdc->logic_block_map[0]) * - ssfdc->map_len, GFP_KERNEL); + ssfdc->logic_block_map = kmalloc_array(ssfdc->map_len, + sizeof(ssfdc->logic_block_map[0]), + GFP_KERNEL); if (!ssfdc->logic_block_map) goto out_err; memset(ssfdc->logic_block_map, 0xff, sizeof(ssfdc->logic_block_map[0]) * diff --git a/drivers/mtd/tests/pagetest.c b/drivers/mtd/tests/pagetest.c index ff1e0565b020..985fb1eaaf12 100644 --- a/drivers/mtd/tests/pagetest.c +++ b/drivers/mtd/tests/pagetest.c @@ -127,7 +127,7 @@ static int crosstest(void) unsigned char *pp1, *pp2, *pp3, *pp4; pr_info("crosstest\n"); - pp1 = kzalloc(pgsize * 4, GFP_KERNEL); + pp1 = kcalloc(pgsize, 4, GFP_KERNEL); if (!pp1) return -ENOMEM; pp2 = pp1 + pgsize; diff --git a/drivers/mtd/tests/stresstest.c b/drivers/mtd/tests/stresstest.c index e509f8aa9a7e..0fe1217f94b9 100644 --- a/drivers/mtd/tests/stresstest.c +++ b/drivers/mtd/tests/stresstest.c @@ -199,7 +199,7 @@ static int __init mtd_stresstest_init(void) err = -ENOMEM; readbuf = vmalloc(bufsize); writebuf = vmalloc(bufsize); - offsets = kmalloc(ebcnt * sizeof(int), GFP_KERNEL); + offsets = kmalloc_array(ebcnt, sizeof(int), GFP_KERNEL); if (!readbuf || !writebuf || !offsets) goto out; for (i = 0; i < ebcnt; i++) diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index c4d4b8f07630..f9cb8528e29f 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -1519,11 +1519,11 @@ int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap, num_volumes = ubi->vtbl_slots + UBI_INT_VOL_COUNT; - scan_eba = kmalloc(sizeof(*scan_eba) * num_volumes, GFP_KERNEL); + scan_eba = kmalloc_array(num_volumes, sizeof(*scan_eba), GFP_KERNEL); if (!scan_eba) return -ENOMEM; - fm_eba = kmalloc(sizeof(*fm_eba) * num_volumes, GFP_KERNEL); + fm_eba = kmalloc_array(num_volumes, sizeof(*fm_eba), GFP_KERNEL); if (!fm_eba) { kfree(scan_eba); return -ENOMEM; @@ -1534,15 +1534,17 @@ int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap, if (!vol) continue; - scan_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**scan_eba), - GFP_KERNEL); + scan_eba[i] = kmalloc_array(vol->reserved_pebs, + sizeof(**scan_eba), + GFP_KERNEL); if (!scan_eba[i]) { ret = -ENOMEM; goto out_free; } - fm_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**fm_eba), - GFP_KERNEL); + fm_eba[i] = kmalloc_array(vol->reserved_pebs, + sizeof(**fm_eba), + GFP_KERNEL); if (!fm_eba[i]) { ret = -ENOMEM; goto out_free; diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 5c0332e31138..80cb793fdabf 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1846,7 +1846,7 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) sprintf(ubi->bgt_name, UBI_BGT_NAME_PATTERN, ubi->ubi_num); err = -ENOMEM; - ubi->lookuptbl = kzalloc(ubi->peb_count * sizeof(void *), GFP_KERNEL); + ubi->lookuptbl = kcalloc(ubi->peb_count, sizeof(void *), GFP_KERNEL); if (!ubi->lookuptbl) return err; diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 1f867e275408..90e1df5b7dab 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2407,7 +2407,7 @@ struct bond_vlan_tag *bond_verify_device_path(struct net_device *start_dev, struct list_head *iter; if (start_dev == end_dev) { - tags = kzalloc(sizeof(*tags) * (level + 1), GFP_ATOMIC); + tags = kcalloc(level + 1, sizeof(*tags), GFP_ATOMIC); if (!tags) return ERR_PTR(-ENOMEM); tags[level].vlan_proto = VLAN_N_VID; diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c index a7be12d9a139..55f75f48bffe 100644 --- a/drivers/net/can/grcan.c +++ b/drivers/net/can/grcan.c @@ -1057,7 +1057,7 @@ static int grcan_open(struct net_device *dev) return err; } - priv->echo_skb = kzalloc(dma->tx.size * sizeof(*priv->echo_skb), + priv->echo_skb = kcalloc(dma->tx.size, sizeof(*priv->echo_skb), GFP_KERNEL); if (!priv->echo_skb) { err = -ENOMEM; @@ -1066,7 +1066,7 @@ static int grcan_open(struct net_device *dev) priv->can.echo_skb_max = dma->tx.size; priv->can.echo_skb = priv->echo_skb; - priv->txdlc = kzalloc(dma->tx.size * sizeof(*priv->txdlc), GFP_KERNEL); + priv->txdlc = kcalloc(dma->tx.size, sizeof(*priv->txdlc), GFP_KERNEL); if (!priv->txdlc) { err = -ENOMEM; goto exit_free_echo_skb; diff --git a/drivers/net/can/peak_canfd/peak_pciefd_main.c b/drivers/net/can/peak_canfd/peak_pciefd_main.c index fa689854f16b..455a3797a200 100644 --- a/drivers/net/can/peak_canfd/peak_pciefd_main.c +++ b/drivers/net/can/peak_canfd/peak_pciefd_main.c @@ -756,8 +756,7 @@ static int peak_pciefd_probe(struct pci_dev *pdev, can_count = 1; /* allocate board structure object */ - pciefd = devm_kzalloc(&pdev->dev, sizeof(*pciefd) + - can_count * sizeof(*pciefd->can), + pciefd = devm_kzalloc(&pdev->dev, struct_size(pciefd, can, can_count), GFP_KERNEL); if (!pciefd) { err = -ENOMEM; diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index c5a616395c49..d2ec861b5a7d 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -714,7 +714,7 @@ static int __init slcan_init(void) pr_info("slcan: serial line CAN interface driver\n"); pr_info("slcan: %d dynamic interface channels.\n", maxdev); - slcan_devs = kzalloc(sizeof(struct net_device *)*maxdev, GFP_KERNEL); + slcan_devs = kcalloc(maxdev, sizeof(struct net_device *), GFP_KERNEL); if (!slcan_devs) return -ENOMEM; diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 274d36915110..4479bfc228cd 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -1825,14 +1825,14 @@ static int b53_switch_init(struct b53_device *dev) dev->num_ports = dev->cpu_port + 1; dev->enabled_ports |= BIT(dev->cpu_port); - dev->ports = devm_kzalloc(dev->dev, - sizeof(struct b53_port) * dev->num_ports, + dev->ports = devm_kcalloc(dev->dev, + dev->num_ports, sizeof(struct b53_port), GFP_KERNEL); if (!dev->ports) return -ENOMEM; - dev->vlans = devm_kzalloc(dev->dev, - sizeof(struct b53_vlan) * dev->num_vlans, + dev->vlans = devm_kcalloc(dev->dev, + dev->num_vlans, sizeof(struct b53_vlan), GFP_KERNEL); if (!dev->vlans) return -ENOMEM; diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c b/drivers/net/ethernet/amazon/ena/ena_ethtool.c index d29e256bf610..53683eb51bbd 100644 --- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c +++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c @@ -877,8 +877,8 @@ static void ena_dump_stats_ex(struct ena_adapter *adapter, u8 *buf) return; } - strings_buf = devm_kzalloc(&adapter->pdev->dev, - strings_num * ETH_GSTRING_LEN, + strings_buf = devm_kcalloc(&adapter->pdev->dev, + ETH_GSTRING_LEN, strings_num, GFP_ATOMIC); if (!strings_buf) { netif_err(adapter, drv, netdev, @@ -886,8 +886,8 @@ static void ena_dump_stats_ex(struct ena_adapter *adapter, u8 *buf) return; } - data_buf = devm_kzalloc(&adapter->pdev->dev, - strings_num * sizeof(u64), + data_buf = devm_kcalloc(&adapter->pdev->dev, + strings_num, sizeof(u64), GFP_ATOMIC); if (!data_buf) { netif_err(adapter, drv, netdev, diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c index d9ece9ac6f53..7e1e00d77ea0 100644 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c @@ -517,7 +517,7 @@ static int ena_refill_rx_bufs(struct ena_ring *rx_ring, u32 num) rc = ena_alloc_rx_page(rx_ring, rx_info, - __GFP_COLD | GFP_ATOMIC | __GFP_COMP); + GFP_ATOMIC | __GFP_COMP); if (unlikely(rc < 0)) { netif_warn(rx_ring->adapter, rx_err, rx_ring->netdev, "failed to alloc buffer for rx queue %d\n", diff --git a/drivers/net/ethernet/amd/lance.c b/drivers/net/ethernet/amd/lance.c index 12a6a93d221b..e4326908456e 100644 --- a/drivers/net/ethernet/amd/lance.c +++ b/drivers/net/ethernet/amd/lance.c @@ -551,13 +551,13 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int if (lance_debug > 6) printk(" (#0x%05lx)", (unsigned long)lp); dev->ml_priv = lp; lp->name = chipname; - lp->rx_buffs = (unsigned long)kmalloc(PKT_BUF_SZ*RX_RING_SIZE, - GFP_DMA | GFP_KERNEL); + lp->rx_buffs = (unsigned long) kmalloc_array(RX_RING_SIZE, PKT_BUF_SZ, + GFP_DMA | GFP_KERNEL); if (!lp->rx_buffs) goto out_lp; if (lance_need_isa_bounce_buffers) { - lp->tx_bounce_buffs = kmalloc(PKT_BUF_SZ*TX_RING_SIZE, - GFP_DMA | GFP_KERNEL); + lp->tx_bounce_buffs = kmalloc_array(TX_RING_SIZE, PKT_BUF_SZ, + GFP_DMA | GFP_KERNEL); if (!lp->tx_bounce_buffs) goto out_rx; } else diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c index a5eaf174d914..533094233659 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c @@ -295,7 +295,7 @@ again: order = alloc_order; /* Try to obtain pages, decreasing order if necessary */ - gfp = GFP_ATOMIC | __GFP_COLD | __GFP_COMP | __GFP_NOWARN; + gfp = GFP_ATOMIC | __GFP_COMP | __GFP_NOWARN; while (order >= 0) { pages = alloc_pages_node(node, gfp, order); if (pages) diff --git a/drivers/net/ethernet/aquantia/atlantic-fwd/atl_ring.c b/drivers/net/ethernet/aquantia/atlantic-fwd/atl_ring.c index 93d99db69178..03ddf02f1017 100644 --- a/drivers/net/ethernet/aquantia/atlantic-fwd/atl_ring.c +++ b/drivers/net/ethernet/aquantia/atlantic-fwd/atl_ring.c @@ -1476,7 +1476,7 @@ static int atl_alloc_ring(struct atl_desc_ring *ring, size_t buf_size, return ret; } - ring->bufs = vzalloc(ring->hw.size * buf_size); + ring->bufs = vzalloc(array_size(ring->hw.size, buf_size)); if (!ring->bufs) { atl_nic_err("Couldn't alloc %s[%d] %sbufs\n", type, idx, type); ret = -ENOMEM; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c index 784c3522aaa3..b81ff84d1555 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c @@ -309,8 +309,7 @@ int aq_ring_rx_fill(struct aq_ring_s *self) buff->flags = 0U; buff->len = AQ_CFG_RX_FRAME_MAX; - buff->page = alloc_pages(GFP_ATOMIC | __GFP_COLD | - __GFP_COMP, pages_order); + buff->page = alloc_pages(GFP_ATOMIC | __GFP_COMP, pages_order); if (!buff->page) { err = -ENOMEM; goto err_exit; diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c b/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c index cfe86a20c899..28e9ae1a193b 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c @@ -209,8 +209,8 @@ static int atl1c_get_eeprom(struct net_device *netdev, first_dword = eeprom->offset >> 2; last_dword = (eeprom->offset + eeprom->len - 1) >> 2; - eeprom_buff = kmalloc(sizeof(u32) * - (last_dword - first_dword + 1), GFP_KERNEL); + eeprom_buff = kmalloc_array(last_dword - first_dword + 1, sizeof(u32), + GFP_KERNEL); if (eeprom_buff == NULL) return -ENOMEM; diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c b/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c index cb489e7e8374..282ebdde4769 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c @@ -236,8 +236,8 @@ static int atl1e_get_eeprom(struct net_device *netdev, first_dword = eeprom->offset >> 2; last_dword = (eeprom->offset + eeprom->len - 1) >> 2; - eeprom_buff = kmalloc(sizeof(u32) * - (last_dword - first_dword + 1), GFP_KERNEL); + eeprom_buff = kmalloc_array(last_dword - first_dword + 1, sizeof(u32), + GFP_KERNEL); if (eeprom_buff == NULL) return -ENOMEM; diff --git a/drivers/net/ethernet/atheros/atlx/atl2.c b/drivers/net/ethernet/atheros/atlx/atl2.c index 225b4d452e0e..ee6983e6bb14 100644 --- a/drivers/net/ethernet/atheros/atlx/atl2.c +++ b/drivers/net/ethernet/atheros/atlx/atl2.c @@ -1940,8 +1940,8 @@ static int atl2_get_eeprom(struct net_device *netdev, first_dword = eeprom->offset >> 2; last_dword = (eeprom->offset + eeprom->len - 1) >> 2; - eeprom_buff = kmalloc(sizeof(u32) * (last_dword - first_dword + 1), - GFP_KERNEL); + eeprom_buff = kmalloc_array(last_dword - first_dword + 1, sizeof(u32), + GFP_KERNEL); if (!eeprom_buff) return -ENOMEM; diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c index 35eb0119b015..fb57abb409c2 100644 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c @@ -2182,7 +2182,7 @@ static int bcm_enetsw_open(struct net_device *dev) priv->tx_desc_alloc_size = size; priv->tx_desc_cpu = p; - priv->tx_skb = kzalloc(sizeof(struct sk_buff *) * priv->tx_ring_size, + priv->tx_skb = kcalloc(priv->tx_ring_size, sizeof(struct sk_buff *), GFP_KERNEL); if (!priv->tx_skb) { dev_err(kdev, "cannot allocate rx skb queue\n"); @@ -2196,7 +2196,7 @@ static int bcm_enetsw_open(struct net_device *dev) spin_lock_init(&priv->tx_lock); /* init & fill rx ring with skbs */ - priv->rx_skb = kzalloc(sizeof(struct sk_buff *) * priv->rx_ring_size, + priv->rx_skb = kcalloc(priv->rx_ring_size, sizeof(struct sk_buff *), GFP_KERNEL); if (!priv->rx_skb) { dev_err(kdev, "cannot allocate rx skb queue\n"); diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index e3af1f3cb61f..10618f09bd57 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -778,7 +778,7 @@ bnx2_alloc_rx_mem(struct bnx2 *bp) int j; rxr->rx_buf_ring = - vzalloc(SW_RXBD_RING_SIZE * bp->rx_max_ring); + vzalloc(array_size(SW_RXBD_RING_SIZE, bp->rx_max_ring)); if (rxr->rx_buf_ring == NULL) return -ENOMEM; @@ -794,8 +794,7 @@ bnx2_alloc_rx_mem(struct bnx2 *bp) } if (bp->rx_pg_ring_size) { - rxr->rx_pg_ring = vzalloc(SW_RXPG_RING_SIZE * - bp->rx_max_pg_ring); + rxr->rx_pg_ring = vzalloc(array_size(SW_RXPG_RING_SIZE, bp->rx_max_pg_ring)); if (rxr->rx_pg_ring == NULL) return -ENOMEM; @@ -2666,7 +2665,7 @@ bnx2_alloc_bad_rbuf(struct bnx2 *bp) u32 good_mbuf_cnt; u32 val; - good_mbuf = kmalloc(512 * sizeof(u16), GFP_KERNEL); + good_mbuf = kmalloc_array(512, sizeof(u16), GFP_KERNEL); if (good_mbuf == NULL) return -ENOMEM; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index 1977e0c552df..4ec2d1a5b955 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -571,7 +571,7 @@ int bnx2x_vf_mcast(struct bnx2x *bp, struct bnx2x_virtf *vf, else set_bit(RAMROD_COMP_WAIT, &mcast.ramrod_flags); if (mc_num) { - mc = kzalloc(mc_num * sizeof(struct bnx2x_mcast_list_elem), + mc = kcalloc(mc_num, sizeof(struct bnx2x_mcast_list_elem), GFP_KERNEL); if (!mc) { BNX2X_ERR("Cannot Configure multicasts due to lack of memory\n"); @@ -1251,8 +1251,9 @@ int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, num_vfs_param, iov->nr_virtfn); /* allocate the vf array */ - bp->vfdb->vfs = kzalloc(sizeof(struct bnx2x_virtf) * - BNX2X_NR_VIRTFN(bp), GFP_KERNEL); + bp->vfdb->vfs = kcalloc(BNX2X_NR_VIRTFN(bp), + sizeof(struct bnx2x_virtf), + GFP_KERNEL); if (!bp->vfdb->vfs) { BNX2X_ERR("failed to allocate vf array\n"); err = -ENOMEM; @@ -1276,9 +1277,9 @@ int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, } /* allocate the queue arrays for all VFs */ - bp->vfdb->vfqs = kzalloc( - BNX2X_MAX_NUM_VF_QUEUES * sizeof(struct bnx2x_vf_queue), - GFP_KERNEL); + bp->vfdb->vfqs = kcalloc(BNX2X_MAX_NUM_VF_QUEUES, + sizeof(struct bnx2x_vf_queue), + GFP_KERNEL); if (!bp->vfdb->vfqs) { BNX2X_ERR("failed to allocate vf queue array\n"); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c index e75db04c6cdc..3d85568ddc58 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c @@ -350,8 +350,8 @@ static int bnxt_vf_reps_create(struct bnxt *bp) return -ENOMEM; /* storage for cfa_code to vf-idx mapping */ - cfa_code_map = kmalloc(sizeof(*bp->cfa_code_map) * MAX_CFA_CODE, - GFP_KERNEL); + cfa_code_map = kmalloc_array(MAX_CFA_CODE, sizeof(*bp->cfa_code_map), + GFP_KERNEL); if (!cfa_code_map) { rc = -ENOMEM; goto err; diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index 8bc126a156e8..30273a7717e2 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -660,7 +660,7 @@ static int cnic_init_id_tbl(struct cnic_id_tbl *id_tbl, u32 size, u32 start_id, id_tbl->max = size; id_tbl->next = next; spin_lock_init(&id_tbl->lock); - id_tbl->table = kzalloc(DIV_ROUND_UP(size, 32) * 4, GFP_KERNEL); + id_tbl->table = kcalloc(DIV_ROUND_UP(size, 32), 4, GFP_KERNEL); if (!id_tbl->table) return -ENOMEM; @@ -1255,13 +1255,13 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) cp->fcoe_init_cid = 0x10; } - cp->iscsi_tbl = kzalloc(sizeof(struct cnic_iscsi) * MAX_ISCSI_TBL_SZ, + cp->iscsi_tbl = kcalloc(MAX_ISCSI_TBL_SZ, sizeof(struct cnic_iscsi), GFP_KERNEL); if (!cp->iscsi_tbl) goto error; - cp->ctx_tbl = kzalloc(sizeof(struct cnic_context) * - cp->max_cid_space, GFP_KERNEL); + cp->ctx_tbl = kcalloc(cp->max_cid_space, sizeof(struct cnic_context), + GFP_KERNEL); if (!cp->ctx_tbl) goto error; @@ -4100,7 +4100,7 @@ static int cnic_cm_alloc_mem(struct cnic_dev *dev) struct cnic_local *cp = dev->cnic_priv; u32 port_id; - cp->csk_tbl = kzalloc(sizeof(struct cnic_sock) * MAX_CM_SK_TBL_SZ, + cp->csk_tbl = kcalloc(MAX_CM_SK_TBL_SZ, sizeof(struct cnic_sock), GFP_KERNEL); if (!cp->csk_tbl) return -ENOMEM; diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index e40d31b40525..0d10ca2c844b 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -8621,8 +8621,9 @@ static int tg3_mem_tx_acquire(struct tg3 *tp) tnapi++; for (i = 0; i < tp->txq_cnt; i++, tnapi++) { - tnapi->tx_buffers = kzalloc(sizeof(struct tg3_tx_ring_info) * - TG3_TX_RING_SIZE, GFP_KERNEL); + tnapi->tx_buffers = kcalloc(TG3_TX_RING_SIZE, + sizeof(struct tg3_tx_ring_info), + GFP_KERNEL); if (!tnapi->tx_buffers) goto err_out; diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index 6e13c937d715..ec73b1122b68 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c @@ -3143,7 +3143,7 @@ bnad_set_rx_ucast_fltr(struct bnad *bnad) if (uc_count > bna_attr(&bnad->bna)->num_ucmac) goto mode_default; - mac_list = kzalloc(uc_count * ETH_ALEN, GFP_ATOMIC); + mac_list = kcalloc(ETH_ALEN, uc_count, GFP_ATOMIC); if (mac_list == NULL) goto mode_default; @@ -3184,7 +3184,7 @@ bnad_set_rx_mcast_fltr(struct bnad *bnad) if (mc_count > bna_attr(&bnad->bna)->num_mcmac) goto mode_allmulti; - mac_list = kzalloc((mc_count + 1) * ETH_ALEN, GFP_ATOMIC); + mac_list = kcalloc(mc_count + 1, ETH_ALEN, GFP_ATOMIC); if (mac_list == NULL) goto mode_allmulti; diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c index 2bd7c638b178..2c63afff1382 100644 --- a/drivers/net/ethernet/calxeda/xgmac.c +++ b/drivers/net/ethernet/calxeda/xgmac.c @@ -739,7 +739,7 @@ static int xgmac_dma_desc_rings_init(struct net_device *dev) netdev_dbg(priv->dev, "mtu [%d] bfsize [%d]\n", dev->mtu, bfsize); - priv->rx_skbuff = kzalloc(sizeof(struct sk_buff *) * DMA_RX_RING_SZ, + priv->rx_skbuff = kcalloc(DMA_RX_RING_SZ, sizeof(struct sk_buff *), GFP_KERNEL); if (!priv->rx_skbuff) return -ENOMEM; @@ -752,7 +752,7 @@ static int xgmac_dma_desc_rings_init(struct net_device *dev) if (!priv->dma_rx) goto err_dma_rx; - priv->tx_skbuff = kzalloc(sizeof(struct sk_buff *) * DMA_TX_RING_SZ, + priv->tx_skbuff = kcalloc(DMA_TX_RING_SZ, sizeof(struct sk_buff *), GFP_KERNEL); if (!priv->tx_skbuff) goto err_tx_skb; diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c index 4d2db22e011b..d1e0e651fd94 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c @@ -468,12 +468,12 @@ static int setup_glists(struct lio *lio, int num_iqs) int i, j; lio->glist_lock = - kzalloc(sizeof(*lio->glist_lock) * num_iqs, GFP_KERNEL); + kcalloc(num_iqs, sizeof(*lio->glist_lock), GFP_KERNEL); if (!lio->glist_lock) return -ENOMEM; lio->glist = - kzalloc(sizeof(*lio->glist) * num_iqs, GFP_KERNEL); + kcalloc(num_iqs, sizeof(*lio->glist), GFP_KERNEL); if (!lio->glist) { kfree(lio->glist_lock); lio->glist_lock = NULL; diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_droq.c b/drivers/net/ethernet/cavium/liquidio/octeon_droq.c index 9372d4ce9954..fe1eca433253 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_droq.c +++ b/drivers/net/ethernet/cavium/liquidio/octeon_droq.c @@ -281,13 +281,11 @@ int octeon_init_droq(struct octeon_device *oct, droq->max_count); droq->recv_buf_list = (struct octeon_recv_buffer *) - vzalloc_node(droq->max_count * - OCT_DROQ_RECVBUF_SIZE, + vzalloc_node(array_size(droq->max_count, OCT_DROQ_RECVBUF_SIZE), numa_node); if (!droq->recv_buf_list) droq->recv_buf_list = (struct octeon_recv_buffer *) - vzalloc(droq->max_count * - OCT_DROQ_RECVBUF_SIZE); + vzalloc(array_size(droq->max_count, OCT_DROQ_RECVBUF_SIZE)); if (!droq->recv_buf_list) { dev_err(&oct->pci_dev->dev, "Output queue recv buf list alloc failed\n"); goto init_droq_fail; diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_network.h b/drivers/net/ethernet/cavium/liquidio/octeon_network.h index 9e36319cead6..57853eead4b5 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_network.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_network.h @@ -195,7 +195,7 @@ static inline void struct sk_buff *skb; struct octeon_skb_page_info *skb_pg_info; - page = alloc_page(GFP_ATOMIC | __GFP_COLD); + page = alloc_page(GFP_ATOMIC); if (unlikely(!page)) return NULL; diff --git a/drivers/net/ethernet/cavium/liquidio/request_manager.c b/drivers/net/ethernet/cavium/liquidio/request_manager.c index 0ea623768783..ad7e451ae14d 100644 --- a/drivers/net/ethernet/cavium/liquidio/request_manager.c +++ b/drivers/net/ethernet/cavium/liquidio/request_manager.c @@ -98,8 +98,7 @@ int octeon_init_instr_queue(struct octeon_device *oct, iq->request_list = vmalloc_node((sizeof(*iq->request_list) * num_descs), numa_node); if (!iq->request_list) - iq->request_list = vmalloc(sizeof(*iq->request_list) * - num_descs); + iq->request_list = vmalloc(array_size(num_descs, sizeof(*iq->request_list))); if (!iq->request_list) { lio_dma_free(oct, q_size, iq->base_addr, iq->base_addr_dma); dev_err(&oct->pci_dev->dev, "Alloc failed for IQ[%d] nr free list\n", diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c index 7ad1d56d8389..47304dba6a5e 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c @@ -291,8 +291,8 @@ static int nicvf_init_rbdr(struct nicvf *nic, struct rbdr *rbdr, rbdr->is_xdp = true; } rbdr->pgcnt = roundup_pow_of_two(rbdr->pgcnt); - rbdr->pgcache = kzalloc(sizeof(*rbdr->pgcache) * - rbdr->pgcnt, GFP_KERNEL); + rbdr->pgcache = kcalloc(rbdr->pgcnt, sizeof(*rbdr->pgcache), + GFP_KERNEL); if (!rbdr->pgcache) return -ENOMEM; rbdr->pgidx = 0; diff --git a/drivers/net/ethernet/chelsio/cxgb4/clip_tbl.c b/drivers/net/ethernet/chelsio/cxgb4/clip_tbl.c index 3103ef9b561d..778376eecc28 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/clip_tbl.c +++ b/drivers/net/ethernet/chelsio/cxgb4/clip_tbl.c @@ -305,7 +305,7 @@ struct clip_tbl *t4_init_clip_tbl(unsigned int clipt_start, for (i = 0; i < ctbl->clipt_size; ++i) INIT_LIST_HEAD(&ctbl->hash_list[i]); - cl_list = kvzalloc(clipt_size*sizeof(struct clip_entry), GFP_KERNEL); + cl_list = kvcalloc(clipt_size, sizeof(struct clip_entry), GFP_KERNEL); if (!cl_list) { kvfree(ctbl); return NULL; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c index 8bd90ad15607..2812ea7a1fb3 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c @@ -868,7 +868,7 @@ static int cctrl_tbl_show(struct seq_file *seq, void *v) u16 (*incr)[NCCTRL_WIN]; struct adapter *adap = seq->private; - incr = kmalloc(sizeof(*incr) * NMTUS, GFP_KERNEL); + incr = kmalloc_array(NMTUS, sizeof(*incr), GFP_KERNEL); if (!incr) return -ENOMEM; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 6eb65b870da7..946c763e5109 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -682,7 +682,7 @@ int cxgb4_write_rss(const struct port_info *pi, const u16 *queues) const struct sge_eth_rxq *rxq; rxq = &adapter->sge.ethrxq[pi->first_qset]; - rss = kmalloc(pi->rss_size * sizeof(u16), GFP_KERNEL); + rss = kmalloc_array(pi->rss_size, sizeof(u16), GFP_KERNEL); if (!rss) return -ENOMEM; @@ -4376,8 +4376,8 @@ static int enable_msix(struct adapter *adap) max_ingq += (MAX_OFLD_QSETS * adap->num_uld); if (is_offload(adap)) max_ingq += (MAX_OFLD_QSETS * adap->num_ofld_uld); - entries = kmalloc(sizeof(*entries) * (max_ingq + 1), - GFP_KERNEL); + entries = kmalloc_array(max_ingq + 1, sizeof(*entries), + GFP_KERNEL); if (!entries) return -ENOMEM; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c index de5804ddefbd..00e8967abc3c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c @@ -457,7 +457,8 @@ struct cxgb4_tc_u32_table *cxgb4_init_tc_u32(struct adapter *adap) unsigned int bmap_size; bmap_size = BITS_TO_LONGS(max_tids); - link->tid_map = kvzalloc(sizeof(unsigned long) * bmap_size, GFP_KERNEL); + link->tid_map = kvcalloc(bmap_size, sizeof(unsigned long), + GFP_KERNEL); if (!link->tid_map) goto out_no_mem; bitmap_zero(link->tid_map, max_tids); diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c index ad4c9f17d77c..d6733df3d43f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c @@ -564,13 +564,13 @@ int t4_uld_mem_alloc(struct adapter *adap) if (!adap->uld) return -ENOMEM; - s->uld_rxq_info = kzalloc(CXGB4_ULD_MAX * + s->uld_rxq_info = kcalloc(CXGB4_ULD_MAX, sizeof(struct sge_uld_rxq_info *), GFP_KERNEL); if (!s->uld_rxq_info) goto err_uld; - s->uld_txq_info = kzalloc(CXGB4_TX_MAX * + s->uld_txq_info = kcalloc(CXGB4_TX_MAX, sizeof(struct sge_uld_txq_info *), GFP_KERNEL); if (!s->uld_txq_info) diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index 0a5c4c7da505..66ae40df1aea 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -708,7 +708,7 @@ static void *alloc_ring(struct device *dev, size_t nelem, size_t elem_size, if (!p) return NULL; if (sw_size) { - s = kzalloc_node(nelem * sw_size, GFP_KERNEL, node); + s = kcalloc_node(sw_size, nelem, GFP_KERNEL, node); if (!s) { dma_free_coherent(dev, len, p, *phys); @@ -1812,6 +1812,7 @@ static inline int uld_send(struct adapter *adap, struct sk_buff *skb, txq_info = adap->sge.uld_txq_info[tx_uld_type]; if (unlikely(!txq_info)) { WARN_ON(true); + kfree_skb(skb); return NET_XMIT_DROP; } diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c index 8bb0db990c8f..c30565134c7b 100644 --- a/drivers/net/ethernet/ethoc.c +++ b/drivers/net/ethernet/ethoc.c @@ -1141,7 +1141,8 @@ static int ethoc_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "ethoc: num_tx: %d num_rx: %d\n", priv->num_tx, priv->num_rx); - priv->vma = devm_kzalloc(&pdev->dev, num_bd*sizeof(void *), GFP_KERNEL); + priv->vma = devm_kcalloc(&pdev->dev, num_bd, sizeof(void *), + GFP_KERNEL); if (!priv->vma) { ret = -ENOMEM; goto free; diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index 67246d42c3d9..49f318c1c8c3 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -672,7 +672,7 @@ static struct dpaa_fq *dpaa_fq_alloc(struct device *dev, struct dpaa_fq *dpaa_fq; int i; - dpaa_fq = devm_kzalloc(dev, sizeof(*dpaa_fq) * count, + dpaa_fq = devm_kcalloc(dev, count, sizeof(*dpaa_fq), GFP_KERNEL); if (!dpaa_fq) return NULL; diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index 7c2a9fd4dc1a..0ea5ee1a44a7 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c @@ -2256,9 +2256,9 @@ static int ucc_geth_alloc_tx(struct ucc_geth_private *ugeth) /* Init Tx bds */ for (j = 0; j < ug_info->numQueuesTx; j++) { /* Setup the skbuff rings */ - ugeth->tx_skbuff[j] = kmalloc(sizeof(struct sk_buff *) * - ugeth->ug_info->bdRingLenTx[j], - GFP_KERNEL); + ugeth->tx_skbuff[j] = kmalloc_array(ugeth->ug_info->bdRingLenTx[j], + sizeof(struct sk_buff *), + GFP_KERNEL); if (ugeth->tx_skbuff[j] == NULL) { if (netif_msg_ifup(ugeth)) @@ -2329,9 +2329,9 @@ static int ucc_geth_alloc_rx(struct ucc_geth_private *ugeth) /* Init Rx bds */ for (j = 0; j < ug_info->numQueuesRx; j++) { /* Setup the skbuff rings */ - ugeth->rx_skbuff[j] = kmalloc(sizeof(struct sk_buff *) * - ugeth->ug_info->bdRingLenRx[j], - GFP_KERNEL); + ugeth->rx_skbuff[j] = kmalloc_array(ugeth->ug_info->bdRingLenRx[j], + sizeof(struct sk_buff *), + GFP_KERNEL); if (ugeth->rx_skbuff[j] == NULL) { if (netif_msg_ifup(ugeth)) diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c index 9e1e2d5b80dc..3549269f6906 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c @@ -1462,8 +1462,7 @@ static int hns_dsaf_init(struct dsaf_device *dsaf_dev) return ret; /* malloc mem for tcam mac key(vlan+mac) */ - priv->soft_mac_tbl = vzalloc(sizeof(*priv->soft_mac_tbl) - * DSAF_TCAM_SUM); + priv->soft_mac_tbl = vzalloc(array_size(DSAF_TCAM_SUM, sizeof(*priv->soft_mac_tbl))); if (!priv->soft_mac_tbl) { ret = -ENOMEM; goto remove_hw; diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c index 0733745f4be6..e02128a5ef60 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c @@ -2248,7 +2248,7 @@ static int hns_nic_init_ring_data(struct hns_nic_priv *priv) return -EINVAL; } - priv->ring_data = kzalloc(h->q_num * sizeof(*priv->ring_data) * 2, + priv->ring_data = kzalloc(array3_size(h->q_num, sizeof(*priv->ring_data), 2), GFP_KERNEL); if (!priv->ring_data) return -ENOMEM; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c index e9cff8ed5e07..06d22a9c8651 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c @@ -2554,8 +2554,8 @@ static int hns3_get_ring_config(struct hns3_nic_priv *priv) struct pci_dev *pdev = h->pdev; int i, ret; - priv->ring_data = devm_kzalloc(&pdev->dev, h->kinfo.num_tqps * - sizeof(*priv->ring_data) * 2, + priv->ring_data = devm_kzalloc(&pdev->dev, + array3_size(h->kinfo.num_tqps, sizeof(*priv->ring_data), 2), GFP_KERNEL); if (!priv->ring_data) return -ENOMEM; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c index e1de97effcd2..9793720180ce 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c @@ -754,11 +754,11 @@ static int init_cmdq(struct hinic_cmdq *cmdq, struct hinic_wq *wq, spin_lock_init(&cmdq->cmdq_lock); - cmdq->done = vzalloc(wq->q_depth * sizeof(*cmdq->done)); + cmdq->done = vzalloc(array_size(sizeof(*cmdq->done), wq->q_depth)); if (!cmdq->done) return -ENOMEM; - cmdq->errcode = vzalloc(wq->q_depth * sizeof(*cmdq->errcode)); + cmdq->errcode = vzalloc(array_size(sizeof(*cmdq->errcode), wq->q_depth)); if (!cmdq->errcode) { err = -ENOMEM; goto err_errcode; diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index b43aebfc7f5b..819c22b23eb3 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c @@ -171,7 +171,7 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool) { int i; - pool->free_map = kmalloc(sizeof(u16) * pool->size, GFP_KERNEL); + pool->free_map = kmalloc_array(pool->size, sizeof(u16), GFP_KERNEL); if (!pool->free_map) return -1; diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 85c11dafb4cd..8b8a0c4fbc99 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -2324,7 +2324,7 @@ req_rx_irq_failed: req_tx_irq_failed: for (j = 0; j < i; j++) { free_irq(adapter->tx_scrq[j]->irq, adapter->tx_scrq[j]); - irq_dispose_mapping(adapter->rx_scrq[j]->irq); + irq_dispose_mapping(adapter->tx_scrq[j]->irq); } release_sub_crqs(adapter); return rc; diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c index 88b34f722337..a562c443d9d4 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c +++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c @@ -455,8 +455,8 @@ static int e1000_get_eeprom(struct net_device *netdev, first_word = eeprom->offset >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1; - eeprom_buff = kmalloc(sizeof(u16) * - (last_word - first_word + 1), GFP_KERNEL); + eeprom_buff = kmalloc_array(last_word - first_word + 1, sizeof(u16), + GFP_KERNEL); if (!eeprom_buff) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 003cbd605799..6faf7bf3497e 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -527,8 +527,8 @@ static int e1000_get_eeprom(struct net_device *netdev, first_word = eeprom->offset >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1; - eeprom_buff = kmalloc(sizeof(u16) * (last_word - first_word + 1), - GFP_KERNEL); + eeprom_buff = kmalloc_array(last_word - first_word + 1, sizeof(u16), + GFP_KERNEL); if (!eeprom_buff) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index fff55f0bed30..b9246cba8fea 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -3330,7 +3330,7 @@ static int e1000e_write_mc_addr_list(struct net_device *netdev) return 0; } - mta_list = kzalloc(netdev_mc_count(netdev) * ETH_ALEN, GFP_ATOMIC); + mta_list = kcalloc(netdev_mc_count(netdev), ETH_ALEN, GFP_ATOMIC); if (!mta_list) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c index c7234f35f8ff..42778f53d475 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c @@ -577,7 +577,7 @@ static int fm10k_set_ringparam(struct net_device *netdev, /* allocate temporary buffer to store rings in */ i = max_t(int, interface->num_tx_queues, interface->num_rx_queues); - temp_ring = vmalloc(i * sizeof(struct fm10k_ring)); + temp_ring = vmalloc(array_size(i, sizeof(struct fm10k_ring))); if (!temp_ring) { err = -ENOMEM; diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index ff2be34bff39..98f3264d2e1e 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c @@ -757,8 +757,8 @@ static int igb_get_eeprom(struct net_device *netdev, first_word = eeprom->offset >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1; - eeprom_buff = kmalloc(sizeof(u16) * - (last_word - first_word + 1), GFP_KERNEL); + eeprom_buff = kmalloc_array(last_word - first_word + 1, sizeof(u16), + GFP_KERNEL); if (!eeprom_buff) return -ENOMEM; @@ -923,11 +923,9 @@ static int igb_set_ringparam(struct net_device *netdev, } if (adapter->num_tx_queues > adapter->num_rx_queues) - temp_ring = vmalloc(adapter->num_tx_queues * - sizeof(struct igb_ring)); + temp_ring = vmalloc(array_size(sizeof(struct igb_ring), adapter->num_tx_queues)); else - temp_ring = vmalloc(adapter->num_rx_queues * - sizeof(struct igb_ring)); + temp_ring = vmalloc(array_size(sizeof(struct igb_ring), adapter->num_rx_queues)); if (!temp_ring) { err = -ENOMEM; @@ -3203,8 +3201,8 @@ static int igb_get_module_eeprom(struct net_device *netdev, first_word = ee->offset >> 1; last_word = (ee->offset + ee->len - 1) >> 1; - dataword = kmalloc(sizeof(u16) * (last_word - first_word + 1), - GFP_KERNEL); + dataword = kmalloc_array(last_word - first_word + 1, sizeof(u16), + GFP_KERNEL); if (!dataword) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 9c7e75b3b6c7..78fa1ebb3987 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -3151,8 +3151,9 @@ static int igb_sw_init(struct igb_adapter *adapter) /* Assume MSI-X interrupts, will be checked during IRQ allocation */ adapter->flags |= IGB_FLAG_HAS_MSIX; - adapter->mac_table = kzalloc(sizeof(struct igb_mac_addr) * - hw->mac.rar_entry_count, GFP_ATOMIC); + adapter->mac_table = kcalloc(hw->mac.rar_entry_count, + sizeof(struct igb_mac_addr), + GFP_ATOMIC); if (!adapter->mac_table) return -ENOMEM; @@ -4136,7 +4137,7 @@ static int igb_write_mc_addr_list(struct net_device *netdev) return 0; } - mta_list = kzalloc(netdev_mc_count(netdev) * 6, GFP_ATOMIC); + mta_list = kcalloc(netdev_mc_count(netdev), 6, GFP_ATOMIC); if (!mta_list) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c b/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c index d10a0d242dda..488020475cec 100644 --- a/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c +++ b/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c @@ -400,8 +400,9 @@ ixgb_get_eeprom(struct net_device *netdev, first_word = eeprom->offset >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1; - eeprom_buff = kmalloc(sizeof(__le16) * - (last_word - first_word + 1), GFP_KERNEL); + eeprom_buff = kmalloc_array(last_word - first_word + 1, + sizeof(__le16), + GFP_KERNEL); if (!eeprom_buff) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c index 5a713199653c..49c65ba4bdf3 100644 --- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c +++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c @@ -1120,8 +1120,9 @@ ixgb_set_multi(struct net_device *netdev) rctl |= IXGB_RCTL_MPE; IXGB_WRITE_REG(hw, RCTL, rctl); } else { - u8 *mta = kmalloc(IXGB_MAX_NUM_MULTICAST_ADDRESSES * - ETH_ALEN, GFP_ATOMIC); + u8 *mta = kmalloc_array(ETH_ALEN, + IXGB_MAX_NUM_MULTICAST_ADDRESSES, + GFP_ATOMIC); u8 *addr; if (!mta) goto alloc_failed; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index f7e68083200c..329ec6d8db00 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -922,7 +922,7 @@ static int ixgbe_get_eeprom(struct net_device *netdev, last_word = (eeprom->offset + eeprom->len - 1) >> 1; eeprom_len = last_word - first_word + 1; - eeprom_buff = kmalloc(sizeof(u16) * eeprom_len, GFP_KERNEL); + eeprom_buff = kmalloc_array(eeprom_len, sizeof(u16), GFP_KERNEL); if (!eeprom_buff) return -ENOMEM; @@ -1087,7 +1087,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev, /* allocate temporary buffer to store rings in */ i = max_t(int, adapter->num_tx_queues + adapter->num_xdp_queues, adapter->num_rx_queues); - temp_ring = vmalloc(i * sizeof(struct ixgbe_ring)); + temp_ring = vmalloc(array_size(i, sizeof(struct ixgbe_ring))); if (!temp_ring) { err = -ENOMEM; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 9c3fa0b55551..1eeb1b6fa249 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -6099,8 +6099,8 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter, for (i = 1; i < IXGBE_MAX_LINK_HANDLE; i++) adapter->jump_tables[i] = NULL; - adapter->mac_table = kzalloc(sizeof(struct ixgbe_mac_addr) * - hw->mac.num_rar_entries, + adapter->mac_table = kcalloc(hw->mac.num_rar_entries, + sizeof(struct ixgbe_mac_addr), GFP_ATOMIC); if (!adapter->mac_table) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c index ff9d05f308ee..35bd7f8fa1d9 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c +++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c @@ -289,7 +289,7 @@ static int ixgbevf_set_ringparam(struct net_device *netdev, } if (new_tx_count != adapter->tx_ring_count) { - tx_ring = vmalloc(adapter->num_tx_queues * sizeof(*tx_ring)); + tx_ring = vmalloc(array_size(sizeof(*tx_ring), adapter->num_tx_queues)); if (!tx_ring) { err = -ENOMEM; goto clear_reset; @@ -315,7 +315,7 @@ static int ixgbevf_set_ringparam(struct net_device *netdev, } if (new_rx_count != adapter->rx_ring_count) { - rx_ring = vmalloc(adapter->num_rx_queues * sizeof(*rx_ring)); + rx_ring = vmalloc(array_size(sizeof(*rx_ring), adapter->num_rx_queues)); if (!rx_ring) { err = -ENOMEM; goto clear_reset; diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index 62d848df26ef..a171c3264458 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c @@ -589,8 +589,9 @@ jme_setup_tx_resources(struct jme_adapter *jme) atomic_set(&txring->next_to_clean, 0); atomic_set(&txring->nr_free, jme->tx_ring_size); - txring->bufinf = kzalloc(sizeof(struct jme_buffer_info) * - jme->tx_ring_size, GFP_ATOMIC); + txring->bufinf = kcalloc(jme->tx_ring_size, + sizeof(struct jme_buffer_info), + GFP_ATOMIC); if (unlikely(!(txring->bufinf))) goto err_free_txring; @@ -838,8 +839,9 @@ jme_setup_rx_resources(struct jme_adapter *jme) rxring->next_to_use = 0; atomic_set(&rxring->next_to_clean, 0); - rxring->bufinf = kzalloc(sizeof(struct jme_buffer_info) * - jme->rx_ring_size, GFP_ATOMIC); + rxring->bufinf = kcalloc(jme->rx_ring_size, + sizeof(struct jme_buffer_info), + GFP_ATOMIC); if (unlikely(!(rxring->bufinf))) goto err_free_rxring; diff --git a/drivers/net/ethernet/mellanox/mlx4/alloc.c b/drivers/net/ethernet/mellanox/mlx4/alloc.c index 94f4dc4a77e9..21788d4f9881 100644 --- a/drivers/net/ethernet/mellanox/mlx4/alloc.c +++ b/drivers/net/ethernet/mellanox/mlx4/alloc.c @@ -185,8 +185,8 @@ int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask, bitmap->avail = num - reserved_top - reserved_bot; bitmap->effective_len = bitmap->avail; spin_lock_init(&bitmap->lock); - bitmap->table = kzalloc(BITS_TO_LONGS(bitmap->max) * - sizeof(long), GFP_KERNEL); + bitmap->table = kcalloc(BITS_TO_LONGS(bitmap->max), sizeof(long), + GFP_KERNEL); if (!bitmap->table) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 4c2ee9fd9e57..857588e2488d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c @@ -2377,20 +2377,23 @@ int mlx4_multi_func_init(struct mlx4_dev *dev) struct mlx4_vf_admin_state *vf_admin; priv->mfunc.master.slave_state = - kzalloc(dev->num_slaves * - sizeof(struct mlx4_slave_state), GFP_KERNEL); + kcalloc(dev->num_slaves, + sizeof(struct mlx4_slave_state), + GFP_KERNEL); if (!priv->mfunc.master.slave_state) goto err_comm; priv->mfunc.master.vf_admin = - kzalloc(dev->num_slaves * - sizeof(struct mlx4_vf_admin_state), GFP_KERNEL); + kcalloc(dev->num_slaves, + sizeof(struct mlx4_vf_admin_state), + GFP_KERNEL); if (!priv->mfunc.master.vf_admin) goto err_comm_admin; priv->mfunc.master.vf_oper = - kzalloc(dev->num_slaves * - sizeof(struct mlx4_vf_oper_state), GFP_KERNEL); + kcalloc(dev->num_slaves, + sizeof(struct mlx4_vf_oper_state), + GFP_KERNEL); if (!priv->mfunc.master.vf_oper) goto err_comm_oper; @@ -2636,9 +2639,9 @@ int mlx4_cmd_use_events(struct mlx4_dev *dev) int i; int err = 0; - priv->cmd.context = kmalloc(priv->cmd.max_cmds * - sizeof(struct mlx4_cmd_context), - GFP_KERNEL); + priv->cmd.context = kmalloc_array(priv->cmd.max_cmds, + sizeof(struct mlx4_cmd_context), + GFP_KERNEL); if (!priv->cmd.context) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 0fb85d71c11b..ab8c8498b7e3 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -2227,13 +2227,15 @@ static int mlx4_en_copy_priv(struct mlx4_en_priv *dst, if (!dst->tx_ring_num[t]) continue; - dst->tx_ring[t] = kzalloc(sizeof(struct mlx4_en_tx_ring *) * - MAX_TX_RINGS, GFP_KERNEL); + dst->tx_ring[t] = kcalloc(MAX_TX_RINGS, + sizeof(struct mlx4_en_tx_ring *), + GFP_KERNEL); if (!dst->tx_ring[t]) goto err_free_tx; - dst->tx_cq[t] = kzalloc(sizeof(struct mlx4_en_cq *) * - MAX_TX_RINGS, GFP_KERNEL); + dst->tx_cq[t] = kcalloc(MAX_TX_RINGS, + sizeof(struct mlx4_en_cq *), + GFP_KERNEL); if (!dst->tx_cq[t]) { kfree(dst->tx_ring[t]); goto err_free_tx; @@ -3314,14 +3316,16 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, if (!priv->tx_ring_num[t]) continue; - priv->tx_ring[t] = kzalloc(sizeof(struct mlx4_en_tx_ring *) * - MAX_TX_RINGS, GFP_KERNEL); + priv->tx_ring[t] = kcalloc(MAX_TX_RINGS, + sizeof(struct mlx4_en_tx_ring *), + GFP_KERNEL); if (!priv->tx_ring[t]) { err = -ENOMEM; goto out; } - priv->tx_cq[t] = kzalloc(sizeof(struct mlx4_en_cq *) * - MAX_TX_RINGS, GFP_KERNEL); + priv->tx_cq[t] = kcalloc(MAX_TX_RINGS, + sizeof(struct mlx4_en_cq *), + GFP_KERNEL); if (!priv->tx_cq[t]) { err = -ENOMEM; goto out; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index c6d101351537..82841cb9b98a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -193,7 +193,7 @@ static int mlx4_en_fill_rx_buffers(struct mlx4_en_priv *priv) if (mlx4_en_prepare_rx_desc(priv, ring, ring->actual_size, - GFP_KERNEL | __GFP_COLD)) { + GFP_KERNEL)) { if (ring->actual_size < MLX4_EN_MIN_RX_SIZE) { en_err(priv, "Failed to allocate enough rx buffers\n"); return -ENOMEM; @@ -556,8 +556,7 @@ static void mlx4_en_refill_rx_buffers(struct mlx4_en_priv *priv, do { if (mlx4_en_prepare_rx_desc(priv, ring, ring->prod & ring->size_mask, - GFP_ATOMIC | __GFP_COLD | - __GFP_MEMALLOC)) + GFP_ATOMIC | __GFP_MEMALLOC)) break; ring->prod++; } while (likely(--missing)); diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index 050dc213e8db..2df92dbd38e1 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c @@ -1212,8 +1212,9 @@ int mlx4_init_eq_table(struct mlx4_dev *dev) } priv->eq_table.irq_names = - kmalloc(MLX4_IRQNAME_SIZE * (dev->caps.num_comp_vectors + 1), - GFP_KERNEL); + kmalloc_array(MLX4_IRQNAME_SIZE, + (dev->caps.num_comp_vectors + 1), + GFP_KERNEL); if (!priv->eq_table.irq_names) { err = -ENOMEM; goto err_out_clr_int; diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index cf9011bb6e0f..79d41834fcbe 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -3058,7 +3058,8 @@ static int mlx4_init_steering(struct mlx4_dev *dev) int num_entries = dev->caps.num_ports; int i, j; - priv->steer = kzalloc(sizeof(struct mlx4_steer) * num_entries, GFP_KERNEL); + priv->steer = kcalloc(num_entries, sizeof(struct mlx4_steer), + GFP_KERNEL); if (!priv->steer) return -ENOMEM; @@ -3179,7 +3180,7 @@ static u64 mlx4_enable_sriov(struct mlx4_dev *dev, struct pci_dev *pdev, } } - dev->dev_vfs = kzalloc(total_vfs * sizeof(*dev->dev_vfs), GFP_KERNEL); + dev->dev_vfs = kcalloc(total_vfs, sizeof(*dev->dev_vfs), GFP_KERNEL); if (NULL == dev->dev_vfs) { mlx4_err(dev, "Failed to allocate memory for VFs\n"); goto disable_sriov; @@ -4190,12 +4191,14 @@ end: static void mlx4_shutdown(struct pci_dev *pdev) { struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev); + struct mlx4_dev *dev = persist->dev; mlx4_info(persist->dev, "mlx4_shutdown was called\n"); mutex_lock(&persist->interface_state_mutex); if (persist->interface_state & MLX4_INTERFACE_STATE_UP) mlx4_unload_one(pdev); mutex_unlock(&persist->interface_state_mutex); + mlx4_pci_disable_device(dev); } static const struct pci_error_handlers mlx4_err_handler = { diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 66e8054a8966..4638998e4f25 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -505,7 +505,7 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev) int t; priv->mfunc.master.res_tracker.slave_list = - kzalloc(dev->num_slaves * sizeof(struct slave_list), + kcalloc(dev->num_slaves, sizeof(struct slave_list), GFP_KERNEL); if (!priv->mfunc.master.res_tracker.slave_list) return -ENOMEM; @@ -525,19 +525,20 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev) for (i = 0; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) { struct resource_allocator *res_alloc = &priv->mfunc.master.res_tracker.res_alloc[i]; - res_alloc->quota = kmalloc((dev->persist->num_vfs + 1) * - sizeof(int), GFP_KERNEL); - res_alloc->guaranteed = kmalloc((dev->persist->num_vfs + 1) * - sizeof(int), GFP_KERNEL); + res_alloc->quota = kmalloc_array(dev->persist->num_vfs + 1, + sizeof(int), + GFP_KERNEL); + res_alloc->guaranteed = kmalloc_array(dev->persist->num_vfs + 1, + sizeof(int), + GFP_KERNEL); if (i == RES_MAC || i == RES_VLAN) - res_alloc->allocated = kzalloc(MLX4_MAX_PORTS * - (dev->persist->num_vfs - + 1) * - sizeof(int), GFP_KERNEL); + res_alloc->allocated = kcalloc(MLX4_MAX_PORTS * (dev->persist->num_vfs + 1), + sizeof(int), + GFP_KERNEL); else - res_alloc->allocated = kzalloc((dev->persist-> - num_vfs + 1) * - sizeof(int), GFP_KERNEL); + res_alloc->allocated = kcalloc(dev->persist->num_vfs + 1, + sizeof(int), + GFP_KERNEL); /* Reduce the sink counter */ if (i == RES_COUNTER) res_alloc->res_free = dev->caps.max_counters - 1; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c b/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c index 7ecadb501743..413080a312a7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c @@ -494,7 +494,7 @@ static int add_res_tree(struct mlx5_core_dev *dev, enum dbg_rsc_type type, int err; int i; - d = kzalloc(sizeof(*d) + nfile * sizeof(d->fields[0]), GFP_KERNEL); + d = kzalloc(struct_size(d, fields, nfile), GFP_KERNEL); if (!d) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_clock.c b/drivers/net/ethernet/mellanox/mlx5/core/en_clock.c index 27040009d87a..d54bf2264dd2 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_clock.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_clock.c @@ -456,8 +456,9 @@ static int mlx5e_init_pin_config(struct mlx5e_tstamp *tstamp) int i; tstamp->ptp_info.pin_config = - kzalloc(sizeof(*tstamp->ptp_info.pin_config) * - tstamp->ptp_info.n_pins, GFP_KERNEL); + kcalloc(tstamp->ptp_info.n_pins, + sizeof(*tstamp->ptp_info.pin_config), + GFP_KERNEL); if (!tstamp->ptp_info.pin_config) return -ENOMEM; tstamp->ptp_info.enable = mlx5e_ptp_enable; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 14bab8a5550d..65820fca1361 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -449,14 +449,14 @@ static int mlx5e_rq_alloc_mpwqe_info(struct mlx5e_rq *rq, int mtt_alloc = mtt_sz + MLX5_UMR_ALIGN - 1; int i; - rq->mpwqe.info = kzalloc_node(wq_sz * sizeof(*rq->mpwqe.info), + rq->mpwqe.info = kcalloc_node(wq_sz, sizeof(*rq->mpwqe.info), GFP_KERNEL, cpu_to_node(c->cpu)); if (!rq->mpwqe.info) goto err_out; /* We allocate more than mtt_sz as we will align the pointer */ - rq->mpwqe.mtt_no_align = kzalloc_node(mtt_alloc * wq_sz, GFP_KERNEL, - cpu_to_node(c->cpu)); + rq->mpwqe.mtt_no_align = kcalloc_node(wq_sz, mtt_alloc, GFP_KERNEL, + cpu_to_node(c->cpu)); if (unlikely(!rq->mpwqe.mtt_no_align)) goto err_free_wqe_info; @@ -629,7 +629,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c, break; default: /* MLX5_WQ_TYPE_LINKED_LIST */ rq->wqe.frag_info = - kzalloc_node(wq_sz * sizeof(*rq->wqe.frag_info), + kcalloc_node(wq_sz, sizeof(*rq->wqe.frag_info), GFP_KERNEL, cpu_to_node(c->cpu)); if (!rq->wqe.frag_info) { err = -ENOMEM; @@ -975,7 +975,7 @@ static int mlx5e_alloc_xdpsq_db(struct mlx5e_xdpsq *sq, int numa) { int wq_sz = mlx5_wq_cyc_get_size(&sq->wq); - sq->db.di = kzalloc_node(sizeof(*sq->db.di) * wq_sz, + sq->db.di = kcalloc_node(wq_sz, sizeof(*sq->db.di), GFP_KERNEL, numa); if (!sq->db.di) { mlx5e_free_xdpsq_db(sq); @@ -1033,7 +1033,7 @@ static int mlx5e_alloc_icosq_db(struct mlx5e_icosq *sq, int numa) { u8 wq_sz = mlx5_wq_cyc_get_size(&sq->wq); - sq->db.ico_wqe = kzalloc_node(sizeof(*sq->db.ico_wqe) * wq_sz, + sq->db.ico_wqe = kcalloc_node(wq_sz, sizeof(*sq->db.ico_wqe), GFP_KERNEL, numa); if (!sq->db.ico_wqe) return -ENOMEM; @@ -1090,9 +1090,9 @@ static int mlx5e_alloc_txqsq_db(struct mlx5e_txqsq *sq, int numa) int wq_sz = mlx5_wq_cyc_get_size(&sq->wq); int df_sz = wq_sz * MLX5_SEND_WQEBB_NUM_DS; - sq->db.dma_fifo = kzalloc_node(df_sz * sizeof(*sq->db.dma_fifo), + sq->db.dma_fifo = kcalloc_node(df_sz, sizeof(*sq->db.dma_fifo), GFP_KERNEL, numa); - sq->db.wqe_info = kzalloc_node(wq_sz * sizeof(*sq->db.wqe_info), + sq->db.wqe_info = kcalloc_node(wq_sz, sizeof(*sq->db.wqe_info), GFP_KERNEL, numa); if (!sq->db.dma_fifo || !sq->db.wqe_info) { mlx5e_free_txqsq_db(sq); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index 387758fc6be4..e070ba0a15ce 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -1634,7 +1634,7 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev) } esw->offloads.vport_reps = - kzalloc(total_vports * sizeof(struct mlx5_eswitch_rep), + kcalloc(total_vports, sizeof(struct mlx5_eswitch_rep), GFP_KERNEL); if (!esw->offloads.vport_reps) { err = -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c index 5212428031a4..6f27cd31d73c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c @@ -551,15 +551,17 @@ static int mlx5_fpga_conn_create_qp(struct mlx5_fpga_conn *conn, if (err) goto out; - conn->qp.rq.bufs = kvzalloc(sizeof(conn->qp.rq.bufs[0]) * - conn->qp.rq.size, GFP_KERNEL); + conn->qp.rq.bufs = kvcalloc(conn->qp.rq.size, + sizeof(conn->qp.rq.bufs[0]), + GFP_KERNEL); if (!conn->qp.rq.bufs) { err = -ENOMEM; goto err_wq; } - conn->qp.sq.bufs = kvzalloc(sizeof(conn->qp.sq.bufs[0]) * - conn->qp.sq.size, GFP_KERNEL); + conn->qp.sq.bufs = kvcalloc(conn->qp.sq.size, + sizeof(conn->qp.sq.bufs[0]), + GFP_KERNEL); if (!conn->qp.sq.bufs) { err = -ENOMEM; goto err_rq_bufs; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c index 35d0e33381ca..375e1dd72fb3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c @@ -290,7 +290,7 @@ int mlx5_fpga_ipsec_counters_read(struct mlx5_core_dev *mdev, u64 *counters, count = mlx5_fpga_ipsec_counters_count(mdev); - data = kzalloc(sizeof(*data) * count * 2, GFP_KERNEL); + data = kzalloc(array3_size(sizeof(*data), count, 2), GFP_KERNEL); if (!data) { ret = -ENOMEM; goto out; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 24d1b0be5a68..bfa54d1f785c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -1053,8 +1053,7 @@ static struct mlx5_flow_handle *alloc_handle(int num_rules) { struct mlx5_flow_handle *handle; - handle = kzalloc(sizeof(*handle) + sizeof(handle->rule[0]) * - num_rules, GFP_KERNEL); + handle = kzalloc(struct_size(handle, rule, num_rules), GFP_KERNEL); if (!handle) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c index 96f9f267d16d..dc12ab33afff 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core.c @@ -1361,7 +1361,7 @@ static int mlxsw_core_reg_access_emad(struct mlxsw_core *mlxsw_core, err = mlxsw_emad_reg_access(mlxsw_core, reg, payload, type, trans, bulk_list, cb, cb_priv, tid); if (err) { - kfree(trans); + kfree_rcu(trans, rcu); return err; } return 0; @@ -1574,11 +1574,13 @@ void mlxsw_core_skb_receive(struct mlxsw_core *mlxsw_core, struct sk_buff *skb, break; } } - rcu_read_unlock(); - if (!found) + if (!found) { + rcu_read_unlock(); goto drop; + } rxl->func(skb, local_port, rxl_item->priv); + rcu_read_unlock(); return; drop: diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index e798fbe08600..83160c79a6ab 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -4372,7 +4372,7 @@ static void ksz_update_timer(struct ksz_timer_info *info) */ static int ksz_alloc_soft_desc(struct ksz_desc_info *desc_info, int transmit) { - desc_info->ring = kzalloc(sizeof(struct ksz_desc) * desc_info->alloc, + desc_info->ring = kcalloc(desc_info->alloc, sizeof(struct ksz_desc), GFP_KERNEL); if (!desc_info->ring) return 1; diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c index beb730ff5d42..4db3431b79ac 100644 --- a/drivers/net/ethernet/moxa/moxart_ether.c +++ b/drivers/net/ethernet/moxa/moxart_ether.c @@ -507,15 +507,15 @@ static int moxart_mac_probe(struct platform_device *pdev) goto init_fail; } - priv->tx_buf_base = kmalloc(priv->tx_buf_size * TX_DESC_NUM, - GFP_ATOMIC); + priv->tx_buf_base = kmalloc_array(priv->tx_buf_size, TX_DESC_NUM, + GFP_ATOMIC); if (!priv->tx_buf_base) { ret = -ENOMEM; goto init_fail; } - priv->rx_buf_base = kmalloc(priv->rx_buf_size * RX_DESC_NUM, - GFP_ATOMIC); + priv->rx_buf_base = kmalloc_array(priv->rx_buf_size, RX_DESC_NUM, + GFP_ATOMIC); if (!priv->rx_buf_base) { ret = -ENOMEM; goto init_fail; diff --git a/drivers/net/ethernet/neterion/vxge/vxge-config.c b/drivers/net/ethernet/neterion/vxge/vxge-config.c index 6f57b0b7d57a..afa5c4ec9d10 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-config.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-config.c @@ -2220,22 +2220,22 @@ __vxge_hw_channel_allocate(struct __vxge_hw_vpath_handle *vph, channel->length = length; channel->vp_id = vp_id; - channel->work_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL); + channel->work_arr = kcalloc(length, sizeof(void *), GFP_KERNEL); if (channel->work_arr == NULL) goto exit1; - channel->free_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL); + channel->free_arr = kcalloc(length, sizeof(void *), GFP_KERNEL); if (channel->free_arr == NULL) goto exit1; channel->free_ptr = length; - channel->reserve_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL); + channel->reserve_arr = kcalloc(length, sizeof(void *), GFP_KERNEL); if (channel->reserve_arr == NULL) goto exit1; channel->reserve_ptr = length; channel->reserve_top = 0; - channel->orig_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL); + channel->orig_arr = kcalloc(length, sizeof(void *), GFP_KERNEL); if (channel->orig_arr == NULL) goto exit1; @@ -2565,7 +2565,7 @@ __vxge_hw_mempool_grow(struct vxge_hw_mempool *mempool, u32 num_allocate, * allocate new memblock and its private part at once. * This helps to minimize memory usage a lot. */ mempool->memblocks_priv_arr[i] = - vzalloc(mempool->items_priv_size * n_items); + vzalloc(array_size(mempool->items_priv_size, n_items)); if (mempool->memblocks_priv_arr[i] == NULL) { status = VXGE_HW_ERR_OUT_OF_MEMORY; goto exit; @@ -2665,7 +2665,7 @@ __vxge_hw_mempool_create(struct __vxge_hw_device *devh, /* allocate array of memblocks */ mempool->memblocks_arr = - vzalloc(sizeof(void *) * mempool->memblocks_max); + vzalloc(array_size(sizeof(void *), mempool->memblocks_max)); if (mempool->memblocks_arr == NULL) { __vxge_hw_mempool_destroy(mempool); status = VXGE_HW_ERR_OUT_OF_MEMORY; @@ -2675,7 +2675,7 @@ __vxge_hw_mempool_create(struct __vxge_hw_device *devh, /* allocate array of private parts of items per memblocks */ mempool->memblocks_priv_arr = - vzalloc(sizeof(void *) * mempool->memblocks_max); + vzalloc(array_size(sizeof(void *), mempool->memblocks_max)); if (mempool->memblocks_priv_arr == NULL) { __vxge_hw_mempool_destroy(mempool); status = VXGE_HW_ERR_OUT_OF_MEMORY; @@ -2685,8 +2685,7 @@ __vxge_hw_mempool_create(struct __vxge_hw_device *devh, /* allocate array of memblocks DMA objects */ mempool->memblocks_dma_arr = - vzalloc(sizeof(struct vxge_hw_mempool_dma) * - mempool->memblocks_max); + vzalloc(array_size(sizeof(struct vxge_hw_mempool_dma), mempool->memblocks_max)); if (mempool->memblocks_dma_arr == NULL) { __vxge_hw_mempool_destroy(mempool); status = VXGE_HW_ERR_OUT_OF_MEMORY; @@ -2695,7 +2694,7 @@ __vxge_hw_mempool_create(struct __vxge_hw_device *devh, } /* allocate hash array of items */ - mempool->items_arr = vzalloc(sizeof(void *) * mempool->items_max); + mempool->items_arr = vzalloc(array_size(sizeof(void *), mempool->items_max)); if (mempool->items_arr == NULL) { __vxge_hw_mempool_destroy(mempool); status = VXGE_HW_ERR_OUT_OF_MEMORY; diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c index 50ea69d88480..54d6a42a6140 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-main.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c @@ -3437,8 +3437,8 @@ static int vxge_device_register(struct __vxge_hw_device *hldev, vxge_initialize_ethtool_ops(ndev); /* Allocate memory for vpath */ - vdev->vpaths = kzalloc((sizeof(struct vxge_vpath)) * - no_of_vpath, GFP_KERNEL); + vdev->vpaths = kcalloc(no_of_vpath, sizeof(struct vxge_vpath), + GFP_KERNEL); if (!vdev->vpaths) { vxge_debug_init(VXGE_ERR, "%s: vpath memory allocation failed", diff --git a/drivers/net/ethernet/netronome/nfp/flower/metadata.c b/drivers/net/ethernet/netronome/nfp/flower/metadata.c index d9582ccc0025..18f46aa23622 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/metadata.c +++ b/drivers/net/ethernet/netronome/nfp/flower/metadata.c @@ -413,7 +413,7 @@ int nfp_flower_metadata_init(struct nfp_app *app) /* Init ring buffer and unallocated stats_ids. */ priv->stats_ids.free_list.buf = - vmalloc(NFP_FL_STATS_ENTRY_RS * NFP_FL_STATS_ELEM_RS); + vmalloc(array_size(NFP_FL_STATS_ELEM_RS, NFP_FL_STATS_ENTRY_RS)); if (!priv->stats_ids.free_list.buf) goto err_free_last_used; diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c index bffa25d6dc29..a5ed330b88e8 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c @@ -1203,7 +1203,7 @@ static void *nfp_net_rx_alloc_one(struct nfp_net_dp *dp, dma_addr_t *dma_addr) } else { struct page *page; - page = alloc_page(GFP_KERNEL | __GFP_COLD); + page = alloc_page(GFP_KERNEL); frag = page ? page_address(page) : NULL; } if (!frag) { @@ -1230,7 +1230,7 @@ static void *nfp_net_napi_alloc_one(struct nfp_net_dp *dp, dma_addr_t *dma_addr) } else { struct page *page; - page = alloc_page(GFP_ATOMIC | __GFP_COLD); + page = alloc_page(GFP_ATOMIC); frag = page ? page_address(page) : NULL; } if (!frag) { diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index 994a83a1f0a5..1f869f1267ca 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -4599,8 +4599,10 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri sizeof(struct ring_desc_ex) * (ring->rx_pending + ring->tx_pending), &ring_addr); } - rx_skbuff = kmalloc(sizeof(struct nv_skb_map) * ring->rx_pending, GFP_KERNEL); - tx_skbuff = kmalloc(sizeof(struct nv_skb_map) * ring->tx_pending, GFP_KERNEL); + rx_skbuff = kmalloc_array(ring->rx_pending, sizeof(struct nv_skb_map), + GFP_KERNEL); + tx_skbuff = kmalloc_array(ring->tx_pending, sizeof(struct nv_skb_map), + GFP_KERNEL); if (!rxtx_ring || !rx_skbuff || !tx_skbuff) { /* fall back to old rings */ if (!nv_optimized(np)) { 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 5ae9681a2da7..069d78a44cbd 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 @@ -2187,7 +2187,7 @@ static void pch_gbe_set_multi(struct net_device *netdev) if (mc_count >= PCH_GBE_MAR_ENTRIES) return; - mta_list = kmalloc(mc_count * ETH_ALEN, GFP_ATOMIC); + mta_list = kmalloc_array(ETH_ALEN, mc_count, GFP_ATOMIC); if (!mta_list) return; diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.c b/drivers/net/ethernet/pasemi/pasemi_mac.c index c9b4ac9d3330..728d4169d81e 100644 --- a/drivers/net/ethernet/pasemi/pasemi_mac.c +++ b/drivers/net/ethernet/pasemi/pasemi_mac.c @@ -392,8 +392,9 @@ static int pasemi_mac_setup_rx_resources(const struct net_device *dev) spin_lock_init(&ring->lock); ring->size = RX_RING_SIZE; - ring->ring_info = kzalloc(sizeof(struct pasemi_mac_buffer) * - RX_RING_SIZE, GFP_KERNEL); + ring->ring_info = kcalloc(RX_RING_SIZE, + sizeof(struct pasemi_mac_buffer), + GFP_KERNEL); if (!ring->ring_info) goto out_ring_info; @@ -475,8 +476,9 @@ pasemi_mac_setup_tx_resources(const struct net_device *dev) spin_lock_init(&ring->lock); ring->size = TX_RING_SIZE; - ring->ring_info = kzalloc(sizeof(struct pasemi_mac_buffer) * - TX_RING_SIZE, GFP_KERNEL); + ring->ring_info = kcalloc(TX_RING_SIZE, + sizeof(struct pasemi_mac_buffer), + GFP_KERNEL); if (!ring->ring_info) goto out_ring_info; diff --git a/drivers/net/ethernet/qlogic/qed/qed_debug.c b/drivers/net/ethernet/qlogic/qed/qed_debug.c index 99f32202a85c..5f0f1af135b4 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_debug.c +++ b/drivers/net/ethernet/qlogic/qed/qed_debug.c @@ -6468,7 +6468,8 @@ static enum dbg_status qed_mcp_trace_alloc_meta(struct qed_hwfn *p_hwfn, /* Read no. of modules and allocate memory for their pointers */ meta->modules_num = qed_read_byte_from_buf(meta_buf_bytes, &offset); - meta->modules = kzalloc(meta->modules_num * sizeof(char *), GFP_KERNEL); + meta->modules = kcalloc(meta->modules_num, sizeof(char *), + GFP_KERNEL); if (!meta->modules) return DBG_STATUS_VIRT_MEM_ALLOC_FAILED; @@ -6496,7 +6497,7 @@ static enum dbg_status qed_mcp_trace_alloc_meta(struct qed_hwfn *p_hwfn, /* Read number of formats and allocate memory for all formats */ meta->formats_num = qed_read_dword_from_buf(meta_buf_bytes, &offset); - meta->formats = kzalloc(meta->formats_num * + meta->formats = kcalloc(meta->formats_num, sizeof(struct mcp_trace_format), GFP_KERNEL); if (!meta->formats) diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c index 6024b832b4d9..8812fb5ad07f 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c @@ -831,26 +831,26 @@ static int qed_alloc_qm_data(struct qed_hwfn *p_hwfn) if (rc) goto alloc_err; - qm_info->qm_pq_params = kzalloc(sizeof(*qm_info->qm_pq_params) * - qed_init_qm_get_num_pqs(p_hwfn), + qm_info->qm_pq_params = kcalloc(qed_init_qm_get_num_pqs(p_hwfn), + sizeof(*qm_info->qm_pq_params), GFP_KERNEL); if (!qm_info->qm_pq_params) goto alloc_err; - qm_info->qm_vport_params = kzalloc(sizeof(*qm_info->qm_vport_params) * - qed_init_qm_get_num_vports(p_hwfn), + qm_info->qm_vport_params = kcalloc(qed_init_qm_get_num_vports(p_hwfn), + sizeof(*qm_info->qm_vport_params), GFP_KERNEL); if (!qm_info->qm_vport_params) goto alloc_err; - qm_info->qm_port_params = kzalloc(sizeof(*qm_info->qm_port_params) * - p_hwfn->cdev->num_ports_in_engine, + qm_info->qm_port_params = kcalloc(p_hwfn->cdev->num_ports_in_engine, + sizeof(*qm_info->qm_port_params), GFP_KERNEL); if (!qm_info->qm_port_params) goto alloc_err; - qm_info->wfq_data = kzalloc(sizeof(*qm_info->wfq_data) * - qed_init_qm_get_num_vports(p_hwfn), + qm_info->wfq_data = kcalloc(qed_init_qm_get_num_vports(p_hwfn), + sizeof(*qm_info->wfq_data), GFP_KERNEL); if (!qm_info->wfq_data) goto alloc_err; diff --git a/drivers/net/ethernet/qlogic/qed/qed_init_ops.c b/drivers/net/ethernet/qlogic/qed/qed_init_ops.c index e3f368882f46..bc2373b2aab8 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_init_ops.c +++ b/drivers/net/ethernet/qlogic/qed/qed_init_ops.c @@ -149,12 +149,12 @@ int qed_init_alloc(struct qed_hwfn *p_hwfn) if (IS_VF(p_hwfn->cdev)) return 0; - rt_data->b_valid = kzalloc(sizeof(bool) * RUNTIME_ARRAY_SIZE, + rt_data->b_valid = kcalloc(RUNTIME_ARRAY_SIZE, sizeof(bool), GFP_KERNEL); if (!rt_data->b_valid) return -ENOMEM; - rt_data->init_val = kzalloc(sizeof(u32) * RUNTIME_ARRAY_SIZE, + rt_data->init_val = kcalloc(RUNTIME_ARRAY_SIZE, sizeof(u32), GFP_KERNEL); if (!rt_data->init_val) { kfree(rt_data->b_valid); diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c b/drivers/net/ethernet/qlogic/qed/qed_int.c index c5d9f290ec4c..f8d1d02a3cd4 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_int.c +++ b/drivers/net/ethernet/qlogic/qed/qed_int.c @@ -1015,7 +1015,8 @@ static int qed_int_attentions(struct qed_hwfn *p_hwfn) index, attn_bits, attn_acks, asserted_bits, deasserted_bits, p_sb_attn_sw->known_attn); } else if (asserted_bits == 0x100) { - DP_INFO(p_hwfn, "MFW indication via attention\n"); + DP_VERBOSE(p_hwfn, NETIF_MSG_INTR, + "MFW indication via attention\n"); } else { DP_VERBOSE(p_hwfn, NETIF_MSG_INTR, "MFW indication [deassertion]\n"); diff --git a/drivers/net/ethernet/qlogic/qed/qed_l2.c b/drivers/net/ethernet/qlogic/qed/qed_l2.c index 5d7adedac68d..844dc2a3589e 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_l2.c +++ b/drivers/net/ethernet/qlogic/qed/qed_l2.c @@ -98,7 +98,7 @@ int qed_l2_alloc(struct qed_hwfn *p_hwfn) p_l2_info->queues = max_t(u8, rx, tx); } - pp_qids = kzalloc(sizeof(unsigned long *) * p_l2_info->queues, + pp_qids = kcalloc(p_l2_info->queues, sizeof(unsigned long *), GFP_KERNEL); if (!pp_qids) return -ENOMEM; @@ -2399,7 +2399,7 @@ static int qed_update_vport(struct qed_dev *cdev, if (!cdev) return -ENODEV; - rss = vzalloc(sizeof(*rss) * cdev->num_hwfns); + rss = vzalloc(array_size(sizeof(*rss), cdev->num_hwfns)); if (!rss) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c index e7ad95de3da8..ab5a6709d00c 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_filter.c +++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c @@ -307,8 +307,7 @@ int qede_alloc_arfs(struct qede_dev *edev) for (i = 0; i <= QEDE_RFS_FLW_MASK; i++) INIT_HLIST_HEAD(QEDE_ARFS_BUCKET_HEAD(edev, i)); - edev->arfs->arfs_fltr_bmap = vzalloc(BITS_TO_LONGS(QEDE_RFS_MAX_FLTR) * - sizeof(long)); + edev->arfs->arfs_fltr_bmap = vzalloc(array_size(sizeof(long), BITS_TO_LONGS(QEDE_RFS_MAX_FLTR))); if (!edev->arfs->arfs_fltr_bmap) { vfree(edev->arfs); edev->arfs = NULL; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index aae81226a0a4..7c9e45d4ff5b 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -386,8 +386,7 @@ int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter) } /* setup interrupt mapping table for fw */ - ahw->intr_tbl = vzalloc(num_msix * - sizeof(struct qlcnic_intrpt_config)); + ahw->intr_tbl = vzalloc(array_size(num_msix, sizeof(struct qlcnic_intrpt_config))); if (!ahw->intr_tbl) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 1b5f7d57b6f8..58b6538dc7be 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -916,8 +916,7 @@ int qlcnic_82xx_mq_intrpt(struct qlcnic_adapter *adapter, int op_type) if (qlcnic_check_multi_tx(adapter) && !ahw->diag_test && (adapter->flags & QLCNIC_MSIX_ENABLED)) { - ahw->intr_tbl = vzalloc(ahw->num_msix * - sizeof(struct qlcnic_intrpt_config)); + ahw->intr_tbl = vzalloc(array_size(sizeof(struct qlcnic_intrpt_config), ahw->num_msix)); if (!ahw->intr_tbl) return -ENOMEM; @@ -1025,15 +1024,17 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) act_pci_func = ahw->total_nic_func; - adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) * - act_pci_func, GFP_KERNEL); + adapter->npars = kcalloc(act_pci_func, + sizeof(struct qlcnic_npar_info), + GFP_KERNEL); if (!adapter->npars) { ret = -ENOMEM; goto err_pci_info; } - adapter->eswitch = kzalloc(sizeof(struct qlcnic_eswitch) * - QLCNIC_NIU_MAX_XG_PORTS, GFP_KERNEL); + adapter->eswitch = kcalloc(QLCNIC_NIU_MAX_XG_PORTS, + sizeof(struct qlcnic_eswitch), + GFP_KERNEL); if (!adapter->eswitch) { ret = -ENOMEM; goto err_npars; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c index c58180f40844..0c744b9c6e0a 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c @@ -157,8 +157,8 @@ int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs) adapter->ahw->sriov = sriov; sriov->num_vfs = num_vfs; bc = &sriov->bc; - sriov->vf_info = kzalloc(sizeof(struct qlcnic_vf_info) * - num_vfs, GFP_KERNEL); + sriov->vf_info = kcalloc(num_vfs, sizeof(struct qlcnic_vf_info), + GFP_KERNEL); if (!sriov->vf_info) { err = -ENOMEM; goto qlcnic_free_sriov; @@ -450,7 +450,7 @@ static int qlcnic_sriov_set_guest_vlan_mode(struct qlcnic_adapter *adapter, return 0; num_vlans = sriov->num_allowed_vlans; - sriov->allowed_vlans = kzalloc(sizeof(u16) * num_vlans, GFP_KERNEL); + sriov->allowed_vlans = kcalloc(num_vlans, sizeof(u16), GFP_KERNEL); if (!sriov->allowed_vlans) return -ENOMEM; @@ -706,7 +706,7 @@ static inline int qlcnic_sriov_alloc_bc_trans(struct qlcnic_bc_trans **trans) static inline int qlcnic_sriov_alloc_bc_msg(struct qlcnic_bc_hdr **hdr, u32 size) { - *hdr = kzalloc(sizeof(struct qlcnic_bc_hdr) * size, GFP_ATOMIC); + *hdr = kcalloc(size, sizeof(struct qlcnic_bc_hdr), GFP_ATOMIC); if (!*hdr) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index 0e3b2890b925..af9dab53a0a6 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -1092,8 +1092,7 @@ static int ql_get_next_chunk(struct ql_adapter *qdev, struct rx_ring *rx_ring, { if (!rx_ring->pg_chunk.page) { u64 map; - rx_ring->pg_chunk.page = alloc_pages(__GFP_COLD | __GFP_COMP | - GFP_ATOMIC, + rx_ring->pg_chunk.page = alloc_pages(__GFP_COMP | GFP_ATOMIC, qdev->lbq_buf_order); if (unlikely(!rx_ring->pg_chunk.page)) { netif_err(qdev, drv, qdev->ndev, @@ -2805,7 +2804,8 @@ static int ql_alloc_tx_resources(struct ql_adapter *qdev, goto pci_alloc_err; tx_ring->q = - kmalloc(tx_ring->wq_len * sizeof(struct tx_ring_desc), GFP_KERNEL); + kmalloc_array(tx_ring->wq_len, sizeof(struct tx_ring_desc), + GFP_KERNEL); if (tx_ring->q == NULL) goto err; diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c index 390323cadb92..99d66239907d 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c @@ -183,6 +183,11 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev, data_format = RMNET_INGRESS_FORMAT_IP_ROUTE | RMNET_EGRESS_FORMAT_IP_ROUTE; + if (!tb[IFLA_LINK]) { + NL_SET_ERR_MSG_MOD(extack, "link not specified"); + return -EINVAL; + } + real_dev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK])); if (!real_dev || !dev) return -ENODEV; diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c index 3ee89fdd8c54..2e658278fa70 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_descriptor.c @@ -103,6 +103,7 @@ EXPORT_SYMBOL(rmnet_descriptor_add_frag); int rmnet_frag_ipv6_skip_exthdr(struct rmnet_frag_descriptor *frag_desc, int start, u8 *nexthdrp, __be16 *fragp) { + u32 frag_size = skb_frag_size(&frag_desc->frag); u8 nexthdr = *nexthdrp; *fragp = 0; @@ -114,11 +115,17 @@ int rmnet_frag_ipv6_skip_exthdr(struct rmnet_frag_descriptor *frag_desc, if (nexthdr == NEXTHDR_NONE) return -EINVAL; - hp = rmnet_frag_data_ptr(frag_desc) + start; + if (start >= frag_size) + return -EINVAL; + hp = rmnet_frag_data_ptr(frag_desc) + start; if (nexthdr == NEXTHDR_FRAGMENT) { __be16 *fp; + if (start + offsetof(struct frag_hdr, frag_off) >= + frag_size) + return -EINVAL; + fp = rmnet_frag_data_ptr(frag_desc) + start + offsetof(struct frag_hdr, frag_off); *fragp = *fp; diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index d73617cc3b15..9f4d93a16b7e 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c @@ -1482,6 +1482,7 @@ static void ravb_tx_timeout_work(struct work_struct *work) struct ravb_private *priv = container_of(work, struct ravb_private, work); struct net_device *ndev = priv->ndev; + int error; netif_tx_stop_all_queues(ndev); @@ -1490,15 +1491,36 @@ static void ravb_tx_timeout_work(struct work_struct *work) ravb_ptp_stop(ndev); /* Wait for DMA stopping */ - ravb_stop_dma(ndev); + if (ravb_stop_dma(ndev)) { + /* If ravb_stop_dma() fails, the hardware is still operating + * for TX and/or RX. So, this should not call the following + * functions because ravb_dmac_init() is possible to fail too. + * Also, this should not retry ravb_stop_dma() again and again + * here because it's possible to wait forever. So, this just + * re-enables the TX and RX and skip the following + * re-initialization procedure. + */ + ravb_rcv_snd_enable(ndev); + goto out; + } ravb_ring_free(ndev, RAVB_BE); ravb_ring_free(ndev, RAVB_NC); /* Device init */ - ravb_dmac_init(ndev); + error = ravb_dmac_init(ndev); + if (error) { + /* If ravb_dmac_init() fails, descriptors are freed. So, this + * should return here to avoid re-enabling the TX and RX in + * ravb_emac_init(). + */ + netdev_err(ndev, "%s: ravb_dmac_init() failed, error %d\n", + __func__, error); + return; + } ravb_emac_init(ndev); +out: /* Initialise PTP Clock driver */ if (priv->chip_id == RCAR_GEN2) ravb_ptp_init(ndev, priv->pdev); diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 2d92a9fe4606..9e504a27f0fa 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -4820,7 +4820,7 @@ static int efx_ef10_filter_table_probe(struct efx_nic *efx) net_dev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER; } - table->entry = vzalloc(HUNT_FILTER_TBL_ROWS * sizeof(*table->entry)); + table->entry = vzalloc(array_size(HUNT_FILTER_TBL_ROWS, sizeof(*table->entry))); if (!table->entry) { rc = -ENOMEM; goto fail; diff --git a/drivers/net/ethernet/sfc/falcon/farch.c b/drivers/net/ethernet/sfc/falcon/farch.c index 05916c710d8c..2527cdc55863 100644 --- a/drivers/net/ethernet/sfc/falcon/farch.c +++ b/drivers/net/ethernet/sfc/falcon/farch.c @@ -2755,7 +2755,7 @@ int ef4_farch_filter_table_probe(struct ef4_nic *efx) GFP_KERNEL); if (!table->used_bitmap) goto fail; - table->spec = vzalloc(table->size * sizeof(*table->spec)); + table->spec = vzalloc(array_size(sizeof(*table->spec), table->size)); if (!table->spec) goto fail; } diff --git a/drivers/net/ethernet/sfc/falcon/rx.c b/drivers/net/ethernet/sfc/falcon/rx.c index 6a8406dc0c2b..91097aea6c41 100644 --- a/drivers/net/ethernet/sfc/falcon/rx.c +++ b/drivers/net/ethernet/sfc/falcon/rx.c @@ -163,7 +163,7 @@ static int ef4_init_rx_buffers(struct ef4_rx_queue *rx_queue, bool atomic) do { page = ef4_reuse_page(rx_queue); if (page == NULL) { - page = alloc_pages(__GFP_COLD | __GFP_COMP | + page = alloc_pages(__GFP_COMP | (atomic ? GFP_ATOMIC : GFP_KERNEL), efx->rx_buffer_order); if (unlikely(page == NULL)) diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c index ba45150f53c7..63b561a6de2c 100644 --- a/drivers/net/ethernet/sfc/farch.c +++ b/drivers/net/ethernet/sfc/farch.c @@ -2834,7 +2834,7 @@ int efx_farch_filter_table_probe(struct efx_nic *efx) GFP_KERNEL); if (!table->used_bitmap) goto fail; - table->spec = vzalloc(table->size * sizeof(*table->spec)); + table->spec = vzalloc(array_size(sizeof(*table->spec), table->size)); if (!table->spec) goto fail; } diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 42443f434569..0004c50d3c83 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -163,7 +163,7 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue, bool atomic) do { page = efx_reuse_page(rx_queue); if (page == NULL) { - page = alloc_pages(__GFP_COLD | __GFP_COMP | + page = alloc_pages(__GFP_COMP | (atomic ? GFP_ATOMIC : GFP_KERNEL), efx->rx_buffer_order); if (unlikely(page == NULL)) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c index da5c40c74ed2..651fd5500151 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c @@ -1042,9 +1042,15 @@ static irqreturn_t ETHQOS_PHY_ISR(int irq, void *dev_data) return IRQ_HANDLED; } -static int ethqos_phy_intr_enable(struct qcom_ethqos *ethqos) +int ethqos_phy_intr_enable(struct stmmac_priv *priv) { int ret = 0; + struct qcom_ethqos *ethqos = priv->plat->bsp_priv; + + if (ethqos_phy_intr_config(ethqos)) { + ret = 1; + return ret; + } INIT_WORK(ðqos->emac_phy_work, ethqos_defer_phy_isr_work); init_completion(ðqos->clk_enable_done); @@ -1056,7 +1062,6 @@ static int ethqos_phy_intr_enable(struct qcom_ethqos *ethqos) ethqos->phy_intr); return ret; } - phy_intr_en = true; return ret; } @@ -1916,10 +1921,6 @@ static int qcom_ethqos_probe(struct platform_device *pdev) if (ret) goto err_clk; - if (!ethqos_phy_intr_config(ethqos)) - ethqos_phy_intr_enable(ethqos); - else - ETHQOSERR("Phy interrupt configuration failed"); rgmii_dump(ethqos); if (ethqos->emac_ver == EMAC_HW_v2_3_2) { diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.h b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.h index 0df87f533ab8..40dbd4392288 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.h @@ -222,7 +222,6 @@ do {\ #define ATH8035_PHY_ID 0x004dd072 #define QCA8337_PHY_ID 0x004dd036 #define ATH8030_PHY_ID 0x004dd076 -#define MICREL_PHY_ID PHY_ID_KSZ9031 #define DWC_ETH_QOS_MICREL_PHY_INTCS 0x1b #define DWC_ETH_QOS_MICREL_PHY_CTL 0x1f #define DWC_ETH_QOS_BASIC_STATUS 0x0001 diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 1d6802ea1b50..0b2b4cbb26cc 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -173,9 +173,12 @@ extern struct stmmac_emb_smmu_cb_ctx stmmac_emb_smmu_ctx; #define GET_MEM_PDEV_DEV (stmmac_emb_smmu_ctx.valid ? \ &stmmac_emb_smmu_ctx.smmu_pdev->dev : priv->device) +#define MICREL_PHY_ID 0x00221620 + int ethqos_handle_prv_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); int ethqos_init_pps(struct stmmac_priv *priv); +int ethqos_phy_intr_enable(struct stmmac_priv *priv); extern bool phy_intr_en; void qcom_ethqos_request_phy_wol(struct plat_stmmacenet_data *plat_dat); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 784c009a65ff..e23cf61e8479 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1059,6 +1059,15 @@ static int stmmac_init_phy(struct net_device *dev) if (phydev->is_pseudo_fixed_link) phydev->irq = PHY_POLL; + if (((phydev->phy_id & phydev->drv->phy_id_mask) == MICREL_PHY_ID) && + !priv->plat->phy_intr_en) { + ret = ethqos_phy_intr_enable(priv); + if (ret) + pr_alert("qcom-ethqos: Unable to enable PHY interrupt\n"); + else + priv->plat->phy_intr_en = true; + } + if (phy_intr_en) { if (phydev->drv->config_intr && !phydev->drv->config_intr(phydev)) { diff --git a/drivers/net/ethernet/synopsys/dwc-xlgmac-desc.c b/drivers/net/ethernet/synopsys/dwc-xlgmac-desc.c index e9672b1f9968..031cf9c3435a 100644 --- a/drivers/net/ethernet/synopsys/dwc-xlgmac-desc.c +++ b/drivers/net/ethernet/synopsys/dwc-xlgmac-desc.c @@ -335,7 +335,7 @@ static int xlgmac_alloc_pages(struct xlgmac_pdata *pdata, dma_addr_t pages_dma; /* Try to obtain pages, decreasing order if necessary */ - gfp |= __GFP_COLD | __GFP_COMP | __GFP_NOWARN; + gfp |= __GFP_COMP | __GFP_NOWARN; while (order >= 0) { pages = alloc_pages(gfp, order); if (pages) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 3189afcd5888..a592b1e90442 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -2630,8 +2630,9 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, } data->active_slave = prop; - data->slave_data = devm_kzalloc(&pdev->dev, data->slaves - * sizeof(struct cpsw_slave_data), + data->slave_data = devm_kcalloc(&pdev->dev, + data->slaves, + sizeof(struct cpsw_slave_data), GFP_KERNEL); if (!data->slave_data) return -ENOMEM; @@ -2959,8 +2960,8 @@ static int cpsw_probe(struct platform_device *pdev) memcpy(ndev->dev_addr, priv->mac_addr, ETH_ALEN); - cpsw->slaves = devm_kzalloc(&pdev->dev, - sizeof(struct cpsw_slave) * data->slaves, + cpsw->slaves = devm_kcalloc(&pdev->dev, + data->slaves, sizeof(struct cpsw_slave), GFP_KERNEL); if (!cpsw->slaves) { ret = -ENOMEM; diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c index 437d36289786..50d2b76771b5 100644 --- a/drivers/net/ethernet/ti/netcp_core.c +++ b/drivers/net/ethernet/ti/netcp_core.c @@ -906,7 +906,7 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq) sw_data[0] = (u32)bufptr; } else { /* Allocate a secondary receive queue entry */ - page = alloc_page(GFP_ATOMIC | GFP_DMA | __GFP_COLD); + page = alloc_page(GFP_ATOMIC | GFP_DMA); if (unlikely(!page)) { dev_warn_ratelimited(netcp->ndev_dev, "Secondary page alloc failed\n"); goto fail; diff --git a/drivers/net/ethernet/ti/netcp_ethss.c b/drivers/net/ethernet/ti/netcp_ethss.c index ff7a71ca0b13..ba14f5dd7e04 100644 --- a/drivers/net/ethernet/ti/netcp_ethss.c +++ b/drivers/net/ethernet/ti/netcp_ethss.c @@ -3173,8 +3173,8 @@ static int set_xgbe_ethss10_priv(struct gbe_priv *gbe_dev, gbe_dev->et_stats = xgbe10_et_stats; gbe_dev->num_et_stats = ARRAY_SIZE(xgbe10_et_stats); - gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev, - gbe_dev->num_et_stats * sizeof(u64), + gbe_dev->hw_stats = devm_kcalloc(gbe_dev->dev, + gbe_dev->num_et_stats, sizeof(u64), GFP_KERNEL); if (!gbe_dev->hw_stats) { dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n"); @@ -3182,8 +3182,8 @@ static int set_xgbe_ethss10_priv(struct gbe_priv *gbe_dev, } gbe_dev->hw_stats_prev = - devm_kzalloc(gbe_dev->dev, - gbe_dev->num_et_stats * sizeof(u32), + devm_kcalloc(gbe_dev->dev, + gbe_dev->num_et_stats, sizeof(u32), GFP_KERNEL); if (!gbe_dev->hw_stats_prev) { dev_err(gbe_dev->dev, @@ -3293,8 +3293,8 @@ static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev, gbe_dev->et_stats = gbe13_et_stats; gbe_dev->num_et_stats = ARRAY_SIZE(gbe13_et_stats); - gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev, - gbe_dev->num_et_stats * sizeof(u64), + gbe_dev->hw_stats = devm_kcalloc(gbe_dev->dev, + gbe_dev->num_et_stats, sizeof(u64), GFP_KERNEL); if (!gbe_dev->hw_stats) { dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n"); @@ -3302,8 +3302,8 @@ static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev, } gbe_dev->hw_stats_prev = - devm_kzalloc(gbe_dev->dev, - gbe_dev->num_et_stats * sizeof(u32), + devm_kcalloc(gbe_dev->dev, + gbe_dev->num_et_stats, sizeof(u32), GFP_KERNEL); if (!gbe_dev->hw_stats_prev) { dev_err(gbe_dev->dev, @@ -3365,8 +3365,8 @@ static int set_gbenu_ethss_priv(struct gbe_priv *gbe_dev, gbe_dev->num_et_stats = GBENU_ET_STATS_HOST_SIZE + GBENU_ET_STATS_PORT_SIZE; - gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev, - gbe_dev->num_et_stats * sizeof(u64), + gbe_dev->hw_stats = devm_kcalloc(gbe_dev->dev, + gbe_dev->num_et_stats, sizeof(u64), GFP_KERNEL); if (!gbe_dev->hw_stats) { dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n"); @@ -3374,8 +3374,8 @@ static int set_gbenu_ethss_priv(struct gbe_priv *gbe_dev, } gbe_dev->hw_stats_prev = - devm_kzalloc(gbe_dev->dev, - gbe_dev->num_et_stats * sizeof(u32), + devm_kcalloc(gbe_dev->dev, + gbe_dev->num_et_stats, sizeof(u32), GFP_KERNEL); if (!gbe_dev->hw_stats_prev) { dev_err(gbe_dev->dev, diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c index eed18f88bdff..302079e22b06 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c +++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c @@ -2320,8 +2320,9 @@ static struct net_device *gelic_wl_alloc(struct gelic_card *card) pr_debug("%s: wl=%p port=%p\n", __func__, wl, port); /* allocate scan list */ - wl->networks = kzalloc(sizeof(struct gelic_wl_scan_info) * - GELIC_WL_BSS_MAX_ENT, GFP_KERNEL); + wl->networks = kcalloc(GELIC_WL_BSS_MAX_ENT, + sizeof(struct gelic_wl_scan_info), + GFP_KERNEL); if (!wl->networks) goto fail_bss; diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index 090607e725a2..848b69ca3e1f 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -771,13 +771,13 @@ static int gtp_hashtable_new(struct gtp_dev *gtp, int hsize) { int i; - gtp->addr_hash = kmalloc(sizeof(struct hlist_head) * hsize, - GFP_KERNEL | __GFP_NOWARN); + gtp->addr_hash = kmalloc_array(hsize, sizeof(struct hlist_head), + GFP_KERNEL | __GFP_NOWARN); if (gtp->addr_hash == NULL) return -ENOMEM; - gtp->tid_hash = kmalloc(sizeof(struct hlist_head) * hsize, - GFP_KERNEL | __GFP_NOWARN); + gtp->tid_hash = kmalloc_array(hsize, sizeof(struct hlist_head), + GFP_KERNEL | __GFP_NOWARN); if (gtp->tid_hash == NULL) goto err1; diff --git a/drivers/net/hippi/rrunner.c b/drivers/net/hippi/rrunner.c index 40ef4aeb0ef0..aa684660cc84 100644 --- a/drivers/net/hippi/rrunner.c +++ b/drivers/net/hippi/rrunner.c @@ -1585,7 +1585,7 @@ static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return -EPERM; } - image = kmalloc(EEPROM_WORDS * sizeof(u32), GFP_KERNEL); + image = kmalloc_array(EEPROM_WORDS, sizeof(u32), GFP_KERNEL); if (!image) return -ENOMEM; diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 55d2d5a9228a..b1dd56c2749b 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -3539,6 +3539,9 @@ static int macsec_newlink(struct net *net, struct net_device *dev, struct netlink_ext_ack *extack) { struct macsec_dev *macsec = macsec_priv(dev); + struct macsec_context ctx; + const struct macsec_ops *ops; + u8 icv_len = DEFAULT_ICV_LEN; rx_handler_func_t *rx_handler; u8 icv_len = DEFAULT_ICV_LEN; struct net_device *real_dev; diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 5752280fdb40..206270f7d47b 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -1102,8 +1102,9 @@ static struct dp83640_clock *dp83640_clock_get_bus(struct mii_bus *bus) if (!clock) goto out; - clock->caps.pin_config = kzalloc(sizeof(struct ptp_pin_desc) * - DP83640_N_PINS, GFP_KERNEL); + clock->caps.pin_config = kcalloc(DP83640_N_PINS, + sizeof(struct ptp_pin_desc), + GFP_KERNEL); if (!clock->caps.pin_config) { kfree(clock); clock = NULL; diff --git a/drivers/net/phy/mdio-bcm-unimac.c b/drivers/net/phy/mdio-bcm-unimac.c index 52703bbd4d66..df75efa96a7d 100644 --- a/drivers/net/phy/mdio-bcm-unimac.c +++ b/drivers/net/phy/mdio-bcm-unimac.c @@ -237,6 +237,8 @@ static int unimac_mdio_probe(struct platform_device *pdev) return -ENOMEM; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) + return -EINVAL; /* Just ioremap, as this MDIO block is usually integrated into an * Ethernet MAC controller register range diff --git a/drivers/net/phy/phy_led_triggers.c b/drivers/net/phy/phy_led_triggers.c index 94ca42e630bb..0049dcae5f30 100644 --- a/drivers/net/phy/phy_led_triggers.c +++ b/drivers/net/phy/phy_led_triggers.c @@ -99,9 +99,9 @@ int phy_led_triggers_register(struct phy_device *phy) if (!phy->phy_num_led_triggers) return 0; - phy->phy_led_triggers = devm_kzalloc(&phy->mdio.dev, - sizeof(struct phy_led_trigger) * - phy->phy_num_led_triggers, + phy->phy_led_triggers = devm_kcalloc(&phy->mdio.dev, + phy->phy_num_led_triggers, + sizeof(struct phy_led_trigger), GFP_KERNEL); if (!phy->phy_led_triggers) { err = -ENOMEM; diff --git a/drivers/net/ppp/bsd_comp.c b/drivers/net/ppp/bsd_comp.c index a9b759add187..61fedb23d3cf 100644 --- a/drivers/net/ppp/bsd_comp.c +++ b/drivers/net/ppp/bsd_comp.c @@ -406,7 +406,7 @@ static void *bsd_alloc (unsigned char *options, int opt_len, int decomp) * Allocate space for the dictionary. This may be more than one page in * length. */ - db->dict = vmalloc(hsize * sizeof(struct bsd_dict)); + db->dict = vmalloc(array_size(hsize, sizeof(struct bsd_dict))); if (!db->dict) { bsd_free (db); @@ -425,7 +425,7 @@ static void *bsd_alloc (unsigned char *options, int opt_len, int decomp) */ else { - db->lens = vmalloc((maxmaxcode + 1) * sizeof(db->lens[0])); + db->lens = vmalloc(array_size(sizeof(db->lens[0]), (maxmaxcode + 1))); if (!db->lens) { bsd_free (db); diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c index c22a7892648e..f7e102df23e8 100644 --- a/drivers/net/ppp/pptp.c +++ b/drivers/net/ppp/pptp.c @@ -650,7 +650,7 @@ static int __init pptp_init_module(void) int err = 0; pr_info("PPTP driver version " PPTP_DRIVER_VERSION "\n"); - callid_sock = vzalloc((MAX_CALLID + 1) * sizeof(void *)); + callid_sock = vzalloc(array_size(sizeof(void *), (MAX_CALLID + 1))); if (!callid_sock) return -ENOMEM; diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index d7882b548b79..6a49a9979905 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -1324,7 +1324,7 @@ static int __init slip_init(void) printk(KERN_INFO "SLIP linefill/keepalive option.\n"); #endif - slip_devs = kzalloc(sizeof(struct net_device *)*slip_maxdev, + slip_devs = kcalloc(slip_maxdev, sizeof(struct net_device *), GFP_KERNEL); if (!slip_devs) return -ENOMEM; diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 396a8c6cb999..2e43aa7d9b3f 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -269,7 +269,7 @@ static int __team_options_register(struct team *team, struct team_option **dst_opts; int err; - dst_opts = kzalloc(sizeof(struct team_option *) * option_count, + dst_opts = kcalloc(option_count, sizeof(struct team_option *), GFP_KERNEL); if (!dst_opts) return -ENOMEM; @@ -784,7 +784,8 @@ static int team_queue_override_init(struct team *team) if (!queue_cnt) return 0; - listarr = kmalloc(sizeof(struct list_head) * queue_cnt, GFP_KERNEL); + listarr = kmalloc_array(queue_cnt, sizeof(struct list_head), + GFP_KERNEL); if (!listarr) return -ENOMEM; team->qom_lists = listarr; diff --git a/drivers/net/usb/asix_common.c b/drivers/net/usb/asix_common.c index e9fcf6ef716a..347ef693c3b9 100644 --- a/drivers/net/usb/asix_common.c +++ b/drivers/net/usb/asix_common.c @@ -643,8 +643,8 @@ int asix_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, first_word = eeprom->offset >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1; - eeprom_buff = kmalloc(sizeof(u16) * (last_word - first_word + 1), - GFP_KERNEL); + eeprom_buff = kmalloc_array(last_word - first_word + 1, sizeof(u16), + GFP_KERNEL); if (!eeprom_buff) return -ENOMEM; @@ -683,8 +683,8 @@ int asix_set_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, first_word = eeprom->offset >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1; - eeprom_buff = kmalloc(sizeof(u16) * (last_word - first_word + 1), - GFP_KERNEL); + eeprom_buff = kmalloc_array(last_word - first_word + 1, sizeof(u16), + GFP_KERNEL); if (!eeprom_buff) return -ENOMEM; diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index 5a2cdd2ccce6..75fbb8188c5c 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -602,8 +602,8 @@ ax88179_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, first_word = eeprom->offset >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1; - eeprom_buff = kmalloc(sizeof(u16) * (last_word - first_word + 1), - GFP_KERNEL); + eeprom_buff = kmalloc_array(last_word - first_word + 1, sizeof(u16), + GFP_KERNEL); if (!eeprom_buff) return -ENOMEM; diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 6597d1f8d68c..7988c41bff1d 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1402,8 +1402,9 @@ static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old) unsigned long flags; if (old) - hso_dbg(0x16, "Termios called with: cflags new[%d] - old[%d]\n", - tty->termios.c_cflag, old->c_cflag); + hso_dbg(0x16, "Termios called with: cflags new[%u] - old[%u]\n", + (unsigned int)tty->termios.c_cflag, + (unsigned int)old->c_cflag); /* the actual setup */ spin_lock_irqsave(&serial->serial_lock, flags); diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 8c370d57e198..17a571a32fab 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -3626,6 +3626,11 @@ static int lan78xx_probe(struct usb_interface *intf, netdev->max_mtu = MAX_SINGLE_PACKET_SIZE; netif_set_gso_max_size(netdev, MAX_SINGLE_PACKET_SIZE - MAX_HEADER); + if (intf->cur_altsetting->desc.bNumEndpoints < 3) { + ret = -ENODEV; + goto out3; + } + dev->ep_blkin = (intf->cur_altsetting)->endpoint + 0; dev->ep_blkout = (intf->cur_altsetting)->endpoint + 1; dev->ep_intr = (intf->cur_altsetting)->endpoint + 2; @@ -3650,6 +3655,7 @@ static int lan78xx_probe(struct usb_interface *intf, usb_fill_int_urb(dev->urb_intr, dev->udev, dev->pipe_intr, buf, maxp, intr_complete, dev, period); + dev->urb_intr->transfer_flags |= URB_FREE_BUFFER; } } diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index bc6bcea67bff..4f29010e1aef 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -1676,7 +1676,7 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message) } if (pdata->wolopts & (WAKE_BCAST | WAKE_MCAST | WAKE_ARP | WAKE_UCAST)) { - u32 *filter_mask = kzalloc(sizeof(u32) * 32, GFP_KERNEL); + u32 *filter_mask = kcalloc(32, sizeof(u32), GFP_KERNEL); u32 command[2]; u32 offset[2]; u32 crc[4]; diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 167106f634a5..29f4959a9ce8 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1405,8 +1405,8 @@ static int build_dma_sg(const struct sk_buff *skb, struct urb *urb) return 0; /* reserve one for zero packet */ - urb->sg = kmalloc((num_sgs + 1) * sizeof(struct scatterlist), - GFP_ATOMIC); + urb->sg = kmalloc_array(num_sgs + 1, sizeof(struct scatterlist), + GFP_ATOMIC); if (!urb->sg) return -ENOMEM; @@ -1437,7 +1437,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, struct skb_data *entry; struct driver_info *info = dev->driver_info; unsigned long flags; - int retval; + int retval = 0; struct timespec64 now; if (skb) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 0b457c81c448..9ca7ce7f6cd5 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -999,7 +999,6 @@ static bool try_fill_recv(struct virtnet_info *vi, struct receive_queue *rq, int err; bool oom; - gfp |= __GFP_COLD; do { if (vi->mergeable_rx_bufs) err = add_recvbuf_mergeable(vi, rq, gfp); @@ -2279,17 +2278,17 @@ static int virtnet_find_vqs(struct virtnet_info *vi) virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ); /* Allocate space for find_vqs parameters */ - vqs = kzalloc(total_vqs * sizeof(*vqs), GFP_KERNEL); + vqs = kcalloc(total_vqs, sizeof(*vqs), GFP_KERNEL); if (!vqs) goto err_vq; - callbacks = kmalloc(total_vqs * sizeof(*callbacks), GFP_KERNEL); + callbacks = kmalloc_array(total_vqs, sizeof(*callbacks), GFP_KERNEL); if (!callbacks) goto err_callback; - names = kmalloc(total_vqs * sizeof(*names), GFP_KERNEL); + names = kmalloc_array(total_vqs, sizeof(*names), GFP_KERNEL); if (!names) goto err_names; if (!vi->big_packets || vi->mergeable_rx_bufs) { - ctx = kzalloc(total_vqs * sizeof(*ctx), GFP_KERNEL); + ctx = kcalloc(total_vqs, sizeof(*ctx), GFP_KERNEL); if (!ctx) goto err_ctx; } else { @@ -2357,10 +2356,10 @@ static int virtnet_alloc_queues(struct virtnet_info *vi) vi->ctrl = kzalloc(sizeof(*vi->ctrl), GFP_KERNEL); if (!vi->ctrl) goto err_ctrl; - vi->sq = kzalloc(sizeof(*vi->sq) * vi->max_queue_pairs, GFP_KERNEL); + vi->sq = kcalloc(vi->max_queue_pairs, sizeof(*vi->sq), GFP_KERNEL); if (!vi->sq) goto err_sq; - vi->rq = kzalloc(sizeof(*vi->rq) * vi->max_queue_pairs, GFP_KERNEL); + vi->rq = kcalloc(vi->max_queue_pairs, sizeof(*vi->rq), GFP_KERNEL); if (!vi->rq) goto err_rq; diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c index 6a26cef62193..668c6704af51 100644 --- a/drivers/net/wan/fsl_ucc_hdlc.c +++ b/drivers/net/wan/fsl_ucc_hdlc.c @@ -198,12 +198,14 @@ static int uhdlc_init(struct ucc_hdlc_private *priv) goto free_tx_bd; } - priv->rx_skbuff = kzalloc(priv->rx_ring_size * sizeof(*priv->rx_skbuff), + priv->rx_skbuff = kcalloc(priv->rx_ring_size, + sizeof(*priv->rx_skbuff), GFP_KERNEL); if (!priv->rx_skbuff) goto free_ucc_pram; - priv->tx_skbuff = kzalloc(priv->tx_ring_size * sizeof(*priv->tx_skbuff), + priv->tx_skbuff = kcalloc(priv->tx_ring_size, + sizeof(*priv->tx_skbuff), GFP_KERNEL); if (!priv->tx_skbuff) goto free_rx_skbuff; diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 3eaefecd4448..229cab00c4b0 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -183,7 +183,7 @@ static inline void x25_asy_unlock(struct x25_asy *sl) netif_wake_queue(sl->dev); } -/* Send one completely decapsulated IP datagram to the IP layer. */ +/* Send an LAPB frame to the LAPB module to process. */ static void x25_asy_bump(struct x25_asy *sl) { @@ -195,13 +195,12 @@ static void x25_asy_bump(struct x25_asy *sl) count = sl->rcount; dev->stats.rx_bytes += count; - skb = dev_alloc_skb(count+1); + skb = dev_alloc_skb(count); if (skb == NULL) { netdev_warn(sl->dev, "memory squeeze, dropping packet\n"); dev->stats.rx_dropped++; return; } - skb_push(skb, 1); /* LAPB internal control */ skb_put_data(skb, sl->rbuff, count); skb->protocol = x25_type_trans(skb, sl->dev); err = lapb_data_received(skb->dev, skb); @@ -209,7 +208,6 @@ static void x25_asy_bump(struct x25_asy *sl) kfree_skb(skb); printk(KERN_DEBUG "x25_asy: data received err - %d\n", err); } else { - netif_rx(skb); dev->stats.rx_packets++; } } @@ -355,12 +353,21 @@ static netdev_tx_t x25_asy_xmit(struct sk_buff *skb, */ /* - * Called when I frame data arrives. We did the work above - throw it - * at the net layer. + * Called when I frame data arrive. We add a pseudo header for upper + * layers and pass it to upper layers. */ static int x25_asy_data_indication(struct net_device *dev, struct sk_buff *skb) { + if (skb_cow(skb, 1)) { + kfree_skb(skb); + return NET_RX_DROP; + } + skb_push(skb, 1); + skb->data[0] = X25_IFACE_DATA; + + skb->protocol = x25_type_trans(skb, dev); + return netif_rx(skb); } @@ -656,7 +663,7 @@ static void x25_asy_unesc(struct x25_asy *sl, unsigned char s) switch (s) { case X25_END: if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && - sl->rcount > 2) + sl->rcount >= 2) x25_asy_bump(sl); clear_bit(SLF_ESCAPE, &sl->flags); sl->rcount = 0; diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 81e9b36c056a..54637f36013b 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -538,6 +539,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .hw_ops = &wcn3990_ops, .decap_align_bytes = 1, .num_peers = TARGET_HL_10_TLV_NUM_PEERS, + .n_cipher_suites = 11, .ast_skid_limit = TARGET_HL_10_TLV_AST_SKID_LIMIT, .num_wds_entries = TARGET_HL_10_TLV_NUM_WDS_ENTRIES, .target_64bit = true, @@ -2100,6 +2102,7 @@ static void ath10k_core_restart(struct work_struct *work) complete(&ar->offchan_tx_completed); complete(&ar->install_key_done); complete(&ar->vdev_setup_done); + complete(&ar->vdev_delete_done); complete(&ar->thermal.wmi_sync); complete(&ar->bss_survey_done); wake_up(&ar->htt.empty_tx_wq); @@ -3002,8 +3005,10 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, init_completion(&ar->install_key_done); init_completion(&ar->vdev_setup_done); + init_completion(&ar->vdev_delete_done); init_completion(&ar->thermal.wmi_sync); init_completion(&ar->bss_survey_done); + init_completion(&ar->peer_delete_done); INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work); diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 04dab735de7f..4136a8e8d190 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -374,7 +375,8 @@ struct ath10k_sta { #endif }; -#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5 * HZ) +#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5 * HZ) +#define ATH10K_VDEV_DELETE_TIMEOUT_HZ (5 * HZ) enum ath10k_beacon_state { ATH10K_BEACON_SCHEDULED = 0, @@ -913,6 +915,7 @@ struct ath10k { int last_wmi_vdev_start_status; struct completion vdev_setup_done; + struct completion vdev_delete_done; struct workqueue_struct *workqueue; /* Auxiliary workqueue */ @@ -1037,8 +1040,11 @@ struct ath10k { u32 ampdu_reference; + const u8 *wmi_key_cipher; void *ce_priv; + struct completion peer_delete_done; + /* must be last */ u8 drv_priv[0] __aligned(sizeof(void *)); }; diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 717110481b88..0e8ef8262f5f 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -583,7 +583,7 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt) } htt->rx_ring.netbufs_ring = - kzalloc(htt->rx_ring.size * sizeof(struct sk_buff *), + kcalloc(htt->rx_ring.size, sizeof(struct sk_buff *), GFP_KERNEL); if (!htt->rx_ring.netbufs_ring) goto err_netbuf; diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index e55524749f8f..a920660a114a 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -231,24 +231,24 @@ static int ath10k_send_key(struct ath10k_vif *arvif, switch (key->cipher) { case WLAN_CIPHER_SUITE_CCMP: - arg.key_cipher = WMI_CIPHER_AES_CCM; + arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_CCM]; key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT; break; case WLAN_CIPHER_SUITE_TKIP: - arg.key_cipher = WMI_CIPHER_TKIP; + arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_TKIP]; arg.key_txmic_len = 8; arg.key_rxmic_len = 8; break; case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: - arg.key_cipher = WMI_CIPHER_WEP; + arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_WEP]; break; case WLAN_CIPHER_SUITE_CCMP_256: - arg.key_cipher = WMI_CIPHER_AES_CCM; + arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_CCM]; break; case WLAN_CIPHER_SUITE_GCMP: case WLAN_CIPHER_SUITE_GCMP_256: - arg.key_cipher = WMI_CIPHER_AES_GCM; + arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_GCM]; break; case WLAN_CIPHER_SUITE_BIP_GMAC_128: case WLAN_CIPHER_SUITE_BIP_GMAC_256: @@ -265,7 +265,7 @@ static int ath10k_send_key(struct ath10k_vif *arvif, key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; if (cmd == DISABLE_KEY) { - arg.key_cipher = WMI_CIPHER_NONE; + arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_NONE]; arg.key_data = NULL; } @@ -685,6 +685,26 @@ ath10k_mac_get_any_chandef_iter(struct ieee80211_hw *hw, *def = &conf->def; } +static void ath10k_wait_for_peer_delete_done(struct ath10k *ar, u32 vdev_id, + const u8 *addr) +{ + unsigned long time_left; + int ret; + + if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) { + ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr); + if (ret) { + ath10k_warn(ar, "failed wait for peer deleted"); + return; + } + + time_left = wait_for_completion_timeout(&ar->peer_delete_done, + 5 * HZ); + if (!time_left) + ath10k_warn(ar, "Timeout in receiving peer delete response\n"); + } +} + static int ath10k_peer_create(struct ath10k *ar, struct ieee80211_vif *vif, struct ieee80211_sta *sta, @@ -729,7 +749,7 @@ static int ath10k_peer_create(struct ath10k *ar, spin_unlock_bh(&ar->data_lock); ath10k_warn(ar, "failed to find peer %pM on vdev %i after creation\n", addr, vdev_id); - ath10k_wmi_peer_delete(ar, vdev_id, addr); + ath10k_wait_for_peer_delete_done(ar, vdev_id, addr); return -ENOENT; } @@ -811,6 +831,18 @@ static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr) if (ret) return ret; + if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) { + unsigned long time_left; + + time_left = wait_for_completion_timeout + (&ar->peer_delete_done, 5 * HZ); + + if (!time_left) { + ath10k_warn(ar, "Timeout in receiving peer delete response\n"); + return -ETIMEDOUT; + } + } + ar->num_peers--; return 0; @@ -1003,6 +1035,7 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) arg.channel.max_antenna_gain = channel->max_antenna_gain * 2; reinit_completion(&ar->vdev_setup_done); + reinit_completion(&ar->vdev_delete_done); ret = ath10k_wmi_vdev_start(ar, &arg); if (ret) { @@ -1052,6 +1085,7 @@ static int ath10k_monitor_vdev_stop(struct ath10k *ar) ar->monitor_vdev_id, ret); reinit_completion(&ar->vdev_setup_done); + reinit_completion(&ar->vdev_delete_done); ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id); if (ret) @@ -1393,6 +1427,7 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif) lockdep_assert_held(&ar->conf_mutex); reinit_completion(&ar->vdev_setup_done); + reinit_completion(&ar->vdev_delete_done); ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id); if (ret) { @@ -1429,6 +1464,7 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif, lockdep_assert_held(&ar->conf_mutex); reinit_completion(&ar->vdev_setup_done); + reinit_completion(&ar->vdev_delete_done); arg.vdev_id = arvif->vdev_id; arg.dtim_period = arvif->dtim_period; @@ -5244,8 +5280,11 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, err_peer_delete: if (arvif->vdev_type == WMI_VDEV_TYPE_AP || - arvif->vdev_type == WMI_VDEV_TYPE_IBSS) + arvif->vdev_type == WMI_VDEV_TYPE_IBSS) { ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr); + ath10k_wait_for_peer_delete_done(ar, arvif->vdev_id, + vif->addr); + } err_vdev_delete: ath10k_wmi_vdev_delete(ar, arvif->vdev_id); @@ -5280,6 +5319,7 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, struct ath10k *ar = hw->priv; struct ath10k_vif *arvif = (void *)vif->drv_priv; struct ath10k_peer *peer; + unsigned long time_left; int ret; int i; @@ -5310,6 +5350,8 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n", arvif->vdev_id, ret); + ath10k_wait_for_peer_delete_done(ar, arvif->vdev_id, + vif->addr); kfree(arvif->u.ap.noa_data); } @@ -5321,6 +5363,15 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n", arvif->vdev_id, ret); + if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) { + time_left = wait_for_completion_timeout(&ar->vdev_delete_done, + ATH10K_VDEV_DELETE_TIMEOUT_HZ); + if (time_left == 0) { + ath10k_warn(ar, "Timeout in receiving vdev delete response\n"); + goto out; + } + } + /* Some firmware revisions don't notify host about self-peer removal * until after associated vdev is deleted. */ @@ -5371,6 +5422,7 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, ath10k_mac_txq_unref(ar, vif->txq); +out: mutex_unlock(&ar->conf_mutex); } diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index 6ab44add9f51..39eba6d6db3d 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -154,7 +155,7 @@ ath10k_wmi_tlv_parse_alloc(struct ath10k *ar, const void *ptr, const void **tb; int ret; - tb = kzalloc(sizeof(*tb) * WMI_TLV_TAG_MAX, gfp); + tb = kcalloc(WMI_TLV_TAG_MAX, sizeof(*tb), gfp); if (!tb) return ERR_PTR(-ENOMEM); @@ -222,6 +223,13 @@ static int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar, return 0; } +static void ath10k_wmi_tlv_event_vdev_delete_resp(struct ath10k *ar, + struct sk_buff *skb) +{ + ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_DELETE_RESP_EVENTID\n"); + complete(&ar->vdev_delete_done); +} + static int ath10k_wmi_tlv_event_diag_data(struct ath10k *ar, struct sk_buff *skb) { @@ -412,6 +420,24 @@ static int ath10k_wmi_tlv_event_tx_pause(struct ath10k *ar, return 0; } +static int ath10k_wmi_tlv_event_peer_delete_resp(struct ath10k *ar, + struct sk_buff *skb) +{ + struct wmi_peer_delete_resp_ev_arg *arg; + struct wmi_tlv *tlv_hdr; + + tlv_hdr = (struct wmi_tlv *)skb->data; + arg = (struct wmi_peer_delete_resp_ev_arg *)tlv_hdr->value; + + ath10k_dbg(ar, ATH10K_DBG_WMI, "vdev id %d", arg->vdev_id); + ath10k_dbg(ar, ATH10K_DBG_WMI, "peer mac addr %pM", &arg->peer_addr); + ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer delete response\n"); + + complete(&ar->peer_delete_done); + + return 0; +} + /***********/ /* TLV ops */ /***********/ @@ -468,6 +494,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb) case WMI_TLV_VDEV_STOPPED_EVENTID: ath10k_wmi_event_vdev_stopped(ar, skb); break; + case WMI_TLV_VDEV_DELETE_RESP_EVENTID: + ath10k_wmi_tlv_event_vdev_delete_resp(ar, skb); + break; case WMI_TLV_PEER_STA_KICKOUT_EVENTID: ath10k_wmi_event_peer_sta_kickout(ar, skb); break; @@ -555,6 +584,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb) case WMI_TLV_TX_PAUSE_EVENTID: ath10k_wmi_tlv_event_tx_pause(ar, skb); break; + case WMI_TLV_PEER_DELETE_RESP_EVENTID: + ath10k_wmi_tlv_event_peer_delete_resp(ar, skb); + break; default: ath10k_warn(ar, "Unknown eventid: %d\n", id); break; @@ -1704,6 +1736,28 @@ ath10k_wmi_tlv_op_gen_stop_scan(struct ath10k *ar, return skb; } +static int ath10k_wmi_tlv_op_get_vdev_subtype(struct ath10k *ar, + enum wmi_vdev_subtype subtype) +{ + switch (subtype) { + case WMI_VDEV_SUBTYPE_NONE: + return WMI_TLV_VDEV_SUBTYPE_NONE; + case WMI_VDEV_SUBTYPE_P2P_DEVICE: + return WMI_TLV_VDEV_SUBTYPE_P2P_DEV; + case WMI_VDEV_SUBTYPE_P2P_CLIENT: + return WMI_TLV_VDEV_SUBTYPE_P2P_CLI; + case WMI_VDEV_SUBTYPE_P2P_GO: + return WMI_TLV_VDEV_SUBTYPE_P2P_GO; + case WMI_VDEV_SUBTYPE_PROXY_STA: + return WMI_TLV_VDEV_SUBTYPE_PROXY_STA; + case WMI_VDEV_SUBTYPE_MESH_11S: + return WMI_TLV_VDEV_SUBTYPE_MESH_11S; + case WMI_VDEV_SUBTYPE_MESH_NON_11S: + return -ENOTSUPP; + } + return -ENOTSUPP; +} + static struct sk_buff * ath10k_wmi_tlv_op_gen_vdev_create(struct ath10k *ar, u32 vdev_id, @@ -1932,9 +1986,11 @@ ath10k_wmi_tlv_op_gen_vdev_install_key(struct ath10k *ar, size_t len; void *ptr; - if (arg->key_cipher == WMI_CIPHER_NONE && arg->key_data != NULL) + if (arg->key_cipher == ar->wmi_key_cipher[WMI_CIPHER_NONE] && + arg->key_data) return ERR_PTR(-EINVAL); - if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL) + if (arg->key_cipher != ar->wmi_key_cipher[WMI_CIPHER_NONE] && + !arg->key_data) return ERR_PTR(-EINVAL); len = sizeof(*tlv) + sizeof(*cmd) + @@ -2611,7 +2667,7 @@ ath10k_wmi_tlv_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) ieee80211_is_deauth(hdr->frame_control) || ieee80211_is_disassoc(hdr->frame_control)) && ieee80211_has_protected(hdr->frame_control)) { - len += IEEE80211_CCMP_MIC_LEN; + skb_put(msdu, IEEE80211_CCMP_MIC_LEN); buf_len += IEEE80211_CCMP_MIC_LEN; } @@ -3826,7 +3882,7 @@ static const struct wmi_ops wmi_tlv_ops = { .gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update, .gen_adaptive_qcs = ath10k_wmi_tlv_op_gen_adaptive_qcs, .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill, - .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, + .get_vdev_subtype = ath10k_wmi_tlv_op_get_vdev_subtype, .gen_echo = ath10k_wmi_tlv_op_gen_echo, .gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf, .gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable, diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h index eac0a5364a57..f9249a50e52b 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -309,11 +310,15 @@ enum wmi_tlv_event_id { WMI_TLV_VDEV_STOPPED_EVENTID, WMI_TLV_VDEV_INSTALL_KEY_COMPLETE_EVENTID, WMI_TLV_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID, + WMI_TLV_VDEV_TSF_REPORT_EVENTID, + WMI_TLV_VDEV_DELETE_RESP_EVENTID, WMI_TLV_PEER_STA_KICKOUT_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_PEER), WMI_TLV_PEER_INFO_EVENTID, WMI_TLV_PEER_TX_FAIL_CNT_THR_EVENTID, WMI_TLV_PEER_ESTIMATED_LINKSPEED_EVENTID, WMI_TLV_PEER_STATE_EVENTID, + WMI_TLV_PEER_ASSOC_CONF_EVENTID, + WMI_TLV_PEER_DELETE_RESP_EVENTID, WMI_TLV_MGMT_RX_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_MGMT), WMI_TLV_HOST_SWBA_EVENTID, WMI_TLV_TBTTOFFSET_UPDATE_EVENTID, @@ -1554,6 +1559,10 @@ wmi_tlv_svc_map(const __le32 *in, unsigned long *out, size_t len) WMI_SERVICE_SAP_AUTH_OFFLOAD, len); SVCMAP(WMI_TLV_SERVICE_MGMT_TX_WMI, WMI_SERVICE_MGMT_TX_WMI, len); + SVCMAP(WMI_TLV_SERVICE_MESH_11S, + WMI_SERVICE_MESH_11S, len); + SVCMAP(WMI_TLV_SERVICE_SYNC_DELETE_CMDS, + WMI_SERVICE_SYNC_DELETE_CMDS, len); } static inline void @@ -1721,6 +1730,16 @@ struct wmi_tlv_start_scan_cmd { struct wmi_mac_addr mac_mask; } __packed; +enum wmi_tlv_vdev_subtype { + WMI_TLV_VDEV_SUBTYPE_NONE = 0, + WMI_TLV_VDEV_SUBTYPE_P2P_DEV = 1, + WMI_TLV_VDEV_SUBTYPE_P2P_CLI = 2, + WMI_TLV_VDEV_SUBTYPE_P2P_GO = 3, + WMI_TLV_VDEV_SUBTYPE_PROXY_STA = 4, + WMI_TLV_VDEV_SUBTYPE_MESH = 5, + WMI_TLV_VDEV_SUBTYPE_MESH_11S = 6, +}; + struct wmi_tlv_vdev_start_cmd { __le32 vdev_id; __le32 requestor_id; diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index be3bade3d101..1d0b8f26afa1 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1588,6 +1588,30 @@ static struct wmi_pdev_param_map wmi_10_4_pdev_param_map = { .enable_btcoex = WMI_10_4_PDEV_PARAM_ENABLE_BTCOEX, }; +static const u8 wmi_key_cipher_suites[] = { + [WMI_CIPHER_NONE] = WMI_CIPHER_NONE, + [WMI_CIPHER_WEP] = WMI_CIPHER_WEP, + [WMI_CIPHER_TKIP] = WMI_CIPHER_TKIP, + [WMI_CIPHER_AES_OCB] = WMI_CIPHER_AES_OCB, + [WMI_CIPHER_AES_CCM] = WMI_CIPHER_AES_CCM, + [WMI_CIPHER_WAPI] = WMI_CIPHER_WAPI, + [WMI_CIPHER_CKIP] = WMI_CIPHER_CKIP, + [WMI_CIPHER_AES_CMAC] = WMI_CIPHER_AES_CMAC, + [WMI_CIPHER_AES_GCM] = WMI_CIPHER_AES_GCM, +}; + +static const u8 wmi_tlv_key_cipher_suites[] = { + [WMI_CIPHER_NONE] = WMI_TLV_CIPHER_NONE, + [WMI_CIPHER_WEP] = WMI_TLV_CIPHER_WEP, + [WMI_CIPHER_TKIP] = WMI_TLV_CIPHER_TKIP, + [WMI_CIPHER_AES_OCB] = WMI_TLV_CIPHER_AES_OCB, + [WMI_CIPHER_AES_CCM] = WMI_TLV_CIPHER_AES_CCM, + [WMI_CIPHER_WAPI] = WMI_TLV_CIPHER_WAPI, + [WMI_CIPHER_CKIP] = WMI_TLV_CIPHER_CKIP, + [WMI_CIPHER_AES_CMAC] = WMI_TLV_CIPHER_AES_CMAC, + [WMI_CIPHER_AES_GCM] = WMI_TLV_CIPHER_AES_GCM, +}; + static const struct wmi_peer_flags_map wmi_peer_flags_map = { .auth = WMI_PEER_AUTH, .qos = WMI_PEER_QOS, @@ -8421,6 +8445,7 @@ int ath10k_wmi_attach(struct ath10k *ar) ar->wmi.vdev_param = &wmi_10_4_vdev_param_map; ar->wmi.pdev_param = &wmi_10_4_pdev_param_map; ar->wmi.peer_flags = &wmi_10_2_peer_flags_map; + ar->wmi_key_cipher = wmi_key_cipher_suites; break; case ATH10K_FW_WMI_OP_VERSION_10_2_4: ar->wmi.cmd = &wmi_10_2_4_cmd_map; @@ -8428,6 +8453,7 @@ int ath10k_wmi_attach(struct ath10k *ar) ar->wmi.vdev_param = &wmi_10_2_4_vdev_param_map; ar->wmi.pdev_param = &wmi_10_2_4_pdev_param_map; ar->wmi.peer_flags = &wmi_10_2_peer_flags_map; + ar->wmi_key_cipher = wmi_key_cipher_suites; break; case ATH10K_FW_WMI_OP_VERSION_10_2: ar->wmi.cmd = &wmi_10_2_cmd_map; @@ -8435,6 +8461,7 @@ int ath10k_wmi_attach(struct ath10k *ar) ar->wmi.vdev_param = &wmi_10x_vdev_param_map; ar->wmi.pdev_param = &wmi_10x_pdev_param_map; ar->wmi.peer_flags = &wmi_10_2_peer_flags_map; + ar->wmi_key_cipher = wmi_key_cipher_suites; break; case ATH10K_FW_WMI_OP_VERSION_10_1: ar->wmi.cmd = &wmi_10x_cmd_map; @@ -8442,6 +8469,7 @@ int ath10k_wmi_attach(struct ath10k *ar) ar->wmi.vdev_param = &wmi_10x_vdev_param_map; ar->wmi.pdev_param = &wmi_10x_pdev_param_map; ar->wmi.peer_flags = &wmi_10x_peer_flags_map; + ar->wmi_key_cipher = wmi_key_cipher_suites; break; case ATH10K_FW_WMI_OP_VERSION_MAIN: ar->wmi.cmd = &wmi_cmd_map; @@ -8449,9 +8477,11 @@ int ath10k_wmi_attach(struct ath10k *ar) ar->wmi.vdev_param = &wmi_vdev_param_map; ar->wmi.pdev_param = &wmi_pdev_param_map; ar->wmi.peer_flags = &wmi_peer_flags_map; + ar->wmi_key_cipher = wmi_key_cipher_suites; break; case ATH10K_FW_WMI_OP_VERSION_TLV: ath10k_wmi_tlv_attach(ar); + ar->wmi_key_cipher = wmi_tlv_key_cipher_suites; break; case ATH10K_FW_WMI_OP_VERSION_UNSET: case ATH10K_FW_WMI_OP_VERSION_MAX: diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 9ca3cea79fce..661f23ffe59f 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -202,6 +202,7 @@ enum wmi_service { WMI_SERVICE_TPC_STATS_FINAL, WMI_SERVICE_RESET_CHIP, WMI_SERVICE_SPOOF_MAC_SUPPORT, + WMI_SERVICE_SYNC_DELETE_CMDS, /* keep last */ WMI_SERVICE_MAX, @@ -453,6 +454,7 @@ static inline char *wmi_service_name(int service_id) SVCSTR(WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE); SVCSTR(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY); SVCSTR(WMI_SERVICE_TDLS_WIDER_BANDWIDTH); + SVCSTR(WMI_SERVICE_SYNC_DELETE_CMDS); default: return NULL; } @@ -4765,15 +4767,30 @@ struct wmi_key_seq_counter { __le32 key_seq_counter_h; } __packed; -#define WMI_CIPHER_NONE 0x0 /* clear key */ -#define WMI_CIPHER_WEP 0x1 -#define WMI_CIPHER_TKIP 0x2 -#define WMI_CIPHER_AES_OCB 0x3 -#define WMI_CIPHER_AES_CCM 0x4 -#define WMI_CIPHER_WAPI 0x5 -#define WMI_CIPHER_CKIP 0x6 -#define WMI_CIPHER_AES_CMAC 0x7 -#define WMI_CIPHER_AES_GCM 0x8 +enum wmi_cipher_suites { + WMI_CIPHER_NONE, + WMI_CIPHER_WEP, + WMI_CIPHER_TKIP, + WMI_CIPHER_AES_OCB, + WMI_CIPHER_AES_CCM, + WMI_CIPHER_WAPI, + WMI_CIPHER_CKIP, + WMI_CIPHER_AES_CMAC, + WMI_CIPHER_AES_GCM, +}; + +enum wmi_tlv_cipher_suites { + WMI_TLV_CIPHER_NONE, + WMI_TLV_CIPHER_WEP, + WMI_TLV_CIPHER_TKIP, + WMI_TLV_CIPHER_AES_OCB, + WMI_TLV_CIPHER_AES_CCM, + WMI_TLV_CIPHER_WAPI, + WMI_TLV_CIPHER_CKIP, + WMI_TLV_CIPHER_AES_CMAC, + WMI_TLV_CIPHER_ANY, + WMI_TLV_CIPHER_AES_GCM, +}; struct wmi_vdev_install_key_cmd { __le32 vdev_id; @@ -6481,6 +6498,11 @@ struct wmi_scan_ev_arg { __le32 vdev_id; }; +struct wmi_peer_delete_resp_ev_arg { + __le32 vdev_id; + struct wmi_mac_addr peer_addr; +}; + struct wmi_mgmt_rx_ev_arg { __le32 channel; __le32 snr; diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index bd7f6d7b199e..c607ee9275e8 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -931,7 +931,7 @@ static int open_file_eeprom(struct inode *inode, struct file *file) /* Create buffer and read in eeprom */ - buf = vmalloc(eesize * 2); + buf = vmalloc(array_size(eesize, 2)); if (!buf) { ret = -ENOMEM; goto err; diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 641b13a279e1..b1b8bc326830 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -890,7 +890,8 @@ ath5k_hw_rfregs_init(struct ath5k_hw *ah, * ah->ah_rf_banks based on ah->ah_rf_banks_size * we set above */ if (ah->ah_rf_banks == NULL) { - ah->ah_rf_banks = kmalloc(sizeof(u32) * ah->ah_rf_banks_size, + ah->ah_rf_banks = kmalloc_array(ah->ah_rf_banks_size, + sizeof(u32), GFP_KERNEL); if (ah->ah_rf_banks == NULL) { ATH5K_ERR(ah, "out of memory\n"); diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 37deb9bae364..83e95f0a9c2a 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -1041,7 +1041,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, n_channels = request->n_channels; - channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL); + channels = kcalloc(n_channels, sizeof(u16), GFP_KERNEL); if (channels == NULL) { ath6kl_warn("failed to set scan channels, scan all channels"); n_channels = 0; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 6343cc91953e..34e100940284 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -925,7 +925,7 @@ int ar9003_paprd_create_curve(struct ath_hw *ah, memset(caldata->pa_table[chain], 0, sizeof(caldata->pa_table[chain])); - buf = kmalloc(2 * 48 * sizeof(u32), GFP_KERNEL); + buf = kmalloc_array(2 * 48, sizeof(u32), GFP_KERNEL); if (!buf) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index d2e062eaf561..f705f0e1cb5b 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -173,6 +173,7 @@ static int htc_config_pipe_credits(struct htc_target *target) time_left = wait_for_completion_timeout(&target->cmd_wait, HZ); if (!time_left) { dev_err(target->dev, "HTC credit config timeout\n"); + kfree_skb(skb); return -ETIMEDOUT; } @@ -208,6 +209,7 @@ static int htc_setup_complete(struct htc_target *target) time_left = wait_for_completion_timeout(&target->cmd_wait, HZ); if (!time_left) { dev_err(target->dev, "HTC start timeout\n"); + kfree_skb(skb); return -ETIMEDOUT; } @@ -280,6 +282,7 @@ int htc_connect_service(struct htc_target *target, if (!time_left) { dev_err(target->dev, "Service connection timeout for: %d\n", service_connreq->service_id); + kfree_skb(skb); return -ETIMEDOUT; } diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 406b52f114f0..2a5039087116 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -127,13 +127,13 @@ void ath9k_hw_read_array(struct ath_hw *ah, u32 array[][2], int size) u32 *tmp_reg_list, *tmp_data; int i; - tmp_reg_list = kmalloc(size * sizeof(u32), GFP_KERNEL); + tmp_reg_list = kmalloc_array(size, sizeof(u32), GFP_KERNEL); if (!tmp_reg_list) { dev_err(ah->dev, "%s: tmp_reg_list: alloc filed\n", __func__); return; } - tmp_data = kmalloc(size * sizeof(u32), GFP_KERNEL); + tmp_data = kmalloc_array(size, sizeof(u32), GFP_KERNEL); if (!tmp_data) { dev_err(ah->dev, "%s tmp_data: alloc filed\n", __func__); goto error_tmp_data; diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index f57f48e4d7a0..4b68804f3742 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -338,6 +338,7 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, ath_dbg(common, WMI, "Timeout waiting for WMI command: %s\n", wmi_cmd_to_name(cmd_id)); mutex_unlock(&wmi->op_mutex); + kfree_skb(skb); return -ETIMEDOUT; } diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 80312b2fddb1..88523c572f0a 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1945,7 +1945,7 @@ static int carl9170_parse_eeprom(struct ar9170 *ar) if (!bands) return -EINVAL; - ar->survey = kzalloc(sizeof(struct survey_info) * chans, GFP_KERNEL); + ar->survey = kcalloc(chans, sizeof(struct survey_info), GFP_KERNEL); if (!ar->survey) return -ENOMEM; ar->num_channels = chans; @@ -1975,8 +1975,9 @@ int carl9170_register(struct ar9170 *ar) if (WARN_ON(ar->mem_bitmap)) return -EINVAL; - ar->mem_bitmap = kzalloc(roundup(ar->fw.mem_blocks, BITS_PER_LONG) * - sizeof(unsigned long), GFP_KERNEL); + ar->mem_bitmap = kcalloc(roundup(ar->fw.mem_blocks, BITS_PER_LONG), + sizeof(unsigned long), + GFP_KERNEL); if (!ar->mem_bitmap) return -ENOMEM; diff --git a/drivers/net/wireless/broadcom/b43/phy_n.c b/drivers/net/wireless/broadcom/b43/phy_n.c index a5557d70689f..b5d3c7fe241c 100644 --- a/drivers/net/wireless/broadcom/b43/phy_n.c +++ b/drivers/net/wireless/broadcom/b43/phy_n.c @@ -1518,7 +1518,7 @@ static int b43_nphy_load_samples(struct b43_wldev *dev, u16 i; u32 *data; - data = kzalloc(len * sizeof(u32), GFP_KERNEL); + data = kcalloc(len, sizeof(u32), GFP_KERNEL); if (!data) { b43err(dev->wl, "allocation for samples loading failed\n"); return -ENOMEM; diff --git a/drivers/net/wireless/broadcom/b43legacy/main.c b/drivers/net/wireless/broadcom/b43legacy/main.c index 6f123a52ae2d..ef1f1b5d63b1 100644 --- a/drivers/net/wireless/broadcom/b43legacy/main.c +++ b/drivers/net/wireless/broadcom/b43legacy/main.c @@ -3301,8 +3301,8 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev) if ((phy->type == B43legacy_PHYTYPE_B) || (phy->type == B43legacy_PHYTYPE_G)) { - phy->_lo_pairs = kzalloc(sizeof(struct b43legacy_lopair) - * B43legacy_LO_COUNT, + phy->_lo_pairs = kcalloc(B43legacy_LO_COUNT, + sizeof(struct b43legacy_lopair), GFP_KERNEL); if (!phy->_lo_pairs) return -ENOMEM; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c index 65e16e3646ec..e5705c40aa49 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c @@ -1478,8 +1478,9 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr) (struct brcmf_commonring **)if_msgbuf->commonrings; msgbuf->flowrings = (struct brcmf_commonring **)if_msgbuf->flowrings; msgbuf->max_flowrings = if_msgbuf->max_flowrings; - msgbuf->flowring_dma_handle = kzalloc(msgbuf->max_flowrings * - sizeof(*msgbuf->flowring_dma_handle), GFP_KERNEL); + msgbuf->flowring_dma_handle = kcalloc(msgbuf->max_flowrings, + sizeof(*msgbuf->flowring_dma_handle), + GFP_KERNEL); if (!msgbuf->flowring_dma_handle) goto fail; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c index 4a883f4bbf88..d70932b8b94a 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c @@ -1063,7 +1063,7 @@ static s32 brcmf_p2p_act_frm_search(struct brcmf_p2p_info *p2p, u16 channel) channel_cnt = AF_PEER_SEARCH_CNT; else channel_cnt = SOCIAL_CHAN_CNT; - default_chan_list = kzalloc(channel_cnt * sizeof(*default_chan_list), + default_chan_list = kcalloc(channel_cnt, sizeof(*default_chan_list), GFP_KERNEL); if (default_chan_list == NULL) { brcmf_err("channel list allocation failed\n"); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c index 0a14942b8216..7d4e8f589fdc 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c @@ -507,7 +507,7 @@ brcms_c_attach_malloc(uint unit, uint *err, uint devid) wlc->hw->wlc = wlc; wlc->hw->bandstate[0] = - kzalloc(sizeof(struct brcms_hw_band) * MAXBANDS, GFP_ATOMIC); + kcalloc(MAXBANDS, sizeof(struct brcms_hw_band), GFP_ATOMIC); if (wlc->hw->bandstate[0] == NULL) { *err = 1006; goto fail; @@ -521,7 +521,8 @@ brcms_c_attach_malloc(uint unit, uint *err, uint devid) } wlc->modulecb = - kzalloc(sizeof(struct modulecb) * BRCMS_MAXMODULES, GFP_ATOMIC); + kcalloc(BRCMS_MAXMODULES, sizeof(struct modulecb), + GFP_ATOMIC); if (wlc->modulecb == NULL) { *err = 1009; goto fail; @@ -553,7 +554,7 @@ brcms_c_attach_malloc(uint unit, uint *err, uint devid) } wlc->bandstate[0] = - kzalloc(sizeof(struct brcms_band)*MAXBANDS, GFP_ATOMIC); + kcalloc(MAXBANDS, sizeof(struct brcms_band), GFP_ATOMIC); if (wlc->bandstate[0] == NULL) { *err = 1025; goto fail; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c index 93d4cde0eb31..a09f96b43a6b 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c @@ -1387,7 +1387,7 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, s16 *ptr; struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; - ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC); + ptr = kmalloc_array(131, sizeof(s16), GFP_ATOMIC); if (NULL == ptr) return false; if (module == 2) { @@ -2670,7 +2670,7 @@ wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, u16 *values_to_save; struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; - values_to_save = kmalloc(sizeof(u16) * 20, GFP_ATOMIC); + values_to_save = kmalloc_array(20, sizeof(u16), GFP_ATOMIC); if (NULL == values_to_save) return; @@ -3683,11 +3683,11 @@ wlc_lcnphy_a1(struct brcms_phy *pi, int cal_type, int num_levels, u16 *phy_c32; phy_c21 = 0; phy_c10 = phy_c13 = phy_c14 = phy_c8 = 0; - ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC); + ptr = kmalloc_array(131, sizeof(s16), GFP_ATOMIC); if (NULL == ptr) return; - phy_c32 = kmalloc(sizeof(u16) * 20, GFP_ATOMIC); + phy_c32 = kmalloc_array(20, sizeof(u16), GFP_ATOMIC); if (NULL == phy_c32) { kfree(ptr); return; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c index ef685465f80a..1e67875cd07f 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c @@ -23116,7 +23116,7 @@ wlc_phy_loadsampletable_nphy(struct brcms_phy *pi, struct cordic_iq *tone_buf, u16 t; u32 *data_buf = NULL; - data_buf = kmalloc(sizeof(u32) * num_samps, GFP_ATOMIC); + data_buf = kmalloc_array(num_samps, sizeof(u32), GFP_ATOMIC); if (data_buf == NULL) return; @@ -23158,7 +23158,8 @@ wlc_phy_gen_load_samples_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val, tbl_len = (phy_bw << 1); } - tone_buf = kmalloc(sizeof(struct cordic_iq) * tbl_len, GFP_ATOMIC); + tone_buf = kmalloc_array(tbl_len, sizeof(struct cordic_iq), + GFP_ATOMIC); if (tone_buf == NULL) return 0; diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c index d06dc446a393..0a69649dd1e9 100644 --- a/drivers/net/wireless/cisco/airo.c +++ b/drivers/net/wireless/cisco/airo.c @@ -7139,7 +7139,7 @@ static int airo_get_aplist(struct net_device *dev, int i; int loseSync = capable(CAP_NET_ADMIN) ? 1: -1; - qual = kmalloc(IW_MAX_AP * sizeof(*qual), GFP_KERNEL); + qual = kmalloc_array(IW_MAX_AP, sizeof(*qual), GFP_KERNEL); if (!qual) return -ENOMEM; diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c index 70f6376afd14..a3beeeb46496 100644 --- a/drivers/net/wireless/cnss2/pci.c +++ b/drivers/net/wireless/cnss2/pci.c @@ -726,9 +726,10 @@ static void cnss_pci_dump_shadow_reg(struct cnss_pci_data *pci_priv) gfp = GFP_ATOMIC; if (!pci_priv->debug_reg) { - pci_priv->debug_reg = devm_kzalloc(&pci_priv->pci_dev->dev, - sizeof(*pci_priv->debug_reg) - * array_size, gfp); + pci_priv->debug_reg = devm_kcalloc(&pci_priv->pci_dev->dev, + array_size, + sizeof(*pci_priv->debug_reg), + gfp); if (!pci_priv->debug_reg) return; } @@ -2604,9 +2605,10 @@ static void cnss_pci_dump_qdss_reg(struct cnss_pci_data *pci_priv) gfp = GFP_ATOMIC; if (!plat_priv->qdss_reg) { - plat_priv->qdss_reg = devm_kzalloc(&pci_priv->pci_dev->dev, - sizeof(*plat_priv->qdss_reg) - * array_size, gfp); + plat_priv->qdss_reg = devm_kcalloc(&pci_priv->pci_dev->dev, + array_size, + sizeof(*plat_priv->qdss_reg), + gfp); if (!plat_priv->qdss_reg) return; } diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c index 8fbdd7d4fd0c..3f12ac09e75b 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c @@ -3446,8 +3446,9 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv) dma_addr_t p; priv->msg_buffers = - kmalloc(IPW_COMMAND_POOL_SIZE * sizeof(struct ipw2100_tx_packet), - GFP_KERNEL); + kmalloc_array(IPW_COMMAND_POOL_SIZE, + sizeof(struct ipw2100_tx_packet), + GFP_KERNEL); if (!priv->msg_buffers) return -ENOMEM; @@ -4589,9 +4590,9 @@ static int ipw2100_rx_allocate(struct ipw2100_priv *priv) /* * allocate packets */ - priv->rx_buffers = kmalloc(RX_QUEUE_LENGTH * - sizeof(struct ipw2100_rx_packet), - GFP_KERNEL); + priv->rx_buffers = kmalloc_array(RX_QUEUE_LENGTH, + sizeof(struct ipw2100_rx_packet), + GFP_KERNEL); if (!priv->rx_buffers) { IPW_DEBUG_INFO("can't allocate rx packet buffer table\n"); diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c index 2d0734ab3f74..54113802b2b9 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c @@ -3216,13 +3216,13 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len) IPW_DEBUG_TRACE("<< :\n"); - virts = kmalloc(sizeof(void *) * CB_NUMBER_OF_ELEMENTS_SMALL, - GFP_KERNEL); + virts = kmalloc_array(CB_NUMBER_OF_ELEMENTS_SMALL, sizeof(void *), + GFP_KERNEL); if (!virts) return -ENOMEM; - phys = kmalloc(sizeof(dma_addr_t) * CB_NUMBER_OF_ELEMENTS_SMALL, - GFP_KERNEL); + phys = kmalloc_array(CB_NUMBER_OF_ELEMENTS_SMALL, sizeof(dma_addr_t), + GFP_KERNEL); if (!phys) { kfree(virts); return -ENOMEM; @@ -3790,7 +3790,7 @@ static int ipw_queue_tx_init(struct ipw_priv *priv, { struct pci_dev *dev = priv->pci_dev; - q->txb = kmalloc(sizeof(q->txb[0]) * count, GFP_KERNEL); + q->txb = kmalloc_array(count, sizeof(q->txb[0]), GFP_KERNEL); if (!q->txb) { IPW_ERROR("vmalloc for auxiliary BD structures failed\n"); return -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c index 6e6b124f0d5e..a77ec6ec80ac 100644 --- a/drivers/net/wireless/intel/iwlegacy/common.c +++ b/drivers/net/wireless/intel/iwlegacy/common.c @@ -922,7 +922,7 @@ il_init_channel_map(struct il_priv *il) D_EEPROM("Parsing data for %d channels.\n", il->channel_count); il->channel_info = - kzalloc(sizeof(struct il_channel_info) * il->channel_count, + kcalloc(il->channel_count, sizeof(struct il_channel_info), GFP_KERNEL); if (!il->channel_info) { IL_ERR("Could not allocate channel_info\n"); @@ -3041,9 +3041,9 @@ il_tx_queue_init(struct il_priv *il, u32 txq_id) } txq->meta = - kzalloc(sizeof(struct il_cmd_meta) * actual_slots, GFP_KERNEL); + kcalloc(actual_slots, sizeof(struct il_cmd_meta), GFP_KERNEL); txq->cmd = - kzalloc(sizeof(struct il_device_cmd *) * actual_slots, GFP_KERNEL); + kcalloc(actual_slots, sizeof(struct il_device_cmd *), GFP_KERNEL); if (!txq->meta || !txq->cmd) goto out_free_arrays; @@ -3455,7 +3455,7 @@ il_init_geos(struct il_priv *il) } channels = - kzalloc(sizeof(struct ieee80211_channel) * il->channel_count, + kcalloc(il->channel_count, sizeof(struct ieee80211_channel), GFP_KERNEL); if (!channels) return -ENOMEM; @@ -4654,8 +4654,9 @@ il_alloc_txq_mem(struct il_priv *il) { if (!il->txq) il->txq = - kzalloc(sizeof(struct il_tx_queue) * - il->cfg->num_of_queues, GFP_KERNEL); + kcalloc(il->cfg->num_of_queues, + sizeof(struct il_tx_queue), + GFP_KERNEL); if (!il->txq) { IL_ERR("Not enough memory for txq\n"); return -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index b86c7a36d3f1..0627b2382d85 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -3020,9 +3020,7 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, mvmsta = iwl_mvm_sta_from_mac80211(sta); WARN_ON(rcu_access_pointer(mvmsta->ptk_pn[keyidx])); - ptk_pn = kzalloc(sizeof(*ptk_pn) + - mvm->trans->num_rx_queues * - sizeof(ptk_pn->q[0]), + ptk_pn = kzalloc(struct_size(ptk_pn, q, mvm->trans->num_rx_queues), GFP_KERNEL); if (!ptk_pn) { ret = -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index e4fd476e9ccb..c36096875c79 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -501,7 +501,7 @@ iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, else blacklist_len = IWL_SCAN_MAX_BLACKLIST_LEN; - blacklist = kzalloc(sizeof(*blacklist) * blacklist_len, GFP_KERNEL); + blacklist = kcalloc(blacklist_len, sizeof(*blacklist), GFP_KERNEL); if (!blacklist) return -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index d9ab85c8eb6a..1b835cee62e0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -2223,9 +2223,7 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, * Allocate here so if allocation fails we can bail out early * before starting the BA session in the firmware */ - baid_data = kzalloc(sizeof(*baid_data) + - mvm->trans->num_rx_queues * - sizeof(baid_data->reorder_buf[0]), + baid_data = kzalloc(struct_size(baid_data, reorder_buf, mvm->trans->num_rx_queues), GFP_KERNEL); if (!baid_data) return -ENOMEM; diff --git a/drivers/net/wireless/intersil/hostap/hostap_info.c b/drivers/net/wireless/intersil/hostap/hostap_info.c index de8a099a9386..da8c30f10d92 100644 --- a/drivers/net/wireless/intersil/hostap/hostap_info.c +++ b/drivers/net/wireless/intersil/hostap/hostap_info.c @@ -271,8 +271,9 @@ static void prism2_info_scanresults(local_info_t *local, unsigned char *buf, left -= 4; new_count = left / sizeof(struct hfa384x_scan_result); - results = kmalloc(new_count * sizeof(struct hfa384x_hostscan_result), - GFP_ATOMIC); + results = kmalloc_array(new_count, + sizeof(struct hfa384x_hostscan_result), + GFP_ATOMIC); if (results == NULL) return; diff --git a/drivers/net/wireless/intersil/hostap/hostap_ioctl.c b/drivers/net/wireless/intersil/hostap/hostap_ioctl.c index c1bc0a6ef300..1ca9731d9b14 100644 --- a/drivers/net/wireless/intersil/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/intersil/hostap/hostap_ioctl.c @@ -513,8 +513,8 @@ static int prism2_ioctl_giwaplist(struct net_device *dev, return -EOPNOTSUPP; } - addr = kmalloc(sizeof(struct sockaddr) * IW_MAX_AP, GFP_KERNEL); - qual = kmalloc(sizeof(struct iw_quality) * IW_MAX_AP, GFP_KERNEL); + addr = kmalloc_array(IW_MAX_AP, sizeof(struct sockaddr), GFP_KERNEL); + qual = kmalloc_array(IW_MAX_AP, sizeof(struct iw_quality), GFP_KERNEL); if (addr == NULL || qual == NULL) { kfree(addr); kfree(qual); diff --git a/drivers/net/wireless/intersil/p54/eeprom.c b/drivers/net/wireless/intersil/p54/eeprom.c index d4c73d39336f..de2ef95c386c 100644 --- a/drivers/net/wireless/intersil/p54/eeprom.c +++ b/drivers/net/wireless/intersil/p54/eeprom.c @@ -161,8 +161,9 @@ static int p54_generate_band(struct ieee80211_hw *dev, if (!tmp) goto err_out; - tmp->channels = kzalloc(sizeof(struct ieee80211_channel) * - list->band_channel_num[band], GFP_KERNEL); + tmp->channels = kcalloc(list->band_channel_num[band], + sizeof(struct ieee80211_channel), + GFP_KERNEL); if (!tmp->channels) goto err_out; @@ -344,7 +345,7 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev) goto free; } priv->chan_num = max_channel_num; - priv->survey = kzalloc(sizeof(struct survey_info) * max_channel_num, + priv->survey = kcalloc(max_channel_num, sizeof(struct survey_info), GFP_KERNEL); if (!priv->survey) { ret = -ENOMEM; @@ -352,8 +353,9 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev) } list->max_entries = max_channel_num; - list->channels = kzalloc(sizeof(struct p54_channel_entry) * - max_channel_num, GFP_KERNEL); + list->channels = kcalloc(max_channel_num, + sizeof(struct p54_channel_entry), + GFP_KERNEL); if (!list->channels) { ret = -ENOMEM; goto free; diff --git a/drivers/net/wireless/intersil/prism54/oid_mgt.c b/drivers/net/wireless/intersil/prism54/oid_mgt.c index 6528ed5b9b1d..6d57e1cbcc07 100644 --- a/drivers/net/wireless/intersil/prism54/oid_mgt.c +++ b/drivers/net/wireless/intersil/prism54/oid_mgt.c @@ -244,7 +244,7 @@ mgt_init(islpci_private *priv) /* Alloc the cache */ for (i = 0; i < OID_NUM_LAST; i++) { if (isl_oid[i].flags & OID_FLAG_CACHED) { - priv->mib[i] = kzalloc(isl_oid[i].size * + priv->mib[i] = kcalloc(isl_oid[i].size, (isl_oid[i].range + 1), GFP_KERNEL); if (!priv->mib[i]) diff --git a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c index 274dd5a1574a..6da0088b3e3a 100644 --- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c @@ -399,8 +399,8 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, new_node->win_size = win_size; - new_node->rx_reorder_ptr = kzalloc(sizeof(void *) * win_size, - GFP_KERNEL); + new_node->rx_reorder_ptr = kcalloc(win_size, sizeof(void *), + GFP_KERNEL); if (!new_node->rx_reorder_ptr) { kfree((u8 *) new_node); mwifiex_dbg(priv->adapter, ERROR, diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c index 79c50aebffc4..4eb0615a24b6 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -4220,8 +4220,7 @@ int mwifiex_init_channel_scan_gap(struct mwifiex_adapter *adapter) n_channels_a = mwifiex_band_5ghz.n_channels; adapter->num_in_chan_stats = n_channels_bg + n_channels_a; - adapter->chan_stats = vmalloc(sizeof(*adapter->chan_stats) * - adapter->num_in_chan_stats); + adapter->chan_stats = vmalloc(array_size(sizeof(*adapter->chan_stats), adapter->num_in_chan_stats)); if (!adapter->chan_stats) return -ENOMEM; diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c index fd5183c10c4e..065c44636157 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.c +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c @@ -2094,15 +2094,16 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter) return -ENOMEM; /* Allocate skb pointer buffers */ - card->mpa_rx.skb_arr = kzalloc((sizeof(void *)) * - card->mp_agg_pkt_limit, GFP_KERNEL); + card->mpa_rx.skb_arr = kcalloc(card->mp_agg_pkt_limit, sizeof(void *), + GFP_KERNEL); if (!card->mpa_rx.skb_arr) { kfree(card->mp_regs); return -ENOMEM; } - card->mpa_rx.len_arr = kzalloc(sizeof(*card->mpa_rx.len_arr) * - card->mp_agg_pkt_limit, GFP_KERNEL); + card->mpa_rx.len_arr = kcalloc(card->mp_agg_pkt_limit, + sizeof(*card->mpa_rx.len_arr), + GFP_KERNEL); if (!card->mpa_rx.len_arr) { kfree(card->mp_regs); kfree(card->mpa_rx.skb_arr); diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c index ed087bbc6f63..620cea6f1b54 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/commands.c +++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c @@ -1022,8 +1022,9 @@ static int qtnf_parse_variable_mac_info(struct qtnf_wmac *mac, /* free earlier iface limits memory */ kfree(mac->macinfo.limits); mac->macinfo.limits = - kzalloc(sizeof(*mac->macinfo.limits) * - record_count, GFP_KERNEL); + kcalloc(record_count, + sizeof(*mac->macinfo.limits), + GFP_KERNEL); if (unlikely(!mac->macinfo.limits)) return -ENOMEM; diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c index 51520a0e2138..660b26e1c662 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c @@ -396,7 +396,7 @@ static ssize_t rt2x00debug_read_crypto_stats(struct file *file, if (*offset) return 0; - data = kzalloc((1 + CIPHER_MAX) * MAX_LINE_LENGTH, GFP_KERNEL); + data = kcalloc(1 + CIPHER_MAX, MAX_LINE_LENGTH, GFP_KERNEL); if (!data) return -ENOMEM; diff --git a/drivers/net/wireless/realtek/rtlwifi/efuse.c b/drivers/net/wireless/realtek/rtlwifi/efuse.c index ef9acd466cca..c8169c92606c 100644 --- a/drivers/net/wireless/realtek/rtlwifi/efuse.c +++ b/drivers/net/wireless/realtek/rtlwifi/efuse.c @@ -253,15 +253,15 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) } /* allocate memory for efuse_tbl and efuse_word */ - efuse_tbl = kzalloc(rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE] * - sizeof(u8), GFP_ATOMIC); + efuse_tbl = kzalloc(rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE], + GFP_ATOMIC); if (!efuse_tbl) return; - efuse_word = kzalloc(EFUSE_MAX_WORD_UNIT * sizeof(u16 *), GFP_ATOMIC); + efuse_word = kcalloc(EFUSE_MAX_WORD_UNIT, sizeof(u16 *), GFP_ATOMIC); if (!efuse_word) goto out; for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { - efuse_word[i] = kzalloc(efuse_max_section * sizeof(u16), + efuse_word[i] = kcalloc(efuse_max_section, sizeof(u16), GFP_ATOMIC); if (!efuse_word[i]) goto done; diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.c b/drivers/net/wireless/realtek/rtlwifi/usb.c index 7a050a75bdcb..530efda5b208 100644 --- a/drivers/net/wireless/realtek/rtlwifi/usb.c +++ b/drivers/net/wireless/realtek/rtlwifi/usb.c @@ -1062,7 +1062,7 @@ int rtl_usb_probe(struct usb_interface *intf, } rtlpriv = hw->priv; rtlpriv->hw = hw; - rtlpriv->usb_data = kzalloc(RTL_USB_MAX_RX_COUNT * sizeof(u32), + rtlpriv->usb_data = kcalloc(RTL_USB_MAX_RX_COUNT, sizeof(u32), GFP_KERNEL); if (!rtlpriv->usb_data) { ieee80211_free_hw(hw); diff --git a/drivers/net/wireless/st/cw1200/queue.c b/drivers/net/wireless/st/cw1200/queue.c index 0ba5ef9b3e7b..e70771636b4e 100644 --- a/drivers/net/wireless/st/cw1200/queue.c +++ b/drivers/net/wireless/st/cw1200/queue.c @@ -154,7 +154,7 @@ int cw1200_queue_stats_init(struct cw1200_queue_stats *stats, spin_lock_init(&stats->lock); init_waitqueue_head(&stats->wait_link_id_empty); - stats->link_map_cache = kzalloc(sizeof(int) * map_capacity, + stats->link_map_cache = kcalloc(map_capacity, sizeof(int), GFP_KERNEL); if (!stats->link_map_cache) return -ENOMEM; @@ -181,13 +181,13 @@ int cw1200_queue_init(struct cw1200_queue *queue, spin_lock_init(&queue->lock); setup_timer(&queue->gc, cw1200_queue_gc, (unsigned long)queue); - queue->pool = kzalloc(sizeof(struct cw1200_queue_item) * capacity, - GFP_KERNEL); + queue->pool = kcalloc(capacity, sizeof(struct cw1200_queue_item), + GFP_KERNEL); if (!queue->pool) return -ENOMEM; - queue->link_map_cache = kzalloc(sizeof(int) * stats->map_capacity, - GFP_KERNEL); + queue->link_map_cache = kcalloc(stats->map_capacity, sizeof(int), + GFP_KERNEL); if (!queue->link_map_cache) { kfree(queue->pool); queue->pool = NULL; diff --git a/drivers/net/wireless/st/cw1200/scan.c b/drivers/net/wireless/st/cw1200/scan.c index 446d973cba81..71e9b91cf15b 100644 --- a/drivers/net/wireless/st/cw1200/scan.c +++ b/drivers/net/wireless/st/cw1200/scan.c @@ -232,9 +232,9 @@ void cw1200_scan_work(struct work_struct *work) scan.type = WSM_SCAN_TYPE_BACKGROUND; scan.flags = WSM_SCAN_FLAG_FORCE_BACKGROUND; } - scan.ch = kzalloc( - sizeof(struct wsm_scan_ch) * (it - priv->scan.curr), - GFP_KERNEL); + scan.ch = kcalloc(it - priv->scan.curr, + sizeof(struct wsm_scan_ch), + GFP_KERNEL); if (!scan.ch) { priv->scan.status = -ENOMEM; goto fail; diff --git a/drivers/net/wireless/zydas/zd1211rw/zd_mac.c b/drivers/net/wireless/zydas/zd1211rw/zd_mac.c index b785742bfd9e..59f48119f2cf 100644 --- a/drivers/net/wireless/zydas/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zydas/zd1211rw/zd_mac.c @@ -733,7 +733,8 @@ static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon, /* Alloc memory for full beacon write at once. */ num_cmds = 1 + zd_chip_is_zd1211b(&mac->chip) + full_len; - ioreqs = kmalloc(num_cmds * sizeof(struct zd_ioreq32), GFP_KERNEL); + ioreqs = kmalloc_array(num_cmds, sizeof(struct zd_ioreq32), + GFP_KERNEL); if (!ioreqs) { r = -ENOMEM; goto out_nofree; diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index a56d3eab35dd..2e7919bbc250 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c @@ -977,8 +977,7 @@ static void connect(struct backend_info *be) } /* Use the number of queues requested by the frontend */ - be->vif->queues = vzalloc(requested_num_queues * - sizeof(struct xenvif_queue)); + be->vif->queues = vzalloc(array_size(requested_num_queues, sizeof(struct xenvif_queue))); if (!be->vif->queues) { xenbus_dev_fatal(dev, -ENOMEM, "allocating queues"); diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 91bf86cee273..1131397454bd 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -63,6 +63,8 @@ module_param_named(max_queues, xennet_max_queues, uint, 0644); MODULE_PARM_DESC(max_queues, "Maximum number of queues per virtual interface"); +#define XENNET_TIMEOUT (5 * HZ) + static const struct ethtool_ops xennet_ethtool_ops; struct netfront_cb { @@ -1336,12 +1338,15 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) netif_carrier_off(netdev); - xenbus_switch_state(dev, XenbusStateInitialising); - wait_event(module_wq, - xenbus_read_driver_state(dev->otherend) != - XenbusStateClosed && - xenbus_read_driver_state(dev->otherend) != - XenbusStateUnknown); + do { + xenbus_switch_state(dev, XenbusStateInitialising); + err = wait_event_timeout(module_wq, + xenbus_read_driver_state(dev->otherend) != + XenbusStateClosed && + xenbus_read_driver_state(dev->otherend) != + XenbusStateUnknown, XENNET_TIMEOUT); + } while (!err); + return netdev; exit: @@ -2142,28 +2147,43 @@ static const struct attribute_group xennet_dev_group = { }; #endif /* CONFIG_SYSFS */ +static void xennet_bus_close(struct xenbus_device *dev) +{ + int ret; + + if (xenbus_read_driver_state(dev->otherend) == XenbusStateClosed) + return; + do { + xenbus_switch_state(dev, XenbusStateClosing); + ret = wait_event_timeout(module_wq, + xenbus_read_driver_state(dev->otherend) == + XenbusStateClosing || + xenbus_read_driver_state(dev->otherend) == + XenbusStateClosed || + xenbus_read_driver_state(dev->otherend) == + XenbusStateUnknown, + XENNET_TIMEOUT); + } while (!ret); + + if (xenbus_read_driver_state(dev->otherend) == XenbusStateClosed) + return; + + do { + xenbus_switch_state(dev, XenbusStateClosed); + ret = wait_event_timeout(module_wq, + xenbus_read_driver_state(dev->otherend) == + XenbusStateClosed || + xenbus_read_driver_state(dev->otherend) == + XenbusStateUnknown, + XENNET_TIMEOUT); + } while (!ret); +} + static int xennet_remove(struct xenbus_device *dev) { struct netfront_info *info = dev_get_drvdata(&dev->dev); - dev_dbg(&dev->dev, "%s\n", dev->nodename); - - if (xenbus_read_driver_state(dev->otherend) != XenbusStateClosed) { - xenbus_switch_state(dev, XenbusStateClosing); - wait_event(module_wq, - xenbus_read_driver_state(dev->otherend) == - XenbusStateClosing || - xenbus_read_driver_state(dev->otherend) == - XenbusStateUnknown); - - xenbus_switch_state(dev, XenbusStateClosed); - wait_event(module_wq, - xenbus_read_driver_state(dev->otherend) == - XenbusStateClosed || - xenbus_read_driver_state(dev->otherend) == - XenbusStateUnknown); - } - + xennet_bus_close(dev); xennet_disconnect_backend(info); if (info->netdev->reg_state == NETREG_REGISTERED) diff --git a/drivers/nfc/fdp/i2c.c b/drivers/nfc/fdp/i2c.c index b86c8447df89..159dc9ed0bad 100644 --- a/drivers/nfc/fdp/i2c.c +++ b/drivers/nfc/fdp/i2c.c @@ -269,8 +269,8 @@ static void fdp_nci_i2c_read_device_properties(struct device *dev, /* Add 1 to the length to inclue the length byte itself */ len++; - *fw_vsc_cfg = devm_kmalloc(dev, - len * sizeof(**fw_vsc_cfg), + *fw_vsc_cfg = devm_kmalloc_array(dev, + len, sizeof(**fw_vsc_cfg), GFP_KERNEL); r = device_property_read_u8_array(dev, FDP_DP_FW_VSC_CFG_NAME, diff --git a/drivers/nfc/s3fwrn5/core.c b/drivers/nfc/s3fwrn5/core.c index 9d9c8d57a042..64b58455e620 100644 --- a/drivers/nfc/s3fwrn5/core.c +++ b/drivers/nfc/s3fwrn5/core.c @@ -209,6 +209,7 @@ int s3fwrn5_recv_frame(struct nci_dev *ndev, struct sk_buff *skb, case S3FWRN5_MODE_FW: return s3fwrn5_fw_recv_frame(ndev, skb); default: + kfree_skb(skb); return -ENODEV; } } diff --git a/drivers/ntb/hw/amd/ntb_hw_amd.c b/drivers/ntb/hw/amd/ntb_hw_amd.c index f0788aae05c9..16c10dfe0919 100644 --- a/drivers/ntb/hw/amd/ntb_hw_amd.c +++ b/drivers/ntb/hw/amd/ntb_hw_amd.c @@ -592,12 +592,12 @@ static int ndev_init_isr(struct amd_ntb_dev *ndev, ndev->db_mask = ndev->db_valid_mask; /* Try to set up msix irq */ - ndev->vec = kzalloc_node(msix_max * sizeof(*ndev->vec), + ndev->vec = kcalloc_node(msix_max, sizeof(*ndev->vec), GFP_KERNEL, node); if (!ndev->vec) goto err_msix_vec_alloc; - ndev->msix = kzalloc_node(msix_max * sizeof(*ndev->msix), + ndev->msix = kcalloc_node(msix_max, sizeof(*ndev->msix), GFP_KERNEL, node); if (!ndev->msix) goto err_msix_alloc; diff --git a/drivers/ntb/hw/intel/ntb_hw_intel.c b/drivers/ntb/hw/intel/ntb_hw_intel.c index 58068f1447bb..156707195fad 100644 --- a/drivers/ntb/hw/intel/ntb_hw_intel.c +++ b/drivers/ntb/hw/intel/ntb_hw_intel.c @@ -463,12 +463,12 @@ static int ndev_init_isr(struct intel_ntb_dev *ndev, /* Try to set up msix irq */ - ndev->vec = kzalloc_node(msix_max * sizeof(*ndev->vec), + ndev->vec = kcalloc_node(msix_max, sizeof(*ndev->vec), GFP_KERNEL, node); if (!ndev->vec) goto err_msix_vec_alloc; - ndev->msix = kzalloc_node(msix_max * sizeof(*ndev->msix), + ndev->msix = kcalloc_node(msix_max, sizeof(*ndev->msix), GFP_KERNEL, node); if (!ndev->msix) goto err_msix_alloc; diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c index 18339b7e88a4..ad65cb7ddf9d 100644 --- a/drivers/ntb/ntb_transport.c +++ b/drivers/ntb/ntb_transport.c @@ -1097,7 +1097,7 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev) max_mw_count_for_spads = (spad_count - MW0_SZ_HIGH) / 2; nt->mw_count = min(mw_count, max_mw_count_for_spads); - nt->mw_vec = kzalloc_node(mw_count * sizeof(*nt->mw_vec), + nt->mw_vec = kcalloc_node(mw_count, sizeof(*nt->mw_vec), GFP_KERNEL, node); if (!nt->mw_vec) { rc = -ENOMEM; @@ -1143,7 +1143,7 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev) nt->qp_bitmap = qp_bitmap; nt->qp_bitmap_free = qp_bitmap; - nt->qp_vec = kzalloc_node(qp_count * sizeof(*nt->qp_vec), + nt->qp_vec = kcalloc_node(qp_count, sizeof(*nt->qp_vec), GFP_KERNEL, node); if (!nt->qp_vec) { rc = -ENOMEM; diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index b144c86f5a78..4c0b8e58b2b2 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -2352,7 +2352,8 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (!dev) return -ENOMEM; - dev->queues = kzalloc_node((num_possible_cpus() + 1) * sizeof(struct nvme_queue), + dev->queues = kcalloc_node(num_possible_cpus() + 1, + sizeof(struct nvme_queue), GFP_KERNEL, node); if (!dev->queues) goto free; diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c index 63e3eb55f3ac..805c31b97f20 100644 --- a/drivers/nvmem/rockchip-efuse.c +++ b/drivers/nvmem/rockchip-efuse.c @@ -112,7 +112,8 @@ static int rockchip_rk3399_efuse_read(void *context, unsigned int offset, addr_offset = offset % RK3399_NBYTES; addr_len = addr_end - addr_start; - buf = kzalloc(sizeof(*buf) * addr_len * RK3399_NBYTES, GFP_KERNEL); + buf = kzalloc(array3_size(addr_len, RK3399_NBYTES, sizeof(*buf)), + GFP_KERNEL); if (!buf) { clk_disable_unprepare(efuse->clk); return -ENOMEM; diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c index 0d6648be93b8..0472a9311949 100644 --- a/drivers/nvmem/sunxi_sid.c +++ b/drivers/nvmem/sunxi_sid.c @@ -157,7 +157,7 @@ static int sunxi_sid_probe(struct platform_device *pdev) if (IS_ERR(nvmem)) return PTR_ERR(nvmem); - randomness = kzalloc(sizeof(u8) * (size), GFP_KERNEL); + randomness = kzalloc(size, GFP_KERNEL); if (!randomness) { ret = -EINVAL; goto err_unreg_nvmem; diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 5a4963060b85..ad3b0b691598 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -130,7 +130,7 @@ struct platform_device *of_device_alloc(struct device_node *np, /* Populate the resource table */ if (num_irq || num_reg) { - res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL); + res = kcalloc(num_irq + num_reg, sizeof(*res), GFP_KERNEL); if (!res) { platform_device_put(dev); return NULL; diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 55c98f119df2..ff3253954773 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -155,7 +155,7 @@ static void __init of_unittest_dynamic(void) } /* Array of 4 properties for the purpose of testing */ - prop = kzalloc(sizeof(*prop) * 4, GFP_KERNEL); + prop = kcalloc(4, sizeof(*prop), GFP_KERNEL); if (!prop) { unittest(0, "kzalloc() failed\n"); return; diff --git a/drivers/oprofile/event_buffer.c b/drivers/oprofile/event_buffer.c index 32888f2bd1a9..12ea4a4ad607 100644 --- a/drivers/oprofile/event_buffer.c +++ b/drivers/oprofile/event_buffer.c @@ -91,7 +91,7 @@ int alloc_event_buffer(void) return -EINVAL; buffer_pos = 0; - event_buffer = vmalloc(sizeof(unsigned long) * buffer_size); + event_buffer = vmalloc(array_size(buffer_size, sizeof(unsigned long))); if (!event_buffer) return -ENOMEM; diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c index 2e0d0b29cdcb..7bfb14a8c49c 100644 --- a/drivers/pci/dwc/pci-dra7xx.c +++ b/drivers/pci/dwc/pci-dra7xx.c @@ -649,11 +649,11 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev) return phy_count; } - phy = devm_kzalloc(dev, sizeof(*phy) * phy_count, GFP_KERNEL); + phy = devm_kcalloc(dev, phy_count, sizeof(*phy), GFP_KERNEL); if (!phy) return -ENOMEM; - link = devm_kzalloc(dev, sizeof(*link) * phy_count, GFP_KERNEL); + link = devm_kcalloc(dev, phy_count, sizeof(*link), GFP_KERNEL); if (!link) return -ENOMEM; diff --git a/drivers/pci/dwc/pcie-designware-ep.c b/drivers/pci/dwc/pcie-designware-ep.c index 71795db41261..aea4b15cf16f 100644 --- a/drivers/pci/dwc/pcie-designware-ep.c +++ b/drivers/pci/dwc/pcie-designware-ep.c @@ -315,19 +315,21 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) return -EINVAL; } - ep->ib_window_map = devm_kzalloc(dev, sizeof(long) * + ep->ib_window_map = devm_kcalloc(dev, BITS_TO_LONGS(ep->num_ib_windows), + sizeof(long), GFP_KERNEL); if (!ep->ib_window_map) return -ENOMEM; - ep->ob_window_map = devm_kzalloc(dev, sizeof(long) * + ep->ob_window_map = devm_kcalloc(dev, BITS_TO_LONGS(ep->num_ob_windows), + sizeof(long), GFP_KERNEL); if (!ep->ob_window_map) return -ENOMEM; - addr = devm_kzalloc(dev, sizeof(phys_addr_t) * ep->num_ob_windows, + addr = devm_kcalloc(dev, ep->num_ob_windows, sizeof(phys_addr_t), GFP_KERNEL); if (!addr) return -ENOMEM; diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c index e2c452ceabd2..2a6cbe368546 100644 --- a/drivers/pci/host/pci-msm.c +++ b/drivers/pci/host/pci-msm.c @@ -3578,8 +3578,9 @@ static int msm_pcie_get_resources(struct msm_pcie_dev_t *dev, cnt = of_property_count_elems_of_size((&pdev->dev)->of_node, "max-clock-frequency-hz", sizeof(u32)); if (cnt > 0) { - clkfreq = kzalloc((MSM_PCIE_MAX_CLK + MSM_PCIE_MAX_PIPE_CLK) * - sizeof(*clkfreq), GFP_KERNEL); + clkfreq = kcalloc(MSM_PCIE_MAX_CLK + MSM_PCIE_MAX_PIPE_CLK, + sizeof(*clkfreq), + GFP_KERNEL); if (!clkfreq) { PCIE_ERR(dev, "PCIe: memory alloc failed for RC%d\n", dev->rc_idx); @@ -3775,8 +3776,9 @@ static int msm_pcie_get_resources(struct msm_pcie_dev_t *dev, "iommu-map", (u32 *)map, size / sizeof(u32)); dev->sid_info_len = map_len; - dev->sid_info = devm_kzalloc(&pdev->dev, - dev->sid_info_len * sizeof(*dev->sid_info), GFP_KERNEL); + dev->sid_info = devm_kcalloc(&pdev->dev, + dev->sid_info_len, sizeof(*dev->sid_info), + GFP_KERNEL); if (!dev->sid_info) { devm_kfree(&pdev->dev, map); ret = -ENOMEM; diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 2a203055b16e..39765cc436c8 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -474,7 +474,7 @@ static int populate_msi_sysfs(struct pci_dev *pdev) return 0; /* Dynamically create the MSI attributes for the PCI device */ - msi_attrs = kzalloc(sizeof(void *) * (num_msi + 1), GFP_KERNEL); + msi_attrs = kcalloc(num_msi + 1, sizeof(void *), GFP_KERNEL); if (!msi_attrs) return -ENOMEM; for_each_pci_msi_entry(entry, pdev) { @@ -501,7 +501,7 @@ static int populate_msi_sysfs(struct pci_dev *pdev) msi_irq_group->name = "msi_irqs"; msi_irq_group->attrs = msi_attrs; - msi_irq_groups = kzalloc(sizeof(void *) * 2, GFP_KERNEL); + msi_irq_groups = kcalloc(2, sizeof(void *), GFP_KERNEL); if (!msi_irq_groups) goto error_irq_group; msi_irq_groups[0] = msi_irq_group; diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index ee7dccab771d..9d9b9e6c680a 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -1094,7 +1094,7 @@ void pci_create_legacy_files(struct pci_bus *b) { int error; - b->legacy_io = kzalloc(sizeof(struct bin_attribute) * 2, + b->legacy_io = kcalloc(2, sizeof(struct bin_attribute), GFP_ATOMIC); if (!b->legacy_io) goto kzalloc_err; diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 5f26c170315c..0eb863e15b18 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2086,6 +2086,19 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f1, quirk_disable_aspm_l0s); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f4, quirk_disable_aspm_l0s); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s); +static void quirk_disable_aspm_l0s_l1(struct pci_dev *dev) +{ + pci_info(dev, "Disabling ASPM L0s/L1\n"); + pci_disable_link_state(dev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); +} + +/* + * ASM1083/1085 PCIe-PCI bridge devices cause AER timeout errors on the + * upstream PCIe root port when ASPM is enabled. At least L0s mode is affected; + * disable both L0s and L1 for now to be safe. + */ +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASMEDIA, 0x1080, quirk_disable_aspm_l0s_l1); + /* * Some Pericom PCIe-to-PCI bridges in reverse mode need the PCIe Retrain * Link bit cleared after starting the link retrain process to allow this @@ -4626,6 +4639,7 @@ static const struct pci_dev_acs_enabled { /* QCOM QDF2xxx root ports */ { 0x17cb, 0x400, pci_quirk_qcom_rp_acs }, { 0x17cb, 0x401, pci_quirk_qcom_rp_acs }, + { 0x17cb, 0x10c, pci_quirk_qcom_rp_acs }, /* Intel PCH root ports */ { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_spt_pch_acs }, diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 55ef7d1fd8da..90be9b0a7b76 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -1481,11 +1481,11 @@ static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf, u_char *tuplebuffer; u_char *tempbuffer; - tuplebuffer = kmalloc(sizeof(u_char) * 256, GFP_KERNEL); + tuplebuffer = kmalloc_array(256, sizeof(u_char), GFP_KERNEL); if (!tuplebuffer) return -ENOMEM; - tempbuffer = kmalloc(sizeof(u_char) * 258, GFP_KERNEL); + tempbuffer = kmalloc_array(258, sizeof(u_char), GFP_KERNEL); if (!tempbuffer) { ret = -ENOMEM; goto free_tuple; diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index 0f70b4d58f9e..7fa731cd4ecc 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c @@ -628,7 +628,7 @@ static int pd6729_pci_probe(struct pci_dev *dev, char configbyte; struct pd6729_socket *socket; - socket = kzalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS, + socket = kcalloc(MAX_SOCKETS, sizeof(struct pd6729_socket), GFP_KERNEL); if (!socket) { dev_warn(&dev->dev, "failed to kzalloc socket.\n"); diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index e72bf2502eca..ef60c2cddfc1 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -775,8 +775,8 @@ static int bcm2835_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, maps_per_pin++; if (num_pulls) maps_per_pin++; - cur_map = maps = kzalloc(num_pins * maps_per_pin * sizeof(*maps), - GFP_KERNEL); + cur_map = maps = kcalloc(num_pins * maps_per_pin, sizeof(*maps), + GFP_KERNEL); if (!maps) return -ENOMEM; diff --git a/drivers/pinctrl/berlin/berlin.c b/drivers/pinctrl/berlin/berlin.c index cc3bd2efafe3..df284e9017e4 100644 --- a/drivers/pinctrl/berlin/berlin.c +++ b/drivers/pinctrl/berlin/berlin.c @@ -219,8 +219,9 @@ static int berlin_pinctrl_build_state(struct platform_device *pdev) } /* we will reallocate later */ - pctrl->functions = devm_kzalloc(&pdev->dev, - max_functions * sizeof(*pctrl->functions), + pctrl->functions = devm_kcalloc(&pdev->dev, + max_functions, + sizeof(*pctrl->functions), GFP_KERNEL); if (!pctrl->functions) return -ENOMEM; @@ -264,8 +265,9 @@ static int berlin_pinctrl_build_state(struct platform_device *pdev) if (!function->groups) { function->groups = - devm_kzalloc(&pdev->dev, - function->ngroups * sizeof(char *), + devm_kcalloc(&pdev->dev, + function->ngroups, + sizeof(char *), GFP_KERNEL); if (!function->groups) diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c index ec0119e1e781..2291cc38edcc 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx.c +++ b/drivers/pinctrl/freescale/pinctrl-imx.c @@ -87,7 +87,8 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev, map_num++; } - new_map = kmalloc(sizeof(struct pinctrl_map) * map_num, GFP_KERNEL); + new_map = kmalloc_array(map_num, sizeof(struct pinctrl_map), + GFP_KERNEL); if (!new_map) return -ENOMEM; @@ -476,10 +477,12 @@ static int imx_pinctrl_parse_groups(struct device_node *np, config = imx_pinconf_parse_generic_config(np, ipctl); grp->num_pins = size / pin_size; - grp->data = devm_kzalloc(info->dev, grp->num_pins * - sizeof(struct imx_pin), GFP_KERNEL); - grp->pins = devm_kzalloc(info->dev, grp->num_pins * - sizeof(unsigned int), GFP_KERNEL); + grp->data = devm_kcalloc(info->dev, + grp->num_pins, sizeof(struct imx_pin), + GFP_KERNEL); + grp->pins = devm_kcalloc(info->dev, + grp->num_pins, sizeof(unsigned int), + GFP_KERNEL); if (!grp->pins || !grp->data) return -ENOMEM; @@ -690,8 +693,9 @@ int imx_pinctrl_probe(struct platform_device *pdev, if (!ipctl) return -ENOMEM; - info->pin_regs = devm_kmalloc(&pdev->dev, sizeof(*info->pin_regs) * - info->npins, GFP_KERNEL); + info->pin_regs = devm_kmalloc_array(&pdev->dev, + info->npins, sizeof(*info->pin_regs), + GFP_KERNEL); if (!info->pin_regs) return -ENOMEM; diff --git a/drivers/pinctrl/freescale/pinctrl-imx1-core.c b/drivers/pinctrl/freescale/pinctrl-imx1-core.c index 68108c4c3969..e423d58d57f7 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx1-core.c +++ b/drivers/pinctrl/freescale/pinctrl-imx1-core.c @@ -246,7 +246,8 @@ static int imx1_dt_node_to_map(struct pinctrl_dev *pctldev, for (i = 0; i < grp->npins; i++) map_num++; - new_map = kmalloc(sizeof(struct pinctrl_map) * map_num, GFP_KERNEL); + new_map = kmalloc_array(map_num, sizeof(struct pinctrl_map), + GFP_KERNEL); if (!new_map) return -ENOMEM; @@ -487,10 +488,10 @@ static int imx1_pinctrl_parse_groups(struct device_node *np, } grp->npins = size / 12; - grp->pins = devm_kzalloc(info->dev, - grp->npins * sizeof(struct imx1_pin), GFP_KERNEL); - grp->pin_ids = devm_kzalloc(info->dev, - grp->npins * sizeof(unsigned int), GFP_KERNEL); + grp->pins = devm_kcalloc(info->dev, + grp->npins, sizeof(struct imx1_pin), GFP_KERNEL); + grp->pin_ids = devm_kcalloc(info->dev, + grp->npins, sizeof(unsigned int), GFP_KERNEL); if (!grp->pins || !grp->pin_ids) return -ENOMEM; @@ -527,8 +528,8 @@ static int imx1_pinctrl_parse_functions(struct device_node *np, if (func->num_groups == 0) return -EINVAL; - func->groups = devm_kzalloc(info->dev, - func->num_groups * sizeof(char *), GFP_KERNEL); + func->groups = devm_kcalloc(info->dev, + func->num_groups, sizeof(char *), GFP_KERNEL); if (!func->groups) return -ENOMEM; @@ -570,12 +571,12 @@ static int imx1_pinctrl_parse_dt(struct platform_device *pdev, } info->nfunctions = nfuncs; - info->functions = devm_kzalloc(&pdev->dev, - nfuncs * sizeof(struct imx1_pmx_func), GFP_KERNEL); + info->functions = devm_kcalloc(&pdev->dev, + nfuncs, sizeof(struct imx1_pmx_func), GFP_KERNEL); info->ngroups = ngroups; - info->groups = devm_kzalloc(&pdev->dev, - ngroups * sizeof(struct imx1_pin_group), GFP_KERNEL); + info->groups = devm_kcalloc(&pdev->dev, + ngroups, sizeof(struct imx1_pin_group), GFP_KERNEL); if (!info->functions || !info->groups) diff --git a/drivers/pinctrl/freescale/pinctrl-mxs.c b/drivers/pinctrl/freescale/pinctrl-mxs.c index 6852010a6d70..1286fdab8632 100644 --- a/drivers/pinctrl/freescale/pinctrl-mxs.c +++ b/drivers/pinctrl/freescale/pinctrl-mxs.c @@ -96,7 +96,7 @@ static int mxs_dt_node_to_map(struct pinctrl_dev *pctldev, if (!purecfg && config) new_num = 2; - new_map = kzalloc(sizeof(*new_map) * new_num, GFP_KERNEL); + new_map = kcalloc(new_num, sizeof(*new_map), GFP_KERNEL); if (!new_map) return -ENOMEM; @@ -377,12 +377,12 @@ static int mxs_pinctrl_parse_group(struct platform_device *pdev, return -EINVAL; g->npins = length / sizeof(u32); - g->pins = devm_kzalloc(&pdev->dev, g->npins * sizeof(*g->pins), + g->pins = devm_kcalloc(&pdev->dev, g->npins, sizeof(*g->pins), GFP_KERNEL); if (!g->pins) return -ENOMEM; - g->muxsel = devm_kzalloc(&pdev->dev, g->npins * sizeof(*g->muxsel), + g->muxsel = devm_kcalloc(&pdev->dev, g->npins, sizeof(*g->muxsel), GFP_KERNEL); if (!g->muxsel) return -ENOMEM; @@ -433,13 +433,16 @@ static int mxs_pinctrl_probe_dt(struct platform_device *pdev, } } - soc->functions = devm_kzalloc(&pdev->dev, soc->nfunctions * - sizeof(*soc->functions), GFP_KERNEL); + soc->functions = devm_kcalloc(&pdev->dev, + soc->nfunctions, + sizeof(*soc->functions), + GFP_KERNEL); if (!soc->functions) return -ENOMEM; - soc->groups = devm_kzalloc(&pdev->dev, soc->ngroups * - sizeof(*soc->groups), GFP_KERNEL); + soc->groups = devm_kcalloc(&pdev->dev, + soc->ngroups, sizeof(*soc->groups), + GFP_KERNEL); if (!soc->groups) return -ENOMEM; @@ -499,7 +502,8 @@ static int mxs_pinctrl_probe_dt(struct platform_device *pdev, if (strcmp(fn, child->name)) { f = &soc->functions[idxf++]; - f->groups = devm_kzalloc(&pdev->dev, f->ngroups * + f->groups = devm_kcalloc(&pdev->dev, + f->ngroups, sizeof(*f->groups), GFP_KERNEL); if (!f->groups) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index 262f591ad8a6..fc00aa4cd982 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -806,9 +806,10 @@ static int armada_37xx_fill_group(struct armada_37xx_pinctrl *info) struct armada_37xx_pin_group *grp = &info->groups[n]; int i, j, f; - grp->pins = devm_kzalloc(info->dev, - (grp->npins + grp->extra_npins) * - sizeof(*grp->pins), GFP_KERNEL); + grp->pins = devm_kcalloc(info->dev, + grp->npins + grp->extra_npins, + sizeof(*grp->pins), + GFP_KERNEL); if (!grp->pins) return -ENOMEM; @@ -858,7 +859,8 @@ static int armada_37xx_fill_func(struct armada_37xx_pinctrl *info) const char **groups; int g; - funcs[n].groups = devm_kzalloc(info->dev, funcs[n].ngroups * + funcs[n].groups = devm_kcalloc(info->dev, + funcs[n].ngroups, sizeof(*(funcs[n].groups)), GFP_KERNEL); if (!funcs[n].groups) @@ -898,8 +900,9 @@ static int armada_37xx_pinctrl_register(struct platform_device *pdev, ctrldesc->pmxops = &armada_37xx_pmx_ops; ctrldesc->confops = &armada_37xx_pinconf_ops; - pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) * - pin_data->nr_pins, GFP_KERNEL); + pindesc = devm_kcalloc(&pdev->dev, + pin_data->nr_pins, sizeof(*pindesc), + GFP_KERNEL); if (!pindesc) return -ENOMEM; @@ -918,8 +921,10 @@ static int armada_37xx_pinctrl_register(struct platform_device *pdev, * we allocate functions for number of pins and hope there are * fewer unique functions than pins available */ - info->funcs = devm_kzalloc(&pdev->dev, pin_data->nr_pins * - sizeof(struct armada_37xx_pmx_func), GFP_KERNEL); + info->funcs = devm_kcalloc(&pdev->dev, + pin_data->nr_pins, + sizeof(struct armada_37xx_pmx_func), + GFP_KERNEL); if (!info->funcs) return -ENOMEM; diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c index b854f1ee5de5..924de31ca133 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c @@ -630,8 +630,8 @@ static int armada_xp_pinctrl_probe(struct platform_device *pdev) nregs = DIV_ROUND_UP(soc->nmodes, MVEBU_MPPS_PER_REG); - mpp_saved_regs = devm_kmalloc(&pdev->dev, nregs * sizeof(u32), - GFP_KERNEL); + mpp_saved_regs = devm_kmalloc_array(&pdev->dev, nregs, sizeof(u32), + GFP_KERNEL); if (!mpp_saved_regs) return -ENOMEM; diff --git a/drivers/pinctrl/mvebu/pinctrl-mvebu.c b/drivers/pinctrl/mvebu/pinctrl-mvebu.c index 163d4614b0f8..30bb9f7117bb 100644 --- a/drivers/pinctrl/mvebu/pinctrl-mvebu.c +++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.c @@ -501,8 +501,9 @@ static int mvebu_pinctrl_build_functions(struct platform_device *pdev, /* we allocate functions for number of pins and hope * there are fewer unique functions than pins available */ - funcs = devm_kzalloc(&pdev->dev, funcsize * - sizeof(struct mvebu_pinctrl_function), GFP_KERNEL); + funcs = devm_kcalloc(&pdev->dev, + funcsize, sizeof(struct mvebu_pinctrl_function), + GFP_KERNEL); if (!funcs) return -ENOMEM; @@ -549,8 +550,9 @@ static int mvebu_pinctrl_build_functions(struct platform_device *pdev, /* allocate group name array if not done already */ if (!f->groups) { - f->groups = devm_kzalloc(&pdev->dev, - f->num_groups * sizeof(char *), + f->groups = devm_kcalloc(&pdev->dev, + f->num_groups, + sizeof(char *), GFP_KERNEL); if (!f->groups) return -ENOMEM; @@ -622,8 +624,10 @@ int mvebu_pinctrl_probe(struct platform_device *pdev) } } - pdesc = devm_kzalloc(&pdev->dev, pctl->desc.npins * - sizeof(struct pinctrl_pin_desc), GFP_KERNEL); + pdesc = devm_kcalloc(&pdev->dev, + pctl->desc.npins, + sizeof(struct pinctrl_pin_desc), + GFP_KERNEL); if (!pdesc) return -ENOMEM; diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c index e9d797707255..abb1c853001e 100644 --- a/drivers/pinctrl/pinctrl-at91-pio4.c +++ b/drivers/pinctrl/pinctrl-at91-pio4.c @@ -941,27 +941,30 @@ static int atmel_pinctrl_probe(struct platform_device *pdev) return PTR_ERR(atmel_pioctrl->clk); } - atmel_pioctrl->pins = devm_kzalloc(dev, sizeof(*atmel_pioctrl->pins) - * atmel_pioctrl->npins, GFP_KERNEL); + atmel_pioctrl->pins = devm_kcalloc(dev, + atmel_pioctrl->npins, + sizeof(*atmel_pioctrl->pins), + GFP_KERNEL); if (!atmel_pioctrl->pins) return -ENOMEM; - pin_desc = devm_kzalloc(dev, sizeof(*pin_desc) - * atmel_pioctrl->npins, GFP_KERNEL); + pin_desc = devm_kcalloc(dev, atmel_pioctrl->npins, sizeof(*pin_desc), + GFP_KERNEL); if (!pin_desc) return -ENOMEM; atmel_pinctrl_desc.pins = pin_desc; atmel_pinctrl_desc.npins = atmel_pioctrl->npins; /* One pin is one group since a pin can achieve all functions. */ - group_names = devm_kzalloc(dev, sizeof(*group_names) - * atmel_pioctrl->npins, GFP_KERNEL); + group_names = devm_kcalloc(dev, + atmel_pioctrl->npins, sizeof(*group_names), + GFP_KERNEL); if (!group_names) return -ENOMEM; atmel_pioctrl->group_names = group_names; - atmel_pioctrl->groups = devm_kzalloc(&pdev->dev, - sizeof(*atmel_pioctrl->groups) * atmel_pioctrl->npins, + atmel_pioctrl->groups = devm_kcalloc(&pdev->dev, + atmel_pioctrl->npins, sizeof(*atmel_pioctrl->groups), GFP_KERNEL); if (!atmel_pioctrl->groups) return -ENOMEM; @@ -997,20 +1000,24 @@ static int atmel_pinctrl_probe(struct platform_device *pdev) atmel_pioctrl->gpio_chip->parent = dev; atmel_pioctrl->gpio_chip->names = atmel_pioctrl->group_names; - atmel_pioctrl->pm_wakeup_sources = devm_kzalloc(dev, - sizeof(*atmel_pioctrl->pm_wakeup_sources) - * atmel_pioctrl->nbanks, GFP_KERNEL); + atmel_pioctrl->pm_wakeup_sources = devm_kcalloc(dev, + atmel_pioctrl->nbanks, + sizeof(*atmel_pioctrl->pm_wakeup_sources), + GFP_KERNEL); if (!atmel_pioctrl->pm_wakeup_sources) return -ENOMEM; - atmel_pioctrl->pm_suspend_backup = devm_kzalloc(dev, - sizeof(*atmel_pioctrl->pm_suspend_backup) - * atmel_pioctrl->nbanks, GFP_KERNEL); + atmel_pioctrl->pm_suspend_backup = devm_kcalloc(dev, + atmel_pioctrl->nbanks, + sizeof(*atmel_pioctrl->pm_suspend_backup), + GFP_KERNEL); if (!atmel_pioctrl->pm_suspend_backup) return -ENOMEM; - atmel_pioctrl->irqs = devm_kzalloc(dev, sizeof(*atmel_pioctrl->irqs) - * atmel_pioctrl->nbanks, GFP_KERNEL); + atmel_pioctrl->irqs = devm_kcalloc(dev, + atmel_pioctrl->nbanks, + sizeof(*atmel_pioctrl->irqs), + GFP_KERNEL); if (!atmel_pioctrl->irqs) return -ENOMEM; diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 404711f0985a..2311eb8ce8c7 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -269,7 +269,8 @@ static int at91_dt_node_to_map(struct pinctrl_dev *pctldev, } map_num += grp->npins; - new_map = devm_kzalloc(pctldev->dev, sizeof(*new_map) * map_num, GFP_KERNEL); + new_map = devm_kcalloc(pctldev->dev, map_num, sizeof(*new_map), + GFP_KERNEL); if (!new_map) return -ENOMEM; @@ -1049,7 +1050,8 @@ static int at91_pinctrl_mux_mask(struct at91_pinctrl *info, } info->nmux = size / gpio_banks; - info->mux_mask = devm_kzalloc(info->dev, sizeof(u32) * size, GFP_KERNEL); + info->mux_mask = devm_kcalloc(info->dev, size, sizeof(u32), + GFP_KERNEL); if (!info->mux_mask) { dev_err(info->dev, "could not alloc mux_mask\n"); return -ENOMEM; @@ -1089,10 +1091,12 @@ static int at91_pinctrl_parse_groups(struct device_node *np, } grp->npins = size / 4; - pin = grp->pins_conf = devm_kzalloc(info->dev, grp->npins * sizeof(struct at91_pmx_pin), - GFP_KERNEL); - grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), - GFP_KERNEL); + pin = grp->pins_conf = devm_kcalloc(info->dev, + grp->npins, + sizeof(struct at91_pmx_pin), + GFP_KERNEL); + grp->pins = devm_kcalloc(info->dev, grp->npins, sizeof(unsigned int), + GFP_KERNEL); if (!grp->pins_conf || !grp->pins) return -ENOMEM; @@ -1131,8 +1135,8 @@ static int at91_pinctrl_parse_functions(struct device_node *np, dev_err(info->dev, "no groups defined\n"); return -EINVAL; } - func->groups = devm_kzalloc(info->dev, - func->ngroups * sizeof(char *), GFP_KERNEL); + func->groups = devm_kcalloc(info->dev, + func->ngroups, sizeof(char *), GFP_KERNEL); if (!func->groups) return -ENOMEM; @@ -1194,12 +1198,16 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev, dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions); dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups); - info->functions = devm_kzalloc(&pdev->dev, info->nfunctions * sizeof(struct at91_pmx_func), + info->functions = devm_kcalloc(&pdev->dev, + info->nfunctions, + sizeof(struct at91_pmx_func), GFP_KERNEL); if (!info->functions) return -ENOMEM; - info->groups = devm_kzalloc(&pdev->dev, info->ngroups * sizeof(struct at91_pin_group), + info->groups = devm_kcalloc(&pdev->dev, + info->ngroups, + sizeof(struct at91_pin_group), GFP_KERNEL); if (!info->groups) return -ENOMEM; @@ -1258,7 +1266,9 @@ static int at91_pinctrl_probe(struct platform_device *pdev) at91_pinctrl_desc.name = dev_name(&pdev->dev); at91_pinctrl_desc.npins = gpio_banks * MAX_NB_GPIO_PER_BANK; at91_pinctrl_desc.pins = pdesc = - devm_kzalloc(&pdev->dev, sizeof(*pdesc) * at91_pinctrl_desc.npins, GFP_KERNEL); + devm_kcalloc(&pdev->dev, + at91_pinctrl_desc.npins, sizeof(*pdesc), + GFP_KERNEL); if (!at91_pinctrl_desc.pins) return -ENOMEM; @@ -1765,7 +1775,7 @@ static int at91_gpio_probe(struct platform_device *pdev) chip->ngpio = ngpio; } - names = devm_kzalloc(&pdev->dev, sizeof(char *) * chip->ngpio, + names = devm_kcalloc(&pdev->dev, chip->ngpio, sizeof(char *), GFP_KERNEL); if (!names) { diff --git a/drivers/pinctrl/pinctrl-digicolor.c b/drivers/pinctrl/pinctrl-digicolor.c index ce269ced4d49..5353b23f775c 100644 --- a/drivers/pinctrl/pinctrl-digicolor.c +++ b/drivers/pinctrl/pinctrl-digicolor.c @@ -291,10 +291,11 @@ static int dc_pinctrl_probe(struct platform_device *pdev) if (IS_ERR(pmap->regs)) return PTR_ERR(pmap->regs); - pins = devm_kzalloc(&pdev->dev, sizeof(*pins)*PINS_COUNT, GFP_KERNEL); + pins = devm_kcalloc(&pdev->dev, PINS_COUNT, sizeof(*pins), + GFP_KERNEL); if (!pins) return -ENOMEM; - pin_names = devm_kzalloc(&pdev->dev, name_len * PINS_COUNT, + pin_names = devm_kcalloc(&pdev->dev, PINS_COUNT, name_len, GFP_KERNEL); if (!pin_names) return -ENOMEM; diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 1541f8cba556..47b1d65f9867 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -772,8 +772,8 @@ int ingenic_pinctrl_probe(struct platform_device *pdev) pctl_desc->pmxops = &ingenic_pmxops; pctl_desc->confops = &ingenic_confops; pctl_desc->npins = chip_info->num_chips * PINS_PER_GPIO_CHIP; - pctl_desc->pins = jzpc->pdesc = devm_kzalloc(&pdev->dev, - sizeof(*jzpc->pdesc) * pctl_desc->npins, GFP_KERNEL); + pctl_desc->pins = jzpc->pdesc = devm_kcalloc(&pdev->dev, + pctl_desc->npins, sizeof(*jzpc->pdesc), GFP_KERNEL); if (!jzpc->pdesc) return -ENOMEM; diff --git a/drivers/pinctrl/pinctrl-lantiq.c b/drivers/pinctrl/pinctrl-lantiq.c index 41dc39c7a7b1..81632af3a86a 100644 --- a/drivers/pinctrl/pinctrl-lantiq.c +++ b/drivers/pinctrl/pinctrl-lantiq.c @@ -158,7 +158,8 @@ static int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, for_each_child_of_node(np_config, np) max_maps += ltq_pinctrl_dt_subnode_size(np); - *map = kzalloc(max_maps * sizeof(struct pinctrl_map) * 2, GFP_KERNEL); + *map = kzalloc(array3_size(max_maps, sizeof(struct pinctrl_map), 2), + GFP_KERNEL); if (!*map) return -ENOMEM; tmp = *map; diff --git a/drivers/pinctrl/pinctrl-lpc18xx.c b/drivers/pinctrl/pinctrl-lpc18xx.c index 8b4e3582af6e..1d3b88e6ab86 100644 --- a/drivers/pinctrl/pinctrl-lpc18xx.c +++ b/drivers/pinctrl/pinctrl-lpc18xx.c @@ -1302,8 +1302,9 @@ static int lpc18xx_create_group_func_map(struct device *dev, } scu->func[func].ngroups = ngroups; - scu->func[func].groups = devm_kzalloc(dev, ngroups * - sizeof(char *), GFP_KERNEL); + scu->func[func].groups = devm_kcalloc(dev, + ngroups, sizeof(char *), + GFP_KERNEL); if (!scu->func[func].groups) return -ENOMEM; diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 5d6cf024ee9c..53cb6c579266 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -506,7 +506,7 @@ static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev, } map_num += grp->npins; - new_map = devm_kzalloc(pctldev->dev, sizeof(*new_map) * map_num, + new_map = devm_kcalloc(pctldev->dev, map_num, sizeof(*new_map), GFP_KERNEL); if (!new_map) return -ENOMEM; @@ -2293,10 +2293,11 @@ static int rockchip_pinctrl_parse_groups(struct device_node *np, grp->npins = size / 4; - grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), + grp->pins = devm_kcalloc(info->dev, grp->npins, sizeof(unsigned int), GFP_KERNEL); - grp->data = devm_kzalloc(info->dev, grp->npins * - sizeof(struct rockchip_pin_config), + grp->data = devm_kcalloc(info->dev, + grp->npins, + sizeof(struct rockchip_pin_config), GFP_KERNEL); if (!grp->pins || !grp->data) return -ENOMEM; @@ -2348,8 +2349,8 @@ static int rockchip_pinctrl_parse_functions(struct device_node *np, if (func->ngroups <= 0) return 0; - func->groups = devm_kzalloc(info->dev, - func->ngroups * sizeof(char *), GFP_KERNEL); + func->groups = devm_kcalloc(info->dev, + func->ngroups, sizeof(char *), GFP_KERNEL); if (!func->groups) return -ENOMEM; @@ -2380,7 +2381,8 @@ static int rockchip_pinctrl_parse_dt(struct platform_device *pdev, dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions); dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups); - info->functions = devm_kzalloc(dev, info->nfunctions * + info->functions = devm_kcalloc(dev, + info->nfunctions, sizeof(struct rockchip_pmx_func), GFP_KERNEL); if (!info->functions) { @@ -2388,7 +2390,8 @@ static int rockchip_pinctrl_parse_dt(struct platform_device *pdev, return -EINVAL; } - info->groups = devm_kzalloc(dev, info->ngroups * + info->groups = devm_kcalloc(dev, + info->ngroups, sizeof(struct rockchip_pin_group), GFP_KERNEL); if (!info->groups) { @@ -2428,8 +2431,9 @@ static int rockchip_pinctrl_register(struct platform_device *pdev, ctrldesc->pmxops = &rockchip_pmx_ops; ctrldesc->confops = &rockchip_pinconf_ops; - pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) * - info->ctrl->nr_pins, GFP_KERNEL); + pindesc = devm_kcalloc(&pdev->dev, + info->ctrl->nr_pins, sizeof(*pindesc), + GFP_KERNEL); if (!pindesc) { dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n"); return -ENOMEM; diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index b8b3d932cd73..7c00775af758 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -690,8 +690,8 @@ static int pcs_allocate_pin_table(struct pcs_device *pcs) } dev_dbg(pcs->dev, "allocating %i pins\n", nr_pins); - pcs->pins.pa = devm_kzalloc(pcs->dev, - sizeof(*pcs->pins.pa) * nr_pins, + pcs->pins.pa = devm_kcalloc(pcs->dev, + nr_pins, sizeof(*pcs->pins.pa), GFP_KERNEL); if (!pcs->pins.pa) return -ENOMEM; @@ -902,15 +902,15 @@ static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np, if (!nconfs) return 0; - func->conf = devm_kzalloc(pcs->dev, - sizeof(struct pcs_conf_vals) * nconfs, + func->conf = devm_kcalloc(pcs->dev, + nconfs, sizeof(struct pcs_conf_vals), GFP_KERNEL); if (!func->conf) return -ENOMEM; func->nconfs = nconfs; conf = &(func->conf[0]); m++; - settings = devm_kzalloc(pcs->dev, sizeof(unsigned long) * nconfs, + settings = devm_kcalloc(pcs->dev, nconfs, sizeof(unsigned long), GFP_KERNEL); if (!settings) return -ENOMEM; @@ -966,11 +966,11 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs, return -EINVAL; } - vals = devm_kzalloc(pcs->dev, sizeof(*vals) * rows, GFP_KERNEL); + vals = devm_kcalloc(pcs->dev, rows, sizeof(*vals), GFP_KERNEL); if (!vals) return -ENOMEM; - pins = devm_kzalloc(pcs->dev, sizeof(*pins) * rows, GFP_KERNEL); + pins = devm_kcalloc(pcs->dev, rows, sizeof(*pins), GFP_KERNEL); if (!pins) goto free_vals; @@ -1067,13 +1067,15 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs, npins_in_row = pcs->width / pcs->bits_per_pin; - vals = devm_kzalloc(pcs->dev, sizeof(*vals) * rows * npins_in_row, - GFP_KERNEL); + vals = devm_kzalloc(pcs->dev, + array3_size(rows, npins_in_row, sizeof(*vals)), + GFP_KERNEL); if (!vals) return -ENOMEM; - pins = devm_kzalloc(pcs->dev, sizeof(*pins) * rows * npins_in_row, - GFP_KERNEL); + pins = devm_kzalloc(pcs->dev, + array3_size(rows, npins_in_row, sizeof(*pins)), + GFP_KERNEL); if (!pins) goto free_vals; @@ -1195,7 +1197,7 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev, pcs = pinctrl_dev_get_drvdata(pctldev); /* create 2 maps. One is for pinmux, and the other is for pinconf. */ - *map = devm_kzalloc(pcs->dev, sizeof(**map) * 2, GFP_KERNEL); + *map = devm_kcalloc(pcs->dev, 2, sizeof(**map), GFP_KERNEL); if (!*map) return -ENOMEM; diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c index a5205b94b2e6..6988935e8ded 100644 --- a/drivers/pinctrl/pinctrl-st.c +++ b/drivers/pinctrl/pinctrl-st.c @@ -823,8 +823,8 @@ static int st_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, } map_num = grp->npins + 1; - new_map = devm_kzalloc(pctldev->dev, - sizeof(*new_map) * map_num, GFP_KERNEL); + new_map = devm_kcalloc(pctldev->dev, + map_num, sizeof(*new_map), GFP_KERNEL); if (!new_map) return -ENOMEM; @@ -1191,9 +1191,9 @@ static int st_pctl_dt_parse_groups(struct device_node *np, grp->npins = npins; grp->name = np->name; - grp->pins = devm_kzalloc(info->dev, npins * sizeof(u32), GFP_KERNEL); - grp->pin_conf = devm_kzalloc(info->dev, - npins * sizeof(*conf), GFP_KERNEL); + grp->pins = devm_kcalloc(info->dev, npins, sizeof(u32), GFP_KERNEL); + grp->pin_conf = devm_kcalloc(info->dev, + npins, sizeof(*conf), GFP_KERNEL); if (!grp->pins || !grp->pin_conf) return -ENOMEM; @@ -1249,8 +1249,8 @@ static int st_pctl_parse_functions(struct device_node *np, dev_err(info->dev, "No groups defined\n"); return -EINVAL; } - func->groups = devm_kzalloc(info->dev, - func->ngroups * sizeof(char *), GFP_KERNEL); + func->groups = devm_kcalloc(info->dev, + func->ngroups, sizeof(char *), GFP_KERNEL); if (!func->groups) return -ENOMEM; @@ -1573,14 +1573,15 @@ static int st_pctl_probe_dt(struct platform_device *pdev, dev_info(&pdev->dev, "nfunctions = %d\n", info->nfunctions); dev_info(&pdev->dev, "ngroups = %d\n", info->ngroups); - info->functions = devm_kzalloc(&pdev->dev, - info->nfunctions * sizeof(*info->functions), GFP_KERNEL); + info->functions = devm_kcalloc(&pdev->dev, + info->nfunctions, sizeof(*info->functions), GFP_KERNEL); - info->groups = devm_kzalloc(&pdev->dev, - info->ngroups * sizeof(*info->groups) , GFP_KERNEL); + info->groups = devm_kcalloc(&pdev->dev, + info->ngroups, sizeof(*info->groups), + GFP_KERNEL); - info->banks = devm_kzalloc(&pdev->dev, - info->nbanks * sizeof(*info->banks), GFP_KERNEL); + info->banks = devm_kcalloc(&pdev->dev, + info->nbanks, sizeof(*info->banks), GFP_KERNEL); if (!info->functions || !info->groups || !info->banks) return -ENOMEM; @@ -1608,8 +1609,8 @@ static int st_pctl_probe_dt(struct platform_device *pdev, } pctl_desc->npins = info->nbanks * ST_GPIO_PINS_PER_BANK; - pdesc = devm_kzalloc(&pdev->dev, - sizeof(*pdesc) * pctl_desc->npins, GFP_KERNEL); + pdesc = devm_kcalloc(&pdev->dev, + pctl_desc->npins, sizeof(*pdesc), GFP_KERNEL); if (!pdesc) return -ENOMEM; diff --git a/drivers/pinctrl/pinctrl-sx150x.c b/drivers/pinctrl/pinctrl-sx150x.c index 75d5a096676d..8d28839de8a0 100644 --- a/drivers/pinctrl/pinctrl-sx150x.c +++ b/drivers/pinctrl/pinctrl-sx150x.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. * * Copyright (c) 2016, BayLibre, SAS. All rights reserved. * Author: Neil Armstrong @@ -40,6 +40,9 @@ #include "pinconf.h" #include "pinctrl-utils.h" +static bool in_kexec_panic; +static struct notifier_block *panic_block; + /* The chip models of sx150x */ enum { SX150X_123 = 0, @@ -581,6 +584,14 @@ static void sx150x_irq_bus_sync_unlock(struct irq_data *d) struct sx150x_pinctrl *pctl = gpiochip_get_data(irq_data_get_irq_chip_data(d)); + /* In crash kexec panic path interrupt is disabled. + * Writing to regmap will need interrupt/polling mode, + * as it goes though i2c. + */ + if (in_kexec_panic) { + mutex_unlock(&pctl->lock); + return; + } regmap_write(pctl->regmap, pctl->data->reg_irq_mask, pctl->irq.masked); regmap_write(pctl->regmap, pctl->data->reg_sense, pctl->irq.sense); mutex_unlock(&pctl->lock); @@ -1102,6 +1113,14 @@ const struct regmap_config sx150x_regmap_config = { .volatile_reg = sx150x_reg_volatile, }; +static int sx150x_panic_handler(struct notifier_block *this, + unsigned long event, void *ptr) +{ + if (crash_kexec_post_notifiers) + in_kexec_panic = 1; + return NOTIFY_DONE; +} + static int sx150x_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -1301,6 +1320,12 @@ static struct i2c_driver sx150x_driver = { static int __init sx150x_init(void) { + panic_block = kzalloc(sizeof(*panic_block), GFP_KERNEL); + if (!panic_block) + return -ENOMEM; + panic_block->notifier_call = sx150x_panic_handler; + atomic_notifier_chain_register(&panic_notifier_list, + panic_block); return i2c_add_driver(&sx150x_driver); } subsys_initcall(sx150x_init); diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c index 1b0c5958c56a..ea65b0041f7e 100644 --- a/drivers/pinctrl/pinctrl-xway.c +++ b/drivers/pinctrl/pinctrl-xway.c @@ -1727,8 +1727,8 @@ static int pinmux_xway_probe(struct platform_device *pdev) xway_chip.ngpio = xway_soc->pin_count; /* load our pad descriptors */ - xway_info.pads = devm_kzalloc(&pdev->dev, - sizeof(struct pinctrl_pin_desc) * xway_chip.ngpio, + xway_info.pads = devm_kcalloc(&pdev->dev, + xway_chip.ngpio, sizeof(struct pinctrl_pin_desc), GFP_KERNEL); if (!xway_info.pads) { dev_err(&pdev->dev, "Failed to allocate pads\n"); diff --git a/drivers/pinctrl/qcom/pinctrl-sm6150.c b/drivers/pinctrl/qcom/pinctrl-sm6150.c index ba2237ed1e1d..b0d685dbd6f2 100644 --- a/drivers/pinctrl/qcom/pinctrl-sm6150.c +++ b/drivers/pinctrl/qcom/pinctrl-sm6150.c @@ -1684,8 +1684,9 @@ static int sm6150_pinctrl_dir_conn_probe(struct platform_device *pdev) dir_conn_length = length / sizeof(u32); - dir_conn_entries = devm_kzalloc(&pdev->dev, - dir_conn_length*sizeof(uint32_t), GFP_KERNEL); + dir_conn_entries = devm_kcalloc(&pdev->dev, + dir_conn_length, sizeof(uint32_t), + GFP_KERNEL); if (!dir_conn_entries) return -ENOMEM; @@ -1700,8 +1701,8 @@ static int sm6150_pinctrl_dir_conn_probe(struct platform_device *pdev) num_dir_conns = (dir_conn_length / 3); - dir_conn_list = devm_kzalloc(&pdev->dev, - num_dir_conns * sizeof(*dir_conn_list), GFP_KERNEL); + dir_conn_list = devm_kcalloc(&pdev->dev, + num_dir_conns, sizeof(*dir_conn_list), GFP_KERNEL); if (!dir_conn_list) return -ENOMEM; diff --git a/drivers/pinctrl/qcom/pinctrl-sm8150.c b/drivers/pinctrl/qcom/pinctrl-sm8150.c index b25777617a30..b1baff68e334 100644 --- a/drivers/pinctrl/qcom/pinctrl-sm8150.c +++ b/drivers/pinctrl/qcom/pinctrl-sm8150.c @@ -1985,8 +1985,9 @@ static int sm8150_pinctrl_dir_conn_probe(struct platform_device *pdev) dir_conn_length = length / sizeof(u32); - dir_conn_entries = devm_kzalloc(&pdev->dev, - dir_conn_length*sizeof(uint32_t), GFP_KERNEL); + dir_conn_entries = devm_kcalloc(&pdev->dev, + dir_conn_length, sizeof(uint32_t), + GFP_KERNEL); if (!dir_conn_entries) return -ENOMEM; @@ -1995,8 +1996,8 @@ static int sm8150_pinctrl_dir_conn_probe(struct platform_device *pdev) num_dir_conns = (dir_conn_length / 3); - dir_conn_list = devm_kzalloc(&pdev->dev, - num_dir_conns * sizeof(*dir_conn_list), GFP_KERNEL); + dir_conn_list = devm_kcalloc(&pdev->dev, + num_dir_conns, sizeof(*dir_conn_list), GFP_KERNEL); if (!dir_conn_list) return -ENOMEM; diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 6925a3d969e2..6e93478027e4 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -499,8 +499,9 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) continue; } - weint_data = devm_kzalloc(dev, bank->nr_pins - * sizeof(*weint_data), GFP_KERNEL); + weint_data = devm_kcalloc(dev, + bank->nr_pins, sizeof(*weint_data), + GFP_KERNEL); if (!weint_data) return -ENOMEM; diff --git a/drivers/pinctrl/samsung/pinctrl-exynos5440.c b/drivers/pinctrl/samsung/pinctrl-exynos5440.c index 32a3a9fd65c4..cf5e066008a4 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos5440.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos5440.c @@ -206,7 +206,7 @@ static int exynos5440_dt_node_to_map(struct pinctrl_dev *pctldev, } /* Allocate memory for pin-map entries */ - map = kzalloc(sizeof(*map) * map_cnt, GFP_KERNEL); + map = kcalloc(map_cnt, sizeof(*map), GFP_KERNEL); if (!map) return -ENOMEM; *nmaps = 0; @@ -227,7 +227,7 @@ static int exynos5440_dt_node_to_map(struct pinctrl_dev *pctldev, goto skip_cfgs; /* Allocate memory for config entries */ - cfg = kzalloc(sizeof(*cfg) * cfg_cnt, GFP_KERNEL); + cfg = kcalloc(cfg_cnt, sizeof(*cfg), GFP_KERNEL); if (!cfg) goto free_gname; @@ -642,7 +642,7 @@ static int exynos5440_pinctrl_parse_dt_pins(struct platform_device *pdev, return -EINVAL; } - *pin_list = devm_kzalloc(dev, *npins * sizeof(**pin_list), GFP_KERNEL); + *pin_list = devm_kcalloc(dev, *npins, sizeof(**pin_list), GFP_KERNEL); if (!*pin_list) return -ENOMEM; @@ -671,13 +671,14 @@ static int exynos5440_pinctrl_parse_dt(struct platform_device *pdev, if (!grp_cnt) return -EINVAL; - groups = devm_kzalloc(dev, grp_cnt * sizeof(*groups), GFP_KERNEL); + groups = devm_kcalloc(dev, grp_cnt, sizeof(*groups), GFP_KERNEL); if (!groups) return -EINVAL; grp = groups; - functions = devm_kzalloc(dev, grp_cnt * sizeof(*functions), GFP_KERNEL); + functions = devm_kcalloc(dev, grp_cnt, sizeof(*functions), + GFP_KERNEL); if (!functions) return -EINVAL; @@ -759,8 +760,9 @@ static int exynos5440_pinctrl_register(struct platform_device *pdev, ctrldesc->pmxops = &exynos5440_pinmux_ops; ctrldesc->confops = &exynos5440_pinconf_ops; - pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) * - EXYNOS5440_MAX_PINS, GFP_KERNEL); + pindesc = devm_kcalloc(&pdev->dev, + EXYNOS5440_MAX_PINS, sizeof(*pindesc), + GFP_KERNEL); if (!pindesc) return -ENOMEM; ctrldesc->pins = pindesc; @@ -774,8 +776,9 @@ static int exynos5440_pinctrl_register(struct platform_device *pdev, * allocate space for storing the dynamically generated names for all * the pins which belong to this pin-controller. */ - pin_names = devm_kzalloc(&pdev->dev, sizeof(char) * PIN_NAME_LENGTH * - ctrldesc->npins, GFP_KERNEL); + pin_names = devm_kzalloc(&pdev->dev, + array3_size(sizeof(char), PIN_NAME_LENGTH, ctrldesc->npins), + GFP_KERNEL); if (!pin_names) return -ENOMEM; @@ -914,7 +917,7 @@ static int exynos5440_gpio_irq_init(struct platform_device *pdev, struct exynos5440_gpio_intr_data *intd; int i, irq, ret; - intd = devm_kzalloc(dev, sizeof(*intd) * EXYNOS5440_MAX_GPIO_INT, + intd = devm_kcalloc(dev, EXYNOS5440_MAX_GPIO_INT, sizeof(*intd), GFP_KERNEL); if (!intd) return -ENOMEM; diff --git a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c index cf3a3af82321..6550239cb311 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c @@ -488,8 +488,8 @@ static int s3c64xx_eint_gpio_init(struct samsung_pinctrl_drv_data *d) ++nr_domains; } - data = devm_kzalloc(dev, sizeof(*data) - + nr_domains * sizeof(*data->domains), GFP_KERNEL); + data = devm_kzalloc(dev, struct_size(data, domains, nr_domains), + GFP_KERNEL); if (!data) return -ENOMEM; data->drvdata = d; diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 7c0f5d4e89f3..306faf2c9a70 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -651,7 +651,7 @@ static struct samsung_pin_group *samsung_pinctrl_create_groups( const struct pinctrl_pin_desc *pdesc; int i; - groups = devm_kzalloc(dev, ctrldesc->npins * sizeof(*groups), + groups = devm_kcalloc(dev, ctrldesc->npins, sizeof(*groups), GFP_KERNEL); if (!groups) return ERR_PTR(-EINVAL); @@ -688,7 +688,7 @@ static int samsung_pinctrl_create_function(struct device *dev, func->name = func_np->full_name; - func->groups = devm_kzalloc(dev, npins * sizeof(char *), GFP_KERNEL); + func->groups = devm_kcalloc(dev, npins, sizeof(char *), GFP_KERNEL); if (!func->groups) return -ENOMEM; @@ -745,7 +745,7 @@ static struct samsung_pmx_func *samsung_pinctrl_create_functions( } } - functions = devm_kzalloc(dev, func_cnt * sizeof(*functions), + functions = devm_kcalloc(dev, func_cnt, sizeof(*functions), GFP_KERNEL); if (!functions) return ERR_PTR(-ENOMEM); @@ -842,8 +842,9 @@ static int samsung_pinctrl_register(struct platform_device *pdev, ctrldesc->pmxops = &samsung_pinmux_ops; ctrldesc->confops = &samsung_pinconf_ops; - pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) * - drvdata->nr_pins, GFP_KERNEL); + pindesc = devm_kcalloc(&pdev->dev, + drvdata->nr_pins, sizeof(*pindesc), + GFP_KERNEL); if (!pindesc) return -ENOMEM; ctrldesc->pins = pindesc; @@ -857,8 +858,9 @@ static int samsung_pinctrl_register(struct platform_device *pdev, * allocate space for storing the dynamically generated names for all * the pins which belong to this pin-controller. */ - pin_names = devm_kzalloc(&pdev->dev, sizeof(char) * PIN_NAME_LENGTH * - drvdata->nr_pins, GFP_KERNEL); + pin_names = devm_kzalloc(&pdev->dev, + array3_size(sizeof(char), PIN_NAME_LENGTH, drvdata->nr_pins), + GFP_KERNEL); if (!pin_names) return -ENOMEM; diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 0c5e952461fd..56d5214ac5f9 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -56,7 +56,7 @@ static int sh_pfc_map_resources(struct sh_pfc *pfc, return -EINVAL; /* Allocate memory windows and IRQs arrays. */ - windows = devm_kzalloc(pfc->dev, num_windows * sizeof(*windows), + windows = devm_kcalloc(pfc->dev, num_windows, sizeof(*windows), GFP_KERNEL); if (windows == NULL) return -ENOMEM; @@ -65,7 +65,7 @@ static int sh_pfc_map_resources(struct sh_pfc *pfc, pfc->windows = windows; if (num_irqs) { - irqs = devm_kzalloc(pfc->dev, num_irqs * sizeof(*irqs), + irqs = devm_kcalloc(pfc->dev, num_irqs, sizeof(*irqs), GFP_KERNEL); if (irqs == NULL) return -ENOMEM; @@ -438,7 +438,7 @@ static int sh_pfc_init_ranges(struct sh_pfc *pfc) } pfc->nr_ranges = nr_ranges; - pfc->ranges = devm_kzalloc(pfc->dev, sizeof(*pfc->ranges) * nr_ranges, + pfc->ranges = devm_kcalloc(pfc->dev, nr_ranges, sizeof(*pfc->ranges), GFP_KERNEL); if (pfc->ranges == NULL) return -ENOMEM; diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 6b5422766f13..b173148e752f 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -107,7 +107,7 @@ static int gpio_setup_data_regs(struct sh_pfc_chip *chip) for (i = 0; pfc->info->data_regs[i].reg_width; ++i) ; - chip->regs = devm_kzalloc(pfc->dev, i * sizeof(*chip->regs), + chip->regs = devm_kcalloc(pfc->dev, i, sizeof(*chip->regs), GFP_KERNEL); if (chip->regs == NULL) return -ENOMEM; @@ -224,8 +224,9 @@ static int gpio_pin_setup(struct sh_pfc_chip *chip) struct gpio_chip *gc = &chip->gpio_chip; int ret; - chip->pins = devm_kzalloc(pfc->dev, pfc->info->nr_pins * - sizeof(*chip->pins), GFP_KERNEL); + chip->pins = devm_kcalloc(pfc->dev, + pfc->info->nr_pins, sizeof(*chip->pins), + GFP_KERNEL); if (chip->pins == NULL) return -ENOMEM; diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 5c9d79981e6d..90fb4c4083fa 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -770,14 +770,14 @@ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) unsigned int i; /* Allocate and initialize the pins and configs arrays. */ - pmx->pins = devm_kzalloc(pfc->dev, - sizeof(*pmx->pins) * pfc->info->nr_pins, + pmx->pins = devm_kcalloc(pfc->dev, + pfc->info->nr_pins, sizeof(*pmx->pins), GFP_KERNEL); if (unlikely(!pmx->pins)) return -ENOMEM; - pmx->configs = devm_kzalloc(pfc->dev, - sizeof(*pmx->configs) * pfc->info->nr_pins, + pmx->configs = devm_kcalloc(pfc->dev, + pfc->info->nr_pins, sizeof(*pmx->configs), GFP_KERNEL); if (unlikely(!pmx->configs)) return -ENOMEM; diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.c b/drivers/pinctrl/sirf/pinctrl-sirf.c index d3ef05973901..3274ecd464d9 100644 --- a/drivers/pinctrl/sirf/pinctrl-sirf.c +++ b/drivers/pinctrl/sirf/pinctrl-sirf.c @@ -108,7 +108,7 @@ static int sirfsoc_dt_node_to_map(struct pinctrl_dev *pctldev, return -ENODEV; } - *map = kzalloc(sizeof(**map) * count, GFP_KERNEL); + *map = kcalloc(count, sizeof(**map), GFP_KERNEL); if (!*map) return -ENOMEM; diff --git a/drivers/pinctrl/spear/pinctrl-plgpio.c b/drivers/pinctrl/spear/pinctrl-plgpio.c index cf6d68c7345b..bd5bea82683e 100644 --- a/drivers/pinctrl/spear/pinctrl-plgpio.c +++ b/drivers/pinctrl/spear/pinctrl-plgpio.c @@ -540,9 +540,9 @@ static int plgpio_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "clk_get() failed, work without it\n"); #ifdef CONFIG_PM_SLEEP - plgpio->csave_regs = devm_kzalloc(&pdev->dev, - sizeof(*plgpio->csave_regs) * + plgpio->csave_regs = devm_kcalloc(&pdev->dev, DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG), + sizeof(*plgpio->csave_regs), GFP_KERNEL); if (!plgpio->csave_regs) { dev_err(&pdev->dev, "csave registers memory allocation fail\n"); diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c index 4db52ba38d8d..3a618db9f58a 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.c +++ b/drivers/pinctrl/spear/pinctrl-spear.c @@ -172,7 +172,7 @@ static int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, return -ENODEV; } - *map = kzalloc(sizeof(**map) * count, GFP_KERNEL); + *map = kcalloc(count, sizeof(**map), GFP_KERNEL); if (!*map) return -ENOMEM; diff --git a/drivers/pinctrl/sprd/pinctrl-sprd.c b/drivers/pinctrl/sprd/pinctrl-sprd.c index 83958bdd0f05..2c850f8059c8 100644 --- a/drivers/pinctrl/sprd/pinctrl-sprd.c +++ b/drivers/pinctrl/sprd/pinctrl-sprd.c @@ -877,8 +877,9 @@ static int sprd_pinctrl_parse_groups(struct device_node *np, grp->name = np->name; grp->npins = ret; - grp->pins = devm_kzalloc(sprd_pctl->dev, grp->npins * - sizeof(unsigned int), GFP_KERNEL); + grp->pins = devm_kcalloc(sprd_pctl->dev, + grp->npins, sizeof(unsigned int), + GFP_KERNEL); if (!grp->pins) return -ENOMEM; @@ -929,14 +930,15 @@ static int sprd_pinctrl_parse_dt(struct sprd_pinctrl *sprd_pctl) if (!info->ngroups) return 0; - info->groups = devm_kzalloc(sprd_pctl->dev, info->ngroups * + info->groups = devm_kcalloc(sprd_pctl->dev, + info->ngroups, sizeof(struct sprd_pin_group), GFP_KERNEL); if (!info->groups) return -ENOMEM; - info->grp_names = devm_kzalloc(sprd_pctl->dev, - info->ngroups * sizeof(char *), + info->grp_names = devm_kcalloc(sprd_pctl->dev, + info->ngroups, sizeof(char *), GFP_KERNEL); if (!info->grp_names) return -ENOMEM; @@ -978,8 +980,8 @@ static int sprd_pinctrl_add_pins(struct sprd_pinctrl *sprd_pctl, int i; info->npins = pins_cnt; - info->pins = devm_kzalloc(sprd_pctl->dev, - info->npins * sizeof(struct sprd_pin), + info->pins = devm_kcalloc(sprd_pctl->dev, + info->npins, sizeof(struct sprd_pin), GFP_KERNEL); if (!info->pins) return -ENOMEM; @@ -1055,7 +1057,8 @@ int sprd_pinctrl_core_probe(struct platform_device *pdev, return ret; } - pin_desc = devm_kzalloc(&pdev->dev, pinctrl_info->npins * + pin_desc = devm_kcalloc(&pdev->dev, + pinctrl_info->npins, sizeof(struct pinctrl_pin_desc), GFP_KERNEL); if (!pin_desc) diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index cc8b86a16da0..c281ac177f72 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -274,7 +274,7 @@ static unsigned long *sunxi_pctrl_build_pin_config(struct device_node *node, if (!configlen) return NULL; - pinconfig = kzalloc(configlen * sizeof(*pinconfig), GFP_KERNEL); + pinconfig = kcalloc(configlen, sizeof(*pinconfig), GFP_KERNEL); if (!pinconfig) return ERR_PTR(-ENOMEM); @@ -349,7 +349,7 @@ static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, * any configuration. */ nmaps = npins * 2; - *map = kmalloc(nmaps * sizeof(struct pinctrl_map), GFP_KERNEL); + *map = kmalloc_array(nmaps, sizeof(struct pinctrl_map), GFP_KERNEL); if (!*map) return -ENOMEM; @@ -1053,8 +1053,8 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev) * this means that the number of pins is the maximum group * number we will ever see. */ - pctl->groups = devm_kzalloc(&pdev->dev, - pctl->desc->npins * sizeof(*pctl->groups), + pctl->groups = devm_kcalloc(&pdev->dev, + pctl->desc->npins, sizeof(*pctl->groups), GFP_KERNEL); if (!pctl->groups) return -ENOMEM; @@ -1077,8 +1077,9 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev) * We suppose that we won't have any more functions than pins, * we'll reallocate that later anyway */ - pctl->functions = devm_kzalloc(&pdev->dev, - pctl->ngroups * sizeof(*pctl->functions), + pctl->functions = devm_kcalloc(&pdev->dev, + pctl->ngroups, + sizeof(*pctl->functions), GFP_KERNEL); if (!pctl->functions) return -ENOMEM; @@ -1137,8 +1138,9 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev) if (!func_item->groups) { func_item->groups = - devm_kzalloc(&pdev->dev, - func_item->ngroups * sizeof(*func_item->groups), + devm_kcalloc(&pdev->dev, + func_item->ngroups, + sizeof(*func_item->groups), GFP_KERNEL); if (!func_item->groups) return -ENOMEM; @@ -1281,8 +1283,8 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev, return ret; } - pins = devm_kzalloc(&pdev->dev, - pctl->desc->npins * sizeof(*pins), + pins = devm_kcalloc(&pdev->dev, + pctl->desc->npins, sizeof(*pins), GFP_KERNEL); if (!pins) return -ENOMEM; diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.c b/drivers/pinctrl/tegra/pinctrl-tegra.c index e5c9b9c68428..c26376690b02 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra.c @@ -679,8 +679,8 @@ int tegra_pinctrl_probe(struct platform_device *pdev, * Each mux group will appear in 4 functions' list of groups. * This over-allocates slightly, since not all groups are mux groups. */ - pmx->group_pins = devm_kzalloc(&pdev->dev, - soc_data->ngroups * 4 * sizeof(*pmx->group_pins), + pmx->group_pins = devm_kcalloc(&pdev->dev, + soc_data->ngroups * 4, sizeof(*pmx->group_pins), GFP_KERNEL); if (!pmx->group_pins) return -ENOMEM; @@ -722,7 +722,7 @@ int tegra_pinctrl_probe(struct platform_device *pdev, } pmx->nbanks = i; - pmx->regs = devm_kzalloc(&pdev->dev, pmx->nbanks * sizeof(*pmx->regs), + pmx->regs = devm_kcalloc(&pdev->dev, pmx->nbanks, sizeof(*pmx->regs), GFP_KERNEL); if (!pmx->regs) { dev_err(&pdev->dev, "Can't alloc regs pointer\n"); diff --git a/drivers/pinctrl/ti/pinctrl-ti-iodelay.c b/drivers/pinctrl/ti/pinctrl-ti-iodelay.c index 8ac1f1ce4442..61f8b8d14b2d 100644 --- a/drivers/pinctrl/ti/pinctrl-ti-iodelay.c +++ b/drivers/pinctrl/ti/pinctrl-ti-iodelay.c @@ -510,11 +510,11 @@ static int ti_iodelay_dt_node_to_map(struct pinctrl_dev *pctldev, goto free_map; } - pins = devm_kzalloc(iod->dev, sizeof(*pins) * rows, GFP_KERNEL); + pins = devm_kcalloc(iod->dev, rows, sizeof(*pins), GFP_KERNEL); if (!pins) goto free_group; - cfg = devm_kzalloc(iod->dev, sizeof(*cfg) * rows, GFP_KERNEL); + cfg = devm_kcalloc(iod->dev, rows, sizeof(*cfg), GFP_KERNEL); if (!cfg) { error = -ENOMEM; goto free_pins; @@ -753,7 +753,7 @@ static int ti_iodelay_alloc_pins(struct device *dev, nr_pins = ti_iodelay_offset_to_pin(iod, r->regmap_config->max_register); dev_dbg(dev, "Allocating %i pins\n", nr_pins); - iod->pa = devm_kzalloc(dev, sizeof(*iod->pa) * nr_pins, GFP_KERNEL); + iod->pa = devm_kcalloc(dev, nr_pins, sizeof(*iod->pa), GFP_KERNEL); if (!iod->pa) return -ENOMEM; diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c index f9267fabe6b0..ea08afa25fde 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c @@ -751,8 +751,7 @@ static int uniphier_pinctrl_add_reg_region(struct device *dev, nregs = DIV_ROUND_UP(count * width, 32); - region = devm_kzalloc(dev, - sizeof(*region) + sizeof(region->vals[0]) * nregs, + region = devm_kzalloc(dev, struct_size(region, vals, nregs), GFP_KERNEL); if (!region) return -ENOMEM; diff --git a/drivers/pinctrl/vt8500/pinctrl-wmt.c b/drivers/pinctrl/vt8500/pinctrl-wmt.c index d73956bdc211..c08318a5a91b 100644 --- a/drivers/pinctrl/vt8500/pinctrl-wmt.c +++ b/drivers/pinctrl/vt8500/pinctrl-wmt.c @@ -352,7 +352,7 @@ static int wmt_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, if (num_pulls) maps_per_pin++; - cur_map = maps = kzalloc(num_pins * maps_per_pin * sizeof(*maps), + cur_map = maps = kcalloc(num_pins * maps_per_pin, sizeof(*maps), GFP_KERNEL); if (!maps) return -ENOMEM; diff --git a/drivers/pinctrl/zte/pinctrl-zx.c b/drivers/pinctrl/zte/pinctrl-zx.c index 91955e770236..3cb69309912b 100644 --- a/drivers/pinctrl/zte/pinctrl-zx.c +++ b/drivers/pinctrl/zte/pinctrl-zx.c @@ -277,7 +277,7 @@ static int zx_pinctrl_build_state(struct platform_device *pdev) /* Every single pin composes a group */ ngroups = info->npins; - groups = devm_kzalloc(&pdev->dev, ngroups * sizeof(*groups), + groups = devm_kcalloc(&pdev->dev, ngroups, sizeof(*groups), GFP_KERNEL); if (!groups) return -ENOMEM; @@ -362,8 +362,8 @@ static int zx_pinctrl_build_state(struct platform_device *pdev) func = functions + j; if (!func->group_names) { - func->group_names = devm_kzalloc(&pdev->dev, - func->num_group_names * + func->group_names = devm_kcalloc(&pdev->dev, + func->num_group_names, sizeof(*func->group_names), GFP_KERNEL); if (!func->group_names) { diff --git a/drivers/platform/chrome/cros_ec_dev.c b/drivers/platform/chrome/cros_ec_dev.c index cf6c4f0846b8..ab7c91b4bba7 100644 --- a/drivers/platform/chrome/cros_ec_dev.c +++ b/drivers/platform/chrome/cros_ec_dev.c @@ -305,13 +305,14 @@ static void cros_ec_sensors_register(struct cros_ec_dev *ec) resp = (struct ec_response_motion_sense *)msg->data; sensor_num = resp->dump.sensor_count; /* Allocate 2 extra sensors in case lid angle or FIFO are needed */ - sensor_cells = kzalloc(sizeof(struct mfd_cell) * (sensor_num + 2), + sensor_cells = kcalloc(sensor_num + 2, sizeof(struct mfd_cell), GFP_KERNEL); if (sensor_cells == NULL) goto error; - sensor_platforms = kzalloc(sizeof(struct cros_ec_sensor_platform) * - (sensor_num + 1), GFP_KERNEL); + sensor_platforms = kcalloc(sensor_num + 1, + sizeof(struct cros_ec_sensor_platform), + GFP_KERNEL); if (sensor_platforms == NULL) goto error_platforms; diff --git a/drivers/platform/msm/Kconfig b/drivers/platform/msm/Kconfig index 25893daa6886..7dbb3fe34e81 100644 --- a/drivers/platform/msm/Kconfig +++ b/drivers/platform/msm/Kconfig @@ -112,6 +112,11 @@ config GSI_REGISTER_VERSION_2 new registers offsets, new registers fields structure and new registers. +config GSI_DEBUG + bool "Debugging part of GSI core" + depends on GSI || DEBUG_FS + default n + config MSM_MHI_DEV tristate "Modem Device Interface Driver" depends on EP_PCIE && IPA3 diff --git a/drivers/platform/msm/ep_pcie/ep_pcie_core.c b/drivers/platform/msm/ep_pcie/ep_pcie_core.c index 0d0a5628780f..61c6e12c99e0 100644 --- a/drivers/platform/msm/ep_pcie/ep_pcie_core.c +++ b/drivers/platform/msm/ep_pcie/ep_pcie_core.c @@ -1895,8 +1895,6 @@ int ep_pcie_core_enable_endpoint(enum ep_pcie_options opt) "PCIe V%d: link initialized for LE PCIe endpoint\n", dev->rev); pr_crit("PCIe - link initialized for LE PCIe endpoint\n"); - place_marker( - "PCIe - link initialized for LE PCIe endpoint\n"); } checkbme: @@ -2558,7 +2556,8 @@ perst_irq: perst_irq = gpio_to_irq(dev->gpio[EP_PCIE_GPIO_PERST].num); ret = devm_request_irq(pdev, perst_irq, ep_pcie_handle_perst_irq, - (dev->perst_deast ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH), + ((dev->perst_deast ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH) + | IRQF_EARLY_RESUME), "ep_pcie_perst", dev); if (ret) { EP_PCIE_ERR(dev, diff --git a/drivers/platform/msm/gsi/Makefile b/drivers/platform/msm/gsi/Makefile index 90d1a19ac366..faf4dc031cc4 100644 --- a/drivers/platform/msm/gsi/Makefile +++ b/drivers/platform/msm/gsi/Makefile @@ -1,4 +1,3 @@ -gsidbg-$(CONFIG_GSI) += gsi_dbg.o -obj-$(CONFIG_GSI) += gsi.o gsidbg.o - +obj-$(CONFIG_GSI) += gsi.o +obj-$(CONFIG_GSI_DEBUG) += gsidbg.o gsi_dbg.o obj-$(CONFIG_IPA_EMULATION) += gsi_emulation.o diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index 1a05c655dd27..17fdb10c8a6c 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -38,8 +38,8 @@ #define GSI_STTS_REG_BITS 32 -#ifndef CONFIG_DEBUG_FS -void gsi_debugfs_init(void) +#ifndef CONFIG_GSI_DEBUG +static inline void gsi_debugfs_init(void) { } #endif @@ -2374,8 +2374,8 @@ int gsi_alloc_channel(struct gsi_chan_props *props, unsigned long dev_hdl, if (props->prot == GSI_CHAN_PROT_GCI) user_data_size += GSI_VEID_MAX; - user_data = devm_kzalloc(gsi_ctx->dev, - user_data_size * sizeof(*user_data), + user_data = devm_kcalloc(gsi_ctx->dev, + user_data_size, sizeof(*user_data), GFP_KERNEL); if (user_data == NULL) { GSIERR("context not allocated\n"); @@ -3852,7 +3852,7 @@ int gsi_config_channel_mode(unsigned long chan_hdl, enum gsi_chan_mode mode) curr = GSI_CHAN_MODE_CALLBACK; if (mode == curr) { - GSIERR("already in requested mode %u chan_hdl=%lu\n", + GSIDBG("already in requested mode %u chan_hdl=%lu\n", curr, chan_hdl); spin_unlock_irqrestore(&gsi_ctx->slock, flags); return -GSI_STATUS_UNSUPPORTED_OP; diff --git a/drivers/platform/msm/gsi/gsi.h b/drivers/platform/msm/gsi/gsi.h index 2f044f2b0d0a..4f09f029639c 100644 --- a/drivers/platform/msm/gsi/gsi.h +++ b/drivers/platform/msm/gsi/gsi.h @@ -342,7 +342,9 @@ enum gsi_generic_ee_cmd_return_code { }; extern struct gsi_ctx *gsi_ctx; +#ifdef CONFIG_GSI_DEBUG void gsi_debugfs_init(void); +#endif uint16_t gsi_find_idx_from_addr(struct gsi_ring_ctx *ctx, uint64_t addr); void gsi_update_ch_dp_stats(struct gsi_chan_ctx *ctx, uint16_t used); diff --git a/drivers/platform/msm/ipa/ipa_api.c b/drivers/platform/msm/ipa/ipa_api.c index 87185692a9cc..da78af4b31ee 100644 --- a/drivers/platform/msm/ipa/ipa_api.c +++ b/drivers/platform/msm/ipa/ipa_api.c @@ -399,7 +399,7 @@ int ipa_smmu_store_sgt(struct sg_table **out_ch_ptr, } memcpy((*out_ch_ptr)->sgl, in_sgt_ptr->sgl, - nents*sizeof((*out_ch_ptr)->sgl)); + nents*sizeof(struct scatterlist)); (*out_ch_ptr)->nents = nents; (*out_ch_ptr)->orig_nents = in_sgt_ptr->orig_nents; } diff --git a/drivers/platform/msm/ipa/ipa_rm_peers_list.c b/drivers/platform/msm/ipa/ipa_rm_peers_list.c index 19032278acb4..9fd79c791a62 100644 --- a/drivers/platform/msm/ipa/ipa_rm_peers_list.c +++ b/drivers/platform/msm/ipa/ipa_rm_peers_list.c @@ -63,8 +63,9 @@ int ipa_rm_peers_list_create(int max_peers, } (*peers_list)->max_peers = max_peers; - (*peers_list)->peers = kzalloc((*peers_list)->max_peers * - sizeof(*((*peers_list)->peers)), GFP_ATOMIC); + (*peers_list)->peers = kcalloc((*peers_list)->max_peers, + sizeof(*((*peers_list)->peers)), + GFP_ATOMIC); if (!((*peers_list)->peers)) { IPA_RM_ERR("no mem\n"); result = -ENOMEM; diff --git a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_net.c b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_net.c index 1fa89cbd39e7..376afd0df4cb 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_net.c +++ b/drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_net.c @@ -1062,8 +1062,8 @@ static int ipa_eth_net_cb_map_ch_mem(struct ipa_eth_device *eth_dev, return -EEXIST; } - ch_mem->cb_mem = kzalloc(sizeof(*ch_mem->cb_mem) * IPA_SMMU_CB_MAX, - GFP_KERNEL); + ch_mem->cb_mem = kcalloc(IPA_SMMU_CB_MAX, sizeof(*ch_mem->cb_mem), + GFP_KERNEL); if (!ch_mem->cb_mem) { ipa_eth_dev_err(eth_dev, "Failed to alloc CB mem resource"); return -ENOMEM; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 37e48df52550..d16590839e3c 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -6605,6 +6605,9 @@ static ssize_t ipa3_write(struct file *file, const char __user *buf, /* Check MHI configuration on MDM devices */ if (!ipa3_is_msm_device()) { + /* reset ecm default as non-vlan mode */ + if (!ipa3_ctx->vlan_mode_set && ipa3_ctx->ipa_config_is_auto) + ipa3_ctx->vlan_mode_iface[IPA_VLAN_IF_ECM] = false; if (strnstr(dbg_buff, "vlan", strlen(dbg_buff))) { if (strnstr(dbg_buff, "eth", strlen(dbg_buff))) @@ -6621,6 +6624,13 @@ static ssize_t ipa3_write(struct file *file, const char __user *buf, * when vlan mode is passed to our dev we expect * another write */ + ipa3_ctx->vlan_mode_set = true; + IPAERR("emac vlan(%d)\n", + ipa3_ctx->vlan_mode_iface[IPA_VLAN_IF_EMAC]); + IPAERR("rndis vlan(%d)\n", + ipa3_ctx->vlan_mode_iface[IPA_VLAN_IF_RNDIS]); + IPAERR("ecm vlan(%d)\n", + ipa3_ctx->vlan_mode_iface[IPA_VLAN_IF_ECM]); return count; } @@ -7366,6 +7376,10 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, mutex_init(&ipa3_ctx->app_clock_vote.mutex); + /* put ecm default as vlan mode */ + if (ipa3_ctx->ipa_config_is_auto) + ipa3_ctx->vlan_mode_iface[IPA_VLAN_IF_ECM] = true; + return 0; fail_cdev_add: diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c index fc25fbc6eb0b..20911f34fd33 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c @@ -433,14 +433,33 @@ int ipa3_smmu_map_peer_buff(u64 iova, u32 size, bool map, struct sg_table *sgt, } } } else { - res = iommu_unmap(smmu_domain, - rounddown(iova, PAGE_SIZE), - roundup(size + iova - rounddown(iova, PAGE_SIZE), - PAGE_SIZE)); - if (res != roundup(size + iova - rounddown(iova, PAGE_SIZE), - PAGE_SIZE)) { - IPAERR("Fail to unmap 0x%llx\n", iova); - return -EINVAL; + if (sgt != NULL) { + va = rounddown(iova, PAGE_SIZE); + len = 0; + for_each_sg(sgt->sgl, sg, sgt->nents, i) { + len = PAGE_ALIGN(sg->offset + sg->length); + res = iommu_unmap(smmu_domain, va, + roundup(len, PAGE_SIZE)); + if (res != + roundup(len, PAGE_SIZE)) { + IPAERR("Fail to unmap iova=%llx\n", + iova); + return -EINVAL; + } + va += len; + count++; + } + } else { + res = iommu_unmap(smmu_domain, + rounddown(iova, PAGE_SIZE), + roundup(size + iova - + rounddown(iova, PAGE_SIZE), + PAGE_SIZE)); + if (res != roundup(size + iova - + rounddown(iova, PAGE_SIZE), PAGE_SIZE)) { + IPAERR("Fail to unmap 0x%llx\n", iova); + return -EINVAL; + } } } IPADBG("Peer buff %s 0x%llx\n", map ? "map" : "unmap", iova); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c index e14df33caf7c..b09b69f20121 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c @@ -110,6 +110,7 @@ const char *ipa3_hdr_proc_type_name[] = { __stringify(IPA_HDR_PROC_ETHII_TO_ETHII_EX), __stringify(IPA_HDR_PROC_L2TP_UDP_HEADER_ADD), __stringify(IPA_HDR_PROC_L2TP_UDP_HEADER_REMOVE), + __stringify(IPA_HDR_PROC_SET_DSCP), }; static struct dentry *dent; @@ -827,7 +828,7 @@ static ssize_t ipa3_read_rt_hw(struct file *file, char __user *ubuf, IPADBG("Tring to parse %d H/W routing tables - IP=%d\n", tbls_num, ip); - rules = kzalloc(sizeof(*rules) * IPA_DBG_MAX_RULE_IN_TBL, GFP_KERNEL); + rules = kcalloc(IPA_DBG_MAX_RULE_IN_TBL, sizeof(*rules), GFP_KERNEL); if (!rules) { IPAERR("failed to allocate mem for tbl rules\n"); return -ENOMEM; @@ -1052,7 +1053,7 @@ static ssize_t ipa3_read_flt_hw(struct file *file, char __user *ubuf, IPADBG("Tring to parse %d H/W filtering tables - IP=%d\n", ipa3_ctx->ep_flt_num, ip); - rules = kzalloc(sizeof(*rules) * IPA_DBG_MAX_RULE_IN_TBL, GFP_KERNEL); + rules = kcalloc(IPA_DBG_MAX_RULE_IN_TBL, sizeof(*rules), GFP_KERNEL); if (!rules) return -ENOMEM; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index 3173fbcd3e68..3833d71220dc 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -1646,7 +1646,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, * 1 desc may be needed for the PACKET_INIT; * 1 desc for each frag */ - desc = kzalloc(sizeof(*desc) * (num_frags + 3), GFP_ATOMIC); + desc = kcalloc(num_frags + 3, sizeof(*desc), GFP_ATOMIC); if (!desc) { IPAERR("failed to alloc desc array\n"); goto fail_gen; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index 3901a0f8387b..c2c6aa896859 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -1988,6 +1988,7 @@ struct ipa3_context { int num_ipa_cne_evt_req; struct mutex ipa_cne_evt_lock; bool use_ipa_pm; + bool vlan_mode_set; bool vlan_mode_iface[IPA_VLAN_IF_MAX]; bool wdi_over_pcie; u32 entire_ipa_block_size; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c index d1a9ab8bf8a5..c2422e8b2a52 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c @@ -642,7 +642,6 @@ static void ipa_mpm_smmu_unmap(dma_addr_t carved_iova, int sz, int dir, if (carved_iova <= 0) { IPA_MPM_ERR("carved_iova is zero/negative\n"); - WARN_ON(1); return; } @@ -1444,9 +1443,8 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, if ((atomic_read( &ipa_mpm_ctx->md[probe_id].clk_cnt.pcie_clk_cnt) == 0)) { - IPA_MPM_DBG("probe_id %d PCIE clock already devoted\n", + IPA_MPM_ERR("probe_id %d PCIE clock already devoted\n", probe_id); - WARN_ON(1); return 0; } mhi_device_put(ipa_mpm_ctx->md[probe_id].mhi_dev, MHI_VOTE_BUS); @@ -1480,9 +1478,8 @@ static void ipa_mpm_vote_unvote_ipa_clk(enum ipa_mpm_clk_vote_type vote, if ((atomic_read (&ipa_mpm_ctx->md[probe_id].clk_cnt.ipa_clk_cnt) == 0)) { - IPA_MPM_DBG("probe_id %d IPA clock count < 0\n", + IPA_MPM_ERR("probe_id %d IPA clock count < 0\n", probe_id); - WARN_ON(1); return; } IPA_ACTIVE_CLIENTS_DEC_SPECIAL(ipa_mpm_mhip_chan_str[probe_id]); @@ -2037,7 +2034,6 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, ret = mhi_prepare_for_transfer(ipa_mpm_ctx->md[probe_id].mhi_dev); if (ret) { IPA_MPM_ERR("mhi_prepare_for_transfer failed %d\n", ret); - WARN_ON(1); /* * WA to handle prepare_for_tx failures. * Though prepare for transfer fails, indicate success diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c index 266734f4ba9f..af148df76365 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c @@ -685,7 +685,6 @@ static int ipa3_qmi_init_modem_send_sync_msg(void) pr_info("QMI_IPA_INIT_MODEM_DRIVER_REQ_V01 response received\n"); - place_marker("M - QMI ready for commands"); return ipa3_check_qmi_response(rc, QMI_IPA_INIT_MODEM_DRIVER_REQ_V01, resp.resp.result, diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index 083b3360229a..71e8572259dd 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -6645,7 +6645,7 @@ int ipa3_tag_process(struct ipa3_desc desc[], } sys = ipa3_ctx->ep[ep_idx].sys; - tag_desc = kzalloc(sizeof(*tag_desc) * IPA_TAG_MAX_DESC, GFP_KERNEL); + tag_desc = kcalloc(IPA_TAG_MAX_DESC, sizeof(*tag_desc), GFP_KERNEL); if (!tag_desc) { IPAERR("failed to allocate memory\n"); return -ENOMEM; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c index e16003813a9c..4d261f862d97 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c @@ -1428,6 +1428,9 @@ static int ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type, case IPA_HDR_PROC_802_3_TO_802_3: ctx->cmd.value = IPA_HDR_UCP_802_3_TO_802_3; break; + case IPA_HDR_PROC_SET_DSCP: + ctx->cmd.value = IPA_HDR_UCP_SET_DSCP; + break; default: IPAHAL_ERR("unknown ipa_hdr_proc_type %d", type); WARN_ON(1); @@ -1480,6 +1483,9 @@ static int ipahal_get_proc_ctx_needed_len_v3(enum ipa_hdr_proc_type type) case IPA_HDR_PROC_ETHII_TO_ETHII_EX: ret = sizeof(struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq_ex); break; + case IPA_HDR_PROC_SET_DSCP: + ret = sizeof(struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq); + break; default: /* invalid value to make sure failure */ IPAHAL_ERR_RL("invalid ipa_hdr_proc_type %d\n", type); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h index 77524c4a5227..787da2a651ff 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h @@ -624,6 +624,7 @@ struct ipa_pkt_status_hw { #define IPA_HDR_UCP_L2TP_UDP_HEADER_ADD 12 #define IPA_HDR_UCP_L2TP_UDP_HEADER_REMOVE 13 #define IPA_HDR_UCP_ETHII_TO_ETHII_EX 14 +#define IPA_HDR_UCP_SET_DSCP 16 /* Processing context TLV type */ #define IPA_PROC_CTX_TLV_TYPE_END 0 diff --git a/drivers/platform/msm/ipa/test/ipa_test_dma.c b/drivers/platform/msm/ipa/test/ipa_test_dma.c index e1c46f45c2ce..207fc00c6191 100644 --- a/drivers/platform/msm/ipa/test/ipa_test_dma.c +++ b/drivers/platform/msm/ipa/test/ipa_test_dma.c @@ -969,8 +969,9 @@ static int ipa_test_dma_parallel_async_memcpy_in_loop(void *priv) return rc; } - udata = kzalloc(IPA_DMA_TEST_ASYNC_PARALLEL_LOOP_NUM * - sizeof(struct ipa_test_dma_async_user_data), GFP_KERNEL); + udata = kcalloc(IPA_DMA_TEST_ASYNC_PARALLEL_LOOP_NUM, + sizeof(struct ipa_test_dma_async_user_data), + GFP_KERNEL); if (!udata) { IPA_UT_ERR("fail allocate user_data array\n"); (void)ipa_dma_disable(); diff --git a/drivers/platform/msm/ipa/test/ipa_test_hw_stats.c b/drivers/platform/msm/ipa/test/ipa_test_hw_stats.c index 97be4138be26..811b9b67d49a 100644 --- a/drivers/platform/msm/ipa/test/ipa_test_hw_stats.c +++ b/drivers/platform/msm/ipa/test/ipa_test_hw_stats.c @@ -146,8 +146,9 @@ static int ipa_test_hw_stats_add_FnR(void *priv) IPA_UT_DBG("no mem\n"); return -ENOMEM; } - rt_rule->rules = (uint64_t)kzalloc(1 * - sizeof(struct ipa_rt_rule_add_v2), GFP_KERNEL); + rt_rule->rules = (uint64_t) kcalloc(1, + sizeof(struct ipa_rt_rule_add_v2), + GFP_KERNEL); if (!rt_rule->rules) { IPA_UT_DBG("no mem\n"); ret = -ENOMEM; @@ -160,8 +161,9 @@ static int ipa_test_hw_stats_add_FnR(void *priv) ret = -ENOMEM; goto free_rt; } - flt_rule->rules = (uint64_t)kzalloc(1 * - sizeof(struct ipa_flt_rule_add_v2), GFP_KERNEL); + flt_rule->rules = (uint64_t) kcalloc(1, + sizeof(struct ipa_flt_rule_add_v2), + GFP_KERNEL); if (!flt_rule->rules) { IPA_UT_DBG("no mem\n"); ret = -ENOMEM; diff --git a/drivers/platform/msm/mhi_dev/mhi.c b/drivers/platform/msm/mhi_dev/mhi.c index f2336be13d8d..484fc1ec3b53 100644 --- a/drivers/platform/msm/mhi_dev/mhi.c +++ b/drivers/platform/msm/mhi_dev/mhi.c @@ -1276,7 +1276,6 @@ static void mhi_hwc_cb(void *priv, enum ipa_mhi_event_type event, } mhi_log(MHI_MSG_CRITICAL, "Device in M0 State\n"); - place_marker("MHI - Device in M0 State\n"); break; case IPA_MHI_EVENT_DATA_AVAILABLE: rc = mhi_dev_notify_sm_event(MHI_DEV_EVENT_HW_ACC_WAKEUP); @@ -2406,34 +2405,51 @@ static int mhi_dev_cache_host_cfg(struct mhi_dev *mhi) mhi->cfg.event_rings; mhi->ch_ctx_shadow.size = sizeof(struct mhi_dev_ch_ctx) * mhi->cfg.channels; - - mhi->cmd_ctx_cache = dma_alloc_coherent(&pdev->dev, - sizeof(struct mhi_dev_cmd_ctx), - &mhi->cmd_ctx_cache_dma_handle, - GFP_KERNEL); + /* + * This func mhi_dev_cache_host_cfg will be called when + * processing mhi device reset as well, do not allocate + * the command, event and channel context caches if they + * were already allocated during device boot, to avoid + * memory leak. + */ if (!mhi->cmd_ctx_cache) { - pr_err("no memory while allocating cmd ctx\n"); - return -ENOMEM; + mhi->cmd_ctx_cache = dma_alloc_coherent(&pdev->dev, + sizeof(struct mhi_dev_cmd_ctx), + &mhi->cmd_ctx_cache_dma_handle, + GFP_KERNEL); + if (!mhi->cmd_ctx_cache) { + pr_err("no memory while allocating cmd ctx\n"); + rc = -ENOMEM; + goto exit; + } } memset(mhi->cmd_ctx_cache, 0, sizeof(struct mhi_dev_cmd_ctx)); - mhi->ev_ctx_cache = dma_alloc_coherent(&pdev->dev, - sizeof(struct mhi_dev_ev_ctx) * - mhi->cfg.event_rings, - &mhi->ev_ctx_cache_dma_handle, - GFP_KERNEL); - if (!mhi->ev_ctx_cache) - return -ENOMEM; + if (!mhi->ev_ctx_cache) { + mhi->ev_ctx_cache = dma_alloc_coherent(&pdev->dev, + sizeof(struct mhi_dev_ev_ctx) * + mhi->cfg.event_rings, + &mhi->ev_ctx_cache_dma_handle, + GFP_KERNEL); + if (!mhi->ev_ctx_cache) { + rc = -ENOMEM; + goto exit; + } + } memset(mhi->ev_ctx_cache, 0, sizeof(struct mhi_dev_ev_ctx) * mhi->cfg.event_rings); - mhi->ch_ctx_cache = dma_alloc_coherent(&pdev->dev, - sizeof(struct mhi_dev_ch_ctx) * - mhi->cfg.channels, - &mhi->ch_ctx_cache_dma_handle, - GFP_KERNEL); - if (!mhi->ch_ctx_cache) - return -ENOMEM; + if (!mhi->ch_ctx_cache) { + mhi->ch_ctx_cache = dma_alloc_coherent(&pdev->dev, + sizeof(struct mhi_dev_ch_ctx) * + mhi->cfg.channels, + &mhi->ch_ctx_cache_dma_handle, + GFP_KERNEL); + if (!mhi->ch_ctx_cache) { + rc = -ENOMEM; + goto exit; + } + } memset(mhi->ch_ctx_cache, 0, sizeof(struct mhi_dev_ch_ctx) * mhi->cfg.channels); @@ -2469,6 +2485,20 @@ static int mhi_dev_cache_host_cfg(struct mhi_dev *mhi) return mhi_ring_start(&mhi->ring[0], (union mhi_dev_ring_ctx *)mhi->cmd_ctx_cache, mhi); + +exit: + if (mhi->cmd_ctx_cache) + dma_free_coherent(&pdev->dev, + sizeof(struct mhi_dev_cmd_ctx), + mhi->cmd_ctx_cache, + mhi->cmd_ctx_cache_dma_handle); + if (mhi->ev_ctx_cache) + dma_free_coherent(&pdev->dev, + sizeof(struct mhi_dev_ev_ctx) * + mhi->cfg.event_rings, + mhi->ev_ctx_cache, + mhi->ev_ctx_cache_dma_handle); + return rc; } void mhi_dev_pm_relax(void) diff --git a/drivers/platform/msm/mhi_dev/mhi_sm.c b/drivers/platform/msm/mhi_dev/mhi_sm.c index 62d4fe0bf7de..4d208bb931c1 100644 --- a/drivers/platform/msm/mhi_dev/mhi_sm.c +++ b/drivers/platform/msm/mhi_dev/mhi_sm.c @@ -1102,7 +1102,7 @@ int mhi_dev_sm_init(struct mhi_dev *mhi_dev) /*init debugfs*/ mhi_sm_debugfs_init(); - mhi_sm_ctx->mhi_sm_wq = create_singlethread_workqueue("mhi_sm_wq"); + mhi_sm_ctx->mhi_sm_wq = alloc_workqueue("mhi_sm_wq", WQ_HIGHPRI, 0); if (!mhi_sm_ctx->mhi_sm_wq) { MHI_SM_ERR("Failed to create singlethread_workqueue: sm_wq\n"); res = -ENOMEM; diff --git a/drivers/platform/msm/qcom-geni-se.c b/drivers/platform/msm/qcom-geni-se.c index 66a8d3f45274..a3ca53d4a11a 100644 --- a/drivers/platform/msm/qcom-geni-se.c +++ b/drivers/platform/msm/qcom-geni-se.c @@ -1282,8 +1282,9 @@ int geni_se_clk_tbl_get(struct se_geni_rsc *rsc, unsigned long **tbl) goto exit_se_clk_tbl_get; } - geni_se_dev->clk_perf_tbl = kzalloc(sizeof(*geni_se_dev->clk_perf_tbl) * - MAX_CLK_PERF_LEVEL, GFP_KERNEL); + geni_se_dev->clk_perf_tbl = kcalloc(MAX_CLK_PERF_LEVEL, + sizeof(*geni_se_dev->clk_perf_tbl), + GFP_KERNEL); if (!geni_se_dev->clk_perf_tbl) { ret = -ENOMEM; goto exit_se_clk_tbl_get; @@ -1860,8 +1861,10 @@ static struct msm_bus_scale_pdata *ab_ib_register(struct platform_device *pdev, for (i = 0; i < pdata->num_usecases; i++) { usecase[i].num_paths = host->num_paths; - usecase[i].vectors = devm_kzalloc(dev, host->num_paths * - sizeof(struct msm_bus_vectors), GFP_KERNEL); + usecase[i].vectors = devm_kcalloc(dev, + host->num_paths, + sizeof(struct msm_bus_vectors), + GFP_KERNEL); if (!usecase[i].vectors) { mem_err = true; pr_err("Error: Mem alloc failure in vectors\n"); @@ -2040,7 +2043,8 @@ static int geni_se_probe(struct platform_device *pdev) ret = devm_clk_bulk_get(dev, SSC_NUM_CLKS, geni_se_dev->ssc_clks); if (ret) { - dev_err(dev, "%s: Err getting core/2x clk:%d\n", ret); + dev_err(dev, "%s: Err getting core/2x clk:%d\n", + __func__, ret); return ret; } diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c index d0079e39e84d..8bdb7e108cdc 100644 --- a/drivers/platform/msm/usb_bam.c +++ b/drivers/platform/msm/usb_bam.c @@ -2952,8 +2952,10 @@ static struct msm_usb_bam_data *usb_bam_dt_to_data( goto err; } - usb_bam_connections = devm_kzalloc(&pdev->dev, max_connections * - sizeof(struct usb_bam_pipe_connect), GFP_KERNEL); + usb_bam_connections = devm_kcalloc(&pdev->dev, + max_connections, + sizeof(struct usb_bam_pipe_connect), + GFP_KERNEL); if (!usb_bam_connections) { log_event_err("%s: devm_kzalloc failed(%d)\n", @@ -3165,8 +3167,8 @@ static int enable_usb_bam(struct platform_device *pdev) if (ret) return ret; - ctx->usb_bam_sps.sps_pipes = devm_kzalloc(&pdev->dev, - ctx->max_connections * sizeof(struct sps_pipe *), + ctx->usb_bam_sps.sps_pipes = devm_kcalloc(&pdev->dev, + ctx->max_connections, sizeof(struct sps_pipe *), GFP_KERNEL); if (!ctx->usb_bam_sps.sps_pipes) { @@ -3174,8 +3176,8 @@ static int enable_usb_bam(struct platform_device *pdev) return -ENOMEM; } - ctx->usb_bam_sps.sps_connections = devm_kzalloc(&pdev->dev, - ctx->max_connections * sizeof(struct sps_connect), + ctx->usb_bam_sps.sps_connections = devm_kcalloc(&pdev->dev, + ctx->max_connections, sizeof(struct sps_connect), GFP_KERNEL); if (!ctx->usb_bam_sps.sps_connections) { log_event_err("%s: failed to allocate sps_connections\n", diff --git a/drivers/platform/x86/alienware-wmi.c b/drivers/platform/x86/alienware-wmi.c index 2c82188f8486..d04a9b80a9c0 100644 --- a/drivers/platform/x86/alienware-wmi.c +++ b/drivers/platform/x86/alienware-wmi.c @@ -441,19 +441,19 @@ static int alienware_zone_init(struct platform_device *dev) * - zone_data num_zones is for the distinct zones */ zone_dev_attrs = - kzalloc(sizeof(struct device_attribute) * (quirks->num_zones + 1), + kcalloc(quirks->num_zones + 1, sizeof(struct device_attribute), GFP_KERNEL); if (!zone_dev_attrs) return -ENOMEM; zone_attrs = - kzalloc(sizeof(struct attribute *) * (quirks->num_zones + 2), + kcalloc(quirks->num_zones + 2, sizeof(struct attribute *), GFP_KERNEL); if (!zone_attrs) return -ENOMEM; zone_data = - kzalloc(sizeof(struct platform_zone) * (quirks->num_zones), + kcalloc(quirks->num_zones, sizeof(struct platform_zone), GFP_KERNEL); if (!zone_data) return -ENOMEM; diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index 58dcee562d64..054005051133 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -968,12 +968,12 @@ static int ips_monitor(void *data) u16 *mcp_samples, *ctv1_samples, *ctv2_samples, *mch_samples; u8 cur_seqno, last_seqno; - mcp_samples = kzalloc(sizeof(u16) * IPS_SAMPLE_COUNT, GFP_KERNEL); - ctv1_samples = kzalloc(sizeof(u16) * IPS_SAMPLE_COUNT, GFP_KERNEL); - ctv2_samples = kzalloc(sizeof(u16) * IPS_SAMPLE_COUNT, GFP_KERNEL); - mch_samples = kzalloc(sizeof(u16) * IPS_SAMPLE_COUNT, GFP_KERNEL); - cpu_samples = kzalloc(sizeof(u32) * IPS_SAMPLE_COUNT, GFP_KERNEL); - mchp_samples = kzalloc(sizeof(u32) * IPS_SAMPLE_COUNT, GFP_KERNEL); + mcp_samples = kcalloc(IPS_SAMPLE_COUNT, sizeof(u16), GFP_KERNEL); + ctv1_samples = kcalloc(IPS_SAMPLE_COUNT, sizeof(u16), GFP_KERNEL); + ctv2_samples = kcalloc(IPS_SAMPLE_COUNT, sizeof(u16), GFP_KERNEL); + mch_samples = kcalloc(IPS_SAMPLE_COUNT, sizeof(u16), GFP_KERNEL); + cpu_samples = kcalloc(IPS_SAMPLE_COUNT, sizeof(u32), GFP_KERNEL); + mchp_samples = kcalloc(IPS_SAMPLE_COUNT, sizeof(u32), GFP_KERNEL); if (!mcp_samples || !ctv1_samples || !ctv2_samples || !mch_samples || !cpu_samples || !mchp_samples) { dev_err(&ips->dev->dev, diff --git a/drivers/platform/x86/mlxcpld-hotplug.c b/drivers/platform/x86/mlxcpld-hotplug.c index aff3686b3b37..c6fdd4e1d2c5 100644 --- a/drivers/platform/x86/mlxcpld-hotplug.c +++ b/drivers/platform/x86/mlxcpld-hotplug.c @@ -140,7 +140,8 @@ static int mlxcpld_hotplug_attr_init(struct mlxcpld_hotplug_priv_data *priv) priv->plat->fan_count; int i; - priv->group.attrs = devm_kzalloc(&priv->pdev->dev, num_attrs * + priv->group.attrs = devm_kcalloc(&priv->pdev->dev, + num_attrs, sizeof(struct attribute *), GFP_KERNEL); if (!priv->group.attrs) diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index 5c39b3211709..8361ad75389a 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c @@ -571,7 +571,7 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) return -ENOMEM; } - pcc->sinf = kzalloc(sizeof(u32) * (num_sifr + 1), GFP_KERNEL); + pcc->sinf = kcalloc(num_sifr + 1, sizeof(u32), GFP_KERNEL); if (!pcc->sinf) { result = -ENOMEM; goto out_hotkey; diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 00d16cdef064..69fe49ceadf7 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -5966,7 +5966,7 @@ static int __init led_init(struct ibm_init_struct *iibm) if (led_supported == TPACPI_LED_NONE) return 1; - tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS, + tpacpi_leds = kcalloc(TPACPI_LED_NUMLEDS, sizeof(*tpacpi_leds), GFP_KERNEL); if (!tpacpi_leds) { pr_err("Out of memory for LED data\n"); diff --git a/drivers/power/supply/charger-manager.c b/drivers/power/supply/charger-manager.c index f60dfc213257..d0ad8229133b 100644 --- a/drivers/power/supply/charger-manager.c +++ b/drivers/power/supply/charger-manager.c @@ -1379,7 +1379,7 @@ static int charger_manager_register_sysfs(struct charger_manager *cm) snprintf(buf, 10, "charger.%d", i); str = devm_kzalloc(cm->dev, - sizeof(char) * (strlen(buf) + 1), GFP_KERNEL); + strlen(buf) + 1, GFP_KERNEL); if (!str) return -ENOMEM; @@ -1521,8 +1521,10 @@ static struct charger_desc *of_cm_parse_desc(struct device *dev) of_property_read_u32(np, "cm-num-chargers", &num_chgs); if (num_chgs) { /* Allocate empty bin at the tail of array */ - desc->psy_charger_stat = devm_kzalloc(dev, sizeof(char *) - * (num_chgs + 1), GFP_KERNEL); + desc->psy_charger_stat = devm_kcalloc(dev, + num_chgs + 1, + sizeof(char *), + GFP_KERNEL); if (desc->psy_charger_stat) { int i; for (i = 0; i < num_chgs; i++) @@ -1554,8 +1556,9 @@ static struct charger_desc *of_cm_parse_desc(struct device *dev) struct charger_regulator *chg_regs; struct device_node *child; - chg_regs = devm_kzalloc(dev, sizeof(*chg_regs) - * desc->num_charger_regulators, + chg_regs = devm_kcalloc(dev, + desc->num_charger_regulators, + sizeof(*chg_regs), GFP_KERNEL); if (!chg_regs) return ERR_PTR(-ENOMEM); @@ -1572,9 +1575,10 @@ static struct charger_desc *of_cm_parse_desc(struct device *dev) /* charger cables */ chg_regs->num_cables = of_get_child_count(child); if (chg_regs->num_cables) { - cables = devm_kzalloc(dev, sizeof(*cables) - * chg_regs->num_cables, - GFP_KERNEL); + cables = devm_kcalloc(dev, + chg_regs->num_cables, + sizeof(*cables), + GFP_KERNEL); if (!cables) { of_node_put(child); return ERR_PTR(-ENOMEM); @@ -1723,10 +1727,10 @@ static int charger_manager_probe(struct platform_device *pdev) cm->charger_psy_desc.name = cm->psy_name_buf; /* Allocate for psy properties because they may vary */ - cm->charger_psy_desc.properties = devm_kzalloc(&pdev->dev, - sizeof(enum power_supply_property) - * (ARRAY_SIZE(default_charger_props) + - NUM_CHARGER_PSY_OPTIONAL), GFP_KERNEL); + cm->charger_psy_desc.properties = devm_kcalloc(&pdev->dev, + ARRAY_SIZE(default_charger_props) + NUM_CHARGER_PSY_OPTIONAL, + sizeof(enum power_supply_property), + GFP_KERNEL); if (!cm->charger_psy_desc.properties) return -ENOMEM; diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c index 4bcfcf67dcf6..ec0e1a26fc77 100644 --- a/drivers/power/supply/power_supply_core.c +++ b/drivers/power/supply/power_supply_core.c @@ -272,8 +272,8 @@ static int power_supply_check_supplies(struct power_supply *psy) if (!psy->supplied_from) return -ENOMEM; - *psy->supplied_from = devm_kzalloc(&psy->dev, - sizeof(char *) * (cnt - 1), + *psy->supplied_from = devm_kcalloc(&psy->dev, + cnt - 1, sizeof(char *), GFP_KERNEL); if (!*psy->supplied_from) return -ENOMEM; diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c index 44b142f77150..650f7652ad28 100644 --- a/drivers/power/supply/qcom/battery.c +++ b/drivers/power/supply/qcom/battery.c @@ -202,7 +202,8 @@ static int cp_get_parallel_mode(struct pl_data *chip, int mode) static int get_adapter_icl_based_ilim(struct pl_data *chip) { - int main_icl, adapter_icl = -EINVAL, rc = -EINVAL, final_icl = -EINVAL; + int main_icl = -EINVAL, adapter_icl = -EINVAL, final_icl = -EINVAL; + int rc = -EINVAL; union power_supply_propval pval = {0, }; rc = power_supply_get_property(chip->usb_psy, diff --git a/drivers/power/supply/qcom/qpnp-smb5.c b/drivers/power/supply/qcom/qpnp-smb5.c index 5b4f5c619c31..5222f4fb6f9f 100644 --- a/drivers/power/supply/qcom/qpnp-smb5.c +++ b/drivers/power/supply/qcom/qpnp-smb5.c @@ -1153,7 +1153,7 @@ static int smb5_usb_get_prop(struct power_supply *psy, val->intval = get_client_vote(chg->usb_icl_votable, PD_VOTER); break; case POWER_SUPPLY_PROP_CURRENT_MAX: - rc = smblib_get_prop_input_current_settled(chg, val); + rc = smblib_get_prop_input_current_max(chg, val); break; case POWER_SUPPLY_PROP_TYPE: val->intval = POWER_SUPPLY_TYPE_USB_PD; diff --git a/drivers/power/supply/qcom/smb1390-charger-psy.c b/drivers/power/supply/qcom/smb1390-charger-psy.c index bb2daa1a1bed..2ba33936e048 100644 --- a/drivers/power/supply/qcom/smb1390-charger-psy.c +++ b/drivers/power/supply/qcom/smb1390-charger-psy.c @@ -211,10 +211,10 @@ struct smb1390 { int cp_isns_slave; int cp_ilim; int die_temp; + int min_ilim_ua; bool suspended; bool disabled; u32 debug_mask; - u32 min_ilim_ua; u32 max_temp_alarm_degc; u32 max_cutoff_soc; u32 pl_output_mode; @@ -1240,7 +1240,7 @@ static void smb1390_taper_work(struct work_struct *work) { struct smb1390 *chip = container_of(work, struct smb1390, taper_work); union power_supply_propval pval = {0, }; - int rc, fcc_uA, delta_fcc_uA, main_fcc_ua = 0; + int rc, fcc_uA, delta_fcc_uA, main_fcc_ua = 0, fcc_cp_ua; if (!is_psy_voter_available(chip)) goto out; @@ -1290,7 +1290,21 @@ static void smb1390_taper_work(struct work_struct *work) goto out; } - if ((fcc_uA - main_fcc_ua) < (chip->min_ilim_ua * 2)) { + /* + * fcc and fcc_main are the same for VPH config, hence + * reduce fcc_main from fcc only in VBAT (output config) + * where fcc_main is a portion of full-fcc. + */ + fcc_cp_ua = fcc_uA; + if (chip->pl_output_mode == POWER_SUPPLY_PL_OUTPUT_VBAT) + fcc_cp_ua = fcc_uA - main_fcc_ua; + + smb1390_dbg(chip, PR_INFO, + "Taper: fcc_ua=%d fcc_cp_ua=%d fcc_main_ua=%d min_ilim_ua(x2) = %u\n", + fcc_uA, fcc_cp_ua, main_fcc_ua, + (chip->min_ilim_ua*2)); + + if (fcc_cp_ua < (chip->min_ilim_ua * 2)) { vote(chip->disable_votable, TAPER_END_VOTER, true, 0); /* diff --git a/drivers/power/supply/qcom/smb1398-charger.c b/drivers/power/supply/qcom/smb1398-charger.c index 2c1abcdc471c..d52d1410d7eb 100644 --- a/drivers/power/supply/qcom/smb1398-charger.c +++ b/drivers/power/supply/qcom/smb1398-charger.c @@ -99,6 +99,7 @@ #define MISC_CFG0_REG 0x2634 #define DIS_SYNC_DRV_BIT BIT(5) #define SW_EN_SWITCHER_BIT BIT(3) +#define CFG_DIS_FPF_IREV_BIT BIT(1) #define MISC_CFG1_REG 0x2635 #define MISC_CFG1_MASK GENMASK(7, 0) @@ -1907,6 +1908,14 @@ static int smb1398_div2_cp_hw_init(struct smb1398_chip *chip) return rc; } + /* Configure window (Vin/2 - Vout) UV level to 10mV */ + rc = smb1398_masked_write(chip, NOLOCK_SPARE_REG, + DIV2_WIN_UV_SEL_BIT, 0); + if (rc < 0) { + dev_err(chip->dev, "Couldn't set WIN_UV_10_MV rc=%d\n", rc); + return rc; + } + /* Configure master TEMP pin to output Vtemp signal by default */ rc = smb1398_masked_write(chip, SSUPLY_TEMP_CTRL_REG, SEL_OUT_TEMP_MAX_MASK, SEL_OUT_VTEMP); @@ -1947,6 +1956,14 @@ static int smb1398_div2_cp_hw_init(struct smb1398_chip *chip) return rc; } + /* Do not disable FP_FET during IREV conditions */ + rc = smb1398_masked_write(chip, MISC_CFG0_REG, CFG_DIS_FPF_IREV_BIT, 0); + if (rc < 0) { + dev_err(chip->dev, "Couldn't set CFG_DIS_FPF_IREV_BIT, rc=%d\n", + rc); + return rc; + } + /* switcher enable controlled by register */ rc = smb1398_masked_write(chip, MISC_CFG0_REG, SW_EN_SWITCHER_BIT, SW_EN_SWITCHER_BIT); @@ -2232,6 +2249,14 @@ static int smb1398_div2_cp_slave_probe(struct smb1398_chip *chip) return rc; } + /* Configure window (Vin/2 - Vout) UV level to 10mV */ + rc = smb1398_masked_write(chip, NOLOCK_SPARE_REG, + DIV2_WIN_UV_SEL_BIT, 0); + if (rc < 0) { + dev_err(chip->dev, "Couldn't set WIN_UV_10_MV rc=%d\n", rc); + return rc; + } + /* * Disable slave WIN_UV detection, otherwise slave might not be * enabled due to WIN_UV until master drawing very high current. diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c index 991a0a60058c..6fc97afea5d8 100644 --- a/drivers/power/supply/qcom/smb5-lib.c +++ b/drivers/power/supply/qcom/smb5-lib.c @@ -1500,6 +1500,7 @@ static int smblib_get_pulse_cnt(struct smb_charger *chg, int *count) #define USBIN_150MA 150000 #define USBIN_500MA 500000 #define USBIN_900MA 900000 +#define USBIN_1000MA 1000000 static int set_sdp_current(struct smb_charger *chg, int icl_ua) { int rc; @@ -4798,6 +4799,24 @@ int smblib_get_prop_input_current_settled(struct smb_charger *chg, return smblib_get_charge_param(chg, &chg->param.icl_stat, &val->intval); } +int smblib_get_prop_input_current_max(struct smb_charger *chg, + union power_supply_propval *val) +{ + int icl_ua = 0, rc; + + rc = smblib_get_charge_param(chg, &chg->param.usb_icl, &icl_ua); + if (rc < 0) + return rc; + + if (is_override_vote_enabled_locked(chg->usb_icl_votable) && + icl_ua < USBIN_1000MA) { + val->intval = USBIN_1000MA; + return 0; + } + + return smblib_get_charge_param(chg, &chg->param.icl_stat, &val->intval); +} + int smblib_get_prop_input_voltage_settled(struct smb_charger *chg, union power_supply_propval *val) { diff --git a/drivers/power/supply/qcom/smb5-lib.h b/drivers/power/supply/qcom/smb5-lib.h index deef4d4b8561..8272610df53a 100644 --- a/drivers/power/supply/qcom/smb5-lib.h +++ b/drivers/power/supply/qcom/smb5-lib.h @@ -913,6 +913,8 @@ int smblib_get_prop_charger_temp(struct smb_charger *chg, int smblib_get_prop_die_health(struct smb_charger *chg); int smblib_get_prop_smb_health(struct smb_charger *chg); int smblib_get_prop_connector_health(struct smb_charger *chg); +int smblib_get_prop_input_current_max(struct smb_charger *chg, + union power_supply_propval *val); int smblib_set_prop_thermal_overheat(struct smb_charger *chg, int therm_overheat); int smblib_get_skin_temp_status(struct smb_charger *chg); diff --git a/drivers/power/supply/wm97xx_battery.c b/drivers/power/supply/wm97xx_battery.c index bd4f66651513..6754e761778a 100644 --- a/drivers/power/supply/wm97xx_battery.c +++ b/drivers/power/supply/wm97xx_battery.c @@ -201,7 +201,7 @@ static int wm97xx_bat_probe(struct platform_device *dev) if (pdata->min_voltage >= 0) props++; /* POWER_SUPPLY_PROP_VOLTAGE_MIN */ - prop = kzalloc(props * sizeof(*prop), GFP_KERNEL); + prop = kcalloc(props, sizeof(*prop), GFP_KERNEL); if (!prop) { ret = -ENOMEM; goto err3; diff --git a/drivers/power/supply/z2_battery.c b/drivers/power/supply/z2_battery.c index 8a43b49cfd35..bcc2d1a9b0a7 100644 --- a/drivers/power/supply/z2_battery.c +++ b/drivers/power/supply/z2_battery.c @@ -146,7 +146,7 @@ static int z2_batt_ps_init(struct z2_charger *charger, int props) if (info->min_voltage >= 0) props++; /* POWER_SUPPLY_PROP_VOLTAGE_MIN */ - prop = kzalloc(props * sizeof(*prop), GFP_KERNEL); + prop = kcalloc(props, sizeof(*prop), GFP_KERNEL); if (!prop) return -ENOMEM; diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c index 5b10b50f8686..f9bce9e93f90 100644 --- a/drivers/powercap/powercap_sys.c +++ b/drivers/powercap/powercap_sys.c @@ -545,15 +545,16 @@ struct powercap_zone *powercap_register_zone( dev_set_name(&power_zone->dev, "%s:%x", dev_name(power_zone->dev.parent), power_zone->id); - power_zone->constraints = kzalloc(sizeof(*power_zone->constraints) * - nr_constraints, GFP_KERNEL); + power_zone->constraints = kcalloc(nr_constraints, + sizeof(*power_zone->constraints), + GFP_KERNEL); if (!power_zone->constraints) goto err_const_alloc; nr_attrs = nr_constraints * POWERCAP_CONSTRAINTS_ATTRS + POWERCAP_ZONE_MAX_ATTRS + 1; - power_zone->zone_dev_attrs = kzalloc(sizeof(void *) * - nr_attrs, GFP_KERNEL); + power_zone->zone_dev_attrs = kcalloc(nr_attrs, sizeof(void *), + GFP_KERNEL); if (!power_zone->zone_dev_attrs) goto err_attr_alloc; create_power_zone_common_attributes(power_zone); diff --git a/drivers/pwm/pwm-lp3943.c b/drivers/pwm/pwm-lp3943.c index 52584e9962ed..15b40a8bc4fb 100644 --- a/drivers/pwm/pwm-lp3943.c +++ b/drivers/pwm/pwm-lp3943.c @@ -225,7 +225,7 @@ static int lp3943_pwm_parse_dt(struct device *dev, if (num_outputs == 0) continue; - output = devm_kzalloc(dev, sizeof(*output) * num_outputs, + output = devm_kcalloc(dev, num_outputs, sizeof(*output), GFP_KERNEL); if (!output) return -ENOMEM; diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c index f15f6d1e1070..d802389acee2 100644 --- a/drivers/rapidio/devices/rio_mport_cdev.c +++ b/drivers/rapidio/devices/rio_mport_cdev.c @@ -1032,7 +1032,7 @@ static int rio_mport_transfer_ioctl(struct file *filp, void __user *arg) priv->md->properties.transfer_mode) == 0) return -ENODEV; - transfer = vmalloc(transaction.count * sizeof(*transfer)); + transfer = vmalloc(array_size(sizeof(*transfer), transaction.count)); if (!transfer) return -ENOMEM; diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 23429bdaca84..887b3316385f 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -425,9 +425,8 @@ static struct rio_dev *rio_setup_device(struct rio_net *net, rswitch = rdev->rswitch; rswitch->port_ok = 0; spin_lock_init(&rswitch->lock); - rswitch->route_table = kzalloc(sizeof(u8)* - RIO_MAX_ROUTE_ENTRIES(port->sys_size), - GFP_KERNEL); + rswitch->route_table = kzalloc(RIO_MAX_ROUTE_ENTRIES(port->sys_size), + GFP_KERNEL); if (!rswitch->route_table) goto cleanup; /* Initialize switch route table */ diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index 39e8d60df060..e0239cf3f56d 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -425,9 +425,10 @@ static int act8865_pdata_from_dt(struct device *dev, if (matched <= 0) return matched; - pdata->regulators = devm_kzalloc(dev, - sizeof(struct act8865_regulator_data) * - num_matches, GFP_KERNEL); + pdata->regulators = devm_kcalloc(dev, + num_matches, + sizeof(struct act8865_regulator_data), + GFP_KERNEL); if (!pdata->regulators) return -ENOMEM; diff --git a/drivers/regulator/as3711-regulator.c b/drivers/regulator/as3711-regulator.c index 874d415d6b4f..565a71343a8e 100644 --- a/drivers/regulator/as3711-regulator.c +++ b/drivers/regulator/as3711-regulator.c @@ -239,8 +239,10 @@ static int as3711_regulator_probe(struct platform_device *pdev) } } - regs = devm_kzalloc(&pdev->dev, AS3711_REGULATOR_NUM * - sizeof(struct as3711_regulator), GFP_KERNEL); + regs = devm_kcalloc(&pdev->dev, + AS3711_REGULATOR_NUM, + sizeof(struct as3711_regulator), + GFP_KERNEL); if (!regs) return -ENOMEM; diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c index 9dd715407b39..92d6d7b10cf7 100644 --- a/drivers/regulator/bcm590xx-regulator.c +++ b/drivers/regulator/bcm590xx-regulator.c @@ -383,8 +383,10 @@ static int bcm590xx_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pmu); - pmu->desc = devm_kzalloc(&pdev->dev, BCM590XX_NUM_REGS * - sizeof(struct regulator_desc), GFP_KERNEL); + pmu->desc = devm_kcalloc(&pdev->dev, + BCM590XX_NUM_REGS, + sizeof(struct regulator_desc), + GFP_KERNEL); if (!pmu->desc) return -ENOMEM; diff --git a/drivers/regulator/cpr-regulator.c b/drivers/regulator/cpr-regulator.c index 0fc02056add3..210439c0a85e 100644 --- a/drivers/regulator/cpr-regulator.c +++ b/drivers/regulator/cpr-regulator.c @@ -1751,8 +1751,8 @@ static int cpr_config(struct cpr_regulator *cpr_vreg, struct device *dev) cpr_vreg->flags |= FLAGS_IGNORE_1ST_IRQ_STATUS; size = cpr_vreg->num_corners + 1; - cpr_vreg->save_ctl = devm_kzalloc(dev, sizeof(int) * size, GFP_KERNEL); - cpr_vreg->save_irq = devm_kzalloc(dev, sizeof(int) * size, GFP_KERNEL); + cpr_vreg->save_ctl = devm_kcalloc(dev, size, sizeof(int), GFP_KERNEL); + cpr_vreg->save_irq = devm_kcalloc(dev, size, sizeof(int), GFP_KERNEL); if (!cpr_vreg->save_ctl || !cpr_vreg->save_irq) return -ENOMEM; @@ -1903,7 +1903,7 @@ static int cpr_pvs_per_corner_init(struct device_node *of_node, "fuse position for init voltages is invalid\n"); return -EINVAL; } - fuse_sel = kzalloc(sizeof(u32) * size, GFP_KERNEL); + fuse_sel = kcalloc(size, sizeof(u32), GFP_KERNEL); if (!fuse_sel) return -ENOMEM; rc = of_property_read_u32_array(of_node, init_volt_str, @@ -1923,8 +1923,8 @@ static int cpr_pvs_per_corner_init(struct device_node *of_node, return rc; } - ref_uv = kzalloc((cpr_vreg->num_fuse_corners + 1) * sizeof(*ref_uv), - GFP_KERNEL); + ref_uv = kcalloc(cpr_vreg->num_fuse_corners + 1, sizeof(*ref_uv), + GFP_KERNEL); if (!ref_uv) { kfree(fuse_sel); return -ENOMEM; @@ -2036,7 +2036,8 @@ static int cpr_pvs_single_bin_init(struct device_node *of_node, ((1 << pvs_fuse[2]) - 1); pvs_bins = 1 << pvs_fuse[2]; stripe_size = cpr_vreg->num_fuse_corners; - tmp = kzalloc(sizeof(u32) * pvs_bins * stripe_size, GFP_KERNEL); + tmp = kzalloc(array3_size(pvs_bins, stripe_size, sizeof(u32)), + GFP_KERNEL); if (!tmp) return -ENOMEM; @@ -2117,9 +2118,9 @@ static int cpr_parse_vdd_mx_parameters(struct platform_device *pdev, return -EINVAL; } - cpr_vreg->vdd_mx_corner_map = devm_kzalloc(&pdev->dev, - (corner_map_len + 1) * sizeof(*cpr_vreg->vdd_mx_corner_map), - GFP_KERNEL); + cpr_vreg->vdd_mx_corner_map = devm_kcalloc(&pdev->dev, + corner_map_len + 1, sizeof(*cpr_vreg->vdd_mx_corner_map), + GFP_KERNEL); if (!cpr_vreg->vdd_mx_corner_map) return -ENOMEM; @@ -2368,8 +2369,8 @@ static int cpr_get_open_loop_voltage(struct cpr_regulator *cpr_vreg, u64 volt_high, volt_low, freq_high, freq_low, freq, temp, temp_limit; u32 *max_factor = NULL; - cpr_vreg->open_loop_volt = devm_kzalloc(dev, - sizeof(int) * (cpr_vreg->num_corners + 1), GFP_KERNEL); + cpr_vreg->open_loop_volt = devm_kcalloc(dev, + cpr_vreg->num_corners + 1, sizeof(int), GFP_KERNEL); if (!cpr_vreg->open_loop_volt) return -ENOMEM; @@ -2392,7 +2393,7 @@ static int cpr_get_open_loop_voltage(struct cpr_regulator *cpr_vreg, } max_factor - = kzalloc(sizeof(*max_factor) * (cpr_vreg->num_fuse_corners + 1), + = kcalloc(cpr_vreg->num_fuse_corners + 1, sizeof(*max_factor), GFP_KERNEL); if (!max_factor) return -ENOMEM; @@ -2604,7 +2605,7 @@ static int cpr_get_fuse_quot_offset(struct cpr_regulator *cpr_vreg, return -EINVAL; } - fuse_sel = kzalloc(sizeof(u32) * size, GFP_KERNEL); + fuse_sel = kcalloc(size, sizeof(u32), GFP_KERNEL); if (!fuse_sel) return -ENOMEM; @@ -2618,8 +2619,8 @@ static int cpr_get_fuse_quot_offset(struct cpr_regulator *cpr_vreg, return rc; } - cpr_vreg->fuse_quot_offset = devm_kzalloc(dev, - sizeof(u32) * (cpr_vreg->num_fuse_corners + 1), + cpr_vreg->fuse_quot_offset = devm_kcalloc(dev, + cpr_vreg->num_fuse_corners + 1, sizeof(u32), GFP_KERNEL); if (!cpr_vreg->fuse_quot_offset) { kfree(fuse_sel); @@ -2636,9 +2637,9 @@ static int cpr_get_fuse_quot_offset(struct cpr_regulator *cpr_vreg, return -EINVAL; } - offset_multiplier = kzalloc(sizeof(*offset_multiplier) - * (cpr_vreg->num_fuse_corners + 1), - GFP_KERNEL); + offset_multiplier = kcalloc(cpr_vreg->num_fuse_corners + 1, + sizeof(*offset_multiplier), + GFP_KERNEL); if (!offset_multiplier) { kfree(fuse_sel); return -ENOMEM; @@ -2823,14 +2824,14 @@ static int cpr_get_corner_quot_adjustment(struct cpr_regulator *cpr_vreg, corners_mapped = false; } - cpr_vreg->corner_map = devm_kzalloc(dev, sizeof(int) * (size + 1), - GFP_KERNEL); + cpr_vreg->corner_map = devm_kcalloc(dev, size + 1, sizeof(int), + GFP_KERNEL); if (!cpr_vreg->corner_map) return -ENOMEM; cpr_vreg->num_corners = size; - cpr_vreg->quot_adjust = devm_kzalloc(dev, - sizeof(u32) * (cpr_vreg->num_corners + 1), + cpr_vreg->quot_adjust = devm_kcalloc(dev, + cpr_vreg->num_corners + 1, sizeof(u32), GFP_KERNEL); if (!cpr_vreg->quot_adjust) return -ENOMEM; @@ -3208,8 +3209,8 @@ static int cpr_read_ro_select(struct platform_device *pdev, int i; bp_ro_sel - = kzalloc((cpr_vreg->num_fuse_corners + 1) * sizeof(*bp_ro_sel), - GFP_KERNEL); + = kcalloc(cpr_vreg->num_fuse_corners + 1, sizeof(*bp_ro_sel), + GFP_KERNEL); if (!bp_ro_sel) return -ENOMEM; @@ -4117,7 +4118,8 @@ static int cpr_init_cpr_voltages(struct cpr_regulator *cpr_vreg, int i; int size = cpr_vreg->num_corners + 1; - cpr_vreg->last_volt = devm_kzalloc(dev, sizeof(int) * size, GFP_KERNEL); + cpr_vreg->last_volt = devm_kcalloc(dev, size, sizeof(int), + GFP_KERNEL); if (!cpr_vreg->last_volt) return -EINVAL; @@ -4226,12 +4228,12 @@ static int cpr_init_ceiling_floor_override_voltages( int rc, i; int size = cpr_vreg->num_corners + 1; - cpr_vreg->ceiling_volt = devm_kzalloc(dev, sizeof(int) * size, + cpr_vreg->ceiling_volt = devm_kcalloc(dev, size, sizeof(int), GFP_KERNEL); - cpr_vreg->floor_volt = devm_kzalloc(dev, sizeof(int) * size, - GFP_KERNEL); - cpr_vreg->cpr_max_ceiling = devm_kzalloc(dev, sizeof(int) * size, + cpr_vreg->floor_volt = devm_kcalloc(dev, size, sizeof(int), GFP_KERNEL); + cpr_vreg->cpr_max_ceiling = devm_kcalloc(dev, size, sizeof(int), + GFP_KERNEL); if (!cpr_vreg->ceiling_volt || !cpr_vreg->floor_volt || !cpr_vreg->cpr_max_ceiling) return -ENOMEM; @@ -4585,9 +4587,10 @@ static int cpr_rpm_apc_init(struct platform_device *pdev, return -EINVAL; } - cpr_vreg->rpm_apc_corner_map = devm_kzalloc(&pdev->dev, - (cpr_vreg->num_corners + 1) * - sizeof(*cpr_vreg->rpm_apc_corner_map), GFP_KERNEL); + cpr_vreg->rpm_apc_corner_map = devm_kcalloc(&pdev->dev, + cpr_vreg->num_corners + 1, + sizeof(*cpr_vreg->rpm_apc_corner_map), + GFP_KERNEL); if (!cpr_vreg->rpm_apc_corner_map) return -ENOMEM; @@ -4824,7 +4827,7 @@ static int cpr_remap_efuse_data(struct platform_device *pdev, return rc; } - temp = kzalloc(sizeof(*temp) * size * 4, GFP_KERNEL); + temp = kzalloc(array3_size(sizeof(*temp), size, 4), GFP_KERNEL); if (!temp) return -ENOMEM; @@ -4844,8 +4847,8 @@ static int cpr_remap_efuse_data(struct platform_device *pdev, bits += temp[i * 4 + 2]; cpr_vreg->num_remapped_rows = DIV_ROUND_UP(bits, 64); - cpr_vreg->remapped_row = devm_kzalloc(&pdev->dev, - sizeof(*cpr_vreg->remapped_row) * cpr_vreg->num_remapped_rows, + cpr_vreg->remapped_row = devm_kcalloc(&pdev->dev, + cpr_vreg->num_remapped_rows, sizeof(*cpr_vreg->remapped_row), GFP_KERNEL); if (!cpr_vreg->remapped_row) { rc = -ENOMEM; @@ -5024,18 +5027,18 @@ static int cpr_fuse_corner_array_alloc(struct device *dev, */ len = cpr_vreg->num_fuse_corners + 1; - cpr_vreg->pvs_corner_v = devm_kzalloc(dev, - len * sizeof(*cpr_vreg->pvs_corner_v), GFP_KERNEL); - cpr_vreg->cpr_fuse_target_quot = devm_kzalloc(dev, - len * sizeof(*cpr_vreg->cpr_fuse_target_quot), GFP_KERNEL); - cpr_vreg->cpr_fuse_ro_sel = devm_kzalloc(dev, - len * sizeof(*cpr_vreg->cpr_fuse_ro_sel), GFP_KERNEL); - cpr_vreg->fuse_ceiling_volt = devm_kzalloc(dev, - len * (sizeof(*cpr_vreg->fuse_ceiling_volt)), GFP_KERNEL); - cpr_vreg->fuse_floor_volt = devm_kzalloc(dev, - len * (sizeof(*cpr_vreg->fuse_floor_volt)), GFP_KERNEL); - cpr_vreg->step_quotient = devm_kzalloc(dev, - len * sizeof(*cpr_vreg->step_quotient), GFP_KERNEL); + cpr_vreg->pvs_corner_v = devm_kcalloc(dev, + len, sizeof(*cpr_vreg->pvs_corner_v), GFP_KERNEL); + cpr_vreg->cpr_fuse_target_quot = devm_kcalloc(dev, + len, sizeof(*cpr_vreg->cpr_fuse_target_quot), GFP_KERNEL); + cpr_vreg->cpr_fuse_ro_sel = devm_kcalloc(dev, + len, sizeof(*cpr_vreg->cpr_fuse_ro_sel), GFP_KERNEL); + cpr_vreg->fuse_ceiling_volt = devm_kcalloc(dev, + len, sizeof(*cpr_vreg->fuse_ceiling_volt), GFP_KERNEL); + cpr_vreg->fuse_floor_volt = devm_kcalloc(dev, + len, sizeof(*cpr_vreg->fuse_floor_volt), GFP_KERNEL); + cpr_vreg->step_quotient = devm_kcalloc(dev, + len, sizeof(*cpr_vreg->step_quotient), GFP_KERNEL); if (cpr_vreg->pvs_corner_v == NULL || cpr_vreg->cpr_fuse_ro_sel == NULL || cpr_vreg->fuse_ceiling_volt == NULL @@ -5126,8 +5129,8 @@ static int cpr_mem_acc_init(struct platform_device *pdev, } size = prop->length / sizeof(u32); - cpr_vreg->mem_acc_corner_map = devm_kzalloc(&pdev->dev, - sizeof(int) * (size + 1), + cpr_vreg->mem_acc_corner_map = devm_kcalloc(&pdev->dev, + size + 1, sizeof(int), GFP_KERNEL); rc = of_property_read_u32_array(pdev->dev.of_node, corner_map_str, diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c index 6a8f9cd69f52..2df26f36c687 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c @@ -681,8 +681,8 @@ static struct da9063_regulators_pdata *da9063_parse_regulators_dt( if (!pdata) return ERR_PTR(-ENOMEM); - pdata->regulator_data = devm_kzalloc(&pdev->dev, - num * sizeof(*pdata->regulator_data), + pdata->regulator_data = devm_kcalloc(&pdev->dev, + num, sizeof(*pdata->regulator_data), GFP_KERNEL); if (!pdata->regulator_data) return ERR_PTR(-ENOMEM); diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index a2eb50719c7b..953966f5e84d 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -172,8 +172,8 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np, if (ret > 0) { config->nr_gpios = ret; - config->gpios = devm_kzalloc(dev, - sizeof(struct gpio) * config->nr_gpios, + config->gpios = devm_kcalloc(dev, + config->nr_gpios, sizeof(struct gpio), GFP_KERNEL); if (!config->gpios) return ERR_PTR(-ENOMEM); @@ -213,9 +213,9 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np, return ERR_PTR(-EINVAL); } - config->states = devm_kzalloc(dev, - sizeof(struct gpio_regulator_state) - * (proplen / 2), + config->states = devm_kcalloc(dev, + proplen / 2, + sizeof(struct gpio_regulator_state), GFP_KERNEL); if (!config->states) return ERR_PTR(-ENOMEM); diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index 66bbaa999433..cc52779b53f7 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c @@ -194,8 +194,10 @@ static int of_get_max1586_platform_data(struct device *dev, if (matched <= 0) return matched; - pdata->subdevs = devm_kzalloc(dev, sizeof(struct max1586_subdev_data) * - matched, GFP_KERNEL); + pdata->subdevs = devm_kcalloc(dev, + matched, + sizeof(struct max1586_subdev_data), + GFP_KERNEL); if (!pdata->subdevs) return -ENOMEM; diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index a6183425f27d..4cf6897a401f 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c @@ -351,8 +351,10 @@ static int max8660_pdata_from_dt(struct device *dev, if (matched <= 0) return matched; - pdata->subdevs = devm_kzalloc(dev, sizeof(struct max8660_subdev_data) * - matched, GFP_KERNEL); + pdata->subdevs = devm_kcalloc(dev, + matched, + sizeof(struct max8660_subdev_data), + GFP_KERNEL); if (!pdata->subdevs) return -ENOMEM; diff --git a/drivers/regulator/max8997-regulator.c b/drivers/regulator/max8997-regulator.c index 559b9ac45404..a8ea30ee18a6 100644 --- a/drivers/regulator/max8997-regulator.c +++ b/drivers/regulator/max8997-regulator.c @@ -929,8 +929,9 @@ static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev, /* count the number of regulators to be supported in pmic */ pdata->num_regulators = of_get_child_count(regulators_np); - rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * - pdata->num_regulators, GFP_KERNEL); + rdata = devm_kcalloc(&pdev->dev, + pdata->num_regulators, sizeof(*rdata), + GFP_KERNEL); if (!rdata) { of_node_put(regulators_np); return -ENOMEM; diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 3027e7ce100b..050082230ad0 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c @@ -671,8 +671,9 @@ static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev, /* count the number of regulators to be supported in pmic */ pdata->num_regulators = of_get_child_count(regulators_np); - rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) * - pdata->num_regulators, GFP_KERNEL); + rdata = devm_kcalloc(iodev->dev, + pdata->num_regulators, sizeof(*rdata), + GFP_KERNEL); if (!rdata) { of_node_put(regulators_np); return -ENOMEM; diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index fe4c7d677f9c..0e0277bd91a8 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c @@ -409,9 +409,9 @@ static int mc13783_regulator_probe(struct platform_device *pdev) if (num_regulators <= 0) return -EINVAL; - priv = devm_kzalloc(&pdev->dev, sizeof(*priv) + - num_regulators * sizeof(priv->regulators[0]), - GFP_KERNEL); + priv = devm_kzalloc(&pdev->dev, + struct_size(priv, regulators, num_regulators), + GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c index 0d17c9206816..15dd7bc7b529 100644 --- a/drivers/regulator/mc13892-regulator.c +++ b/drivers/regulator/mc13892-regulator.c @@ -547,9 +547,9 @@ static int mc13892_regulator_probe(struct platform_device *pdev) if (num_regulators <= 0) return -EINVAL; - priv = devm_kzalloc(&pdev->dev, sizeof(*priv) + - num_regulators * sizeof(priv->regulators[0]), - GFP_KERNEL); + priv = devm_kzalloc(&pdev->dev, + struct_size(priv, regulators, num_regulators), + GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c index 0281c31ae2ed..eb63b11330f0 100644 --- a/drivers/regulator/mc13xxx-regulator-core.c +++ b/drivers/regulator/mc13xxx-regulator-core.c @@ -175,7 +175,7 @@ struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt( if (!parent) return NULL; - data = devm_kzalloc(&pdev->dev, sizeof(*data) * priv->num_regulators, + data = devm_kcalloc(&pdev->dev, priv->num_regulators, sizeof(*data), GFP_KERNEL); if (!data) { of_node_put(parent); diff --git a/drivers/regulator/mem-acc-regulator.c b/drivers/regulator/mem-acc-regulator.c index ebe50c185481..30cff9373c26 100644 --- a/drivers/regulator/mem-acc-regulator.c +++ b/drivers/regulator/mem-acc-regulator.c @@ -334,8 +334,8 @@ static int __mem_acc_sel_init(struct mem_acc_regulator *mem_acc_vreg, int i; u32 bit, mask; - mem_acc_vreg->acc_sel_mask[mem_type] = devm_kzalloc(mem_acc_vreg->dev, - mem_acc_vreg->num_acc_sel[mem_type] * sizeof(u32), GFP_KERNEL); + mem_acc_vreg->acc_sel_mask[mem_type] = devm_kcalloc(mem_acc_vreg->dev, + mem_acc_vreg->num_acc_sel[mem_type], sizeof(u32), GFP_KERNEL); if (!mem_acc_vreg->acc_sel_mask[mem_type]) return -ENOMEM; @@ -396,7 +396,7 @@ static int populate_acc_data(struct mem_acc_regulator *mem_acc_vreg, return -EINVAL; } - *value = devm_kzalloc(mem_acc_vreg->dev, (*len) * sizeof(u32), + *value = devm_kcalloc(mem_acc_vreg->dev, *len, sizeof(u32), GFP_KERNEL); if (!(*value)) { pr_err("Unable to allocate memory for %s\n", prop_name); @@ -1403,9 +1403,11 @@ static int mem_acc_init(struct platform_device *pdev, return rc; } if (acc_type_present) { - mem_acc_vreg->mem_acc_type_data = devm_kzalloc( - mem_acc_vreg->dev, mem_acc_vreg->num_corners * - MEM_ACC_TYPE_MAX * sizeof(u32), GFP_KERNEL); + mem_acc_vreg->mem_acc_type_data = devm_kcalloc( + mem_acc_vreg->dev, + mem_acc_vreg->num_corners * MEM_ACC_TYPE_MAX, + sizeof(u32), + GFP_KERNEL); if (!mem_acc_vreg->mem_acc_type_data) { pr_err("Unable to allocate memory for mem_acc_type\n"); diff --git a/drivers/regulator/pbias-regulator.c b/drivers/regulator/pbias-regulator.c index 0cb76ba29e84..6fca1968869a 100644 --- a/drivers/regulator/pbias-regulator.c +++ b/drivers/regulator/pbias-regulator.c @@ -158,8 +158,9 @@ static int pbias_regulator_probe(struct platform_device *pdev) if (count < 0) return count; - drvdata = devm_kzalloc(&pdev->dev, sizeof(struct pbias_regulator_data) - * count, GFP_KERNEL); + drvdata = devm_kcalloc(&pdev->dev, + count, sizeof(struct pbias_regulator_data), + GFP_KERNEL); if (!drvdata) return -ENOMEM; diff --git a/drivers/regulator/rc5t583-regulator.c b/drivers/regulator/rc5t583-regulator.c index d0f1340168b1..2ec51af43673 100644 --- a/drivers/regulator/rc5t583-regulator.c +++ b/drivers/regulator/rc5t583-regulator.c @@ -132,8 +132,10 @@ static int rc5t583_regulator_probe(struct platform_device *pdev) return -ENODEV; } - regs = devm_kzalloc(&pdev->dev, RC5T583_REGULATOR_MAX * - sizeof(struct rc5t583_regulator), GFP_KERNEL); + regs = devm_kcalloc(&pdev->dev, + RC5T583_REGULATOR_MAX, + sizeof(struct rc5t583_regulator), + GFP_KERNEL); if (!regs) return -ENOMEM; diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index 8f7c19901339..5193146bfbbe 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -1139,8 +1139,8 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) return -EINVAL; } - s2mps11->ext_control_gpio = devm_kmalloc(&pdev->dev, - sizeof(*s2mps11->ext_control_gpio) * rdev_num, + s2mps11->ext_control_gpio = devm_kmalloc_array(&pdev->dev, + rdev_num, sizeof(*s2mps11->ext_control_gpio), GFP_KERNEL); if (!s2mps11->ext_control_gpio) return -ENOMEM; @@ -1162,7 +1162,7 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) } } - rdata = kzalloc(sizeof(*rdata) * rdev_num, GFP_KERNEL); + rdata = kcalloc(rdev_num, sizeof(*rdata), GFP_KERNEL); if (!rdata) return -ENOMEM; diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 4836947e1521..ad94489aaf23 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -553,13 +553,15 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, /* count the number of regulators to be supported in pmic */ pdata->num_regulators = of_get_child_count(regulators_np); - rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * - pdata->num_regulators, GFP_KERNEL); + rdata = devm_kcalloc(&pdev->dev, + pdata->num_regulators, sizeof(*rdata), + GFP_KERNEL); if (!rdata) return -ENOMEM; - rmode = devm_kzalloc(&pdev->dev, sizeof(*rmode) * - pdata->num_regulators, GFP_KERNEL); + rmode = devm_kcalloc(&pdev->dev, + pdata->num_regulators, sizeof(*rmode), + GFP_KERNEL); if (!rmode) return -ENOMEM; diff --git a/drivers/regulator/ti-abb-regulator.c b/drivers/regulator/ti-abb-regulator.c index 6d17357b3a24..89b9314d64c9 100644 --- a/drivers/regulator/ti-abb-regulator.c +++ b/drivers/regulator/ti-abb-regulator.c @@ -522,13 +522,13 @@ static int ti_abb_init_table(struct device *dev, struct ti_abb *abb, } num_entries /= num_values; - info = devm_kzalloc(dev, sizeof(*info) * num_entries, GFP_KERNEL); + info = devm_kcalloc(dev, num_entries, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; abb->info = info; - volt_table = devm_kzalloc(dev, sizeof(unsigned int) * num_entries, + volt_table = devm_kcalloc(dev, num_entries, sizeof(unsigned int), GFP_KERNEL); if (!volt_table) return -ENOMEM; diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index 395f35dc8cdb..42a6cea64104 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c @@ -351,8 +351,9 @@ static struct tps65090_platform_data *tps65090_parse_dt_reg_data( if (!tps65090_pdata) return ERR_PTR(-ENOMEM); - reg_pdata = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * - sizeof(*reg_pdata), GFP_KERNEL); + reg_pdata = devm_kcalloc(&pdev->dev, + TPS65090_REGULATOR_MAX, sizeof(*reg_pdata), + GFP_KERNEL); if (!reg_pdata) return ERR_PTR(-ENOMEM); @@ -432,8 +433,9 @@ static int tps65090_regulator_probe(struct platform_device *pdev) return tps65090_pdata ? PTR_ERR(tps65090_pdata) : -EINVAL; } - pmic = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * sizeof(*pmic), - GFP_KERNEL); + pmic = devm_kcalloc(&pdev->dev, + TPS65090_REGULATOR_MAX, sizeof(*pmic), + GFP_KERNEL); if (!pmic) return -ENOMEM; diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 5324dc9e6d6e..77247e4d52b3 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -234,8 +234,9 @@ static int tps65217_regulator_probe(struct platform_device *pdev) } /* Allocate memory for strobes */ - tps->strobes = devm_kzalloc(&pdev->dev, sizeof(u8) * - TPS65217_NUM_REGULATOR, GFP_KERNEL); + tps->strobes = devm_kcalloc(&pdev->dev, + TPS65217_NUM_REGULATOR, sizeof(u8), + GFP_KERNEL); platform_set_drvdata(pdev, tps); diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index 9aafbb03482d..e5917ad4e5e3 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -327,8 +327,9 @@ static int tps65218_regulator_probe(struct platform_device *pdev) config.regmap = tps->regmap; /* Allocate memory for strobes */ - tps->strobes = devm_kzalloc(&pdev->dev, sizeof(u8) * - TPS65218_NUM_REGULATOR, GFP_KERNEL); + tps->strobes = devm_kcalloc(&pdev->dev, + TPS65218_NUM_REGULATOR, sizeof(u8), + GFP_KERNEL); for (i = 0; i < ARRAY_SIZE(regulators); i++) { rdev = devm_regulator_register(&pdev->dev, ®ulators[i], diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 194fa0cbbc04..5ebb6ee73f07 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -1133,18 +1133,24 @@ static int tps65910_probe(struct platform_device *pdev) return -ENODEV; } - pmic->desc = devm_kzalloc(&pdev->dev, pmic->num_regulators * - sizeof(struct regulator_desc), GFP_KERNEL); + pmic->desc = devm_kcalloc(&pdev->dev, + pmic->num_regulators, + sizeof(struct regulator_desc), + GFP_KERNEL); if (!pmic->desc) return -ENOMEM; - pmic->info = devm_kzalloc(&pdev->dev, pmic->num_regulators * - sizeof(struct tps_info *), GFP_KERNEL); + pmic->info = devm_kcalloc(&pdev->dev, + pmic->num_regulators, + sizeof(struct tps_info *), + GFP_KERNEL); if (!pmic->info) return -ENOMEM; - pmic->rdev = devm_kzalloc(&pdev->dev, pmic->num_regulators * - sizeof(struct regulator_dev *), GFP_KERNEL); + pmic->rdev = devm_kcalloc(&pdev->dev, + pmic->num_regulators, + sizeof(struct regulator_dev *), + GFP_KERNEL); if (!pmic->rdev) return -ENOMEM; diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c index d4cc60ad18ae..1001147404c3 100644 --- a/drivers/regulator/tps80031-regulator.c +++ b/drivers/regulator/tps80031-regulator.c @@ -691,8 +691,8 @@ static int tps80031_regulator_probe(struct platform_device *pdev) return -EINVAL; } - pmic = devm_kzalloc(&pdev->dev, - TPS80031_REGULATOR_MAX * sizeof(*pmic), GFP_KERNEL); + pmic = devm_kcalloc(&pdev->dev, + TPS80031_REGULATOR_MAX, sizeof(*pmic), GFP_KERNEL); if (!pmic) return -ENOMEM; diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 7e0a14211c88..d40afaee7a08 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -638,8 +638,7 @@ of_reset_control_array_get(struct device_node *np, bool shared, bool optional) if (num < 0) return optional ? NULL : ERR_PTR(num); - resets = kzalloc(sizeof(*resets) + sizeof(resets->rstc[0]) * num, - GFP_KERNEL); + resets = kzalloc(struct_size(resets, rstc, num), GFP_KERNEL); if (!resets) return ERR_PTR(-ENOMEM); diff --git a/drivers/reset/reset-ti-syscon.c b/drivers/reset/reset-ti-syscon.c index 99520b0a1329..a2635c21db7f 100644 --- a/drivers/reset/reset-ti-syscon.c +++ b/drivers/reset/reset-ti-syscon.c @@ -189,7 +189,8 @@ static int ti_syscon_reset_probe(struct platform_device *pdev) } nr_controls = (size / sizeof(*list)) / 7; - controls = devm_kzalloc(dev, nr_controls * sizeof(*controls), GFP_KERNEL); + controls = devm_kcalloc(dev, nr_controls, sizeof(*controls), + GFP_KERNEL); if (!controls) return -ENOMEM; diff --git a/drivers/rpmsg/qcom_glink_bgcom.c b/drivers/rpmsg/qcom_glink_bgcom.c index d76658bc031d..09318fa0928e 100644 --- a/drivers/rpmsg/qcom_glink_bgcom.c +++ b/drivers/rpmsg/qcom_glink_bgcom.c @@ -2016,6 +2016,51 @@ static void glink_bgcom_linkup(struct glink_bgcom *glink) GLINK_ERR(glink, "Failed to link up %d\n", ret); } +static int glink_bgcom_remove_device(struct device *dev, void *data) +{ + device_unregister(dev); + + return 0; +} + +static int glink_bgcom_cleanup(struct glink_bgcom *glink) +{ + struct glink_bgcom_channel *channel; + int cid; + int ret; + + GLINK_INFO(glink, "\n"); + + atomic_set(&glink->in_reset, 1); + + kthread_flush_worker(&glink->kworker); + cancel_work_sync(&glink->rx_defer_work); + + ret = device_for_each_child(glink->dev, NULL, + glink_bgcom_remove_device); + if (ret) + dev_warn(glink->dev, "Can't remove GLINK devices: %d\n", ret); + + mutex_lock(&glink->idr_lock); + /* Release any defunct local channels, waiting for close-ack */ + idr_for_each_entry(&glink->lcids, channel, cid) { + /* Wakeup threads waiting for intent*/ + complete(&channel->intent_req_comp); + kref_put(&channel->refcount, glink_bgcom_channel_release); + idr_remove(&glink->lcids, cid); + } + + /* Release any defunct local channels, waiting for close-req */ + idr_for_each_entry(&glink->rcids, channel, cid) { + kref_put(&channel->refcount, glink_bgcom_channel_release); + idr_remove(&glink->rcids, cid); + } + + mutex_unlock(&glink->idr_lock); + + return ret; +} + static void glink_bgcom_event_handler(void *handle, void *priv_data, enum bgcom_event_type event, union bgcom_event_data_type *data) @@ -2066,7 +2111,7 @@ static void glink_bgcom_event_handler(void *handle, break; case BGCOM_EVENT_RESET_OCCURRED: glink->bgcom_status = BGCOM_RESET; - atomic_set(&glink->in_reset, 1); + glink_bgcom_cleanup(glink); break; case BGCOM_EVENT_ERROR_WRITE_FIFO_OVERRUN: case BGCOM_EVENT_ERROR_WRITE_FIFO_BUS_ERR: @@ -2195,18 +2240,9 @@ err_put_dev: } EXPORT_SYMBOL(glink_bgcom_probe); -static int glink_bgcom_remove_device(struct device *dev, void *data) -{ - device_unregister(dev); - - return 0; -} - static int glink_bgcom_remove(struct platform_device *pdev) { struct glink_bgcom *glink = platform_get_drvdata(pdev); - struct glink_bgcom_channel *channel; - int cid; int ret; GLINK_INFO(glink, "\n"); @@ -2215,30 +2251,11 @@ static int glink_bgcom_remove(struct platform_device *pdev) bgcom_close(glink->bgcom_handle); - kthread_flush_worker(&glink->kworker); - kthread_stop(glink->rx_task); - cancel_work_sync(&glink->rx_defer_work); + ret = glink_bgcom_cleanup(glink); - ret = device_for_each_child(glink->dev, NULL, - glink_bgcom_remove_device); - if (ret) - dev_warn(glink->dev, "Can't remove GLINK devices: %d\n", ret); + kthread_stop(glink->rx_task); mutex_lock(&glink->idr_lock); - /* Release any defunct local channels, waiting for close-ack */ - idr_for_each_entry(&glink->lcids, channel, cid) { - /* Wakeup threads waiting for intent*/ - complete(&channel->intent_req_comp); - kref_put(&channel->refcount, glink_bgcom_channel_release); - idr_remove(&glink->lcids, cid); - } - - /* Release any defunct local channels, waiting for close-req */ - idr_for_each_entry(&glink->rcids, channel, cid) { - kref_put(&channel->refcount, glink_bgcom_channel_release); - idr_remove(&glink->rcids, cid); - } - idr_destroy(&glink->lcids); idr_destroy(&glink->rcids); mutex_unlock(&glink->idr_lock); diff --git a/drivers/rpmsg/qcom_glink_smem.c b/drivers/rpmsg/qcom_glink_smem.c index 94175fed4591..c3d416d1c2ab 100644 --- a/drivers/rpmsg/qcom_glink_smem.c +++ b/drivers/rpmsg/qcom_glink_smem.c @@ -229,8 +229,8 @@ struct qcom_glink *qcom_glink_smem_register(struct device *parent, ret = device_register(dev); if (ret) { pr_err("failed to register glink edge\n"); - kfree(dev); put_device(dev); + kfree(dev); return ERR_PTR(ret); } diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c index 4630782b5456..c2a1769ea08d 100644 --- a/drivers/s390/block/dasd_eer.c +++ b/drivers/s390/block/dasd_eer.c @@ -561,8 +561,8 @@ static int dasd_eer_open(struct inode *inp, struct file *filp) return -EINVAL; } eerb->buffersize = eerb->buffer_page_count * PAGE_SIZE; - eerb->buffer = kmalloc(eerb->buffer_page_count * sizeof(char *), - GFP_KERNEL); + eerb->buffer = kmalloc_array(eerb->buffer_page_count, sizeof(char *), + GFP_KERNEL); if (!eerb->buffer) { kfree(eerb); return -ENOMEM; diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 7abb240847c0..e2ac1bc44aff 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -230,9 +230,9 @@ dcssblk_is_continuous(struct dcssblk_dev_info *dev_info) if (dev_info->num_of_segments <= 1) return 0; - sort_list = kzalloc( - sizeof(struct segment_info) * dev_info->num_of_segments, - GFP_KERNEL); + sort_list = kcalloc(dev_info->num_of_segments, + sizeof(struct segment_info), + GFP_KERNEL); if (sort_list == NULL) return -ENOMEM; i = 0; diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index 5b505fdaedec..991ab4cad16a 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c @@ -78,7 +78,7 @@ kbd_alloc(void) { } } kbd->fn_handler = - kzalloc(sizeof(fn_handler_fn *) * NR_FN_HANDLER, GFP_KERNEL); + kcalloc(NR_FN_HANDLER, sizeof(fn_handler_fn *), GFP_KERNEL); if (!kbd->fn_handler) goto out_func; kbd->accent_table = kmemdup(accent_table, diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 401688bf8fd3..046a9ce8f53b 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -717,7 +717,8 @@ tty3270_alloc_view(void) if (!tp) goto out_err; tp->freemem_pages = - kmalloc(sizeof(void *) * TTY3270_STRING_PAGES, GFP_KERNEL); + kmalloc_array(TTY3270_STRING_PAGES, sizeof(void *), + GFP_KERNEL); if (!tp->freemem_pages) goto out_tp; INIT_LIST_HEAD(&tp->freemem); diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 04aceb694d51..6fcbbd55d675 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -241,7 +241,7 @@ static struct ccw1 *alloc_chan_prog(const char __user *ubuf, int rec_count, * That means we allocate room for CCWs to cover count/reclen * records plus a NOP. */ - cpa = kzalloc((rec_count + 1) * sizeof(struct ccw1), + cpa = kcalloc(rec_count + 1, sizeof(struct ccw1), GFP_KERNEL | GFP_DMA); if (!cpa) return ERR_PTR(-ENOMEM); diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index aaed778f67c4..646d36b5c8e8 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -152,7 +152,7 @@ static int zcore_memmap_open(struct inode *inode, struct file *filp) char *buf; int i = 0; - buf = kzalloc(memblock.memory.cnt * CHUNK_INFO_SIZE, GFP_KERNEL); + buf = kcalloc(memblock.memory.cnt, CHUNK_INFO_SIZE, GFP_KERNEL); if (!buf) { return -ENOMEM; } diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 158b5ce45b3b..dffb15311211 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -322,8 +322,7 @@ int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv, struct ccw_dev_id dev_id; int rc, i; - gdev = kzalloc(sizeof(*gdev) + num_devices * sizeof(gdev->cdev[0]), - GFP_KERNEL); + gdev = kzalloc(struct_size(gdev, cdev, num_devices), GFP_KERNEL); if (!gdev) return -ENOMEM; diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c index a64615a10352..d06c50623fdc 100644 --- a/drivers/s390/cio/qdio_setup.c +++ b/drivers/s390/cio/qdio_setup.c @@ -535,7 +535,7 @@ void qdio_print_subchannel_info(struct qdio_irq *irq_ptr, int qdio_enable_async_operation(struct qdio_output_q *outq) { - outq->aobs = kzalloc(sizeof(struct qaob *) * QDIO_MAX_BUFFERS_PER_Q, + outq->aobs = kcalloc(QDIO_MAX_BUFFERS_PER_Q, sizeof(struct qaob *), GFP_ATOMIC); if (!outq->aobs) { outq->use_cq = 0; diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c index 4dc1108069d4..89ef40d574c7 100644 --- a/drivers/s390/cio/qdio_thinint.c +++ b/drivers/s390/cio/qdio_thinint.c @@ -244,8 +244,9 @@ out: /* allocate non-shared indicators and shared indicator */ int __init tiqdio_allocate_memory(void) { - q_indicators = kzalloc(sizeof(struct indicator_t) * TIQDIO_NR_INDICATORS, - GFP_KERNEL); + q_indicators = kcalloc(TIQDIO_NR_INDICATORS, + sizeof(struct indicator_t), + GFP_KERNEL); if (!q_indicators) return -ENOMEM; return 0; diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c index bd0376dc7e1e..93d695c3058e 100644 --- a/drivers/s390/crypto/pkey_api.c +++ b/drivers/s390/crypto/pkey_api.c @@ -126,7 +126,7 @@ static int alloc_and_prep_cprbmem(size_t paramblen, * allocate consecutive memory for request CPRB, request param * block, reply CPRB and reply param block */ - cprbmem = kmalloc(2 * cprbplusparamblen, GFP_KERNEL); + cprbmem = kmalloc_array(2, cprbplusparamblen, GFP_KERNEL); if (!cprbmem) return -ENOMEM; memset(cprbmem, 0, 2 * cprbplusparamblen); diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c index fbe35c2ac898..67338c43608c 100644 --- a/drivers/s390/net/ctcm_main.c +++ b/drivers/s390/net/ctcm_main.c @@ -1378,7 +1378,7 @@ static int add_channel(struct ccw_device *cdev, enum ctcm_channel_types type, } else ccw_num = 8; - ch->ccw = kzalloc(ccw_num * sizeof(struct ccw1), GFP_KERNEL | GFP_DMA); + ch->ccw = kcalloc(ccw_num, sizeof(struct ccw1), GFP_KERNEL | GFP_DMA); if (ch->ccw == NULL) goto nomem_return; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 6566fceef38d..f1d2f250a98d 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -374,9 +374,9 @@ static int qeth_alloc_cq(struct qeth_card *card) } card->qdio.no_in_queues = 2; card->qdio.out_bufstates = - kzalloc(card->qdio.no_out_queues * - QDIO_MAX_BUFFERS_PER_Q * - sizeof(struct qdio_outbuf_state), GFP_KERNEL); + kcalloc(card->qdio.no_out_queues * QDIO_MAX_BUFFERS_PER_Q, + sizeof(struct qdio_outbuf_state), + GFP_KERNEL); outbuf_states = card->qdio.out_bufstates; if (outbuf_states == NULL) { rc = -1; @@ -2517,8 +2517,9 @@ static int qeth_alloc_qdio_buffers(struct qeth_card *card) /* outbound */ card->qdio.out_qs = - kzalloc(card->qdio.no_out_queues * - sizeof(struct qeth_qdio_out_q *), GFP_KERNEL); + kcalloc(card->qdio.no_out_queues, + sizeof(struct qeth_qdio_out_q *), + GFP_KERNEL); if (!card->qdio.out_qs) goto out_freepool; for (i = 0; i < card->qdio.no_out_queues; ++i) { @@ -4951,8 +4952,8 @@ static int qeth_qdio_establish(struct qeth_card *card) QETH_DBF_TEXT(SETUP, 2, "qdioest"); - qib_param_field = kzalloc(QDIO_MAX_BUFFERS_PER_Q * sizeof(char), - GFP_KERNEL); + qib_param_field = kzalloc(QDIO_MAX_BUFFERS_PER_Q, + GFP_KERNEL); if (!qib_param_field) { rc = -ENOMEM; goto out_free_nothing; @@ -4961,8 +4962,8 @@ static int qeth_qdio_establish(struct qeth_card *card) qeth_create_qib_param_field(card, qib_param_field); qeth_create_qib_param_field_blkt(card, qib_param_field); - in_sbal_ptrs = kzalloc(card->qdio.no_in_queues * - QDIO_MAX_BUFFERS_PER_Q * sizeof(void *), + in_sbal_ptrs = kcalloc(card->qdio.no_in_queues * QDIO_MAX_BUFFERS_PER_Q, + sizeof(void *), GFP_KERNEL); if (!in_sbal_ptrs) { rc = -ENOMEM; @@ -4973,7 +4974,7 @@ static int qeth_qdio_establish(struct qeth_card *card) virt_to_phys(card->qdio.in_q->bufs[i].buffer); } - queue_start_poll = kzalloc(sizeof(void *) * card->qdio.no_in_queues, + queue_start_poll = kcalloc(card->qdio.no_in_queues, sizeof(void *), GFP_KERNEL); if (!queue_start_poll) { rc = -ENOMEM; @@ -4985,8 +4986,9 @@ static int qeth_qdio_establish(struct qeth_card *card) qeth_qdio_establish_cq(card, in_sbal_ptrs, queue_start_poll); out_sbal_ptrs = - kzalloc(card->qdio.no_out_queues * QDIO_MAX_BUFFERS_PER_Q * - sizeof(void *), GFP_KERNEL); + kcalloc(card->qdio.no_out_queues * QDIO_MAX_BUFFERS_PER_Q, + sizeof(void *), + GFP_KERNEL); if (!out_sbal_ptrs) { rc = -ENOMEM; goto out_free_queue_start_poll; diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 35380a58d3f0..0d4ffe0ae306 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -2366,7 +2366,7 @@ static int __init blogic_init(void) if (blogic_probe_options.noprobe) return -ENODEV; blogic_probeinfo_list = - kzalloc(BLOGIC_MAX_ADAPTERS * sizeof(struct blogic_probeinfo), + kcalloc(BLOGIC_MAX_ADAPTERS, sizeof(struct blogic_probeinfo), GFP_KERNEL); if (blogic_probeinfo_list == NULL) { blogic_err("BusLogic: Unable to allocate Probe Info List\n", diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 7173ae53c526..1c7b551d6f3c 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -3978,7 +3978,7 @@ static int aac_convert_sgraw2(struct aac_raw_io2 *rio2, int pages, int nseg, int if (aac_convert_sgl == 0) return 0; - sge = kmalloc(nseg_new * sizeof(struct sge_ieee1212), GFP_ATOMIC); + sge = kmalloc_array(nseg_new, sizeof(struct sge_ieee1212), GFP_ATOMIC); if (sge == NULL) return -ENOMEM; diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 053a31c5485f..16900b9fdf4b 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1684,7 +1684,9 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) aac->cardtype = index; INIT_LIST_HEAD(&aac->entry); - aac->fibs = kzalloc(sizeof(struct fib) * (shost->can_queue + AAC_NUM_MGT_FIB), GFP_KERNEL); + aac->fibs = kcalloc(shost->can_queue + AAC_NUM_MGT_FIB, + sizeof(struct fib), + GFP_KERNEL); if (!aac->fibs) goto out_free_host; spin_lock_init(&aac->fib_lock); diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index 124217927c4a..41add33e3f1f 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c @@ -400,7 +400,8 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd) #endif if (bufflen) { /* allocate memory before taking host_lock */ sg_count = scsi_sg_count(cmd); - cptr = kmalloc(sizeof(*cptr) * sg_count, GFP_KERNEL | GFP_DMA); + cptr = kmalloc_array(sg_count, sizeof(*cptr), + GFP_KERNEL | GFP_DMA); if (!cptr) return SCSI_MLQUEUE_HOST_BUSY; } else { diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 95d8f25cbcca..cfa39e0b9953 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c @@ -7074,7 +7074,8 @@ ahd_init(struct ahd_softc *ahd) AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); ahd->stack_size = ahd_probe_stack_size(ahd); - ahd->saved_stack = kmalloc(ahd->stack_size * sizeof(uint16_t), GFP_ATOMIC); + ahd->saved_stack = kmalloc_array(ahd->stack_size, sizeof(uint16_t), + GFP_ATOMIC); if (ahd->saved_stack == NULL) return (ENOMEM); diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c index fdbb0a3dc9b4..6d93551fa56a 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_core.c +++ b/drivers/scsi/aic7xxx/aic7xxx_core.c @@ -4779,8 +4779,8 @@ ahc_init_scbdata(struct ahc_softc *ahc) SLIST_INIT(&scb_data->sg_maps); /* Allocate SCB resources */ - scb_data->scbarray = kzalloc(sizeof(struct scb) * AHC_SCB_MAX_ALLOC, - GFP_ATOMIC); + scb_data->scbarray = kcalloc(AHC_SCB_MAX_ALLOC, sizeof(struct scb), + GFP_ATOMIC); if (scb_data->scbarray == NULL) return (ENOMEM); diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c index f2671a8fa7e3..93bbcb33fd32 100644 --- a/drivers/scsi/aic94xx/aic94xx_hwi.c +++ b/drivers/scsi/aic94xx/aic94xx_hwi.c @@ -220,8 +220,9 @@ static int asd_init_scbs(struct asd_ha_struct *asd_ha) /* allocate the index array and bitmap */ asd_ha->seq.tc_index_bitmap_bits = asd_ha->hw_prof.max_scbs; - asd_ha->seq.tc_index_array = kzalloc(asd_ha->seq.tc_index_bitmap_bits* - sizeof(void *), GFP_KERNEL); + asd_ha->seq.tc_index_array = kcalloc(asd_ha->seq.tc_index_bitmap_bits, + sizeof(void *), + GFP_KERNEL); if (!asd_ha->seq.tc_index_array) return -ENOMEM; @@ -291,7 +292,8 @@ static int asd_alloc_edbs(struct asd_ha_struct *asd_ha, gfp_t gfp_flags) struct asd_seq_data *seq = &asd_ha->seq; int i; - seq->edb_arr = kmalloc(seq->num_edbs*sizeof(*seq->edb_arr), gfp_flags); + seq->edb_arr = kmalloc_array(seq->num_edbs, sizeof(*seq->edb_arr), + gfp_flags); if (!seq->edb_arr) return -ENOMEM; @@ -323,8 +325,8 @@ static int asd_alloc_escbs(struct asd_ha_struct *asd_ha, struct asd_ascb *escb; int i, escbs; - seq->escb_arr = kmalloc(seq->num_escbs*sizeof(*seq->escb_arr), - gfp_flags); + seq->escb_arr = kmalloc_array(seq->num_escbs, sizeof(*seq->escb_arr), + gfp_flags); if (!seq->escb_arr) return -ENOMEM; diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index eb5ee0ec5a2f..702da909cee5 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c @@ -350,7 +350,7 @@ static ssize_t asd_store_update_bios(struct device *dev, int flash_command = FLASH_CMD_NONE; int err = 0; - cmd_ptr = kzalloc(count*2, GFP_KERNEL); + cmd_ptr = kcalloc(count, 2, GFP_KERNEL); if (!cmd_ptr) { err = FAIL_OUT_MEMORY; diff --git a/drivers/scsi/arm/queue.c b/drivers/scsi/arm/queue.c index 3441ce3ebabf..996dfe903928 100644 --- a/drivers/scsi/arm/queue.c +++ b/drivers/scsi/arm/queue.c @@ -70,7 +70,7 @@ int queue_initialise (Queue_t *queue) * need to keep free lists or allocate this * memory. */ - queue->alloc = q = kmalloc(sizeof(QE_t) * nqueues, GFP_KERNEL); + queue->alloc = q = kmalloc_array(nqueues, sizeof(QE_t), GFP_KERNEL); if (q) { for (; nqueues; q++, nqueues--) { SET_MAGIC(q, QUEUE_MAGIC_FREE); diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index b4542e7e2ad5..33f0bb5e5683 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -2455,8 +2455,8 @@ static int beiscsi_alloc_mem(struct beiscsi_hba *phba) /* Allocate memory for wrb_context */ phwi_ctrlr = phba->phwi_ctrlr; - phwi_ctrlr->wrb_context = kzalloc(sizeof(struct hwi_wrb_context) * - phba->params.cxns_per_ctrl, + phwi_ctrlr->wrb_context = kcalloc(phba->params.cxns_per_ctrl, + sizeof(struct hwi_wrb_context), GFP_KERNEL); if (!phwi_ctrlr->wrb_context) { kfree(phba->phwi_ctrlr); @@ -2471,8 +2471,9 @@ static int beiscsi_alloc_mem(struct beiscsi_hba *phba) return -ENOMEM; } - mem_arr_orig = kmalloc(sizeof(*mem_arr_orig) * BEISCSI_MAX_FRAGS_INIT, - GFP_KERNEL); + mem_arr_orig = kmalloc_array(BEISCSI_MAX_FRAGS_INIT, + sizeof(*mem_arr_orig), + GFP_KERNEL); if (!mem_arr_orig) { kfree(phba->init_mem); kfree(phwi_ctrlr->wrb_context); @@ -2521,8 +2522,8 @@ static int beiscsi_alloc_mem(struct beiscsi_hba *phba) } while (alloc_size); mem_descr->num_elements = j; mem_descr->size_in_bytes = phba->mem_req[i]; - mem_descr->mem_array = kmalloc(sizeof(*mem_arr) * j, - GFP_KERNEL); + mem_descr->mem_array = kmalloc_array(j, sizeof(*mem_arr), + GFP_KERNEL); if (!mem_descr->mem_array) goto free_mem; @@ -2608,8 +2609,8 @@ static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba) /* Allocate memory for WRBQ */ phwi_ctxt = phwi_ctrlr->phwi_ctxt; - phwi_ctxt->be_wrbq = kzalloc(sizeof(struct be_queue_info) * - phba->params.cxns_per_ctrl, + phwi_ctxt->be_wrbq = kcalloc(phba->params.cxns_per_ctrl, + sizeof(struct be_queue_info), GFP_KERNEL); if (!phwi_ctxt->be_wrbq) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, @@ -2620,16 +2621,18 @@ static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba) for (index = 0; index < phba->params.cxns_per_ctrl; index++) { pwrb_context = &phwi_ctrlr->wrb_context[index]; pwrb_context->pwrb_handle_base = - kzalloc(sizeof(struct wrb_handle *) * - phba->params.wrbs_per_cxn, GFP_KERNEL); + kcalloc(phba->params.wrbs_per_cxn, + sizeof(struct wrb_handle *), + GFP_KERNEL); if (!pwrb_context->pwrb_handle_base) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, "BM_%d : Mem Alloc Failed. Failing to load\n"); goto init_wrb_hndl_failed; } pwrb_context->pwrb_handle_basestd = - kzalloc(sizeof(struct wrb_handle *) * - phba->params.wrbs_per_cxn, GFP_KERNEL); + kcalloc(phba->params.wrbs_per_cxn, + sizeof(struct wrb_handle *), + GFP_KERNEL); if (!pwrb_context->pwrb_handle_basestd) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, "BM_%d : Mem Alloc Failed. Failing to load\n"); @@ -3341,8 +3344,9 @@ beiscsi_create_wrb_rings(struct beiscsi_hba *phba, idx = 0; mem_descr = phba->init_mem; mem_descr += HWI_MEM_WRB; - pwrb_arr = kmalloc(sizeof(*pwrb_arr) * phba->params.cxns_per_ctrl, - GFP_KERNEL); + pwrb_arr = kmalloc_array(phba->params.cxns_per_ctrl, + sizeof(*pwrb_arr), + GFP_KERNEL); if (!pwrb_arr) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, "BM_%d : Memory alloc failed in create wrb ring.\n"); @@ -3884,17 +3888,16 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba) mem_descr_sglh = phba->init_mem; mem_descr_sglh += HWI_MEM_SGLH; if (1 == mem_descr_sglh->num_elements) { - phba->io_sgl_hndl_base = kzalloc(sizeof(struct sgl_handle *) * - phba->params.ios_per_ctrl, + phba->io_sgl_hndl_base = kcalloc(phba->params.ios_per_ctrl, + sizeof(struct sgl_handle *), GFP_KERNEL); if (!phba->io_sgl_hndl_base) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, "BM_%d : Mem Alloc Failed. Failing to load\n"); return -ENOMEM; } - phba->eh_sgl_hndl_base = kzalloc(sizeof(struct sgl_handle *) * - (phba->params.icds_per_ctrl - - phba->params.ios_per_ctrl), + phba->eh_sgl_hndl_base = kcalloc(phba->params.icds_per_ctrl - phba->params.ios_per_ctrl, + sizeof(struct sgl_handle *), GFP_KERNEL); if (!phba->eh_sgl_hndl_base) { kfree(phba->io_sgl_hndl_base); @@ -4022,8 +4025,9 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba) phba->cid_array_info[ulp_num] = ptr_cid_info; } } - phba->ep_array = kzalloc(sizeof(struct iscsi_endpoint *) * - phba->params.cxns_per_ctrl, GFP_KERNEL); + phba->ep_array = kcalloc(phba->params.cxns_per_ctrl, + sizeof(struct iscsi_endpoint *), + GFP_KERNEL); if (!phba->ep_array) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, "BM_%d : Failed to allocate memory in " @@ -4033,8 +4037,9 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba) goto free_memory; } - phba->conn_table = kzalloc(sizeof(struct beiscsi_conn *) * - phba->params.cxns_per_ctrl, GFP_KERNEL); + phba->conn_table = kcalloc(phba->params.cxns_per_ctrl, + sizeof(struct beiscsi_conn *), + GFP_KERNEL); if (!phba->conn_table) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, "BM_%d : Failed to allocate memory in" diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index 0a70d54a4df6..d2faf6f5ae72 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c @@ -932,7 +932,7 @@ bfad_im_num_of_discovered_ports_show(struct device *dev, struct bfa_rport_qualifier_s *rports = NULL; unsigned long flags; - rports = kzalloc(sizeof(struct bfa_rport_qualifier_s) * nrports, + rports = kcalloc(nrports, sizeof(struct bfa_rport_qualifier_s), GFP_ATOMIC); if (rports == NULL) return snprintf(buf, PAGE_SIZE, "Failed\n"); diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index 9081a5f93aae..9b6ec50373a2 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c @@ -3261,8 +3261,8 @@ bfad_fcxp_map_sg(struct bfad_s *bfad, void *payload_kbuf, struct bfa_sge_s *sg_table; int sge_num = 1; - buf_base = kzalloc((sizeof(struct bfad_buf_info) + - sizeof(struct bfa_sge_s)) * sge_num, GFP_KERNEL); + buf_base = kcalloc(sizeof(struct bfad_buf_info) + sizeof(struct bfa_sge_s), + sge_num, GFP_KERNEL); if (!buf_base) return NULL; diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 116a56f0af01..1d8c56cd0c94 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -1397,7 +1397,7 @@ static struct bnx2fc_hba *bnx2fc_hba_create(struct cnic_dev *cnic) hba->next_conn_id = 0; hba->tgt_ofld_list = - kzalloc(sizeof(struct bnx2fc_rport *) * BNX2FC_NUM_MAX_SESS, + kcalloc(BNX2FC_NUM_MAX_SESS, sizeof(struct bnx2fc_rport *), GFP_KERNEL); if (!hba->tgt_ofld_list) { printk(KERN_ERR PFX "Unable to allocate tgt offload list\n"); diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index 6626b28ba8fe..582daadb85cd 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c @@ -240,15 +240,15 @@ struct bnx2fc_cmd_mgr *bnx2fc_cmd_mgr_alloc(struct bnx2fc_hba *hba) return NULL; } - cmgr->free_list = kzalloc(sizeof(*cmgr->free_list) * - arr_sz, GFP_KERNEL); + cmgr->free_list = kcalloc(arr_sz, sizeof(*cmgr->free_list), + GFP_KERNEL); if (!cmgr->free_list) { printk(KERN_ERR PFX "failed to alloc free_list\n"); goto mem_err; } - cmgr->free_list_lock = kzalloc(sizeof(*cmgr->free_list_lock) * - arr_sz, GFP_KERNEL); + cmgr->free_list_lock = kcalloc(arr_sz, sizeof(*cmgr->free_list_lock), + GFP_KERNEL); if (!cmgr->free_list_lock) { printk(KERN_ERR PFX "failed to alloc free_list_lock\n"); kfree(cmgr->free_list); diff --git a/drivers/scsi/csiostor/csio_wr.c b/drivers/scsi/csiostor/csio_wr.c index c0a17789752f..faa357b62c61 100644 --- a/drivers/scsi/csiostor/csio_wr.c +++ b/drivers/scsi/csiostor/csio_wr.c @@ -276,7 +276,7 @@ csio_wr_alloc_q(struct csio_hw *hw, uint32_t qsize, uint32_t wrsize, q->un.iq.flq_idx = flq_idx; flq = wrm->q_arr[q->un.iq.flq_idx]; - flq->un.fl.bufs = kzalloc(flq->credits * + flq->un.fl.bufs = kcalloc(flq->credits, sizeof(struct csio_dma_buf), GFP_KERNEL); if (!flq->un.fl.bufs) { @@ -1579,7 +1579,7 @@ csio_wrm_init(struct csio_wrm *wrm, struct csio_hw *hw) return -EINVAL; } - wrm->q_arr = kzalloc(sizeof(struct csio_q *) * wrm->num_q, GFP_KERNEL); + wrm->q_arr = kcalloc(wrm->num_q, sizeof(struct csio_q *), GFP_KERNEL); if (!wrm->q_arr) goto err; diff --git a/drivers/scsi/esas2r/esas2r_init.c b/drivers/scsi/esas2r/esas2r_init.c index 5b14dd29b764..ca539e027925 100644 --- a/drivers/scsi/esas2r/esas2r_init.c +++ b/drivers/scsi/esas2r/esas2r_init.c @@ -854,7 +854,7 @@ bool esas2r_init_adapter_struct(struct esas2r_adapter *a, /* allocate requests for asynchronous events */ a->first_ae_req = - kzalloc(num_ae_requests * sizeof(struct esas2r_request), + kcalloc(num_ae_requests, sizeof(struct esas2r_request), GFP_KERNEL); if (a->first_ae_req == NULL) { @@ -864,8 +864,8 @@ bool esas2r_init_adapter_struct(struct esas2r_adapter *a, } /* allocate the S/G list memory descriptors */ - a->sg_list_mds = kzalloc( - num_sg_lists * sizeof(struct esas2r_mem_desc), GFP_KERNEL); + a->sg_list_mds = kcalloc(num_sg_lists, sizeof(struct esas2r_mem_desc), + GFP_KERNEL); if (a->sg_list_mds == NULL) { esas2r_log(ESAS2R_LOG_CRIT, @@ -875,8 +875,9 @@ bool esas2r_init_adapter_struct(struct esas2r_adapter *a, /* allocate the request table */ a->req_table = - kzalloc((num_requests + num_ae_requests + - 1) * sizeof(struct esas2r_request *), GFP_KERNEL); + kcalloc(num_requests + num_ae_requests + 1, + sizeof(struct esas2r_request *), + GFP_KERNEL); if (a->req_table == NULL) { esas2r_log(ESAS2R_LOG_CRIT, diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index d95ba1a07ba3..bda52c11f489 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c @@ -1393,8 +1393,8 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, */ num_vlink_desc = rlen / sizeof(*vp); if (num_vlink_desc) - vlink_desc_arr = kmalloc(sizeof(vp) * num_vlink_desc, - GFP_ATOMIC); + vlink_desc_arr = kmalloc_array(num_vlink_desc, sizeof(vp), + GFP_ATOMIC); if (!vlink_desc_arr) return; num_vlink_desc = 0; diff --git a/drivers/scsi/fnic/fnic_debugfs.c b/drivers/scsi/fnic/fnic_debugfs.c index 5e3d909cfc53..997b76ffa948 100644 --- a/drivers/scsi/fnic/fnic_debugfs.c +++ b/drivers/scsi/fnic/fnic_debugfs.c @@ -251,8 +251,7 @@ static int fnic_trace_debugfs_open(struct inode *inode, return -ENOMEM; if (*rdata_ptr == fc_trc_flag->fnic_trace) { - fnic_dbg_prt->buffer = vmalloc(3 * - (trace_max_pages * PAGE_SIZE)); + fnic_dbg_prt->buffer = vmalloc(array_size(3, (trace_max_pages * PAGE_SIZE))); if (!fnic_dbg_prt->buffer) { kfree(fnic_dbg_prt); return -ENOMEM; @@ -262,7 +261,7 @@ static int fnic_trace_debugfs_open(struct inode *inode, fnic_dbg_prt->buffer_len = fnic_get_trace_data(fnic_dbg_prt); } else { fnic_dbg_prt->buffer = - vmalloc(3 * (fnic_fc_trace_max_pages * PAGE_SIZE)); + vmalloc(array_size(3, (fnic_fc_trace_max_pages * PAGE_SIZE))); if (!fnic_dbg_prt->buffer) { kfree(fnic_dbg_prt); return -ENOMEM; diff --git a/drivers/scsi/fnic/fnic_trace.c b/drivers/scsi/fnic/fnic_trace.c index 4826f596cb31..96670da466e2 100644 --- a/drivers/scsi/fnic/fnic_trace.c +++ b/drivers/scsi/fnic/fnic_trace.c @@ -477,8 +477,7 @@ int fnic_trace_buf_init(void) } memset((void *)fnic_trace_buf_p, 0, (trace_max_pages * PAGE_SIZE)); - fnic_trace_entries.page_offset = vmalloc(fnic_max_trace_entries * - sizeof(unsigned long)); + fnic_trace_entries.page_offset = vmalloc(array_size(fnic_max_trace_entries, sizeof(unsigned long))); if (!fnic_trace_entries.page_offset) { printk(KERN_ERR PFX "Failed to allocate memory for" " page_offset\n"); @@ -555,8 +554,7 @@ int fnic_fc_trace_init(void) fc_trace_max_entries = (fnic_fc_trace_max_pages * PAGE_SIZE)/ FC_TRC_SIZE_BYTES; - fnic_fc_ctlr_trace_buf_p = (unsigned long)vmalloc( - fnic_fc_trace_max_pages * PAGE_SIZE); + fnic_fc_ctlr_trace_buf_p = (unsigned long)vmalloc(array_size(PAGE_SIZE, fnic_fc_trace_max_pages)); if (!fnic_fc_ctlr_trace_buf_p) { pr_err("fnic: Failed to allocate memory for " "FC Control Trace Buf\n"); @@ -568,8 +566,7 @@ int fnic_fc_trace_init(void) fnic_fc_trace_max_pages * PAGE_SIZE); /* Allocate memory for page offset */ - fc_trace_entries.page_offset = vmalloc(fc_trace_max_entries * - sizeof(unsigned long)); + fc_trace_entries.page_offset = vmalloc(array_size(fc_trace_max_entries, sizeof(unsigned long))); if (!fc_trace_entries.page_offset) { pr_err("fnic:Failed to allocate memory for page_offset\n"); if (fnic_fc_ctlr_trace_buf_p) { diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 3b892918d821..3fa80eb6b355 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -1876,8 +1876,8 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, } spin_unlock_irqrestore(&h->reset_lock, flags); - added = kzalloc(sizeof(*added) * HPSA_MAX_DEVICES, GFP_KERNEL); - removed = kzalloc(sizeof(*removed) * HPSA_MAX_DEVICES, GFP_KERNEL); + added = kcalloc(HPSA_MAX_DEVICES, sizeof(*added), GFP_KERNEL); + removed = kcalloc(HPSA_MAX_DEVICES, sizeof(*removed), GFP_KERNEL); if (!added || !removed) { dev_warn(&h->pdev->dev, "out of memory in " @@ -2119,14 +2119,15 @@ static int hpsa_allocate_ioaccel2_sg_chain_blocks(struct ctlr_info *h) return 0; h->ioaccel2_cmd_sg_list = - kzalloc(sizeof(*h->ioaccel2_cmd_sg_list) * h->nr_cmds, + kcalloc(h->nr_cmds, sizeof(*h->ioaccel2_cmd_sg_list), GFP_KERNEL); if (!h->ioaccel2_cmd_sg_list) return -ENOMEM; for (i = 0; i < h->nr_cmds; i++) { h->ioaccel2_cmd_sg_list[i] = - kmalloc(sizeof(*h->ioaccel2_cmd_sg_list[i]) * - h->maxsgentries, GFP_KERNEL); + kmalloc_array(h->maxsgentries, + sizeof(*h->ioaccel2_cmd_sg_list[i]), + GFP_KERNEL); if (!h->ioaccel2_cmd_sg_list[i]) goto clean; } @@ -2158,14 +2159,15 @@ static int hpsa_alloc_sg_chain_blocks(struct ctlr_info *h) if (h->chainsize <= 0) return 0; - h->cmd_sg_list = kzalloc(sizeof(*h->cmd_sg_list) * h->nr_cmds, - GFP_KERNEL); + h->cmd_sg_list = kcalloc(h->nr_cmds, sizeof(*h->cmd_sg_list), + GFP_KERNEL); if (!h->cmd_sg_list) return -ENOMEM; for (i = 0; i < h->nr_cmds; i++) { - h->cmd_sg_list[i] = kmalloc(sizeof(*h->cmd_sg_list[i]) * - h->chainsize, GFP_KERNEL); + h->cmd_sg_list[i] = kmalloc_array(h->chainsize, + sizeof(*h->cmd_sg_list[i]), + GFP_KERNEL); if (!h->cmd_sg_list[i]) goto clean; @@ -4186,7 +4188,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h) bool physical_device; DECLARE_BITMAP(lunzerobits, MAX_EXT_TARGETS); - currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_DEVICES, GFP_KERNEL); + currentsd = kcalloc(HPSA_MAX_DEVICES, sizeof(*currentsd), GFP_KERNEL); physdev_list = kzalloc(sizeof(*physdev_list), GFP_KERNEL); logdev_list = kzalloc(sizeof(*logdev_list), GFP_KERNEL); tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL); @@ -6296,12 +6298,12 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp) status = -EINVAL; goto cleanup1; } - buff = kzalloc(SG_ENTRIES_IN_CMD * sizeof(char *), GFP_KERNEL); + buff = kcalloc(SG_ENTRIES_IN_CMD, sizeof(char *), GFP_KERNEL); if (!buff) { status = -ENOMEM; goto cleanup1; } - buff_size = kmalloc(SG_ENTRIES_IN_CMD * sizeof(int), GFP_KERNEL); + buff_size = kmalloc_array(SG_ENTRIES_IN_CMD, sizeof(int), GFP_KERNEL); if (!buff_size) { status = -ENOMEM; goto cleanup1; @@ -7034,7 +7036,7 @@ static int controller_reset_failed(struct CfgTable __iomem *cfgtable) char *driver_ver, *old_driver_ver; int rc, size = sizeof(cfgtable->driver_version); - old_driver_ver = kmalloc(2 * size, GFP_KERNEL); + old_driver_ver = kmalloc_array(2, size, GFP_KERNEL); if (!old_driver_ver) return -ENOMEM; driver_ver = old_driver_ver + size; @@ -7814,9 +7816,9 @@ static void hpsa_free_cmd_pool(struct ctlr_info *h) static int hpsa_alloc_cmd_pool(struct ctlr_info *h) { - h->cmd_pool_bits = kzalloc( - DIV_ROUND_UP(h->nr_cmds, BITS_PER_LONG) * - sizeof(unsigned long), GFP_KERNEL); + h->cmd_pool_bits = kcalloc(DIV_ROUND_UP(h->nr_cmds, BITS_PER_LONG), + sizeof(unsigned long), + GFP_KERNEL); h->cmd_pool = pci_alloc_consistent(h->pdev, h->nr_cmds * sizeof(*h->cmd_pool), &(h->cmd_pool_dhandle)); @@ -8326,7 +8328,7 @@ static struct ctlr_info *hpda_alloc_ctlr_info(void) if (!h) return NULL; - h->reply_map = kzalloc(sizeof(*h->reply_map) * nr_cpu_ids, GFP_KERNEL); + h->reply_map = kcalloc(nr_cpu_ids, sizeof(*h->reply_map), GFP_KERNEL); if (!h->reply_map) { kfree(h); return NULL; diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index b172f0a02083..2d8ec317b662 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -4376,9 +4376,9 @@ static int ipr_alloc_dump(struct ipr_ioa_cfg *ioa_cfg) } if (ioa_cfg->sis64) - ioa_data = vmalloc(IPR_FMT3_MAX_NUM_DUMP_PAGES * sizeof(__be32 *)); + ioa_data = vmalloc(array_size(IPR_FMT3_MAX_NUM_DUMP_PAGES, sizeof(__be32 *))); else - ioa_data = vmalloc(IPR_FMT2_MAX_NUM_DUMP_PAGES * sizeof(__be32 *)); + ioa_data = vmalloc(array_size(IPR_FMT2_MAX_NUM_DUMP_PAGES, sizeof(__be32 *))); if (!ioa_data) { ipr_err("Dump memory allocation failed\n"); @@ -9759,8 +9759,9 @@ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg) int i, rc = -ENOMEM; ENTER; - ioa_cfg->res_entries = kzalloc(sizeof(struct ipr_resource_entry) * - ioa_cfg->max_devs_supported, GFP_KERNEL); + ioa_cfg->res_entries = kcalloc(ioa_cfg->max_devs_supported, + sizeof(struct ipr_resource_entry), + GFP_KERNEL); if (!ioa_cfg->res_entries) goto out; @@ -9821,8 +9822,9 @@ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg) list_add_tail(&ioa_cfg->hostrcb[i]->queue, &ioa_cfg->hostrcb_free_q); } - ioa_cfg->trace = kzalloc(sizeof(struct ipr_trace_entry) * - IPR_NUM_TRACE_ENTRIES, GFP_KERNEL); + ioa_cfg->trace = kcalloc(IPR_NUM_TRACE_ENTRIES, + sizeof(struct ipr_trace_entry), + GFP_KERNEL); if (!ioa_cfg->trace) goto out_free_hostrcb_dma; diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c index c71e0f3b146a..c1bdcac3fea6 100644 --- a/drivers/scsi/isci/init.c +++ b/drivers/scsi/isci/init.c @@ -232,14 +232,14 @@ static int isci_register_sas_ha(struct isci_host *isci_host) struct asd_sas_phy **sas_phys; struct asd_sas_port **sas_ports; - sas_phys = devm_kzalloc(&isci_host->pdev->dev, - SCI_MAX_PHYS * sizeof(void *), + sas_phys = devm_kcalloc(&isci_host->pdev->dev, + SCI_MAX_PHYS, sizeof(void *), GFP_KERNEL); if (!sas_phys) return -ENOMEM; - sas_ports = devm_kzalloc(&isci_host->pdev->dev, - SCI_MAX_PORTS * sizeof(void *), + sas_ports = devm_kcalloc(&isci_host->pdev->dev, + SCI_MAX_PORTS, sizeof(void *), GFP_KERNEL); if (!sas_ports) return -ENOMEM; diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 662df16b07a4..66169d1881d1 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -2584,7 +2584,7 @@ iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size) * the array. */ if (items) num_arrays++; - q->pool = kvzalloc(num_arrays * max * sizeof(void*), GFP_KERNEL); + q->pool = kvcalloc(num_arrays * max, sizeof(void *), GFP_KERNEL); if (q->pool == NULL) return -ENOMEM; diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index f77d72f01da9..bd9bbfb44479 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -442,7 +442,7 @@ static int sas_expander_discover(struct domain_device *dev) struct expander_device *ex = &dev->ex_dev; int res = -ENOMEM; - ex->ex_phy = kzalloc(sizeof(*ex->ex_phy)*ex->num_phys, GFP_KERNEL); + ex->ex_phy = kcalloc(ex->num_phys, sizeof(*ex->ex_phy), GFP_KERNEL); if (!ex->ex_phy) return -ENOMEM; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 9fc5507ee39e..c6c4aa6faf7e 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -5686,8 +5686,9 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba) } if (!phba->sli.sli3_ring) - phba->sli.sli3_ring = kzalloc(LPFC_SLI3_MAX_RING * - sizeof(struct lpfc_sli_ring), GFP_KERNEL); + phba->sli.sli3_ring = kcalloc(LPFC_SLI3_MAX_RING, + sizeof(struct lpfc_sli_ring), + GFP_KERNEL); if (!phba->sli.sli3_ring) return -ENOMEM; @@ -6176,7 +6177,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) /* Allocate eligible FCF bmask memory for FCF roundrobin failover */ longs = (LPFC_SLI4_FCF_TBL_INDX_MAX + BITS_PER_LONG - 1)/BITS_PER_LONG; - phba->fcf.fcf_rr_bmask = kzalloc(longs * sizeof(unsigned long), + phba->fcf.fcf_rr_bmask = kcalloc(longs, sizeof(unsigned long), GFP_KERNEL); if (!phba->fcf.fcf_rr_bmask) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 87c08ff37ddd..9addd9ee48ea 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c @@ -120,8 +120,9 @@ lpfc_mem_alloc(struct lpfc_hba *phba, int align) if (!phba->lpfc_mbuf_pool) goto fail_free_dma_buf_pool; - pool->elements = kmalloc(sizeof(struct lpfc_dmabuf) * - LPFC_MBUF_POOL_SIZE, GFP_KERNEL); + pool->elements = kmalloc_array(LPFC_MBUF_POOL_SIZE, + sizeof(struct lpfc_dmabuf), + GFP_KERNEL); if (!pool->elements) goto fail_free_lpfc_mbuf_pool; diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 480d2d467f7a..1061b5008a7c 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -1522,7 +1522,7 @@ lpfc_sli_next_iotag(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) - LPFC_IOCBQ_LOOKUP_INCREMENT)) { new_len = psli->iocbq_lookup_len + LPFC_IOCBQ_LOOKUP_INCREMENT; spin_unlock_irq(&phba->hbalock); - new_arr = kzalloc(new_len * sizeof (struct lpfc_iocbq *), + new_arr = kcalloc(new_len, sizeof(struct lpfc_iocbq *), GFP_KERNEL); if (new_arr) { spin_lock_irq(&phba->hbalock); @@ -4936,16 +4936,17 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) */ if ((phba->vpi_bmask == NULL) && (phba->vpi_ids == NULL)) { longs = (phba->max_vpi + BITS_PER_LONG) / BITS_PER_LONG; - phba->vpi_bmask = kzalloc(longs * sizeof(unsigned long), + phba->vpi_bmask = kcalloc(longs, + sizeof(unsigned long), GFP_KERNEL); if (!phba->vpi_bmask) { rc = -ENOMEM; goto lpfc_sli_hba_setup_error; } - phba->vpi_ids = kzalloc( - (phba->max_vpi+1) * sizeof(uint16_t), - GFP_KERNEL); + phba->vpi_ids = kcalloc(phba->max_vpi + 1, + sizeof(uint16_t), + GFP_KERNEL); if (!phba->vpi_ids) { kfree(phba->vpi_bmask); rc = -ENOMEM; @@ -5629,14 +5630,14 @@ lpfc_sli4_alloc_extent(struct lpfc_hba *phba, uint16_t type) length = sizeof(struct lpfc_rsrc_blks); switch (type) { case LPFC_RSC_TYPE_FCOE_RPI: - phba->sli4_hba.rpi_bmask = kzalloc(longs * + phba->sli4_hba.rpi_bmask = kcalloc(longs, sizeof(unsigned long), GFP_KERNEL); if (unlikely(!phba->sli4_hba.rpi_bmask)) { rc = -ENOMEM; goto err_exit; } - phba->sli4_hba.rpi_ids = kzalloc(rsrc_id_cnt * + phba->sli4_hba.rpi_ids = kcalloc(rsrc_id_cnt, sizeof(uint16_t), GFP_KERNEL); if (unlikely(!phba->sli4_hba.rpi_ids)) { @@ -5658,15 +5659,13 @@ lpfc_sli4_alloc_extent(struct lpfc_hba *phba, uint16_t type) ext_blk_list = &phba->sli4_hba.lpfc_rpi_blk_list; break; case LPFC_RSC_TYPE_FCOE_VPI: - phba->vpi_bmask = kzalloc(longs * - sizeof(unsigned long), + phba->vpi_bmask = kcalloc(longs, sizeof(unsigned long), GFP_KERNEL); if (unlikely(!phba->vpi_bmask)) { rc = -ENOMEM; goto err_exit; } - phba->vpi_ids = kzalloc(rsrc_id_cnt * - sizeof(uint16_t), + phba->vpi_ids = kcalloc(rsrc_id_cnt, sizeof(uint16_t), GFP_KERNEL); if (unlikely(!phba->vpi_ids)) { kfree(phba->vpi_bmask); @@ -5680,7 +5679,7 @@ lpfc_sli4_alloc_extent(struct lpfc_hba *phba, uint16_t type) ext_blk_list = &phba->lpfc_vpi_blk_list; break; case LPFC_RSC_TYPE_FCOE_XRI: - phba->sli4_hba.xri_bmask = kzalloc(longs * + phba->sli4_hba.xri_bmask = kcalloc(longs, sizeof(unsigned long), GFP_KERNEL); if (unlikely(!phba->sli4_hba.xri_bmask)) { @@ -5688,7 +5687,7 @@ lpfc_sli4_alloc_extent(struct lpfc_hba *phba, uint16_t type) goto err_exit; } phba->sli4_hba.max_cfg_param.xri_used = 0; - phba->sli4_hba.xri_ids = kzalloc(rsrc_id_cnt * + phba->sli4_hba.xri_ids = kcalloc(rsrc_id_cnt, sizeof(uint16_t), GFP_KERNEL); if (unlikely(!phba->sli4_hba.xri_ids)) { @@ -5703,14 +5702,14 @@ lpfc_sli4_alloc_extent(struct lpfc_hba *phba, uint16_t type) ext_blk_list = &phba->sli4_hba.lpfc_xri_blk_list; break; case LPFC_RSC_TYPE_FCOE_VFI: - phba->sli4_hba.vfi_bmask = kzalloc(longs * + phba->sli4_hba.vfi_bmask = kcalloc(longs, sizeof(unsigned long), GFP_KERNEL); if (unlikely(!phba->sli4_hba.vfi_bmask)) { rc = -ENOMEM; goto err_exit; } - phba->sli4_hba.vfi_ids = kzalloc(rsrc_id_cnt * + phba->sli4_hba.vfi_ids = kcalloc(rsrc_id_cnt, sizeof(uint16_t), GFP_KERNEL); if (unlikely(!phba->sli4_hba.vfi_ids)) { @@ -6043,15 +6042,14 @@ lpfc_sli4_alloc_resource_identifiers(struct lpfc_hba *phba) } base = phba->sli4_hba.max_cfg_param.rpi_base; longs = (count + BITS_PER_LONG - 1) / BITS_PER_LONG; - phba->sli4_hba.rpi_bmask = kzalloc(longs * + phba->sli4_hba.rpi_bmask = kcalloc(longs, sizeof(unsigned long), GFP_KERNEL); if (unlikely(!phba->sli4_hba.rpi_bmask)) { rc = -ENOMEM; goto err_exit; } - phba->sli4_hba.rpi_ids = kzalloc(count * - sizeof(uint16_t), + phba->sli4_hba.rpi_ids = kcalloc(count, sizeof(uint16_t), GFP_KERNEL); if (unlikely(!phba->sli4_hba.rpi_ids)) { rc = -ENOMEM; @@ -6072,15 +6070,13 @@ lpfc_sli4_alloc_resource_identifiers(struct lpfc_hba *phba) } base = phba->sli4_hba.max_cfg_param.vpi_base; longs = (count + BITS_PER_LONG - 1) / BITS_PER_LONG; - phba->vpi_bmask = kzalloc(longs * - sizeof(unsigned long), + phba->vpi_bmask = kcalloc(longs, sizeof(unsigned long), GFP_KERNEL); if (unlikely(!phba->vpi_bmask)) { rc = -ENOMEM; goto free_rpi_ids; } - phba->vpi_ids = kzalloc(count * - sizeof(uint16_t), + phba->vpi_ids = kcalloc(count, sizeof(uint16_t), GFP_KERNEL); if (unlikely(!phba->vpi_ids)) { rc = -ENOMEM; @@ -6101,7 +6097,7 @@ lpfc_sli4_alloc_resource_identifiers(struct lpfc_hba *phba) } base = phba->sli4_hba.max_cfg_param.xri_base; longs = (count + BITS_PER_LONG - 1) / BITS_PER_LONG; - phba->sli4_hba.xri_bmask = kzalloc(longs * + phba->sli4_hba.xri_bmask = kcalloc(longs, sizeof(unsigned long), GFP_KERNEL); if (unlikely(!phba->sli4_hba.xri_bmask)) { @@ -6109,8 +6105,7 @@ lpfc_sli4_alloc_resource_identifiers(struct lpfc_hba *phba) goto free_vpi_ids; } phba->sli4_hba.max_cfg_param.xri_used = 0; - phba->sli4_hba.xri_ids = kzalloc(count * - sizeof(uint16_t), + phba->sli4_hba.xri_ids = kcalloc(count, sizeof(uint16_t), GFP_KERNEL); if (unlikely(!phba->sli4_hba.xri_ids)) { rc = -ENOMEM; @@ -6131,15 +6126,14 @@ lpfc_sli4_alloc_resource_identifiers(struct lpfc_hba *phba) } base = phba->sli4_hba.max_cfg_param.vfi_base; longs = (count + BITS_PER_LONG - 1) / BITS_PER_LONG; - phba->sli4_hba.vfi_bmask = kzalloc(longs * + phba->sli4_hba.vfi_bmask = kcalloc(longs, sizeof(unsigned long), GFP_KERNEL); if (unlikely(!phba->sli4_hba.vfi_bmask)) { rc = -ENOMEM; goto free_xri_ids; } - phba->sli4_hba.vfi_ids = kzalloc(count * - sizeof(uint16_t), + phba->sli4_hba.vfi_ids = kcalloc(count, sizeof(uint16_t), GFP_KERNEL); if (unlikely(!phba->sli4_hba.vfi_ids)) { rc = -ENOMEM; diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index c714482bf4c5..7c282f688b68 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -831,7 +831,7 @@ lpfc_create_vport_work_array(struct lpfc_hba *phba) struct lpfc_vport *port_iterator; struct lpfc_vport **vports; int index = 0; - vports = kzalloc((phba->max_vports + 1) * sizeof(struct lpfc_vport *), + vports = kcalloc(phba->max_vports + 1, sizeof(struct lpfc_vport *), GFP_KERNEL); if (vports == NULL) return NULL; diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index 8c4d3003b68b..177701dfdfcb 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c @@ -464,8 +464,9 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat * +1 to allow for aligning. * XXX FIXME: Use DMA consistent routines */ - dma_cmd_space = kmalloc((host->sg_tablesize + 2) * - sizeof(struct dbdma_cmd), GFP_KERNEL); + dma_cmd_space = kmalloc_array(host->sg_tablesize + 2, + sizeof(struct dbdma_cmd), + GFP_KERNEL); if (dma_cmd_space == 0) { printk(KERN_ERR "mac53c94: couldn't allocate dma " "command space for %pOF\n", node); diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index f5c09bbf9374..270cfcdaed5f 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -4325,7 +4325,8 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) goto out_host_put; } - adapter->scb_list = kmalloc(sizeof(scb_t) * MAX_COMMANDS, GFP_KERNEL); + adapter->scb_list = kmalloc_array(MAX_COMMANDS, sizeof(scb_t), + GFP_KERNEL); if (!adapter->scb_list) { dev_warn(&pdev->dev, "out of RAM\n"); goto out_free_cmd_buffer; diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index 65b6f6ace3a5..12aa285a6513 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c @@ -936,10 +936,12 @@ mraid_mm_register_adp(mraid_mmadp_t *lld_adp) * Allocate single blocks of memory for all required kiocs, * mailboxes and passthru structures. */ - adapter->kioc_list = kmalloc(sizeof(uioc_t) * lld_adp->max_kioc, - GFP_KERNEL); - adapter->mbox_list = kmalloc(sizeof(mbox64_t) * lld_adp->max_kioc, - GFP_KERNEL); + adapter->kioc_list = kmalloc_array(lld_adp->max_kioc, + sizeof(uioc_t), + GFP_KERNEL); + adapter->mbox_list = kmalloc_array(lld_adp->max_kioc, + sizeof(mbox64_t), + GFP_KERNEL); adapter->pthru_dma_pool = dma_pool_create("megaraid mm pthru pool", &adapter->pdev->dev, sizeof(mraid_passthru_t), diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 42d876034741..e1346abb42aa 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -5394,9 +5394,9 @@ static int megasas_init_fw(struct megasas_instance *instance) /* stream detection initialization */ if (instance->adapter_type == VENTURA_SERIES) { fusion->stream_detect_by_ld = - kzalloc(sizeof(struct LD_STREAM_DETECT *) - * MAX_LOGICAL_DRIVES_EXT, - GFP_KERNEL); + kcalloc(MAX_LOGICAL_DRIVES_EXT, + sizeof(struct LD_STREAM_DETECT *), + GFP_KERNEL); if (!fusion->stream_detect_by_ld) { dev_err(&instance->pdev->dev, "unable to allocate stream detection for pool of LDs\n"); @@ -6073,7 +6073,7 @@ static inline int megasas_alloc_mfi_ctrl_mem(struct megasas_instance *instance) */ static int megasas_alloc_ctrl_mem(struct megasas_instance *instance) { - instance->reply_map = kzalloc(sizeof(unsigned int) * nr_cpu_ids, + instance->reply_map = kcalloc(nr_cpu_ids, sizeof(unsigned int), GFP_KERNEL); if (!instance->reply_map) return -ENOMEM; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index b13721290f4b..081acc33955b 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -432,7 +432,7 @@ megasas_alloc_cmdlist_fusion(struct megasas_instance *instance) * commands. */ fusion->cmd_list = - kzalloc(sizeof(struct megasas_cmd_fusion *) * max_mpt_cmd, + kcalloc(max_mpt_cmd, sizeof(struct megasas_cmd_fusion *), GFP_KERNEL); if (!fusion->cmd_list) { dev_err(&instance->pdev->dev, @@ -4508,8 +4508,7 @@ megasas_alloc_fusion_context(struct megasas_instance *instance) (struct LD_LOAD_BALANCE_INFO *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, fusion->load_balance_info_pages); if (!fusion->load_balance_info) { - fusion->load_balance_info = vzalloc(MAX_LOGICAL_DRIVES_EXT * - sizeof(struct LD_LOAD_BALANCE_INFO)); + fusion->load_balance_info = vzalloc(array_size(MAX_LOGICAL_DRIVES_EXT, sizeof(struct LD_LOAD_BALANCE_INFO))); if (!fusion->load_balance_info) dev_err(&instance->pdev->dev, "Failed to allocate load_balance_info, " "continuing without Load Balance support\n"); diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 20ec1c01dbd5..95400fc22bb0 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -381,7 +381,7 @@ static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd, struct scatterlist *sg, *sgl = (struct scatterlist *)buffer; int i; - pages = kzalloc(use_sg * sizeof(struct page *), GFP_KERNEL); + pages = kcalloc(use_sg, sizeof(struct page *), GFP_KERNEL); if (!pages) goto free_req; @@ -1488,7 +1488,7 @@ static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst int dbg = debugging; #endif - if ((buffer = vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL) + if ((buffer = vmalloc(array_size((nframes + 1), OS_DATA_SIZE))) == NULL) return (-EIO); printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n", @@ -5856,7 +5856,9 @@ static int osst_probe(struct device *dev) /* if this is the first attach, build the infrastructure */ write_lock(&os_scsi_tapes_lock); if (os_scsi_tapes == NULL) { - os_scsi_tapes = kmalloc(osst_max_dev * sizeof(struct osst_tape *), GFP_ATOMIC); + os_scsi_tapes = kmalloc_array(osst_max_dev, + sizeof(struct osst_tape *), + GFP_ATOMIC); if (os_scsi_tapes == NULL) { write_unlock(&os_scsi_tapes_lock); printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n"); diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c index be8269c8d127..b989ed968020 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.c +++ b/drivers/scsi/pm8001/pm8001_ctl.c @@ -653,7 +653,7 @@ static ssize_t pm8001_store_update_fw(struct device *cdev, return -EINPROGRESS; pm8001_ha->fw_status = FLASH_IN_PROGRESS; - cmd_ptr = kzalloc(count*2, GFP_KERNEL); + cmd_ptr = kcalloc(count, 2, GFP_KERNEL); if (!cmd_ptr) { pm8001_ha->fw_status = FAIL_OUT_MEMORY; return -ENOMEM; diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index b4d6cd8cd1ad..9baac4f8d948 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -4915,8 +4915,9 @@ static int pmcraid_allocate_config_buffers(struct pmcraid_instance *pinstance) int i; pinstance->res_entries = - kzalloc(sizeof(struct pmcraid_resource_entry) * - PMCRAID_MAX_RESOURCES, GFP_KERNEL); + kcalloc(PMCRAID_MAX_RESOURCES, + sizeof(struct pmcraid_resource_entry), + GFP_KERNEL); if (NULL == pinstance->res_entries) { pmcraid_err("failed to allocate memory for resource table\n"); diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c index 24b945b555ba..84cbaee810b6 100644 --- a/drivers/scsi/qedi/qedi_main.c +++ b/drivers/scsi/qedi/qedi_main.c @@ -523,7 +523,7 @@ static int qedi_init_id_tbl(struct qedi_portid_tbl *id_tbl, u16 size, id_tbl->max = size; id_tbl->next = next; spin_lock_init(&id_tbl->lock); - id_tbl->table = kzalloc(DIV_ROUND_UP(size, 32) * 4, GFP_KERNEL); + id_tbl->table = kcalloc(DIV_ROUND_UP(size, 32), 4, GFP_KERNEL); if (!id_tbl->table) return -ENOMEM; diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index a66f7cec797c..ca1f4ea70a5a 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2842,8 +2842,9 @@ qla2x00_alloc_outstanding_cmds(struct qla_hw_data *ha, struct req_que *req) req->num_outstanding_cmds = ha->cur_fw_iocb_count; } - req->outstanding_cmds = kzalloc(sizeof(srb_t *) * - req->num_outstanding_cmds, GFP_KERNEL); + req->outstanding_cmds = kcalloc(req->num_outstanding_cmds, + sizeof(srb_t *), + GFP_KERNEL); if (!req->outstanding_cmds) { /* @@ -2851,8 +2852,9 @@ qla2x00_alloc_outstanding_cmds(struct qla_hw_data *ha, struct req_que *req) * initialization. */ req->num_outstanding_cmds = MIN_OUTSTANDING_COMMANDS; - req->outstanding_cmds = kzalloc(sizeof(srb_t *) * - req->num_outstanding_cmds, GFP_KERNEL); + req->outstanding_cmds = kcalloc(req->num_outstanding_cmds, + sizeof(srb_t *), + GFP_KERNEL); if (!req->outstanding_cmds) { ql_log(ql_log_fatal, NULL, 0x0126, diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index b39faf2bfa0d..f556c8634fd3 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -3395,8 +3395,9 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) "Adjusted Max no of queues pairs: %d.\n", ha->max_qpairs); } } - ha->msix_entries = kzalloc(sizeof(struct qla_msix_entry) * - ha->msix_count, GFP_KERNEL); + ha->msix_entries = kcalloc(ha->msix_count, + sizeof(struct qla_msix_entry), + GFP_KERNEL); if (!ha->msix_entries) { ql_log(ql_log_fatal, vha, 0x00c8, "Failed to allocate memory for ha->msix_entries.\n"); diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index a5b8313cf491..5becb875ae28 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -1230,7 +1230,7 @@ qla82xx_pinit_from_rom(scsi_qla_host_t *vha) ql_log(ql_log_info, vha, 0x0072, "%d CRB init values found in ROM.\n", n); - buf = kmalloc(n * sizeof(struct crb_addr_pair), GFP_KERNEL); + buf = kmalloc_array(n, sizeof(struct crb_addr_pair), GFP_KERNEL); if (buf == NULL) { ql_log(ql_log_fatal, vha, 0x010c, "Unable to allocate memory.\n"); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index ea60c6e603c0..f60f87daf2bf 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -399,7 +399,7 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req, struct rsp_que *rsp) { scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); - ha->req_q_map = kzalloc(sizeof(struct req_que *) * ha->max_req_queues, + ha->req_q_map = kcalloc(ha->max_req_queues, sizeof(struct req_que *), GFP_KERNEL); if (!ha->req_q_map) { ql_log(ql_log_fatal, vha, 0x003b, @@ -407,7 +407,7 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req, goto fail_req_map; } - ha->rsp_q_map = kzalloc(sizeof(struct rsp_que *) * ha->max_rsp_queues, + ha->rsp_q_map = kcalloc(ha->max_rsp_queues, sizeof(struct rsp_que *), GFP_KERNEL); if (!ha->rsp_q_map) { ql_log(ql_log_fatal, vha, 0x003c, @@ -4003,8 +4003,9 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, (*rsp)->ring); /* Allocate memory for NVRAM data for vports */ if (ha->nvram_npiv_size) { - ha->npiv_info = kzalloc(sizeof(struct qla_npiv_entry) * - ha->nvram_npiv_size, GFP_KERNEL); + ha->npiv_info = kcalloc(ha->nvram_npiv_size, + sizeof(struct qla_npiv_entry), + GFP_KERNEL); if (!ha->npiv_info) { ql_log_pci(ql_log_fatal, ha->pdev, 0x002d, "Failed to allocate memory for npiv_info.\n"); @@ -4038,8 +4039,9 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, INIT_LIST_HEAD(&ha->vp_list); /* Allocate memory for our loop_id bitmap */ - ha->loop_id_map = kzalloc(BITS_TO_LONGS(LOOPID_MAP_SIZE) * sizeof(long), - GFP_KERNEL); + ha->loop_id_map = kcalloc(BITS_TO_LONGS(LOOPID_MAP_SIZE), + sizeof(long), + GFP_KERNEL); if (!ha->loop_id_map) goto fail_loop_id_map; else { diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 21011c5fddeb..52e28b0f2200 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -6109,8 +6109,9 @@ int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha) return -ENOMEM; } - tgt->qphints = kzalloc((ha->max_qpairs + 1) * - sizeof(struct qla_qpair_hint), GFP_KERNEL); + tgt->qphints = kcalloc(ha->max_qpairs + 1, + sizeof(struct qla_qpair_hint), + GFP_KERNEL); if (!tgt->qphints) { kfree(tgt); ql_log(ql_log_warn, base_vha, 0x0197, @@ -6916,8 +6917,9 @@ qlt_mem_alloc(struct qla_hw_data *ha) if (!QLA_TGT_MODE_ENABLED()) return 0; - ha->tgt.tgt_vp_map = kzalloc(sizeof(struct qla_tgt_vp_map) * - MAX_MULTI_ID_FABRIC, GFP_KERNEL); + ha->tgt.tgt_vp_map = kcalloc(MAX_MULTI_ID_FABRIC, + sizeof(struct qla_tgt_vp_map), + GFP_KERNEL); if (!ha->tgt.tgt_vp_map) return -ENOMEM; diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index e7aee067b056..82533406e3db 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -1604,8 +1604,7 @@ static int tcm_qla2xxx_init_lport(struct tcm_qla2xxx_lport *lport) return rc; } - lport->lport_loopid_map = vmalloc(sizeof(struct tcm_qla2xxx_fc_loopid) * - 65536); + lport->lport_loopid_map = vmalloc(array_size(65536, sizeof(struct tcm_qla2xxx_fc_loopid))); if (!lport->lport_loopid_map) { pr_err("Unable to allocate lport->lport_loopid_map of %zu bytes\n", sizeof(struct tcm_qla2xxx_fc_loopid) * 65536); diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index e91abb327745..9815674d937b 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c @@ -1075,7 +1075,7 @@ qla4_82xx_pinit_from_rom(struct scsi_qla_host *ha, int verbose) ql4_printk(KERN_INFO, ha, "%s: %d CRB init values found in ROM.\n", DRIVER_NAME, n); - buf = kmalloc(n * sizeof(struct crb_addr_pair), GFP_KERNEL); + buf = kmalloc_array(n, sizeof(struct crb_addr_pair), GFP_KERNEL); if (buf == NULL) { ql4_printk(KERN_WARNING, ha, "%s: [ERROR] Unable to malloc memory.\n", DRIVER_NAME); diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index ac936b5ca74e..30f77ca780fc 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -3164,7 +3164,7 @@ static int resp_comp_write(struct scsi_cmnd *scp, return check_condition_result; } dnum = 2 * num; - arr = kzalloc(dnum * lb_size, GFP_ATOMIC); + arr = kcalloc(lb_size, dnum, GFP_ATOMIC); if (NULL == arr) { mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, INSUFF_RES_ASCQ); @@ -5072,7 +5072,7 @@ static int __init scsi_debug_init(void) } map_size = lba_to_map_index(sdebug_store_sectors - 1) + 1; - map_storep = vmalloc(BITS_TO_LONGS(map_size) * sizeof(long)); + map_storep = vmalloc(array_size(sizeof(long), BITS_TO_LONGS(map_size))); pr_info("%lu provisioning blocks\n", map_size); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 303c257480e1..489737392c37 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3120,10 +3120,10 @@ static int sd_revalidate_disk(struct gendisk *disk) dev_max = min_not_zero(dev_max, sdkp->max_xfer_blocks); q->limits.max_dev_sectors = logical_to_sectors(sdp, dev_max); - if (sd_validate_opt_xfer_size(sdkp, dev_max)) + if (sd_validate_opt_xfer_size(sdkp, dev_max)) { rw_max = q->limits.io_opt = - sdkp->opt_xfer_blocks * sdp->sector_size; - else { + sdkp->opt_xfer_blocks * sdp->sector_size; + } else { q->limits.io_opt = 0; rw_max = min_not_zero(logical_to_sectors(sdp, dev_max), (sector_t)BLK_DEF_MAX_SECTORS); diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 62f04c0511cf..0fc39224ce1e 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -747,7 +747,7 @@ static int ses_intf_add(struct device *cdev, buf = NULL; } page2_not_supported: - scomp = kzalloc(sizeof(struct ses_component) * components, GFP_KERNEL); + scomp = kcalloc(components, sizeof(struct ses_component), GFP_KERNEL); if (!scomp) goto err_free; diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 633e4beaf7cb..e16e48ae1b57 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1095,7 +1095,7 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) else { sg_req_info_t *rinfo; - rinfo = kzalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE, + rinfo = kcalloc(SG_MAX_QUEUE, SZ_SG_REQ_INFO, GFP_KERNEL); if (!rinfo) return -ENOMEM; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 4055753b495a..9fdbafe69230 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -1826,8 +1826,9 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) num_new_devices = num_physicals + num_logicals; - new_device_list = kmalloc(sizeof(*new_device_list) * - num_new_devices, GFP_KERNEL); + new_device_list = kmalloc_array(num_new_devices, + sizeof(*new_device_list), + GFP_KERNEL); if (!new_device_list) { dev_warn(&ctrl_info->pci_dev->dev, "%s\n", out_of_memory_msg); rc = -ENOMEM; @@ -4296,8 +4297,9 @@ static int pqi_alloc_io_resources(struct pqi_ctrl_info *ctrl_info) struct device *dev; struct pqi_io_request *io_request; - ctrl_info->io_request_pool = kzalloc(ctrl_info->max_io_slots * - sizeof(ctrl_info->io_request_pool[0]), GFP_KERNEL); + ctrl_info->io_request_pool = kcalloc(ctrl_info->max_io_slots, + sizeof(ctrl_info->io_request_pool[0]), + GFP_KERNEL); if (!ctrl_info->io_request_pool) { dev_err(&ctrl_info->pci_dev->dev, diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 94e402ed30f6..481fd71e824f 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3888,7 +3888,7 @@ static struct st_buffer *new_tape_buffer(int need_dma, int max_sg) tb->dma = need_dma; tb->buffer_size = 0; - tb->reserved_pages = kzalloc(max_sg * sizeof(struct page *), + tb->reserved_pages = kcalloc(max_sg, sizeof(struct page *), GFP_ATOMIC); if (!tb->reserved_pages) { kfree(tb); @@ -4915,7 +4915,7 @@ static int sgl_map_user_pages(struct st_buffer *STbp, if (count == 0) return 0; - if ((pages = kmalloc(max_pages * sizeof(*pages), GFP_KERNEL)) == NULL) + if ((pages = kmalloc_array(max_pages, sizeof(*pages), GFP_KERNEL)) == NULL) return -ENOMEM; /* Try to fault in all of the necessary pages */ diff --git a/drivers/scsi/ufs/ufs-debugfs.c b/drivers/scsi/ufs/ufs-debugfs.c index d686f0a304fb..f8a9abac88a5 100644 --- a/drivers/scsi/ufs/ufs-debugfs.c +++ b/drivers/scsi/ufs/ufs-debugfs.c @@ -803,13 +803,13 @@ static int ufshcd_init_statistics(struct ufs_hba *hba) int i; stats->enabled = false; - stats->tag_stats = kzalloc(sizeof(*stats->tag_stats) * hba->nutrs, - GFP_KERNEL); + stats->tag_stats = kcalloc(hba->nutrs, sizeof(*stats->tag_stats), + GFP_KERNEL); if (!hba->ufs_stats.tag_stats) goto no_mem; - stats->tag_stats[0] = kzalloc(sizeof(**stats->tag_stats) * - TS_NUM_STATS * hba->nutrs, GFP_KERNEL); + stats->tag_stats[0] = kzalloc(array3_size(sizeof(**stats->tag_stats), TS_NUM_STATS, hba->nutrs), + GFP_KERNEL); if (!stats->tag_stats[0]) goto no_mem; diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index becb6ae75a33..d6b1f23e2d69 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -1900,28 +1900,16 @@ static int ufs_qcom_pm_qos_init(struct ufs_qcom_host *host) struct device_node *node = host->hba->dev->of_node; struct device_attribute *attr; int ret = 0; - int num_groups; int num_values; char wq_name[sizeof("ufs_pm_qos_00")]; int i; - num_groups = of_property_count_u32_elems(node, - "qcom,pm-qos-cpu-groups"); - if (num_groups <= 0) - goto no_pm_qos; - num_values = of_property_count_u32_elems(node, "qcom,pm-qos-cpu-group-latency-us"); if (num_values <= 0) goto no_pm_qos; - if (num_values != num_groups || num_groups > num_possible_cpus()) { - dev_err(host->hba->dev, "%s: invalid count: num_groups=%d, num_values=%d, num_possible_cpus=%d\n", - __func__, num_groups, num_values, num_possible_cpus()); - goto no_pm_qos; - } - - host->pm_qos.num_groups = num_groups; + host->pm_qos.num_groups = 1; host->pm_qos.groups = kcalloc(host->pm_qos.num_groups, sizeof(struct ufs_qcom_pm_qos_cpu_group), GFP_KERNEL); if (!host->pm_qos.groups) diff --git a/drivers/scsi/ufs/ufs_test.c b/drivers/scsi/ufs/ufs_test.c index 92b348590650..ad38eef26528 100644 --- a/drivers/scsi/ufs/ufs_test.c +++ b/drivers/scsi/ufs/ufs_test.c @@ -1309,8 +1309,8 @@ static int ufs_test_debugfs_init(void) utils_root = test_iosched_get_debugfs_utils_root(); tests_root = test_iosched_get_debugfs_tests_root(); - utd->test_list = kmalloc(sizeof(struct dentry *) * NUM_TESTS, - GFP_KERNEL); + utd->test_list = kmalloc_array(NUM_TESTS, sizeof(struct dentry *), + GFP_KERNEL); if (!utd->test_list) { pr_err("%s: failed to allocate tests dentrys", __func__); return -ENODEV; diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 63c5c7b8cd78..e7b6fd0df2c1 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -102,8 +102,8 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba) goto out; } - clkfreq = devm_kzalloc(dev, sz * sizeof(*clkfreq), - GFP_KERNEL); + clkfreq = devm_kcalloc(dev, sz, sizeof(*clkfreq), + GFP_KERNEL); if (!clkfreq) { ret = -ENOMEM; goto out; diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 2548451bf726..d587fcd7e3a2 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -682,8 +682,9 @@ static void ufshcd_cmd_log_init(struct ufs_hba *hba) { /* Allocate log entries */ if (!hba->cmd_log.entries) { - hba->cmd_log.entries = kzalloc(UFSHCD_MAX_CMD_LOGGING * - sizeof(struct ufshcd_cmd_log_entry), GFP_KERNEL); + hba->cmd_log.entries = kcalloc(UFSHCD_MAX_CMD_LOGGING, + sizeof(struct ufshcd_cmd_log_entry), + GFP_KERNEL); if (!hba->cmd_log.entries) return; dev_dbg(hba->dev, "%s: cmd_log.entries initialized\n", @@ -4882,8 +4883,8 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba) } /* Allocate memory for local reference block */ - hba->lrb = devm_kzalloc(hba->dev, - hba->nutrs * sizeof(struct ufshcd_lrb), + hba->lrb = devm_kcalloc(hba->dev, + hba->nutrs, sizeof(struct ufshcd_lrb), GFP_KERNEL); if (!hba->lrb) { dev_err(hba->dev, "LRB Memory allocation failed\n"); @@ -8065,7 +8066,6 @@ static int ufshcd_detect_device(struct ufs_hba *hba) static int ufshcd_reset_and_restore(struct ufs_hba *hba) { int err = 0; - unsigned long flags; int retries = MAX_HOST_RESET_RETRIES; ufshcd_enable_irq(hba); @@ -8081,15 +8081,6 @@ static int ufshcd_reset_and_restore(struct ufs_hba *hba) if (err && ufshcd_is_embedded_dev(hba)) BUG(); - /* - * After reset the door-bell might be cleared, complete - * outstanding requests in s/w here. - */ - spin_lock_irqsave(hba->host->host_lock, flags); - ufshcd_transfer_req_compl(hba); - ufshcd_tmc_handler(hba); - spin_unlock_irqrestore(hba->host->host_lock, flags); - return err; } diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 1f4bd7d0154d..90540ccc14c5 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -830,9 +830,10 @@ static int virtscsi_init(struct virtio_device *vdev, struct irq_affinity desc = { .pre_vectors = 2 }; num_vqs = vscsi->num_queues + VIRTIO_SCSI_VQ_BASE; - vqs = kmalloc(num_vqs * sizeof(struct virtqueue *), GFP_KERNEL); - callbacks = kmalloc(num_vqs * sizeof(vq_callback_t *), GFP_KERNEL); - names = kmalloc(num_vqs * sizeof(char *), GFP_KERNEL); + vqs = kmalloc_array(num_vqs, sizeof(struct virtqueue *), GFP_KERNEL); + callbacks = kmalloc_array(num_vqs, sizeof(vq_callback_t *), + GFP_KERNEL); + names = kmalloc_array(num_vqs, sizeof(char *), GFP_KERNEL); if (!callbacks || !vqs || !names) { err = -ENOMEM; diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index 7442bc130055..eeb028b9cdb3 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c @@ -249,7 +249,7 @@ static int __init sh_clk_div_register_ops(struct clk *clks, int nr, int k; freq_table_size *= (nr_divs + 1); - freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL); + freq_table = kcalloc(nr, freq_table_size, GFP_KERNEL); if (!freq_table) { pr_err("%s: unable to alloc memory\n", __func__); return -ENOMEM; diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index 8e72bcbd3d6d..46f0f322d4d8 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c @@ -203,7 +203,7 @@ int __init register_intc_controller(struct intc_desc *desc) if (desc->num_resources) { d->nr_windows = desc->num_resources; - d->window = kzalloc(d->nr_windows * sizeof(*d->window), + d->window = kcalloc(d->nr_windows, sizeof(*d->window), GFP_NOWAIT); if (!d->window) goto err1; @@ -230,12 +230,12 @@ int __init register_intc_controller(struct intc_desc *desc) d->nr_reg += hw->ack_regs ? hw->nr_ack_regs : 0; d->nr_reg += hw->subgroups ? hw->nr_subgroups : 0; - d->reg = kzalloc(d->nr_reg * sizeof(*d->reg), GFP_NOWAIT); + d->reg = kcalloc(d->nr_reg, sizeof(*d->reg), GFP_NOWAIT); if (!d->reg) goto err2; #ifdef CONFIG_SMP - d->smp = kzalloc(d->nr_reg * sizeof(*d->smp), GFP_NOWAIT); + d->smp = kcalloc(d->nr_reg, sizeof(*d->smp), GFP_NOWAIT); if (!d->smp) goto err3; #endif @@ -253,7 +253,7 @@ int __init register_intc_controller(struct intc_desc *desc) } if (hw->prio_regs) { - d->prio = kzalloc(hw->nr_vectors * sizeof(*d->prio), + d->prio = kcalloc(hw->nr_vectors, sizeof(*d->prio), GFP_NOWAIT); if (!d->prio) goto err4; @@ -269,7 +269,7 @@ int __init register_intc_controller(struct intc_desc *desc) } if (hw->sense_regs) { - d->sense = kzalloc(hw->nr_vectors * sizeof(*d->sense), + d->sense = kcalloc(hw->nr_vectors, sizeof(*d->sense), GFP_NOWAIT); if (!d->sense) goto err5; diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c index bec81c2404f7..040ba4777d63 100644 --- a/drivers/sh/maple/maple.c +++ b/drivers/sh/maple/maple.c @@ -161,7 +161,7 @@ int maple_add_packet(struct maple_device *mdev, u32 function, u32 command, void *sendbuf = NULL; if (length) { - sendbuf = kzalloc(length * 4, GFP_KERNEL); + sendbuf = kcalloc(length, 4, GFP_KERNEL); if (!sendbuf) { ret = -ENOMEM; goto out; diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c index 3f99b2bc0f78..02e032cf293d 100644 --- a/drivers/slimbus/slim-msm-ctrl.c +++ b/drivers/slimbus/slim-msm-ctrl.c @@ -838,9 +838,9 @@ static void slim_sat_rxprocess(struct work_struct *work) continue; } /* Satellite-channels */ - sat->satch = kzalloc(MSM_MAX_SATCH * - sizeof(struct msm_sat_chan), - GFP_KERNEL); + sat->satch = kcalloc(MSM_MAX_SATCH, + sizeof(struct msm_sat_chan), + GFP_KERNEL); send_capability: txn.mc = SLIM_USR_MC_MASTER_CAPABILITY; txn.mt = SLIM_MSG_MT_SRC_REFERRED_USER; @@ -1198,7 +1198,7 @@ static int msm_slim_probe(struct platform_device *pdev) ret = -ENOMEM; goto err_get_res_failed; } - dev->wr_comp = kzalloc(sizeof(struct completion *) * MSM_TX_BUFS, + dev->wr_comp = kcalloc(MSM_TX_BUFS, sizeof(struct completion *), GFP_KERNEL); if (!dev->wr_comp) return -ENOMEM; diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c index 681e244def0d..bdbc089e7a58 100644 --- a/drivers/slimbus/slim-msm-ngd.c +++ b/drivers/slimbus/slim-msm-ngd.c @@ -1794,7 +1794,7 @@ static int ngd_slim_probe(struct platform_device *pdev) dev_err(&pdev->dev, "no memory for MSM slimbus controller\n"); return PTR_ERR(dev); } - dev->wr_comp = kzalloc(sizeof(struct completion *) * MSM_TX_BUFS, + dev->wr_comp = kcalloc(MSM_TX_BUFS, sizeof(struct completion *), GFP_KERNEL); if (!dev->wr_comp) { ret = -ENOMEM; diff --git a/drivers/soc/actions/owl-sps.c b/drivers/soc/actions/owl-sps.c index 875225bfa21c..077a8305890e 100644 --- a/drivers/soc/actions/owl-sps.c +++ b/drivers/soc/actions/owl-sps.c @@ -116,8 +116,8 @@ static int owl_sps_probe(struct platform_device *pdev) sps_info = match->data; - sps = devm_kzalloc(&pdev->dev, sizeof(*sps) + - sps_info->num_domains * sizeof(sps->domains[0]), + sps = devm_kzalloc(&pdev->dev, + struct_size(sps, domains, sps_info->num_domains), GFP_KERNEL); if (!sps) return -ENOMEM; diff --git a/drivers/soc/bcm/raspberrypi-power.c b/drivers/soc/bcm/raspberrypi-power.c index f7ed1187518b..a78dfe0a2b50 100644 --- a/drivers/soc/bcm/raspberrypi-power.c +++ b/drivers/soc/bcm/raspberrypi-power.c @@ -165,8 +165,10 @@ static int rpi_power_probe(struct platform_device *pdev) return -ENOMEM; rpi_domains->xlate.domains = - devm_kzalloc(dev, sizeof(*rpi_domains->xlate.domains) * - RPI_POWER_DOMAIN_COUNT, GFP_KERNEL); + devm_kcalloc(dev, + RPI_POWER_DOMAIN_COUNT, + sizeof(*rpi_domains->xlate.domains), + GFP_KERNEL); if (!rpi_domains->xlate.domains) return -ENOMEM; diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index 90892a360c61..6e03864e880b 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -989,7 +989,7 @@ int qman_alloc_fq_table(u32 _num_fqids) { num_fqids = _num_fqids; - fq_table = vzalloc(num_fqids * 2 * sizeof(struct qman_fq *)); + fq_table = vzalloc(array_size(sizeof(struct qman_fq *), (num_fqids * 2))); if (!fq_table) return -ENOMEM; @@ -1153,7 +1153,7 @@ static int qman_create_portal(struct qman_portal *portal, qm_dqrr_set_ithresh(p, QMAN_PIRQ_DQRR_ITHRESH); qm_mr_set_ithresh(p, QMAN_PIRQ_MR_ITHRESH); qm_out(p, QM_REG_ITPR, QMAN_PIRQ_IPERIOD); - portal->cgrs = kmalloc(2 * sizeof(*cgrs), GFP_KERNEL); + portal->cgrs = kmalloc_array(2, sizeof(*cgrs), GFP_KERNEL); if (!portal->cgrs) goto fail_cgrs; /* initial snapshot is no-depletion */ diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index fb2a8b1e7979..b0cb5214f659 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -404,15 +404,15 @@ static struct scp *init_scp(struct platform_device *pdev, if (IS_ERR(scp->base)) return ERR_CAST(scp->base); - scp->domains = devm_kzalloc(&pdev->dev, - sizeof(*scp->domains) * num, GFP_KERNEL); + scp->domains = devm_kcalloc(&pdev->dev, + num, sizeof(*scp->domains), GFP_KERNEL); if (!scp->domains) return ERR_PTR(-ENOMEM); pd_data = &scp->pd_data; - pd_data->domains = devm_kzalloc(&pdev->dev, - sizeof(*pd_data->domains) * num, GFP_KERNEL); + pd_data->domains = devm_kcalloc(&pdev->dev, + num, sizeof(*pd_data->domains), GFP_KERNEL); if (!pd_data->domains) return ERR_PTR(-ENOMEM); diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 8ed8dcf443b6..03d828763411 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -1061,4 +1061,10 @@ config QCOM_HYP_CORE_CTL An offline CPU is considered as a reserved CPU since this OS can't use it. +config RENAME_BLOCK_DEVICE + bool "Rename block device node in /dev" + help + This driver is used to rename the block device node assigned by generic driver + to a name that is needed. + source "drivers/soc/qcom/wcnss/Kconfig" diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 077f668f30a5..8edfa4263d1d 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -118,6 +118,7 @@ obj-$(CONFIG_QCOM_ADSP_MANUAL_VOTE) += adsp_vote_qmi.o adsp_lpm_voting_v01.o obj-$(CONFIG_CPU_V7) += idle-v7.o obj-$(CONFIG_MSM_BAM_DMUX) += bam_dmux.o obj-$(CONFIG_WCNSS_CORE) += wcnss/ +obj-$(CONFIG_RENAME_BLOCK_DEVICE) += rename_block_device.o CFLAGS_rpm_stats.o += -DCONFIG_DEBUG_FS CFLAGS_rpm_master_stat.o += -DCONFIG_DEBUG_FS diff --git a/drivers/soc/qcom/bgcom_interface.c b/drivers/soc/qcom/bgcom_interface.c index bcb51a249e54..0705bc7ad16d 100644 --- a/drivers/soc/qcom/bgcom_interface.c +++ b/drivers/soc/qcom/bgcom_interface.c @@ -45,7 +45,6 @@ #define MPPS_DOWN_EVENT_TO_BG_TIMEOUT 3000 #define ADSP_DOWN_EVENT_TO_BG_TIMEOUT 3000 -#define SLEEP_FOR_SPI_BUS 2000 enum { SSR_DOMAIN_BG, @@ -401,8 +400,6 @@ static long bg_com_ioctl(struct file *filp, break; case SET_SPI_BUSY: ret = bgcom_set_spi_state(BGCOM_SPI_BUSY); - /* Add sleep for SPI Bus to release*/ - msleep(SLEEP_FOR_SPI_BUS); break; case BG_SOFT_RESET: ret = bg_soft_reset(); @@ -619,8 +616,6 @@ static int ssr_bg_cb(struct notifier_block *this, send_uevent(&bge); break; case SUBSYS_AFTER_SHUTDOWN: - /* Add sleep for SPI Bus to release*/ - msleep(SLEEP_FOR_SPI_BUS); if (dev->pending_bg_twm_wear_load) { /* Load bg-twm-wear */ dev->pending_bg_twm_wear_load = false; diff --git a/drivers/soc/qcom/bgcom_spi.c b/drivers/soc/qcom/bgcom_spi.c index e7993251a4d8..9ccdde74032a 100644 --- a/drivers/soc/qcom/bgcom_spi.c +++ b/drivers/soc/qcom/bgcom_spi.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "bgcom.h" #include "bgrsb.h" #include "bgcom_interface.h" @@ -160,6 +161,10 @@ int bgcom_set_spi_state(enum bgcom_spi_state state) { struct bg_spi_priv *bg_spi = container_of(bg_com_drv, struct bg_spi_priv, lhandle); + struct device spi_dev = bg_spi->spi->master->dev; + ktime_t time_start, delta; + s64 time_elapsed; + if (state < 0 || state > 1) return -EINVAL; @@ -167,6 +172,15 @@ int bgcom_set_spi_state(enum bgcom_spi_state state) return 0; mutex_lock(&bg_spi->xfer_mutex); + if (state == BGCOM_SPI_BUSY) { + time_start = ktime_get(); + while (!pm_runtime_status_suspended(spi_dev.parent)) { + delta = ktime_sub(ktime_get(), time_start); + time_elapsed = ktime_to_ms(delta); + BUG_ON(time_elapsed > 5 * MSEC_PER_SEC); + msleep(100); + } + } spi_state = state; mutex_unlock(&bg_spi->xfer_mutex); return 0; @@ -263,7 +277,9 @@ static int bgcom_transfer(void *handle, uint8_t *tx_buf, tx_xfer->rx_buf = rx_buf; tx_xfer->len = txn_len; + pm_runtime_get_sync(bg_spi->spi->controller->dev.parent); ret = spi_sync(spi, &bg_spi->msg1); + pm_runtime_put_sync_suspend(bg_spi->spi->controller->dev.parent); mutex_unlock(&bg_spi->xfer_mutex); if (ret) diff --git a/drivers/soc/qcom/gladiator_hang_detect.c b/drivers/soc/qcom/gladiator_hang_detect.c index 4d1f601f204c..4b9bc793ecf1 100644 --- a/drivers/soc/qcom/gladiator_hang_detect.c +++ b/drivers/soc/qcom/gladiator_hang_detect.c @@ -517,15 +517,15 @@ static int msm_gladiator_hang_detect_probe(struct platform_device *pdev) hang_attr_group.attrs = hang_attrs_v3; } - hang_det->threshold = devm_kzalloc(&pdev->dev, - sizeof(phys_addr_t)*NR_GLA_REG, GFP_KERNEL); + hang_det->threshold = devm_kcalloc(&pdev->dev, + NR_GLA_REG, sizeof(phys_addr_t), GFP_KERNEL); if (!hang_det->threshold) { pr_err("Can't allocate hang_detect threshold memory\n"); return -ENOMEM; } - treg = devm_kzalloc(&pdev->dev, sizeof(u32)*NR_GLA_REG, GFP_KERNEL); + treg = devm_kcalloc(&pdev->dev, NR_GLA_REG, sizeof(u32), GFP_KERNEL); if (!treg) return -ENOMEM; diff --git a/drivers/soc/qcom/glink_pkt.c b/drivers/soc/qcom/glink_pkt.c index 376ff9f62efd..2378a5a3c9f9 100644 --- a/drivers/soc/qcom/glink_pkt.c +++ b/drivers/soc/qcom/glink_pkt.c @@ -680,7 +680,7 @@ static int glink_pkt_init_rpmsg(struct glink_pkt_device *gpdev) char *drv_name; /* zalloc array of two to NULL terminate the match list */ - match = devm_kzalloc(dev, 2 * sizeof(*match), GFP_KERNEL); + match = devm_kcalloc(dev, 2, sizeof(*match), GFP_KERNEL); if (!match) return -ENOMEM; snprintf(match->name, RPMSG_NAME_SIZE, "%s", gpdev->ch_name); diff --git a/drivers/soc/qcom/hab/hab_open.c b/drivers/soc/qcom/hab/hab_open.c index a90460a1295e..8caccdd22c7d 100644 --- a/drivers/soc/qcom/hab/hab_open.c +++ b/drivers/soc/qcom/hab/hab_open.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -240,6 +240,8 @@ int hab_open_receive_cancel(struct physical_channel *pchan, request->xdata.vchan_id = data.vchan_id; request->xdata.sub_id = data.sub_id; request->xdata.open_id = data.open_id; + request->xdata.ver_fe = data.ver_fe; + request->xdata.ver_be = data.ver_be; do_gettimeofday(&tv); node->age = tv.tv_sec + HAB_OPEN_REQ_EXPIRE_TIME_S + diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index 1b145e90d7d8..dead80705242 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -3859,8 +3859,6 @@ static int icnss_probe(struct platform_device *pdev) goto out_unregister_ext_modem; } - device_enable_async_suspend(dev); - spin_lock_init(&priv->event_lock); spin_lock_init(&priv->on_off_lock); mutex_init(&priv->dev_lock); diff --git a/drivers/soc/qcom/jtagv8-etm.c b/drivers/soc/qcom/jtagv8-etm.c index 406ad980f70c..7a48013b3527 100644 --- a/drivers/soc/qcom/jtagv8-etm.c +++ b/drivers/soc/qcom/jtagv8-etm.c @@ -1616,8 +1616,8 @@ static int jtag_mm_etm_probe(struct platform_device *pdev, uint32_t cpu) etmdata->save_restore_disabled = 1; /* Allocate etm state save space per core */ - etmdata->state = devm_kzalloc(dev, - MAX_ETM_STATE_SIZE * sizeof(uint64_t), + etmdata->state = devm_kcalloc(dev, + MAX_ETM_STATE_SIZE, sizeof(uint64_t), GFP_KERNEL); if (!etmdata->state) return -ENOMEM; diff --git a/drivers/soc/qcom/msm_bus/msm_bus_arb_adhoc.c b/drivers/soc/qcom/msm_bus/msm_bus_arb_adhoc.c index a96b55cab9fb..3e4ce8efc515 100644 --- a/drivers/soc/qcom/msm_bus/msm_bus_arb_adhoc.c +++ b/drivers/soc/qcom/msm_bus/msm_bus_arb_adhoc.c @@ -127,9 +127,9 @@ static int gen_lnode(struct device *dev, } if (!cur_dev->num_lnodes) { - cur_dev->lnode_list = devm_kzalloc(dev, - sizeof(struct link_node) * NUM_LNODES, - GFP_KERNEL); + cur_dev->lnode_list = devm_kcalloc(dev, + NUM_LNODES, sizeof(struct link_node), + GFP_KERNEL); if (!cur_dev->lnode_list) goto exit_gen_lnode; @@ -916,8 +916,9 @@ static int alloc_handle_lst(int size) struct msm_bus_client **t_cl_list; if (!handle_list.num_entries) { - t_cl_list = kzalloc(sizeof(struct msm_bus_client *) - * NUM_CL_HANDLES, GFP_KERNEL); + t_cl_list = kcalloc(NUM_CL_HANDLES, + sizeof(struct msm_bus_client *), + GFP_KERNEL); if (ZERO_OR_NULL_PTR(t_cl_list)) { ret = -ENOMEM; MSM_BUS_ERR("%s: Failed to allocate handles list", diff --git a/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c b/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c index d376f14e7dd4..ed62bf25d145 100644 --- a/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c +++ b/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c @@ -140,9 +140,9 @@ static void bcm_add_bus_req(struct device *dev) bcm_dev = to_msm_bus_node(cur_dev->node_info->bcm_devs[i]); max_num_lnodes = bcm_dev->bcmdev->num_bus_devs; if (!bcm_dev->num_lnodes) { - bcm_dev->lnode_list = devm_kzalloc(dev, - sizeof(struct link_node) * max_num_lnodes, - GFP_KERNEL); + bcm_dev->lnode_list = devm_kcalloc(dev, + max_num_lnodes, sizeof(struct link_node), + GFP_KERNEL); if (!bcm_dev->lnode_list) goto exit_bcm_add_bus_req; @@ -211,9 +211,9 @@ static int gen_lnode(struct device *dev, } if (!cur_dev->num_lnodes) { - cur_dev->lnode_list = devm_kzalloc(dev, - sizeof(struct link_node) * NUM_LNODES, - GFP_KERNEL); + cur_dev->lnode_list = devm_kcalloc(dev, + NUM_LNODES, sizeof(struct link_node), + GFP_KERNEL); if (!cur_dev->lnode_list) goto exit_gen_lnode; @@ -1165,8 +1165,9 @@ static int alloc_handle_lst(int size) struct msm_bus_client **t_cl_list; if (!handle_list.num_entries) { - t_cl_list = kzalloc(sizeof(struct msm_bus_client *) - * NUM_CL_HANDLES, GFP_KERNEL); + t_cl_list = kcalloc(NUM_CL_HANDLES, + sizeof(struct msm_bus_client *), + GFP_KERNEL); if (ZERO_OR_NULL_PTR(t_cl_list)) { ret = -ENOMEM; MSM_BUS_ERR("%s: Failed to allocate handles list", diff --git a/drivers/soc/qcom/msm_bus/msm_bus_fabric_adhoc.c b/drivers/soc/qcom/msm_bus/msm_bus_fabric_adhoc.c index c214e384f53c..6ba06875c869 100644 --- a/drivers/soc/qcom/msm_bus/msm_bus_fabric_adhoc.c +++ b/drivers/soc/qcom/msm_bus/msm_bus_fabric_adhoc.c @@ -919,9 +919,9 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata, pdata_node_info->agg_params.num_aggports; node_info->agg_params.num_util_levels = pdata_node_info->agg_params.num_util_levels; - node_info->agg_params.util_levels = devm_kzalloc(bus_dev, - sizeof(struct node_util_levels_type) * + node_info->agg_params.util_levels = devm_kcalloc(bus_dev, node_info->agg_params.num_util_levels, + sizeof(struct node_util_levels_type), GFP_KERNEL); if (!node_info->agg_params.util_levels) { MSM_BUS_ERR("%s: Agg util level alloc failed\n", __func__); @@ -933,9 +933,9 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata, sizeof(struct node_util_levels_type) * pdata_node_info->agg_params.num_util_levels); - node_info->dev_connections = devm_kzalloc(bus_dev, - sizeof(struct device *) * - pdata_node_info->num_connections, + node_info->dev_connections = devm_kcalloc(bus_dev, + pdata_node_info->num_connections, + sizeof(struct device *), GFP_KERNEL); if (!node_info->dev_connections) { MSM_BUS_ERR("%s:Bus dev connections alloc failed\n", __func__); @@ -943,8 +943,8 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata, goto exit_copy_node_info; } - node_info->connections = devm_kzalloc(bus_dev, - sizeof(int) * pdata_node_info->num_connections, + node_info->connections = devm_kcalloc(bus_dev, + pdata_node_info->num_connections, sizeof(int), GFP_KERNEL); if (!node_info->connections) { MSM_BUS_ERR("%s:Bus connections alloc failed\n", __func__); @@ -957,9 +957,8 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata, pdata_node_info->connections, sizeof(int) * pdata_node_info->num_connections); - node_info->black_connections = devm_kzalloc(bus_dev, - sizeof(struct device *) * - pdata_node_info->num_blist, + node_info->black_connections = devm_kcalloc(bus_dev, + pdata_node_info->num_blist, sizeof(struct device *), GFP_KERNEL); if (!node_info->black_connections) { MSM_BUS_ERR("%s: Bus black connections alloc failed\n", @@ -970,8 +969,8 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata, goto exit_copy_node_info; } - node_info->bl_cons = devm_kzalloc(bus_dev, - pdata_node_info->num_blist * sizeof(int), + node_info->bl_cons = devm_kcalloc(bus_dev, + pdata_node_info->num_blist, sizeof(int), GFP_KERNEL); if (!node_info->bl_cons) { MSM_BUS_ERR("%s:Bus black list connections alloc failed\n", @@ -987,8 +986,8 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata, pdata_node_info->bl_cons, sizeof(int) * pdata_node_info->num_blist); - node_info->qport = devm_kzalloc(bus_dev, - sizeof(int) * pdata_node_info->num_qports, + node_info->qport = devm_kcalloc(bus_dev, + pdata_node_info->num_qports, sizeof(int), GFP_KERNEL); if (!node_info->qport) { MSM_BUS_ERR("%s:Bus qport allocation failed\n", __func__); diff --git a/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c b/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c index 708713f92762..2bbe261c89e3 100644 --- a/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c +++ b/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c @@ -1384,8 +1384,8 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata, node_info->name = pdata_node_info->name; node_info->id = pdata_node_info->id; - node_info->bcm_req_idx = devm_kzalloc(bus_dev, - sizeof(int) * pdata_node_info->num_bcm_devs, + node_info->bcm_req_idx = devm_kcalloc(bus_dev, + pdata_node_info->num_bcm_devs, sizeof(int), GFP_KERNEL); if (!node_info->bcm_req_idx) { ret = -ENOMEM; @@ -1441,9 +1441,9 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata, pdata_node_info->agg_params.num_aggports; node_info->agg_params.num_util_levels = pdata_node_info->agg_params.num_util_levels; - node_info->agg_params.util_levels = devm_kzalloc(bus_dev, - sizeof(struct node_util_levels_type) * + node_info->agg_params.util_levels = devm_kcalloc(bus_dev, node_info->agg_params.num_util_levels, + sizeof(struct node_util_levels_type), GFP_KERNEL); if (!node_info->agg_params.util_levels) { MSM_BUS_ERR("%s: Agg util level alloc failed\n", __func__); @@ -1455,9 +1455,9 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata, sizeof(struct node_util_levels_type) * pdata_node_info->agg_params.num_util_levels); - node_info->dev_connections = devm_kzalloc(bus_dev, - sizeof(struct device *) * - pdata_node_info->num_connections, + node_info->dev_connections = devm_kcalloc(bus_dev, + pdata_node_info->num_connections, + sizeof(struct device *), GFP_KERNEL); if (!node_info->dev_connections) { MSM_BUS_ERR("%s:Bus dev connections alloc failed\n", __func__); @@ -1465,8 +1465,8 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata, goto exit_copy_node_info; } - node_info->connections = devm_kzalloc(bus_dev, - sizeof(int) * pdata_node_info->num_connections, + node_info->connections = devm_kcalloc(bus_dev, + pdata_node_info->num_connections, sizeof(int), GFP_KERNEL); if (!node_info->connections) { MSM_BUS_ERR("%s:Bus connections alloc failed\n", __func__); @@ -1479,9 +1479,8 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata, pdata_node_info->connections, sizeof(int) * pdata_node_info->num_connections); - node_info->black_connections = devm_kzalloc(bus_dev, - sizeof(struct device *) * - pdata_node_info->num_blist, + node_info->black_connections = devm_kcalloc(bus_dev, + pdata_node_info->num_blist, sizeof(struct device *), GFP_KERNEL); if (!node_info->black_connections) { MSM_BUS_ERR("%s: Bus black connections alloc failed\n", @@ -1492,8 +1491,8 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata, goto exit_copy_node_info; } - node_info->bl_cons = devm_kzalloc(bus_dev, - pdata_node_info->num_blist * sizeof(int), + node_info->bl_cons = devm_kcalloc(bus_dev, + pdata_node_info->num_blist, sizeof(int), GFP_KERNEL); if (!node_info->bl_cons) { MSM_BUS_ERR("%s:Bus black list connections alloc failed\n", @@ -1509,9 +1508,9 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata, pdata_node_info->bl_cons, sizeof(int) * pdata_node_info->num_blist); - node_info->bcm_devs = devm_kzalloc(bus_dev, - sizeof(struct device *) * - pdata_node_info->num_bcm_devs, + node_info->bcm_devs = devm_kcalloc(bus_dev, + pdata_node_info->num_bcm_devs, + sizeof(struct device *), GFP_KERNEL); if (!node_info->bcm_devs) { MSM_BUS_ERR("%s:Bcm dev connections alloc failed\n", __func__); @@ -1519,8 +1518,8 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata, goto exit_copy_node_info; } - node_info->bcm_dev_ids = devm_kzalloc(bus_dev, - sizeof(int) * pdata_node_info->num_bcm_devs, + node_info->bcm_dev_ids = devm_kcalloc(bus_dev, + pdata_node_info->num_bcm_devs, sizeof(int), GFP_KERNEL); if (!node_info->bcm_dev_ids) { MSM_BUS_ERR("%s:Bus connections alloc failed\n", __func__); @@ -1533,9 +1532,9 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata, pdata_node_info->bcm_dev_ids, sizeof(int) * pdata_node_info->num_bcm_devs); - node_info->rsc_devs = devm_kzalloc(bus_dev, - sizeof(struct device *) * - pdata_node_info->num_rsc_devs, + node_info->rsc_devs = devm_kcalloc(bus_dev, + pdata_node_info->num_rsc_devs, + sizeof(struct device *), GFP_KERNEL); if (!node_info->rsc_devs) { MSM_BUS_ERR("%s:rsc dev connections alloc failed\n", __func__); @@ -1543,8 +1542,8 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata, goto exit_copy_node_info; } - node_info->rsc_dev_ids = devm_kzalloc(bus_dev, - sizeof(int) * pdata_node_info->num_rsc_devs, + node_info->rsc_dev_ids = devm_kcalloc(bus_dev, + pdata_node_info->num_rsc_devs, sizeof(int), GFP_KERNEL); if (!node_info->rsc_dev_ids) { MSM_BUS_ERR("%s:Bus connections alloc failed\n", __func__); @@ -1557,8 +1556,8 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata, pdata_node_info->rsc_dev_ids, sizeof(int) * pdata_node_info->num_rsc_devs); - node_info->qport = devm_kzalloc(bus_dev, - sizeof(int) * pdata_node_info->num_qports, + node_info->qport = devm_kcalloc(bus_dev, + pdata_node_info->num_qports, sizeof(int), GFP_KERNEL); if (!node_info->qport) { MSM_BUS_ERR("%s:Bus qport allocation failed\n", __func__); diff --git a/drivers/soc/qcom/msm_bus/msm_bus_of.c b/drivers/soc/qcom/msm_bus/msm_bus_of.c index f24bc92f16bf..f7ade63aca43 100644 --- a/drivers/soc/qcom/msm_bus/msm_bus_of.c +++ b/drivers/soc/qcom/msm_bus/msm_bus_of.c @@ -149,8 +149,10 @@ static struct msm_bus_scale_pdata *get_pdata(struct device *dev, for (i = 0; i < num_usecases; i++) { usecase[i].num_paths = num_paths; - usecase[i].vectors = devm_kzalloc(dev, num_paths * - sizeof(struct msm_bus_vectors), GFP_KERNEL); + usecase[i].vectors = devm_kcalloc(dev, + num_paths, + sizeof(struct msm_bus_vectors), + GFP_KERNEL); if (!usecase[i].vectors) { mem_err = true; pr_err("Error: Mem alloc failure in vectors\n"); @@ -415,8 +417,9 @@ static struct msm_bus_node_info *get_nodes(struct device_node *of_node, pdata->len = i; info = (struct msm_bus_node_info *) - devm_kzalloc(&pdev->dev, sizeof(struct msm_bus_node_info) * - pdata->len, GFP_KERNEL); + devm_kcalloc(&pdev->dev, + pdata->len, sizeof(struct msm_bus_node_info), + GFP_KERNEL); if (ZERO_OR_NULL_PTR(info)) { pr_err("Failed to alloc memory for nodes: %d\n", pdata->len); goto err; diff --git a/drivers/soc/qcom/msm_bus/msm_bus_of_adhoc.c b/drivers/soc/qcom/msm_bus/msm_bus_of_adhoc.c index 34a0c5ce0b60..98ec7d726393 100644 --- a/drivers/soc/qcom/msm_bus/msm_bus_of_adhoc.c +++ b/drivers/soc/qcom/msm_bus/msm_bus_of_adhoc.c @@ -714,9 +714,10 @@ struct msm_bus_device_node_registration pdata->num_devices = of_get_child_count(of_node); - pdata->info = devm_kzalloc(&pdev->dev, - sizeof(struct msm_bus_node_device_type) * - pdata->num_devices, GFP_KERNEL); + pdata->info = devm_kcalloc(&pdev->dev, + pdata->num_devices, + sizeof(struct msm_bus_node_device_type), + GFP_KERNEL); if (!pdata->info) goto node_reg_err; @@ -824,8 +825,8 @@ int msm_bus_of_get_static_rules(struct platform_device *pdev, of_node = pdev->dev.of_node; num_rules = of_get_child_count(of_node); - local_rule = devm_kzalloc(&pdev->dev, - sizeof(struct bus_rule_type) * num_rules, + local_rule = devm_kcalloc(&pdev->dev, + num_rules, sizeof(struct bus_rule_type), GFP_KERNEL); if (IS_ERR_OR_NULL(local_rule)) { diff --git a/drivers/soc/qcom/msm_bus/msm_bus_of_rpmh.c b/drivers/soc/qcom/msm_bus/msm_bus_of_rpmh.c index a97a44c3cd28..7568353f51ca 100644 --- a/drivers/soc/qcom/msm_bus/msm_bus_of_rpmh.c +++ b/drivers/soc/qcom/msm_bus/msm_bus_of_rpmh.c @@ -754,9 +754,10 @@ struct msm_bus_device_node_registration pdata->num_devices = of_get_child_count(of_node); - pdata->info = devm_kzalloc(&pdev->dev, - sizeof(struct msm_bus_node_device_type) * - pdata->num_devices, GFP_KERNEL); + pdata->info = devm_kcalloc(&pdev->dev, + pdata->num_devices, + sizeof(struct msm_bus_node_device_type), + GFP_KERNEL); if (!pdata->info) { dev_err(&pdev->dev, @@ -869,8 +870,8 @@ int msm_bus_of_get_static_rules(struct platform_device *pdev, of_node = pdev->dev.of_node; num_rules = of_get_child_count(of_node); - local_rule = devm_kzalloc(&pdev->dev, - sizeof(struct bus_rule_type) * num_rules, + local_rule = devm_kcalloc(&pdev->dev, + num_rules, sizeof(struct bus_rule_type), GFP_KERNEL); if (IS_ERR_OR_NULL(local_rule)) { diff --git a/drivers/soc/qcom/peripheral-loader.c b/drivers/soc/qcom/peripheral-loader.c index be9d092727d6..b51e434c2a64 100644 --- a/drivers/soc/qcom/peripheral-loader.c +++ b/drivers/soc/qcom/peripheral-loader.c @@ -945,9 +945,6 @@ static int pil_init_mmap(struct pil_desc *desc, const struct pil_mdt *mdt) if (ret) return ret; - if (!strcmp(desc->name, "modem")) - place_marker("M - Modem Image Start Loading"); - pil_info(desc, "loading from %pa to %pa\n", &priv->region_start, &priv->region_end); @@ -1408,9 +1405,6 @@ int pil_boot(struct pil_desc *desc) } pil_log("reset_done", desc); - if (!strcmp(desc->name, "modem")) - place_marker("M - Modem out of reset"); - pil_info(desc, "Brought out of reset\n"); desc->modem_ssr = false; err_auth_and_reset: diff --git a/drivers/soc/qcom/qsee_ipc_irq.c b/drivers/soc/qcom/qsee_ipc_irq.c index 38a90e640835..f586fa0fe2bc 100644 --- a/drivers/soc/qcom/qsee_ipc_irq.c +++ b/drivers/soc/qcom/qsee_ipc_irq.c @@ -267,7 +267,7 @@ static int qsee_irq_probe(struct platform_device *pdev) return -ENODEV; irq_count = platform_irq_count(pdev); - qirq->banks = devm_kzalloc(dev, sizeof(*qirq->banks) * irq_count, + qirq->banks = devm_kcalloc(dev, irq_count, sizeof(*qirq->banks), GFP_KERNEL); if (!qirq->banks) return -ENOMEM; diff --git a/drivers/soc/qcom/rename_block_device.c b/drivers/soc/qcom/rename_block_device.c new file mode 100644 index 000000000000..c2dd284b0ac3 --- /dev/null +++ b/drivers/soc/qcom/rename_block_device.c @@ -0,0 +1,65 @@ +/* Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#define PATH_SIZE 32 + +static int rename_blk_dev_init(void) +{ + dev_t dev; + int index = 0, partno; + struct gendisk *disk; + struct device_node *node; + char dev_path[PATH_SIZE]; + const char *actual_name, *modified_name; + + node = of_find_compatible_node(NULL, NULL, "qcom,blkdev-rename"); + if (!node) { + pr_err("qcom,blkdev-rename is missing\n"); + goto out; + } + while (!of_property_read_string_index(node, "actual-dev", index, + &actual_name)) { + memset(dev_path, '\0', PATH_SIZE); + snprintf(dev_path, PATH_SIZE, "/dev/%s", actual_name); + dev = name_to_dev_t(dev_path); + if (!dev) { + pr_err("No device path : %s\n", dev_path); + return -EINVAL; + } + disk = get_gendisk(dev, &partno); + if (!disk) { + pr_err("No device with dev path : %s\n", dev_path); + return -ENXIO; + } + if (!of_property_read_string_index(node, "rename-dev", index, + &modified_name)) { + device_rename(disk_to_dev(disk), modified_name); + } else { + pr_err("rename-dev for actual-dev = %s is missing", + actual_name); + return -ENXIO; + } + index++; + } +out: + return 0; +} + +late_initcall(rename_blk_dev_init); +MODULE_DESCRIPTION("Rename block devices"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/soc/qcom/rpm_master_stat.c b/drivers/soc/qcom/rpm_master_stat.c index 1cbf2a1dbc02..ccd11684dfe7 100644 --- a/drivers/soc/qcom/rpm_master_stat.c +++ b/drivers/soc/qcom/rpm_master_stat.c @@ -398,7 +398,9 @@ static struct msm_rpm_master_stats_platform_data goto err; } - pdata->masters = devm_kzalloc(dev, sizeof(char *) * pdata->num_masters, + pdata->masters = devm_kcalloc(dev, + pdata->num_masters, + sizeof(char *), GFP_KERNEL); if (!pdata->masters) goto err; diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c index d18d9a925bfd..2325f259bd50 100644 --- a/drivers/soc/qcom/rpmh.c +++ b/drivers/soc/qcom/rpmh.c @@ -1024,8 +1024,8 @@ static struct rpmh_mbox *get_mbox(struct platform_device *pdev, rpmh = &mbox_ctrlr[i]; - rpmh->msg_pool = kzalloc(sizeof(struct rpmh_msg) * - RPMH_MAX_FAST_RES, GFP_KERNEL); + rpmh->msg_pool = kcalloc(RPMH_MAX_FAST_RES, sizeof(struct rpmh_msg), + GFP_KERNEL); if (!rpmh->msg_pool) { of_node_put(spec.np); return ERR_PTR(-ENOMEM); diff --git a/drivers/soc/qcom/sdx_ext_ipc.c b/drivers/soc/qcom/sdx_ext_ipc.c index c7a250ac9cf7..a4d0c35f9353 100644 --- a/drivers/soc/qcom/sdx_ext_ipc.c +++ b/drivers/soc/qcom/sdx_ext_ipc.c @@ -347,7 +347,7 @@ static int sdx_ext_ipc_probe(struct platform_device *pdev) if (mdm->gpios[WAKEUP_IN] >= 0) { ret = devm_request_threaded_irq(mdm->dev, mdm->wakeup_irq, - NULL, sdx_ext_ipc_wakeup_irq, + sdx_ext_ipc_wakeup_irq, NULL, IRQF_TRIGGER_FALLING, "sdx_ext_ipc_wakeup", mdm); if (ret < 0) { @@ -356,7 +356,6 @@ static int sdx_ext_ipc_probe(struct platform_device *pdev) __func__, mdm->wakeup_irq); goto irq_fail; } - disable_irq(mdm->wakeup_irq); } if (mdm->gpios[WAKEUP_OUT] >= 0) { diff --git a/drivers/soc/qcom/service-locator.c b/drivers/soc/qcom/service-locator.c index b35cd3b27d74..619cd44b0d26 100644 --- a/drivers/soc/qcom/service-locator.c +++ b/drivers/soc/qcom/service-locator.c @@ -210,9 +210,9 @@ static int service_locator_send_msg(struct pd_qmi_client_data *pd) goto out; } - pd->domain_list = kmalloc( - sizeof(struct servreg_loc_entry_v01) * - resp->total_domains, GFP_KERNEL); + pd->domain_list = kmalloc_array(resp->total_domains, + sizeof(struct servreg_loc_entry_v01), + GFP_KERNEL); if (!pd->domain_list) { pr_err("Cannot allocate domain list\n"); rc = -ENOMEM; diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index 21455a419231..55483d68a229 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -92,7 +92,7 @@ #define SMEM_GLOBAL_HOST 0xfffe /* Max number of processors/hosts in a system */ -#define SMEM_HOST_COUNT 11 +#define SMEM_HOST_COUNT 13 /** * struct smem_proc_comm - proc_comm communication struct (legacy) diff --git a/drivers/soc/qcom/spcom.c b/drivers/soc/qcom/spcom.c index 64fb72f8a393..25d56591830c 100644 --- a/drivers/soc/qcom/spcom.c +++ b/drivers/soc/qcom/spcom.c @@ -2072,7 +2072,7 @@ static int spcom_register_rpmsg_drv(struct spcom_channel *ch) return -ENOMEM; /* zalloc array of two to NULL terminate the match list */ - match = kzalloc(2 * sizeof(*match), GFP_KERNEL); + match = kcalloc(2, sizeof(*match), GFP_KERNEL); if (!match) { kfree(rpdrv); return -ENOMEM; diff --git a/drivers/soc/qcom/subsys-pil-tz.c b/drivers/soc/qcom/subsys-pil-tz.c index e267ceadf41a..322ad9550757 100644 --- a/drivers/soc/qcom/subsys-pil-tz.c +++ b/drivers/soc/qcom/subsys-pil-tz.c @@ -238,7 +238,7 @@ static int of_read_clocks(struct device *dev, struct clk ***clks_ref, return -EINVAL; } - clks = devm_kzalloc(dev, sizeof(struct clk *) * clk_count, + clks = devm_kcalloc(dev, clk_count, sizeof(struct clk *), GFP_KERNEL); if (!clks) return -ENOMEM; @@ -297,7 +297,7 @@ static int of_read_regs(struct device *dev, struct reg_info **regs_ref, return -EINVAL; } - regs = devm_kzalloc(dev, sizeof(struct reg_info) * reg_count, + regs = devm_kcalloc(dev, reg_count, sizeof(struct reg_info), GFP_KERNEL); if (!regs) return -ENOMEM; diff --git a/drivers/soc/qcom/subsystem_restart.c b/drivers/soc/qcom/subsystem_restart.c index d97b129b7e66..54f501820d73 100644 --- a/drivers/soc/qcom/subsystem_restart.c +++ b/drivers/soc/qcom/subsystem_restart.c @@ -1525,14 +1525,14 @@ static struct subsys_soc_restart_order *ssr_parse_restart_orders(struct if (!order) return ERR_PTR(-ENOMEM); - order->subsys_ptrs = devm_kzalloc(dev, - count * sizeof(struct subsys_device *), + order->subsys_ptrs = devm_kcalloc(dev, + count, sizeof(struct subsys_device *), GFP_KERNEL); if (!order->subsys_ptrs) return ERR_PTR(-ENOMEM); - order->device_ptrs = devm_kzalloc(dev, - count * sizeof(struct device_node *), + order->device_ptrs = devm_kcalloc(dev, + count, sizeof(struct device_node *), GFP_KERNEL); if (!order->device_ptrs) return ERR_PTR(-ENOMEM); diff --git a/drivers/soc/qcom/wcnss/wcnss_wlan.c b/drivers/soc/qcom/wcnss/wcnss_wlan.c index 2ec29350f6f8..b939c02b36ec 100644 --- a/drivers/soc/qcom/wcnss/wcnss_wlan.c +++ b/drivers/soc/qcom/wcnss/wcnss_wlan.c @@ -1573,6 +1573,7 @@ static int wcnss_ctrl_probe(struct rpmsg_device *rpdev) static void wcnss_ctrl_remove(struct rpmsg_device *rpdev) { + penv->smd_channel_ready = 0; of_platform_depopulate(&rpdev->dev); } @@ -2378,6 +2379,8 @@ static void wcnss_process_smd_msg(void *buf, int len) if (nvresp->status != WAIT_FOR_CBC_IND) penv->is_cbc_done = 1; + penv->smd_channel_ready = 1; + if (penv->ops) penv->ops->driver_state(penv->ops->priv_data, WCNSS_SMD_OPEN); diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c index ba009bb9d82b..e1d835324bfe 100644 --- a/drivers/soc/rockchip/pm_domains.c +++ b/drivers/soc/rockchip/pm_domains.c @@ -403,8 +403,7 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, } clk_cnt = of_count_phandle_with_args(node, "clocks", "#clock-cells"); - pd = devm_kzalloc(pmu->dev, - sizeof(*pd) + clk_cnt * sizeof(pd->clks[0]), + pd = devm_kzalloc(pmu->dev, struct_size(pd, clks, clk_cnt), GFP_KERNEL); if (!pd) return -ENOMEM; @@ -637,8 +636,7 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev) pmu_info = match->data; pmu = devm_kzalloc(dev, - sizeof(*pmu) + - pmu_info->num_domains * sizeof(pmu->domains[0]), + struct_size(pmu, domains, pmu_info->num_domains), GFP_KERNEL); if (!pmu) return -ENOMEM; diff --git a/drivers/soc/ti/knav_qmss_acc.c b/drivers/soc/ti/knav_qmss_acc.c index 672aebe1e378..2f7fb2dcc1d6 100644 --- a/drivers/soc/ti/knav_qmss_acc.c +++ b/drivers/soc/ti/knav_qmss_acc.c @@ -405,8 +405,8 @@ static int knav_acc_init_queue(struct knav_range_info *range, { unsigned id = kq->id - range->queue_base; - kq->descs = devm_kzalloc(range->kdev->dev, - ACC_DESCS_MAX * sizeof(u32), GFP_KERNEL); + kq->descs = devm_kcalloc(range->kdev->dev, + ACC_DESCS_MAX, sizeof(u32), GFP_KERNEL); if (!kq->descs) return -ENOMEM; @@ -552,7 +552,7 @@ int knav_init_acc_range(struct knav_device *kdev, info->list_size = list_size; mem_size = PAGE_ALIGN(list_size * 2); info->mem_size = mem_size; - range->acc = devm_kzalloc(kdev->dev, channels * sizeof(*range->acc), + range->acc = devm_kcalloc(kdev->dev, channels, sizeof(*range->acc), GFP_KERNEL); if (!range->acc) return -ENOMEM; diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index c5bbe08771a4..c2b2959f4eea 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -923,9 +923,10 @@ static int davinci_spi_probe(struct platform_device *pdev) /* pdata in dspi is now updated and point pdata to that */ pdata = &dspi->pdata; - dspi->bytes_per_word = devm_kzalloc(&pdev->dev, - sizeof(*dspi->bytes_per_word) * - pdata->num_chipselect, GFP_KERNEL); + dspi->bytes_per_word = devm_kcalloc(&pdev->dev, + pdata->num_chipselect, + sizeof(*dspi->bytes_per_word), + GFP_KERNEL); if (dspi->bytes_per_word == NULL) { ret = -ENOMEM; goto free_master; diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index ce28c910ee48..79fc3940245a 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c @@ -685,8 +685,8 @@ static int ep93xx_spi_probe(struct platform_device *pdev) master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); master->num_chipselect = info->num_chipselect; - master->cs_gpios = devm_kzalloc(&master->dev, - sizeof(int) * master->num_chipselect, + master->cs_gpios = devm_kcalloc(&master->dev, + master->num_chipselect, sizeof(int), GFP_KERNEL); if (!master->cs_gpios) { error = -ENOMEM; diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c index a1a19c0a31c3..2d5ca183da3a 100644 --- a/drivers/spi/spi-geni-qcom.c +++ b/drivers/spi/spi-geni-qcom.c @@ -1049,10 +1049,11 @@ static int spi_geni_unprepare_transfer_hardware(struct spi_master *spi) return 0; } -static void setup_fifo_xfer(struct spi_transfer *xfer, +static int setup_fifo_xfer(struct spi_transfer *xfer, struct spi_geni_master *mas, u16 mode, struct spi_master *spi) { + int ret = 0; u32 m_cmd = 0; u32 m_param = 0; u32 spi_tx_cfg = geni_read_reg(mas->base, SE_SPI_TRANS_CFG); @@ -1065,7 +1066,6 @@ static void setup_fifo_xfer(struct spi_transfer *xfer, /* Speed and bits per word can be overridden per transfer */ if (xfer->speed_hz != mas->cur_speed_hz) { - int ret = 0; u32 clk_sel = 0; u32 m_clk_cfg = 0; int idx = 0; @@ -1075,7 +1075,7 @@ static void setup_fifo_xfer(struct spi_transfer *xfer, if (ret) { dev_err(mas->dev, "%s:Err setting clks:%d\n", __func__, ret); - return; + return ret; } mas->cur_speed_hz = xfer->speed_hz; clk_sel |= (idx & CLK_SEL_MSK); @@ -1156,13 +1156,14 @@ static void setup_fifo_xfer(struct spi_transfer *xfer, __func__, trans_len, xfer->len, spi_tx_cfg, m_cmd, xfer->cs_change, mas->cur_xfer_mode); if ((m_cmd & SPI_RX_ONLY) && (mas->cur_xfer_mode == SE_DMA)) { - int ret = 0; - ret = geni_se_rx_dma_prep(mas->wrapper_dev, mas->base, xfer->rx_buf, xfer->len, &xfer->rx_dma); - if (ret) + if (ret) { GENI_SE_ERR(mas->ipc, true, mas->dev, "Failed to setup Rx dma %d\n", ret); + xfer->rx_dma = 0; + return ret; + } } if (m_cmd & SPI_TX_ONLY) { if (mas->cur_xfer_mode == FIFO_MODE) { @@ -1174,14 +1175,18 @@ static void setup_fifo_xfer(struct spi_transfer *xfer, ret = geni_se_tx_dma_prep(mas->wrapper_dev, mas->base, (void *)xfer->tx_buf, xfer->len, &xfer->tx_dma); - if (ret) + if (ret) { GENI_SE_ERR(mas->ipc, true, mas->dev, "Failed to setup tx dma %d\n", ret); + xfer->tx_dma = 0; + return ret; + } } } /* Ensure all writes are done before the WM interrupt */ mb(); + return ret; } static void handle_fifo_timeout(struct spi_geni_master *mas, @@ -1209,7 +1214,7 @@ static void handle_fifo_timeout(struct spi_geni_master *mas, "Failed to cancel/abort m_cmd\n"); } if (mas->cur_xfer_mode == SE_DMA) { - if (xfer->tx_buf) { + if (xfer->tx_buf && xfer->tx_dma) { reinit_completion(&mas->xfer_done); writel_relaxed(1, mas->base + SE_DMA_TX_FSM_RST); @@ -1221,7 +1226,7 @@ static void handle_fifo_timeout(struct spi_geni_master *mas, geni_se_tx_dma_unprep(mas->wrapper_dev, xfer->tx_dma, xfer->len); } - if (xfer->rx_buf) { + if (xfer->rx_buf && xfer->rx_dma) { reinit_completion(&mas->xfer_done); writel_relaxed(1, mas->base + SE_DMA_RX_FSM_RST); @@ -1264,7 +1269,14 @@ static int spi_geni_transfer_one(struct spi_master *spi, if (mas->cur_xfer_mode != GSI_DMA) { reinit_completion(&mas->xfer_done); - setup_fifo_xfer(xfer, mas, slv->mode, spi); + ret = setup_fifo_xfer(xfer, mas, slv->mode, spi); + if (ret) { + GENI_SE_ERR(mas->ipc, true, mas->dev, + "setup_fifo_xfer failed: %d\n", ret); + mas->cur_xfer = NULL; + goto err_fifo_geni_transfer_one; + } + if (spi->slave) spi->slave_state = true; mutex_unlock(&mas->spi_ssr.ssr_lock); @@ -1303,7 +1315,13 @@ static int spi_geni_transfer_one(struct spi_master *spi, reinit_completion(&mas->tx_cb); reinit_completion(&mas->rx_cb); - setup_gsi_xfer(xfer, mas, slv, spi); + ret = setup_gsi_xfer(xfer, mas, slv, spi); + if (ret) { + GENI_SE_ERR(mas->ipc, true, mas->dev, + "setup_gsi_xfer failed: %d\n", ret); + mas->cur_xfer = NULL; + goto err_gsi_geni_transfer_one; + } if ((mas->num_xfers >= NUM_SPI_XFER) || (list_is_last(&xfer->transfer_list, &spi->cur_msg->transfers))) { @@ -1568,10 +1586,6 @@ static int spi_geni_probe(struct platform_device *pdev) goto spi_geni_probe_err; } - snprintf(boot_marker, sizeof(boot_marker), - "M - DRIVER GENI_SPI Init"); - place_marker(boot_marker); - platform_set_drvdata(pdev, spi); geni_mas = spi_master_get_devdata(spi); rsc = &geni_mas->spi_rsc; @@ -1751,10 +1765,6 @@ static int spi_geni_probe(struct platform_device *pdev) } sysfs_create_file(&(geni_mas->dev->kobj), &dev_attr_spi_slave_state.attr); - snprintf(boot_marker, sizeof(boot_marker), - "M - DRIVER GENI_SPI_%d Ready", spi->bus_num); - place_marker(boot_marker); - return ret; spi_geni_probe_unmap: devm_iounmap(&pdev->dev, geni_mas->base); diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index df18d07d544d..38d830141d0a 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -1415,8 +1415,8 @@ static int spi_imx_probe(struct platform_device *pdev) if (mxc_platform_info) { master->num_chipselect = mxc_platform_info->num_chipselect; - master->cs_gpios = devm_kzalloc(&master->dev, - sizeof(int) * master->num_chipselect, GFP_KERNEL); + master->cs_gpios = devm_kcalloc(&master->dev, + master->num_chipselect, sizeof(int), GFP_KERNEL); if (!master->cs_gpios) return -ENOMEM; diff --git a/drivers/spi/spi-oc-tiny.c b/drivers/spi/spi-oc-tiny.c index b5911282a611..085f580be7ec 100644 --- a/drivers/spi/spi-oc-tiny.c +++ b/drivers/spi/spi-oc-tiny.c @@ -213,8 +213,8 @@ static int tiny_spi_of_probe(struct platform_device *pdev) return 0; hw->gpio_cs_count = of_gpio_count(np); if (hw->gpio_cs_count > 0) { - hw->gpio_cs = devm_kzalloc(&pdev->dev, - hw->gpio_cs_count * sizeof(unsigned int), + hw->gpio_cs = devm_kcalloc(&pdev->dev, + hw->gpio_cs_count, sizeof(unsigned int), GFP_KERNEL); if (!hw->gpio_cs) return -ENOMEM; diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 4797c57f4263..1af8c96b940e 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -2135,7 +2135,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) pl022->master_info = platform_info; pl022->adev = adev; pl022->vendor = id->data; - pl022->chipselects = devm_kzalloc(dev, num_cs * sizeof(int), + pl022->chipselects = devm_kcalloc(dev, num_cs, sizeof(int), GFP_KERNEL); if (!pl022->chipselects) { status = -ENOMEM; diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 49eee894f51d..237099464fec 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -2044,7 +2044,7 @@ static int of_spi_register_master(struct spi_controller *ctlr) else if (nb < 0) return nb; - cs = devm_kzalloc(&ctlr->dev, sizeof(int) * ctlr->num_chipselect, + cs = devm_kcalloc(&ctlr->dev, ctlr->num_chipselect, sizeof(int), GFP_KERNEL); ctlr->cs_gpios = cs; diff --git a/drivers/spmi/simulator/spmi-sim.c b/drivers/spmi/simulator/spmi-sim.c index 19961154a787..db08e0e6df39 100644 --- a/drivers/spmi/simulator/spmi-sim.c +++ b/drivers/spmi/simulator/spmi-sim.c @@ -1201,7 +1201,7 @@ static int spmi_sim_probe(struct platform_device *pdev) } sim->range[i].start = res->start; sim->range[i].end = res->end; - sim->range[i].reg = vzalloc(len * sizeof(*sim->range[i].reg)); + sim->range[i].reg = vzalloc(array_size(len, sizeof(*sim->range[i].reg))); if (!sim->range[i].reg) { rc = -ENOMEM; goto err_free_ranges; diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 9fff1045d24f..627a3e0989fb 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -120,6 +120,4 @@ source "drivers/staging/pi433/Kconfig" source "drivers/staging/qcacld-3.0/Kconfig" -source "drivers/staging/exfat/Kconfig" - endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index d594c288b84d..fbc0d08612ae 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -51,4 +51,3 @@ obj-$(CONFIG_CRYPTO_DEV_CCREE) += ccree/ obj-$(CONFIG_DRM_VBOXVIDEO) += vboxvideo/ obj-$(CONFIG_PI433) += pi433/ obj-$(CONFIG_QCA_CLD_WLAN) += qcacld-3.0/ -obj-$(CONFIG_STAGING_EXFAT_FS) += exfat/ diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig index 2781d2f92356..6a27fb8cfe34 100644 --- a/drivers/staging/android/ion/Kconfig +++ b/drivers/staging/android/ion/Kconfig @@ -44,18 +44,6 @@ config ION_CMA_HEAP by the Contiguous Memory Allocator (CMA). If your system has these regions, you should say Y here. -config ION_FORCE_DMA_SYNC - bool "Force ION to always DMA sync buffer memory" - depends on ION - help - Force ION to DMA sync buffer memory when it is allocated and to - always DMA sync the buffer memory on calls to begin/end cpu - access. This makes ION DMA sync behavior similar to that of the - older version of ION. - We generally don't want to enable this config as it breaks the - cache maintenance model. - If you're not sure say N here. - config ION_DEFER_FREE_NO_SCHED_IDLE bool "Increases the priority of ION defer free thead" depends on ION diff --git a/drivers/staging/android/ion/ion-ioctl.c b/drivers/staging/android/ion/ion-ioctl.c index 83cbcc0dcd8c..3f970b5e2b58 100644 --- a/drivers/staging/android/ion/ion-ioctl.c +++ b/drivers/staging/android/ion/ion-ioctl.c @@ -44,22 +44,11 @@ static int validate_ioctl_arg(unsigned int cmd, union ion_ioctl_arg *arg) return ret ? -EINVAL : 0; } -/* fix up the cases where the ioctl direction bits are incorrect */ -static unsigned int ion_ioctl_dir(unsigned int cmd) -{ - switch (cmd) { - default: - return _IOC_DIR(cmd); - } -} - long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - int ret = 0; - unsigned int dir; + unsigned int dir = _IOC_DIR(cmd); union ion_ioctl_arg data; - - dir = ion_ioctl_dir(cmd); + int ret = 0; if (_IOC_SIZE(cmd) > sizeof(data)) return -EINVAL; @@ -73,10 +62,8 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return -EFAULT; ret = validate_ioctl_arg(cmd, &data); - if (ret) { - pr_warn_once("%s: ioctl validate failed\n", __func__); + if (ret) return ret; - } if (!(dir & _IOC_WRITE)) memset(&data, 0, sizeof(data)); @@ -84,25 +71,19 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) switch (cmd) { case ION_IOC_ALLOC: { - int fd; - - fd = ion_alloc_fd(data.allocation.len, - data.allocation.heap_id_mask, - data.allocation.flags); + int fd = ion_alloc_fd(data.allocation.len, + data.allocation.heap_id_mask, + data.allocation.flags); if (fd < 0) return fd; data.allocation.fd = fd; - break; } case ION_IOC_HEAP_QUERY: ret = ion_query_heaps(&data.query); break; case ION_IOC_PREFETCH: - { - int ret; - ret = ion_walk_heaps(data.prefetch_data.heap_id, (enum ion_heap_type) ION_HEAP_TYPE_SYSTEM_SECURE, @@ -110,22 +91,18 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ion_system_secure_heap_prefetch); if (ret) return ret; - break; - } - case ION_IOC_DRAIN: - { - int ret; + break; + case ION_IOC_DRAIN: ret = ion_walk_heaps(data.prefetch_data.heap_id, (enum ion_heap_type) ION_HEAP_TYPE_SYSTEM_SECURE, (void *)&data.prefetch_data, ion_system_secure_heap_drain); - if (ret) return ret; + break; - } default: return -ENOTTY; } @@ -134,5 +111,6 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) return -EFAULT; } + return ret; } diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index bc0679ec4d20..7d72de29d7a3 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -1,110 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * - * drivers/staging/android/ion/ion.c - * * Copyright (C) 2011 Google, Inc. - * Copyright (c) 2011-2020, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * + * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. + * Copyright (C) 2019 Sultan Alsawaf . */ -#include -#include -#include -#include -#include -#include -#include -#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#define CREATE_TRACE_POINTS -#include -#include +#include +#include +#include #include "ion.h" #include "ion_secure_util.h" static struct ion_device *internal_dev; -static atomic_long_t total_heap_bytes; +static struct kmem_cache *ion_sg_table_pool; int ion_walk_heaps(int heap_id, enum ion_heap_type type, void *data, int (*f)(struct ion_heap *heap, void *data)) { - int ret_val = 0; - struct ion_heap *heap; struct ion_device *dev = internal_dev; - /* - * traverse the list of heaps available in this system - * and find the heap that is specified. - */ - down_write(&dev->lock); + struct ion_heap *heap; + int ret = 0; + + down_write(&dev->heap_lock); plist_for_each_entry(heap, &dev->heaps, node) { - if (ION_HEAP(heap->id) != heap_id || - type != heap->type) - continue; - ret_val = f(heap, data); - break; - } - up_write(&dev->lock); - return ret_val; -} -EXPORT_SYMBOL(ion_walk_heaps); - -bool ion_buffer_cached(struct ion_buffer *buffer) -{ - return !!(buffer->flags & ION_FLAG_CACHED); -} - -/* this function should only be called while dev->lock is held */ -static void ion_buffer_add(struct ion_device *dev, - struct ion_buffer *buffer) -{ - struct rb_node **p = &dev->buffers.rb_node; - struct rb_node *parent = NULL; - struct ion_buffer *entry; - - while (*p) { - parent = *p; - entry = rb_entry(parent, struct ion_buffer, node); - - if (buffer < entry) { - p = &(*p)->rb_left; - } else if (buffer > entry) { - p = &(*p)->rb_right; - } else { - pr_err("%s: buffer already found.", __func__); - BUG(); + if (heap->type == type && ION_HEAP(heap->id) == heap_id) { + ret = f(heap, data); + break; } } + up_write(&dev->heap_lock); - rb_link_node(&buffer->node, parent, p); - rb_insert_color(&buffer->node, &dev->buffers); + return ret; } -/* this function should only be called while dev->lock is held */ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, struct ion_device *dev, unsigned long len, @@ -114,81 +47,54 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, struct sg_table *table; int ret; - buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); + buffer = kmalloc(sizeof(*buffer), GFP_KERNEL); if (!buffer) return ERR_PTR(-ENOMEM); - buffer->heap = heap; - buffer->flags = flags; + *buffer = (typeof(*buffer)){ + .dev = dev, + .heap = heap, + .flags = flags, + .size = len, + .attachments = LIST_HEAD_INIT(buffer->attachments), + .vmas = LIST_HEAD_INIT(buffer->vmas), + .attachment_lock = __MUTEX_INITIALIZER(buffer->attachment_lock), + .kmap_lock = __MUTEX_INITIALIZER(buffer->kmap_lock), + .vma_lock = __MUTEX_INITIALIZER(buffer->vma_lock), + .iommu_data = { + .lock = __MUTEX_INITIALIZER(buffer->iommu_data.lock) + } + }; ret = heap->ops->allocate(heap, buffer, len, flags); - if (ret) { if (!(heap->flags & ION_HEAP_FLAG_DEFER_FREE)) - goto err2; + goto free_buffer; if (ret == -EINTR) - goto err2; + goto free_buffer; ion_heap_freelist_drain(heap, 0); ret = heap->ops->allocate(heap, buffer, len, flags); if (ret) - goto err2; + goto free_buffer; } - if (buffer->sg_table == NULL) { - WARN_ONCE(1, "This heap needs to set the sgtable"); - ret = -EINVAL; - goto err1; - } + if (buffer->sg_table == NULL) + goto free_heap; table = buffer->sg_table; - buffer->dev = dev; - buffer->size = len; - - buffer->dev = dev; - buffer->size = len; - INIT_LIST_HEAD(&buffer->attachments); - INIT_LIST_HEAD(&buffer->vmas); - mutex_init(&buffer->lock); - - if (IS_ENABLED(CONFIG_ION_FORCE_DMA_SYNC)) { - int i; - struct scatterlist *sg; - - /* - * this will set up dma addresses for the sglist -- it is not - * technically correct as per the dma api -- a specific - * device isn't really taking ownership here. However, in - * practice on our systems the only dma_address space is - * physical addresses. - */ - for_each_sg(table->sgl, sg, table->nents, i) { - sg_dma_address(sg) = sg_phys(sg); - sg_dma_len(sg) = sg->length; - } - } - - mutex_lock(&dev->buffer_lock); - ion_buffer_add(dev, buffer); - mutex_unlock(&dev->buffer_lock); - atomic_long_add(len, &heap->total_allocated); - atomic_long_add(len, &total_heap_bytes); return buffer; -err1: +free_heap: heap->ops->free(buffer); -err2: +free_buffer: kfree(buffer); - return ERR_PTR(ret); + return ERR_PTR(-EINVAL); } void ion_buffer_destroy(struct ion_buffer *buffer) { - if (buffer->kmap_cnt > 0) { - pr_warn_ratelimited("ION client likely missing a call to dma_buf_kunmap or dma_buf_vunmap\n"); - buffer->heap->ops->unmap_kernel(buffer->heap, buffer); - } buffer->heap->ops->free(buffer); kfree(buffer); } @@ -196,16 +102,9 @@ void ion_buffer_destroy(struct ion_buffer *buffer) static void _ion_buffer_destroy(struct ion_buffer *buffer) { struct ion_heap *heap = buffer->heap; - struct ion_device *dev = buffer->dev; - msm_dma_buf_freed(buffer); + msm_dma_buf_freed(&buffer->iommu_data); - mutex_lock(&dev->buffer_lock); - rb_erase(&buffer->node, &dev->buffers); - mutex_unlock(&dev->buffer_lock); - atomic_long_sub(buffer->size, &total_heap_bytes); - - atomic_long_sub(buffer->size, &buffer->heap->total_allocated); if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) ion_heap_freelist_add(heap, buffer); else @@ -216,58 +115,60 @@ static void *ion_buffer_kmap_get(struct ion_buffer *buffer) { void *vaddr; + mutex_lock(&buffer->kmap_lock); if (buffer->kmap_cnt) { + vaddr = buffer->vaddr; buffer->kmap_cnt++; - return buffer->vaddr; + } else { + vaddr = buffer->heap->ops->map_kernel(buffer->heap, buffer); + if (IS_ERR_OR_NULL(vaddr)) { + vaddr = ERR_PTR(-EINVAL); + } else { + buffer->vaddr = vaddr; + buffer->kmap_cnt++; + } } - vaddr = buffer->heap->ops->map_kernel(buffer->heap, buffer); - if (WARN_ONCE(vaddr == NULL, - "heap->ops->map_kernel should return ERR_PTR on error")) - return ERR_PTR(-EINVAL); - if (IS_ERR(vaddr)) - return vaddr; - buffer->vaddr = vaddr; - buffer->kmap_cnt++; + mutex_unlock(&buffer->kmap_lock); + return vaddr; } static void ion_buffer_kmap_put(struct ion_buffer *buffer) { - if (buffer->kmap_cnt == 0) { - pr_warn_ratelimited("ION client likely missing a call to dma_buf_kmap or dma_buf_vmap, pid:%d\n", - current->pid); - return; - } - - buffer->kmap_cnt--; - if (!buffer->kmap_cnt) { + mutex_lock(&buffer->kmap_lock); + if (!--buffer->kmap_cnt) buffer->heap->ops->unmap_kernel(buffer->heap, buffer); - buffer->vaddr = NULL; - } + mutex_unlock(&buffer->kmap_lock); } static struct sg_table *dup_sg_table(struct sg_table *table) { + struct scatterlist *sg, *new_sg; struct sg_table *new_table; int ret, i; - struct scatterlist *sg, *new_sg; - new_table = kzalloc(sizeof(*new_table), GFP_KERNEL); + new_table = kmem_cache_alloc(ion_sg_table_pool, GFP_KERNEL); if (!new_table) return ERR_PTR(-ENOMEM); ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL); if (ret) { - kfree(new_table); + kmem_cache_free(ion_sg_table_pool, new_table); return ERR_PTR(-ENOMEM); } new_sg = new_table->sgl; - for_each_sg(table->sgl, sg, table->nents, i) { - memcpy(new_sg, sg, sizeof(*sg)); + if (new_table->nents <= SG_MAX_SINGLE_ALLOC) { + memcpy(new_sg, table->sgl, new_table->nents * sizeof(*new_sg)); sg_dma_address(new_sg) = 0; sg_dma_len(new_sg) = 0; - new_sg = sg_next(new_sg); + } else { + for_each_sg(table->sgl, sg, table->nents, i) { + *new_sg = *sg; + sg_dma_address(new_sg) = 0; + sg_dma_len(new_sg) = 0; + new_sg = sg_next(new_sg); + } } return new_table; @@ -276,7 +177,7 @@ static struct sg_table *dup_sg_table(struct sg_table *table) static void free_duped_table(struct sg_table *table) { sg_free_table(table); - kfree(table); + kmem_cache_free(ion_sg_table_pool, table); } struct ion_dma_buf_attachment { @@ -289,9 +190,10 @@ struct ion_dma_buf_attachment { static int ion_dma_buf_attach(struct dma_buf *dmabuf, struct device *dev, struct dma_buf_attachment *attachment) { + struct ion_buffer *buffer = container_of(dmabuf->priv, typeof(*buffer), + iommu_data); struct ion_dma_buf_attachment *a; struct sg_table *table; - struct ion_buffer *buffer = dmabuf->priv; a = kzalloc(sizeof(*a), GFP_KERNEL); if (!a) @@ -303,31 +205,36 @@ static int ion_dma_buf_attach(struct dma_buf *dmabuf, struct device *dev, return -ENOMEM; } - a->table = table; - a->dev = dev; - a->dma_mapped = false; - INIT_LIST_HEAD(&a->list); + *a = (typeof(*a)){ + .table = table, + .dev = dev + }; attachment->priv = a; - mutex_lock(&buffer->lock); - list_add(&a->list, &buffer->attachments); - mutex_unlock(&buffer->lock); + if (buffer->flags & ION_FLAG_CACHED) { + mutex_lock(&buffer->attachment_lock); + list_add(&a->list, &buffer->attachments); + mutex_unlock(&buffer->attachment_lock); + } return 0; } -static void ion_dma_buf_detatch(struct dma_buf *dmabuf, +static void ion_dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attachment) { + struct ion_buffer *buffer = container_of(dmabuf->priv, typeof(*buffer), + iommu_data); struct ion_dma_buf_attachment *a = attachment->priv; - struct ion_buffer *buffer = dmabuf->priv; - mutex_lock(&buffer->lock); - list_del(&a->list); - mutex_unlock(&buffer->lock); + if (buffer->flags & ION_FLAG_CACHED) { + mutex_lock(&buffer->attachment_lock); + list_del(&a->list); + mutex_unlock(&buffer->attachment_lock); + } + free_duped_table(a->table); - kfree(a); } @@ -347,22 +254,6 @@ static struct sg_table *ion_map_dma_buf(struct dma_buf_attachment *attachment, !hlos_accessible_buffer(buffer)) map_attrs |= DMA_ATTR_SKIP_CPU_SYNC; - mutex_lock(&buffer->lock); - if (map_attrs & DMA_ATTR_SKIP_CPU_SYNC) - trace_ion_dma_map_cmo_skip(attachment->dev, - attachment->dmabuf->buf_name, - ion_buffer_cached(buffer), - hlos_accessible_buffer(buffer), - attachment->dma_map_attrs, - direction); - else - trace_ion_dma_map_cmo_apply(attachment->dev, - attachment->dmabuf->buf_name, - ion_buffer_cached(buffer), - hlos_accessible_buffer(buffer), - attachment->dma_map_attrs, - direction); - if (map_attrs & DMA_ATTR_DELAYED_UNMAP) { count = msm_dma_map_sg_attrs(attachment->dev, table->sgl, table->nents, direction, @@ -373,13 +264,10 @@ static struct sg_table *ion_map_dma_buf(struct dma_buf_attachment *attachment, map_attrs); } - if (count <= 0) { - mutex_unlock(&buffer->lock); + if (count <= 0) return ERR_PTR(-ENOMEM); - } a->dma_mapped = true; - mutex_unlock(&buffer->lock); return table; } @@ -396,22 +284,6 @@ static void ion_unmap_dma_buf(struct dma_buf_attachment *attachment, !hlos_accessible_buffer(buffer)) map_attrs |= DMA_ATTR_SKIP_CPU_SYNC; - mutex_lock(&buffer->lock); - if (map_attrs & DMA_ATTR_SKIP_CPU_SYNC) - trace_ion_dma_unmap_cmo_skip(attachment->dev, - attachment->dmabuf->buf_name, - ion_buffer_cached(buffer), - hlos_accessible_buffer(buffer), - attachment->dma_map_attrs, - direction); - else - trace_ion_dma_unmap_cmo_apply(attachment->dev, - attachment->dmabuf->buf_name, - ion_buffer_cached(buffer), - hlos_accessible_buffer(buffer), - attachment->dma_map_attrs, - direction); - if (map_attrs & DMA_ATTR_DELAYED_UNMAP) msm_dma_unmap_sg_attrs(attachment->dev, table->sgl, table->nents, direction, @@ -421,7 +293,6 @@ static void ion_unmap_dma_buf(struct dma_buf_attachment *attachment, dma_unmap_sg_attrs(attachment->dev, table->sgl, table->nents, direction, map_attrs); a->dma_mapped = false; - mutex_unlock(&buffer->lock); } void ion_pages_sync_for_device(struct device *dev, struct page *page, @@ -431,11 +302,6 @@ void ion_pages_sync_for_device(struct device *dev, struct page *page, sg_init_table(&sg, 1); sg_set_page(&sg, page, size, 0); - /* - * This is not correct - sg_dma_address needs a dma_addr_t that is valid - * for the targeted device, but this works on the currently targeted - * hardware. - */ sg_dma_address(&sg) = page_to_phys(page); dma_sync_sg_for_device(dev, &sg, 1, dir); } @@ -448,43 +314,43 @@ static void ion_vm_open(struct vm_area_struct *vma) vma_list = kmalloc(sizeof(*vma_list), GFP_KERNEL); if (!vma_list) return; + vma_list->vma = vma; - mutex_lock(&buffer->lock); + + mutex_lock(&buffer->vma_lock); list_add(&vma_list->list, &buffer->vmas); - mutex_unlock(&buffer->lock); + mutex_unlock(&buffer->vma_lock); } static void ion_vm_close(struct vm_area_struct *vma) { struct ion_buffer *buffer = vma->vm_private_data; - struct ion_vma_list *vma_list, *tmp; + struct ion_vma_list *vma_list; - mutex_lock(&buffer->lock); - list_for_each_entry_safe(vma_list, tmp, &buffer->vmas, list) { - if (vma_list->vma != vma) - continue; - list_del(&vma_list->list); - kfree(vma_list); - break; + mutex_lock(&buffer->vma_lock); + list_for_each_entry(vma_list, &buffer->vmas, list) { + if (vma_list->vma == vma) { + list_del(&vma_list->list); + break; + } } - mutex_unlock(&buffer->lock); + mutex_unlock(&buffer->vma_lock); + + kfree(vma_list); } static const struct vm_operations_struct ion_vma_ops = { .open = ion_vm_open, - .close = ion_vm_close, + .close = ion_vm_close }; static int ion_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) { - struct ion_buffer *buffer = dmabuf->priv; - int ret = 0; + struct ion_buffer *buffer = container_of(dmabuf->priv, typeof(*buffer), + iommu_data); - if (!buffer->heap->ops->map_user) { - pr_err("%s: this heap does not define a method for mapping to userspace\n", - __func__); + if (!buffer->heap->ops->map_user) return -EINVAL; - } if (!(buffer->flags & ION_FLAG_CACHED)) vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); @@ -493,52 +359,34 @@ static int ion_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) vma->vm_ops = &ion_vma_ops; ion_vm_open(vma); - mutex_lock(&buffer->lock); - /* now map it to userspace */ - ret = buffer->heap->ops->map_user(buffer->heap, buffer, vma); - mutex_unlock(&buffer->lock); - - if (ret) - pr_err("%s: failure mapping buffer to userspace\n", - __func__); - - return ret; + return buffer->heap->ops->map_user(buffer->heap, buffer, vma); } static void ion_dma_buf_release(struct dma_buf *dmabuf) { - struct ion_buffer *buffer = dmabuf->priv; + struct ion_buffer *buffer = container_of(dmabuf->priv, typeof(*buffer), + iommu_data); _ion_buffer_destroy(buffer); - kfree(dmabuf->exp_name); } static void *ion_dma_buf_vmap(struct dma_buf *dmabuf) { - struct ion_buffer *buffer = dmabuf->priv; - void *vaddr = ERR_PTR(-EINVAL); + struct ion_buffer *buffer = container_of(dmabuf->priv, typeof(*buffer), + iommu_data); - if (buffer->heap->ops->map_kernel) { - mutex_lock(&buffer->lock); - vaddr = ion_buffer_kmap_get(buffer); - mutex_unlock(&buffer->lock); - } else { - pr_warn_ratelimited("heap %s doesn't support map_kernel\n", - buffer->heap->name); - } + if (!buffer->heap->ops->map_kernel) + return ERR_PTR(-EINVAL); - return vaddr; + return ion_buffer_kmap_get(buffer); } static void ion_dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr) { - struct ion_buffer *buffer = dmabuf->priv; + struct ion_buffer *buffer = container_of(dmabuf->priv, typeof(*buffer), + iommu_data); - if (buffer->heap->ops->map_kernel) { - mutex_lock(&buffer->lock); - ion_buffer_kmap_put(buffer); - mutex_unlock(&buffer->lock); - } + ion_buffer_kmap_put(buffer); } static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset) @@ -648,67 +496,23 @@ static int __ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction direction, bool sync_only_mapped) { - struct ion_buffer *buffer = dmabuf->priv; + struct ion_buffer *buffer = container_of(dmabuf->priv, typeof(*buffer), + iommu_data); struct ion_dma_buf_attachment *a; int ret = 0; - if (!hlos_accessible_buffer(buffer)) { - trace_ion_begin_cpu_access_cmo_skip(NULL, dmabuf->buf_name, - ion_buffer_cached(buffer), - false, direction, - sync_only_mapped); - ret = -EPERM; - goto out; - } + if (!hlos_accessible_buffer(buffer)) + return -EPERM; - if (!(buffer->flags & ION_FLAG_CACHED)) { - trace_ion_begin_cpu_access_cmo_skip(NULL, dmabuf->buf_name, - false, true, direction, - sync_only_mapped); - goto out; - } - - mutex_lock(&buffer->lock); - - if (IS_ENABLED(CONFIG_ION_FORCE_DMA_SYNC)) { - struct device *dev = buffer->heap->priv; - struct sg_table *table = buffer->sg_table; - - if (sync_only_mapped) - ret = ion_sgl_sync_mapped(dev, table->sgl, - table->nents, &buffer->vmas, - direction, true); - else - dma_sync_sg_for_cpu(dev, table->sgl, - table->nents, direction); - - if (!ret) - trace_ion_begin_cpu_access_cmo_apply(dev, - dmabuf->buf_name, - true, true, - direction, - sync_only_mapped); - else - trace_ion_begin_cpu_access_cmo_skip(dev, - dmabuf->buf_name, - true, true, - direction, - sync_only_mapped); - mutex_unlock(&buffer->lock); - goto out; - } + if (!(buffer->flags & ION_FLAG_CACHED)) + return 0; + mutex_lock(&buffer->attachment_lock); list_for_each_entry(a, &buffer->attachments, list) { int tmp = 0; - if (!a->dma_mapped) { - trace_ion_begin_cpu_access_notmapped(a->dev, - dmabuf->buf_name, - true, true, - direction, - sync_only_mapped); + if (!a->dma_mapped) continue; - } if (sync_only_mapped) tmp = ion_sgl_sync_mapped(a->dev, a->table->sgl, @@ -719,25 +523,11 @@ static int __ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents, direction); - if (!tmp) { - trace_ion_begin_cpu_access_cmo_apply(a->dev, - dmabuf->buf_name, - true, true, - direction, - sync_only_mapped); - } else { - trace_ion_begin_cpu_access_cmo_skip(a->dev, - dmabuf->buf_name, - true, true, - direction, - sync_only_mapped); + if (tmp) ret = tmp; - } - } - mutex_unlock(&buffer->lock); + mutex_unlock(&buffer->attachment_lock); -out: return ret; } @@ -745,64 +535,23 @@ static int __ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction direction, bool sync_only_mapped) { - struct ion_buffer *buffer = dmabuf->priv; + struct ion_buffer *buffer = container_of(dmabuf->priv, typeof(*buffer), + iommu_data); struct ion_dma_buf_attachment *a; int ret = 0; - if (!hlos_accessible_buffer(buffer)) { - trace_ion_end_cpu_access_cmo_skip(NULL, dmabuf->buf_name, - ion_buffer_cached(buffer), - false, direction, - sync_only_mapped); - ret = -EPERM; - goto out; - } + if (!hlos_accessible_buffer(buffer)) + return -EPERM; - if (!(buffer->flags & ION_FLAG_CACHED)) { - trace_ion_end_cpu_access_cmo_skip(NULL, dmabuf->buf_name, false, - true, direction, - sync_only_mapped); - goto out; - } - - mutex_lock(&buffer->lock); - if (IS_ENABLED(CONFIG_ION_FORCE_DMA_SYNC)) { - struct device *dev = buffer->heap->priv; - struct sg_table *table = buffer->sg_table; - - if (sync_only_mapped) - ret = ion_sgl_sync_mapped(dev, table->sgl, - table->nents, &buffer->vmas, - direction, false); - else - dma_sync_sg_for_device(dev, table->sgl, - table->nents, direction); - - if (!ret) - trace_ion_end_cpu_access_cmo_apply(dev, - dmabuf->buf_name, - true, true, - direction, - sync_only_mapped); - else - trace_ion_end_cpu_access_cmo_skip(dev, dmabuf->buf_name, - true, true, direction, - sync_only_mapped); - mutex_unlock(&buffer->lock); - goto out; - } + if (!(buffer->flags & ION_FLAG_CACHED)) + return 0; + mutex_lock(&buffer->attachment_lock); list_for_each_entry(a, &buffer->attachments, list) { int tmp = 0; - if (!a->dma_mapped) { - trace_ion_end_cpu_access_notmapped(a->dev, - dmabuf->buf_name, - true, true, - direction, - sync_only_mapped); + if (!a->dma_mapped) continue; - } if (sync_only_mapped) tmp = ion_sgl_sync_mapped(a->dev, a->table->sgl, @@ -813,23 +562,11 @@ static int __ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents, direction); - if (!tmp) { - trace_ion_end_cpu_access_cmo_apply(a->dev, - dmabuf->buf_name, - true, true, - direction, - sync_only_mapped); - } else { - trace_ion_end_cpu_access_cmo_skip(a->dev, - dmabuf->buf_name, - true, true, direction, - sync_only_mapped); + if (tmp) ret = tmp; - } } - mutex_unlock(&buffer->lock); + mutex_unlock(&buffer->attachment_lock); -out: return ret; } @@ -862,80 +599,32 @@ static int ion_dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf, unsigned int offset, unsigned int len) { - struct ion_buffer *buffer = dmabuf->priv; + struct ion_buffer *buffer = container_of(dmabuf->priv, typeof(*buffer), + iommu_data); struct ion_dma_buf_attachment *a; int ret = 0; - if (!hlos_accessible_buffer(buffer)) { - trace_ion_begin_cpu_access_cmo_skip(NULL, dmabuf->buf_name, - ion_buffer_cached(buffer), - false, dir, - false); - ret = -EPERM; - goto out; - } + if (!hlos_accessible_buffer(buffer)) + return -EPERM; - if (!(buffer->flags & ION_FLAG_CACHED)) { - trace_ion_begin_cpu_access_cmo_skip(NULL, dmabuf->buf_name, - false, true, dir, - false); - goto out; - } - - mutex_lock(&buffer->lock); - if (IS_ENABLED(CONFIG_ION_FORCE_DMA_SYNC)) { - struct device *dev = buffer->heap->priv; - struct sg_table *table = buffer->sg_table; - - ret = ion_sgl_sync_range(dev, table->sgl, table->nents, - offset, len, dir, true); - - if (!ret) - trace_ion_begin_cpu_access_cmo_apply(dev, - dmabuf->buf_name, - true, true, dir, - false); - else - trace_ion_begin_cpu_access_cmo_skip(dev, - dmabuf->buf_name, - true, true, dir, - false); - mutex_unlock(&buffer->lock); - goto out; - } + if (!(buffer->flags & ION_FLAG_CACHED)) + return 0; + mutex_lock(&buffer->attachment_lock); list_for_each_entry(a, &buffer->attachments, list) { int tmp = 0; - if (!a->dma_mapped) { - trace_ion_begin_cpu_access_notmapped(a->dev, - dmabuf->buf_name, - true, true, - dir, - false); + if (!a->dma_mapped) continue; - } - tmp = ion_sgl_sync_range(a->dev, a->table->sgl, a->table->nents, + ret = ion_sgl_sync_range(a->dev, a->table->sgl, a->table->nents, offset, len, dir, true); - if (!tmp) { - trace_ion_begin_cpu_access_cmo_apply(a->dev, - dmabuf->buf_name, - true, true, dir, - false); - } else { - trace_ion_begin_cpu_access_cmo_skip(a->dev, - dmabuf->buf_name, - true, true, dir, - false); + if (tmp) ret = tmp; - } - } - mutex_unlock(&buffer->lock); + mutex_unlock(&buffer->attachment_lock); -out: return ret; } @@ -944,89 +633,42 @@ static int ion_dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf, unsigned int offset, unsigned int len) { - struct ion_buffer *buffer = dmabuf->priv; + struct ion_buffer *buffer = container_of(dmabuf->priv, typeof(*buffer), + iommu_data); struct ion_dma_buf_attachment *a; int ret = 0; - if (!hlos_accessible_buffer(buffer)) { - trace_ion_end_cpu_access_cmo_skip(NULL, dmabuf->buf_name, - ion_buffer_cached(buffer), - false, direction, - false); - ret = -EPERM; - goto out; - } + if (!hlos_accessible_buffer(buffer)) + return -EPERM; - if (!(buffer->flags & ION_FLAG_CACHED)) { - trace_ion_end_cpu_access_cmo_skip(NULL, dmabuf->buf_name, false, - true, direction, - false); - goto out; - } - - mutex_lock(&buffer->lock); - if (IS_ENABLED(CONFIG_ION_FORCE_DMA_SYNC)) { - struct device *dev = buffer->heap->priv; - struct sg_table *table = buffer->sg_table; - - ret = ion_sgl_sync_range(dev, table->sgl, table->nents, - offset, len, direction, false); - - if (!ret) - trace_ion_end_cpu_access_cmo_apply(dev, - dmabuf->buf_name, - true, true, - direction, false); - else - trace_ion_end_cpu_access_cmo_skip(dev, dmabuf->buf_name, - true, true, - direction, false); - - mutex_unlock(&buffer->lock); - goto out; - } + if (!(buffer->flags & ION_FLAG_CACHED)) + return 0; + mutex_lock(&buffer->attachment_lock); list_for_each_entry(a, &buffer->attachments, list) { int tmp = 0; - if (!a->dma_mapped) { - trace_ion_end_cpu_access_notmapped(a->dev, - dmabuf->buf_name, - true, true, - direction, - false); + if (!a->dma_mapped) continue; - } - tmp = ion_sgl_sync_range(a->dev, a->table->sgl, a->table->nents, + ret = ion_sgl_sync_range(a->dev, a->table->sgl, a->table->nents, offset, len, direction, false); - if (!tmp) { - trace_ion_end_cpu_access_cmo_apply(a->dev, - dmabuf->buf_name, - true, true, - direction, false); - - } else { - trace_ion_end_cpu_access_cmo_skip(a->dev, - dmabuf->buf_name, - true, true, direction, - false); + if (tmp) ret = tmp; - } } - mutex_unlock(&buffer->lock); + mutex_unlock(&buffer->attachment_lock); -out: return ret; } static int ion_dma_buf_get_flags(struct dma_buf *dmabuf, unsigned long *flags) { - struct ion_buffer *buffer = dmabuf->priv; - *flags = buffer->flags; + struct ion_buffer *buffer = container_of(dmabuf->priv, typeof(*buffer), + iommu_data); + *flags = buffer->flags; return 0; } @@ -1036,7 +678,7 @@ static const struct dma_buf_ops dma_buf_ops = { .mmap = ion_mmap, .release = ion_dma_buf_release, .attach = ion_dma_buf_attach, - .detach = ion_dma_buf_detatch, + .detach = ion_dma_buf_detach, .begin_cpu_access = ion_dma_buf_begin_cpu_access, .end_cpu_access = ion_dma_buf_end_cpu_access, .begin_cpu_access_umapped = ion_dma_buf_begin_cpu_access_umapped, @@ -1049,116 +691,59 @@ static const struct dma_buf_ops dma_buf_ops = { .unmap = ion_dma_buf_kunmap, .vmap = ion_dma_buf_vmap, .vunmap = ion_dma_buf_vunmap, - .get_flags = ion_dma_buf_get_flags, + .get_flags = ion_dma_buf_get_flags }; -struct dma_buf *ion_alloc_dmabuf(size_t len, unsigned int heap_id_mask, - unsigned int flags) -{ - struct ion_device *dev = internal_dev; - struct ion_buffer *buffer = NULL; - struct ion_heap *heap; - DEFINE_DMA_BUF_EXPORT_INFO(exp_info); - struct dma_buf *dmabuf; - char task_comm[TASK_COMM_LEN]; - - pr_debug("%s: len %zu heap_id_mask %u flags %x\n", __func__, - len, heap_id_mask, flags); - /* - * traverse the list of heaps available in this system in priority - * order. If the heap type is supported by the client, and matches the - * request of the caller allocate from it. Repeat until allocate has - * succeeded or all heaps have been tried - */ - len = PAGE_ALIGN(len); - - if (!len) - return ERR_PTR(-EINVAL); - - down_read(&dev->lock); - plist_for_each_entry(heap, &dev->heaps, node) { - /* if the caller didn't specify this heap id */ - if (!((1 << heap->id) & heap_id_mask)) - continue; - buffer = ion_buffer_create(heap, dev, len, flags); - if (!IS_ERR(buffer) || PTR_ERR(buffer) == -EINTR) - break; - } - up_read(&dev->lock); - - if (!buffer) - return ERR_PTR(-ENODEV); - - if (IS_ERR(buffer)) - return ERR_CAST(buffer); - - get_task_comm(task_comm, current->group_leader); - - exp_info.ops = &dma_buf_ops; - exp_info.size = buffer->size; - exp_info.flags = O_RDWR; - exp_info.priv = buffer; - exp_info.exp_name = kasprintf(GFP_KERNEL, "%s-%s-%d-%s", KBUILD_MODNAME, - heap->name, current->tgid, task_comm); - - dmabuf = dma_buf_export(&exp_info); - if (IS_ERR(dmabuf)) { - _ion_buffer_destroy(buffer); - kfree(exp_info.exp_name); - } - - return dmabuf; -} - struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags) { struct ion_device *dev = internal_dev; + struct dma_buf_export_info exp_info; + struct ion_buffer *buffer = NULL; + struct dma_buf *dmabuf; struct ion_heap *heap; - bool type_valid = false; - pr_debug("%s: len %zu heap_id_mask %u flags %x\n", __func__, - len, heap_id_mask, flags); - /* - * traverse the list of heaps available in this system in priority - * order. Check the heap type is supported. - */ - - down_read(&dev->lock); - plist_for_each_entry(heap, &dev->heaps, node) { - /* if the caller didn't specify this heap id */ - if (!((1 << heap->id) & heap_id_mask)) - continue; - if (heap->type == ION_HEAP_TYPE_SYSTEM || - heap->type == ION_HEAP_TYPE_CARVEOUT || - heap->type == (enum ion_heap_type)ION_HEAP_TYPE_HYP_CMA || - heap->type == - (enum ion_heap_type)ION_HEAP_TYPE_SYSTEM_SECURE) { - type_valid = true; - } else { - pr_warn("%s: heap type not supported, type:%d\n", - __func__, heap->type); - } - break; - } - up_read(&dev->lock); - - if (!type_valid) + len = PAGE_ALIGN(len); + if (!len) return ERR_PTR(-EINVAL); - return ion_alloc_dmabuf(len, heap_id_mask, flags); + down_read(&dev->heap_lock); + plist_for_each_entry(heap, &dev->heaps, node) { + if (!(BIT(heap->id) & heap_id_mask)) + continue; + + buffer = ion_buffer_create(heap, dev, len, flags); + if (!IS_ERR(buffer) || PTR_ERR(buffer) == -EINTR) + break; + } + up_read(&dev->heap_lock); + + if (IS_ERR_OR_NULL(buffer)) + return ERR_PTR(-EINVAL); + + exp_info = (typeof(exp_info)){ + .ops = &dma_buf_ops, + .flags = O_RDWR, + .size = buffer->size, + .priv = &buffer->iommu_data + }; + + dmabuf = dma_buf_export(&exp_info); + if (IS_ERR(dmabuf)) + _ion_buffer_destroy(buffer); + + return dmabuf; } EXPORT_SYMBOL(ion_alloc); int ion_alloc_fd(size_t len, unsigned int heap_id_mask, unsigned int flags) { - int fd; struct dma_buf *dmabuf; + int fd; - dmabuf = ion_alloc_dmabuf(len, heap_id_mask, flags); - if (IS_ERR(dmabuf)) { + dmabuf = ion_alloc(len, heap_id_mask, flags); + if (IS_ERR(dmabuf)) return PTR_ERR(dmabuf); - } fd = dma_buf_fd(dmabuf, O_CLOEXEC); if (fd < 0) @@ -1169,47 +754,47 @@ int ion_alloc_fd(size_t len, unsigned int heap_id_mask, unsigned int flags) int ion_query_heaps(struct ion_heap_query *query) { + struct ion_heap_data __user *ubuf = u64_to_user_ptr(query->heaps); struct ion_device *dev = internal_dev; - struct ion_heap_data __user *buffer = u64_to_user_ptr(query->heaps); - int ret = -EINVAL, cnt = 0, max_cnt; - struct ion_heap *heap; struct ion_heap_data hdata; + struct ion_heap *heap; + int cnt = 0, max_cnt; memset(&hdata, 0, sizeof(hdata)); - down_read(&dev->lock); - if (!buffer) { + if (!ubuf) { + down_read(&dev->heap_lock); query->cnt = dev->heap_cnt; - ret = 0; - goto out; + up_read(&dev->heap_lock); + + return 0; } if (query->cnt <= 0) - goto out; + return -EINVAL; max_cnt = query->cnt; + down_read(&dev->heap_lock); plist_for_each_entry(heap, &dev->heaps, node) { strlcpy(hdata.name, heap->name, sizeof(hdata.name)); hdata.name[sizeof(hdata.name) - 1] = '\0'; hdata.type = heap->type; hdata.heap_id = heap->id; - if (copy_to_user(&buffer[cnt], &hdata, sizeof(hdata))) { - ret = -EFAULT; - goto out; + if (copy_to_user(&ubuf[cnt], &hdata, sizeof(hdata))) { + up_read(&dev->heap_lock); + return -EFAULT; } cnt++; if (cnt >= max_cnt) break; } + up_read(&dev->heap_lock); query->cnt = cnt; - ret = 0; -out: - up_read(&dev->lock); - return ret; + return 0; } static const struct file_operations ion_fops = { @@ -1220,182 +805,55 @@ static const struct file_operations ion_fops = { #endif }; -static int debug_shrink_set(void *data, u64 val) -{ - struct ion_heap *heap = data; - struct shrink_control sc; - int objs; - - sc.gfp_mask = GFP_HIGHUSER; - sc.nr_to_scan = val; - - if (!val) { - objs = heap->shrinker.count_objects(&heap->shrinker, &sc); - sc.nr_to_scan = objs; - } - - heap->shrinker.scan_objects(&heap->shrinker, &sc); - return 0; -} - -static int debug_shrink_get(void *data, u64 *val) -{ - struct ion_heap *heap = data; - struct shrink_control sc; - int objs; - - sc.gfp_mask = GFP_HIGHUSER; - sc.nr_to_scan = 0; - - objs = heap->shrinker.count_objects(&heap->shrinker, &sc); - *val = objs; - return 0; -} - -DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get, - debug_shrink_set, "%llu\n"); - void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap) { - struct dentry *debug_file; - - if (!heap->ops->allocate || !heap->ops->free) - pr_err("%s: can not add heap with invalid ops struct.\n", - __func__); - spin_lock_init(&heap->free_lock); heap->free_list_size = 0; if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) ion_heap_init_deferred_free(heap); - if ((heap->flags & ION_HEAP_FLAG_DEFER_FREE) || heap->ops->shrink) + if (heap->flags & ION_HEAP_FLAG_DEFER_FREE || heap->ops->shrink) ion_heap_init_shrinker(heap); heap->dev = dev; - down_write(&dev->lock); - /* - * use negative heap->id to reverse the priority -- when traversing - * the list later attempt higher id numbers first - */ plist_node_init(&heap->node, -heap->id); + + down_write(&dev->heap_lock); plist_add(&heap->node, &dev->heaps); - - if (heap->shrinker.count_objects && heap->shrinker.scan_objects) { - char debug_name[64]; - - snprintf(debug_name, 64, "%s_shrink", heap->name); - debug_file = debugfs_create_file( - debug_name, 0644, dev->debug_root, heap, - &debug_shrink_fops); - if (!debug_file) { - char buf[256], *path; - - path = dentry_path(dev->debug_root, buf, 256); - pr_err("Failed to create heap shrinker debugfs at %s/%s\n", - path, debug_name); - } - } - dev->heap_cnt++; - up_write(&dev->lock); -} -EXPORT_SYMBOL(ion_device_add_heap); - -static ssize_t -total_heaps_kb_show(struct kobject *kobj, struct kobj_attribute *attr, - char *buf) -{ - u64 size_in_bytes = atomic_long_read(&total_heap_bytes); - - return sprintf(buf, "%llu\n", div_u64(size_in_bytes, 1024)); -} - -static ssize_t -total_pools_kb_show(struct kobject *kobj, struct kobj_attribute *attr, - char *buf) -{ - u64 size_in_bytes = ion_page_pool_nr_pages() * PAGE_SIZE; - - return sprintf(buf, "%llu\n", div_u64(size_in_bytes, 1024)); -} - -static struct kobj_attribute total_heaps_kb_attr = - __ATTR_RO(total_heaps_kb); - -static struct kobj_attribute total_pools_kb_attr = - __ATTR_RO(total_pools_kb); - -static struct attribute *ion_device_attrs[] = { - &total_heaps_kb_attr.attr, - &total_pools_kb_attr.attr, - NULL, -}; - -ATTRIBUTE_GROUPS(ion_device); - -static int ion_init_sysfs(void) -{ - struct kobject *ion_kobj; - int ret; - - ion_kobj = kobject_create_and_add("ion", kernel_kobj); - if (!ion_kobj) - return -ENOMEM; - - ret = sysfs_create_groups(ion_kobj, ion_device_groups); - if (ret) { - kobject_put(ion_kobj); - return ret; - } - - return 0; + up_write(&dev->heap_lock); } struct ion_device *ion_device_create(void) { - struct ion_device *idev; + struct ion_device *dev; int ret; - idev = kzalloc(sizeof(*idev), GFP_KERNEL); - if (!idev) + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) return ERR_PTR(-ENOMEM); - idev->dev.minor = MISC_DYNAMIC_MINOR; - idev->dev.name = "ion"; - idev->dev.fops = &ion_fops; - idev->dev.parent = NULL; - ret = misc_register(&idev->dev); - if (ret) { - pr_err("ion: failed to register misc device.\n"); - goto err_reg; - } + ion_sg_table_pool = KMEM_CACHE(sg_table, SLAB_HWCACHE_ALIGN); + if (!ion_sg_table_pool) + goto free_dev; - ret = ion_init_sysfs(); - if (ret) { - pr_err("ion: failed to add sysfs attributes.\n"); - goto err_sysfs; - } + dev->dev.minor = MISC_DYNAMIC_MINOR; + dev->dev.name = "ion"; + dev->dev.fops = &ion_fops; + dev->dev.parent = NULL; + ret = misc_register(&dev->dev); + if (ret) + goto free_table_pool; - idev->debug_root = debugfs_create_dir("ion", NULL); - if (!idev->debug_root) { - pr_err("ion: failed to create debugfs root directory.\n"); - goto debugfs_done; - } + init_rwsem(&dev->heap_lock); + plist_head_init(&dev->heaps); + internal_dev = dev; + return dev; -debugfs_done: - - idev->buffers = RB_ROOT; - mutex_init(&idev->buffer_lock); - init_rwsem(&idev->lock); - plist_head_init(&idev->heaps); - internal_dev = idev; - return idev; - -err_sysfs: - misc_deregister(&idev->dev); -err_reg: - kfree(idev); - return ERR_PTR(ret); +free_table_pool: + kmem_cache_destroy(ion_sg_table_pool); +free_dev: + kfree(dev); + return ERR_PTR(-ENOMEM); } -EXPORT_SYMBOL(ion_device_create); diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h index e5b293dc8889..a2cc1e548263 100644 --- a/drivers/staging/android/ion/ion.h +++ b/drivers/staging/android/ion/ion.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -48,21 +49,6 @@ #define ION_IS_CACHED(__flags) ((__flags) & ION_FLAG_CACHED) -/** - * Debug feature. Make ION allocations DMA - * ready to help identify clients who are wrongly - * dependending on ION allocations being DMA - * ready. - * - * As default set to 'false' since ION allocations - * are no longer required to be DMA ready - */ -#ifdef CONFIG_ION_FORCE_DMA_SYNC -#define MAKE_ION_ALLOC_DMA_READY 1 -#else -#define MAKE_ION_ALLOC_DMA_READY 0 -#endif - /** * struct ion_platform_heap - defines a heap in the given platform * @type: type of the heap from ion_heap_type enum @@ -121,51 +107,33 @@ struct ion_vma_list { * @vmas: list of vma's mapping this buffer */ struct ion_buffer { - union { - struct rb_node node; - struct list_head list; - }; + struct list_head list; struct ion_device *dev; struct ion_heap *heap; unsigned long flags; unsigned long private_flags; size_t size; void *priv_virt; - /* Protect ion buffer */ - struct mutex lock; + struct mutex attachment_lock; + struct mutex kmap_lock; + struct mutex vma_lock; int kmap_cnt; void *vaddr; struct sg_table *sg_table; struct list_head attachments; struct list_head vmas; + struct msm_iommu_data iommu_data; }; void ion_buffer_destroy(struct ion_buffer *buffer); -/** - * struct ion_device - the metadata of the ion device node - * @dev: the actual misc device - * @buffers: an rb tree of all the existing buffers - * @buffer_lock: lock protecting the tree of buffers - * @lock: rwsem protecting the tree of heaps and clients - */ struct ion_device { struct miscdevice dev; - struct rb_root buffers; - /* buffer_lock used for adding and removing buffers */ - struct mutex buffer_lock; - struct rw_semaphore lock; struct plist_head heaps; - struct dentry *debug_root; + struct rw_semaphore heap_lock; int heap_cnt; }; -/* refer to include/linux/pm.h */ -struct ion_pm_ops { - int (*freeze)(struct ion_heap *heap); - int (*restore)(struct ion_heap *heap); -}; - /** * struct ion_heap_ops - ops to operate on a given heap * @allocate: allocate memory @@ -191,7 +159,6 @@ struct ion_heap_ops { int (*map_user)(struct ion_heap *mapper, struct ion_buffer *buffer, struct vm_area_struct *vma); int (*shrink)(struct ion_heap *heap, gfp_t gfp_mask, int nr_to_scan); - struct ion_pm_ops pm; }; /** @@ -228,8 +195,6 @@ struct ion_heap_ops { * @lock: protects the free list * @waitqueue: queue to wait on from deferred free thread * @task: task struct of deferred free thread - * @debug_show: called when heap debug file is read to add any - * heap specific debug info to output * * Represents a pool of memory from which buffers can be made. In some * systems the only heap is regular system memory allocated via vmalloc. @@ -251,28 +216,12 @@ struct ion_heap { /* Protect the free list */ spinlock_t free_lock; wait_queue_head_t waitqueue; - struct task_struct *task; - atomic_long_t total_allocated; - - int (*debug_show)(struct ion_heap *heap, struct seq_file *, void *); }; -/** - * ion_buffer_cached - this ion buffer is cached - * @buffer: buffer - * - * indicates whether this ion buffer is cached - */ -bool ion_buffer_cached(struct ion_buffer *buffer); - -/** - * ion_buffer_fault_user_mappings - fault in user mappings of this buffer - * @buffer: buffer - * - * indicates whether userspace mappings of this buffer will be faulted - * in, this can affect how buffers are allocated from the heap. - */ -bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer); +static inline bool ion_buffer_cached(struct ion_buffer *buffer) +{ + return buffer->flags & ION_FLAG_CACHED; +} /** * ion_device_create - allocates and returns an ion device @@ -445,7 +394,7 @@ struct ion_page_pool { struct list_head high_items; struct list_head low_items; /* Protect the pool */ - struct mutex mutex; + spinlock_t lock; gfp_t gfp_mask; unsigned int order; struct plist_node list; @@ -464,12 +413,6 @@ void ion_page_pool_free_immediate(struct ion_page_pool *pool, int ion_page_pool_total(struct ion_page_pool *pool, bool high); size_t ion_system_heap_secure_page_pool_total(struct ion_heap *heap, int vmid); -#ifdef CONFIG_ION_SYSTEM_HEAP -long ion_page_pool_nr_pages(void); -#else -static inline long ion_page_pool_nr_pages(void) { return 0; } -#endif - /** ion_page_pool_shrink - shrinks the size of the memory cached in the pool * @pool: the pool * @gfp_mask: the memory type to reclaim diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c index 19c8ad23cf06..b9e1d63303be 100644 --- a/drivers/staging/android/ion/ion_carveout_heap.c +++ b/drivers/staging/android/ion/ion_carveout_heap.c @@ -186,8 +186,6 @@ struct ion_sc_entry { struct list_head list; struct ion_heap *heap; u32 token; - u64 base; - u64 size; }; struct ion_sc_heap { @@ -244,39 +242,9 @@ static void ion_sc_heap_free(struct ion_buffer *buffer) kfree(table); } -static int ion_secure_carveout_pm_freeze(struct ion_heap *heap) -{ - long sz; - - sz = atomic_long_read(&heap->total_allocated); - if (sz) { - pr_err("%s: %lx bytes won't be saved across hibernation. Aborting.", - __func__, sz); - return -EINVAL; - } - return 0; -} - -static int ion_secure_carveout_pm_restore(struct ion_heap *heap) -{ - struct ion_sc_heap *manager; - struct ion_sc_entry *child; - - manager = container_of(heap, struct ion_sc_heap, heap); - - list_for_each_entry(child, &manager->children, list) - ion_hyp_assign_from_flags( - child->base, child->size, child->token); - return 0; -} - static struct ion_heap_ops ion_sc_heap_ops = { .allocate = ion_sc_heap_allocate, .free = ion_sc_heap_free, - .pm = { - .freeze = ion_secure_carveout_pm_freeze, - .restore = ion_secure_carveout_pm_restore, - } }; static int ion_sc_get_dt_token(struct ion_sc_entry *entry, @@ -330,8 +298,6 @@ static int ion_sc_add_child(struct ion_sc_heap *manager, heap_data.priv = dev; heap_data.base = base; heap_data.size = size; - entry->base = base; - entry->size = size; /* This will zero memory initially */ entry->heap = __ion_carveout_heap_create(&heap_data, false); diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index 658571d13d34..de1123e16602 100644 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -124,8 +124,7 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, } } - if (MAKE_ION_ALLOC_DMA_READY || - (!hlos_accessible_buffer(buffer)) || + if ((!hlos_accessible_buffer(buffer)) || !ion_buffer_cached(buffer)) ion_pages_sync_for_device(dev, pages, size, DMA_BIDIRECTIONAL); @@ -276,29 +275,12 @@ static int ion_secure_cma_map_user(struct ion_heap *mapper, return ion_heap_map_user(mapper, buffer, vma); } -static int ion_secure_cma_pm_freeze(struct ion_heap *heap) -{ - long sz; - - sz = atomic_long_read(&heap->total_allocated); - if (sz) { - pr_err("%s: %lx bytes won't be saved across hibernation. Aborting.", - __func__, sz); - return -EINVAL; - } - - return 0; -} - static struct ion_heap_ops ion_secure_cma_ops = { .allocate = ion_secure_cma_allocate, .free = ion_secure_cma_free, .map_user = ion_secure_cma_map_user, .map_kernel = ion_secure_cma_map_kernel, .unmap_kernel = ion_heap_unmap_kernel, - .pm = { - .freeze = ion_secure_cma_pm_freeze, - } }; struct ion_heap *ion_cma_secure_heap_create(struct ion_platform_heap *data) diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index c682f1ea745c..8970fe8d5f7e 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -34,7 +34,7 @@ void *ion_heap_map_kernel(struct ion_heap *heap, pgprot_t pgprot; struct sg_table *table = buffer->sg_table; int npages = PAGE_ALIGN(buffer->size) / PAGE_SIZE; - struct page **pages = vmalloc(sizeof(struct page *) * npages); + struct page **pages = vmalloc(array_size(npages, sizeof(struct page *))); struct page **tmp = pages; if (!pages) @@ -224,8 +224,17 @@ size_t ion_heap_freelist_shrink(struct ion_heap *heap, size_t size) static int ion_heap_deferred_free(void *data) { +#ifndef CONFIG_ION_DEFER_FREE_NO_SCHED_IDLE + static const struct sched_param param = { + .sched_priority = 0 + }; +#endif struct ion_heap *heap = data; +#ifndef CONFIG_ION_DEFER_FREE_NO_SCHED_IDLE + sched_setscheduler(current, SCHED_IDLE, ¶m); +#endif + while (true) { struct ion_buffer *buffer; @@ -250,21 +259,16 @@ static int ion_heap_deferred_free(void *data) int ion_heap_init_deferred_free(struct ion_heap *heap) { -#ifndef CONFIG_ION_DEFER_FREE_NO_SCHED_IDLE - struct sched_param param = { .sched_priority = 0 }; -#endif + struct task_struct *thread; + INIT_LIST_HEAD(&heap->free_list); init_waitqueue_head(&heap->waitqueue); - heap->task = kthread_run(ion_heap_deferred_free, heap, - "%s", heap->name); - if (IS_ERR(heap->task)) { + thread = kthread_run(ion_heap_deferred_free, heap, "%s", heap->name); + if (IS_ERR(thread)) { pr_err("%s: creating thread for deferred free failed\n", __func__); - return PTR_ERR_OR_ZERO(heap->task); + return PTR_ERR_OR_ZERO(thread); } -#ifndef CONFIG_ION_DEFER_FREE_NO_SCHED_IDLE - sched_setscheduler(heap->task, SCHED_IDLE, ¶m); -#endif return 0; } diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c index 82e5007b45b4..180cb231aff9 100644 --- a/drivers/staging/android/ion/ion_page_pool.c +++ b/drivers/staging/android/ion/ion_page_pool.c @@ -26,13 +26,6 @@ #include "ion.h" -/* - * We avoid atomic_long_t to minimize cache flushes at the cost of possible - * race which would result in a small accounting inaccuracy that we can - * tolerate. - */ -static long nr_total_pages; - static void *ion_page_pool_alloc_pages(struct ion_page_pool *pool) { struct page *page = alloc_pages(pool->gfp_mask, pool->order); @@ -48,7 +41,7 @@ static void ion_page_pool_free_pages(struct ion_page_pool *pool, static int ion_page_pool_add(struct ion_page_pool *pool, struct page *page) { - mutex_lock(&pool->mutex); + spin_lock(&pool->lock); if (PageHighMem(page)) { list_add_tail(&page->lru, &pool->high_items); pool->high_count++; @@ -57,10 +50,9 @@ static int ion_page_pool_add(struct ion_page_pool *pool, struct page *page) pool->low_count++; } - nr_total_pages += 1 << pool->order; mod_node_page_state(page_pgdat(page), NR_KERNEL_MISC_RECLAIMABLE, 1 << pool->order); - mutex_unlock(&pool->mutex); + spin_unlock(&pool->lock); return 0; } @@ -79,7 +71,6 @@ static struct page *ion_page_pool_remove(struct ion_page_pool *pool, bool high) } list_del(&page->lru); - nr_total_pages -= 1 << pool->order; mod_node_page_state(page_pgdat(page), NR_KERNEL_MISC_RECLAIMABLE, -(1 << pool->order)); return page; @@ -94,12 +85,12 @@ struct page *ion_page_pool_alloc(struct ion_page_pool *pool, bool *from_pool) if (fatal_signal_pending(current)) return ERR_PTR(-EINTR); - if (*from_pool && mutex_trylock(&pool->mutex)) { + if (*from_pool && spin_trylock(&pool->lock)) { if (pool->high_count) page = ion_page_pool_remove(pool, true); else if (pool->low_count) page = ion_page_pool_remove(pool, false); - mutex_unlock(&pool->mutex); + spin_unlock(&pool->lock); } if (!page) { page = ion_page_pool_alloc_pages(pool); @@ -121,12 +112,12 @@ struct page *ion_page_pool_alloc_pool_only(struct ion_page_pool *pool) if (!pool) return ERR_PTR(-EINVAL); - if (mutex_trylock(&pool->mutex)) { + if (spin_trylock(&pool->lock)) { if (pool->high_count) page = ion_page_pool_remove(pool, true); else if (pool->low_count) page = ion_page_pool_remove(pool, false); - mutex_unlock(&pool->mutex); + spin_unlock(&pool->lock); } if (!page) @@ -158,16 +149,6 @@ int ion_page_pool_total(struct ion_page_pool *pool, bool high) return count << pool->order; } -#ifdef CONFIG_ION_SYSTEM_HEAP -long ion_page_pool_nr_pages(void) -{ - /* Correct possible overflow caused by racing writes */ - if (nr_total_pages < 0) - nr_total_pages = 0; - return nr_total_pages; -} -#endif - int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, int nr_to_scan) { @@ -185,16 +166,16 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, while (freed < nr_to_scan) { struct page *page; - mutex_lock(&pool->mutex); + spin_lock(&pool->lock); if (pool->low_count) { page = ion_page_pool_remove(pool, false); } else if (high && pool->high_count) { page = ion_page_pool_remove(pool, true); } else { - mutex_unlock(&pool->mutex); + spin_unlock(&pool->lock); break; } - mutex_unlock(&pool->mutex); + spin_unlock(&pool->lock); ion_page_pool_free_pages(pool, page); freed += (1 << pool->order); } @@ -215,7 +196,7 @@ struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order, INIT_LIST_HEAD(&pool->high_items); pool->gfp_mask = gfp_mask; pool->order = order; - mutex_init(&pool->mutex); + spin_lock_init(&pool->lock); plist_node_init(&pool->list, order); if (cached) pool->cached = true; diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 8f57416b930f..614144927da9 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -86,7 +86,7 @@ static struct page *alloc_buffer_page(struct ion_system_heap *heap, if (IS_ERR(page)) return page; - if ((MAKE_ION_ALLOC_DMA_READY && vmid <= 0) || !(*from_pool)) + if (!(*from_pool)) ion_pages_sync_for_device(dev, page, PAGE_SIZE << order, DMA_BIDIRECTIONAL); @@ -525,106 +525,6 @@ static struct ion_heap_ops system_heap_ops = { .shrink = ion_system_heap_shrink, }; -static int ion_system_heap_debug_show(struct ion_heap *heap, struct seq_file *s, - void *unused) -{ - - struct ion_system_heap *sys_heap = container_of( - heap, struct ion_system_heap, heap); - bool use_seq = s; - unsigned long uncached_total = 0; - unsigned long cached_total = 0; - unsigned long secure_total = 0; - struct ion_page_pool *pool; - int i, j; - - for (i = 0; i < NUM_ORDERS; i++) { - pool = sys_heap->uncached_pools[i]; - if (use_seq) { - seq_printf(s, - "%d order %u highmem pages in uncached pool = %lu total\n", - pool->high_count, pool->order, - (1 << pool->order) * PAGE_SIZE * - pool->high_count); - seq_printf(s, - "%d order %u lowmem pages in uncached pool = %lu total\n", - pool->low_count, pool->order, - (1 << pool->order) * PAGE_SIZE * - pool->low_count); - } - - uncached_total += (1 << pool->order) * PAGE_SIZE * - pool->high_count; - uncached_total += (1 << pool->order) * PAGE_SIZE * - pool->low_count; - } - - for (i = 0; i < NUM_ORDERS; i++) { - pool = sys_heap->cached_pools[i]; - if (use_seq) { - seq_printf(s, - "%d order %u highmem pages in cached pool = %lu total\n", - pool->high_count, pool->order, - (1 << pool->order) * PAGE_SIZE * - pool->high_count); - seq_printf(s, - "%d order %u lowmem pages in cached pool = %lu total\n", - pool->low_count, pool->order, - (1 << pool->order) * PAGE_SIZE * - pool->low_count); - } - - cached_total += (1 << pool->order) * PAGE_SIZE * - pool->high_count; - cached_total += (1 << pool->order) * PAGE_SIZE * - pool->low_count; - } - - for (i = 0; i < NUM_ORDERS; i++) { - for (j = 0; j < VMID_LAST; j++) { - if (!is_secure_vmid_valid(j)) - continue; - pool = sys_heap->secure_pools[j][i]; - - if (use_seq) { - seq_printf(s, - "VMID %d: %d order %u highmem pages in secure pool = %lu total\n", - j, pool->high_count, pool->order, - (1 << pool->order) * PAGE_SIZE * - pool->high_count); - seq_printf(s, - "VMID %d: %d order %u lowmem pages in secure pool = %lu total\n", - j, pool->low_count, pool->order, - (1 << pool->order) * PAGE_SIZE * - pool->low_count); - } - - secure_total += (1 << pool->order) * PAGE_SIZE * - pool->high_count; - secure_total += (1 << pool->order) * PAGE_SIZE * - pool->low_count; - } - } - - if (use_seq) { - seq_puts(s, "--------------------------------------------\n"); - seq_printf(s, "uncached pool = %lu cached pool = %lu secure pool = %lu\n", - uncached_total, cached_total, secure_total); - seq_printf(s, "pool total (uncached + cached + secure) = %lu\n", - uncached_total + cached_total + secure_total); - seq_puts(s, "--------------------------------------------\n"); - } else { - pr_info("-------------------------------------------------\n"); - pr_info("uncached pool = %lu cached pool = %lu secure pool = %lu\n", - uncached_total, cached_total, secure_total); - pr_info("pool total (uncached + cached + secure) = %lu\n", - uncached_total + cached_total + secure_total); - pr_info("-------------------------------------------------\n"); - } - - return 0; -} - static void ion_system_heap_destroy_pools(struct ion_page_pool **pools) { int i; @@ -695,7 +595,6 @@ struct ion_heap *ion_system_heap_create(struct ion_platform_heap *data) mutex_init(&heap->split_page_mutex); - heap->heap.debug_show = ion_system_heap_debug_show; return &heap->heap; destroy_uncached_pools: diff --git a/drivers/staging/android/ion/ion_system_secure_heap.c b/drivers/staging/android/ion/ion_system_secure_heap.c index 64c3c14e78c2..050765fb0187 100644 --- a/drivers/staging/android/ion/ion_system_secure_heap.c +++ b/drivers/staging/android/ion/ion_system_secure_heap.c @@ -352,41 +352,6 @@ static int ion_system_secure_heap_shrink(struct ion_heap *heap, gfp_t gfp_mask, gfp_mask, nr_to_scan); } -static int ion_system_secure_heap_pm_freeze(struct ion_heap *heap) -{ - struct ion_system_secure_heap *secure_heap; - unsigned long count; - long sz; - struct shrink_control sc = { - .gfp_mask = GFP_HIGHUSER, - }; - - secure_heap = container_of(heap, struct ion_system_secure_heap, heap); - - sz = atomic_long_read(&heap->total_allocated); - if (sz) { - pr_err("%s: %lx bytes won't be saved across hibernation. Aborting.", - __func__, sz); - return -EINVAL; - } - - /* Since userspace is frozen, no more requests will be queued */ - cancel_delayed_work_sync(&secure_heap->prefetch_work); - - count = heap->shrinker.count_objects(&heap->shrinker, &sc); - sc.nr_to_scan = count; - heap->shrinker.scan_objects(&heap->shrinker, &sc); - - count = heap->shrinker.count_objects(&heap->shrinker, &sc); - if (count) { - pr_err("%s: Failed to free all objects - %ld remaining", - __func__, count); - return -EINVAL; - } - - return 0; -} - static struct ion_heap_ops system_secure_heap_ops = { .allocate = ion_system_secure_heap_allocate, .free = ion_system_secure_heap_free, @@ -394,9 +359,6 @@ static struct ion_heap_ops system_secure_heap_ops = { .unmap_kernel = ion_system_secure_heap_unmap_kernel, .map_user = ion_system_secure_heap_map_user, .shrink = ion_system_secure_heap_shrink, - .pm = { - .freeze = ion_system_secure_heap_pm_freeze, - } }; struct ion_heap *ion_system_secure_heap_create(struct ion_platform_heap *unused) diff --git a/drivers/staging/android/ion/msm/msm_ion_of.c b/drivers/staging/android/ion/msm/msm_ion_of.c index 96b5f4f3e633..e1fbe941f892 100644 --- a/drivers/staging/android/ion/msm/msm_ion_of.c +++ b/drivers/staging/android/ion/msm/msm_ion_of.c @@ -34,6 +34,7 @@ struct ion_heap_desc { const char *name; }; +#ifdef CONFIG_OF static struct ion_heap_desc ion_heap_meta[] = { { .id = ION_SYSTEM_HEAP_ID, @@ -84,7 +85,9 @@ static struct ion_heap_desc ion_heap_meta[] = { .name = ION_SECURE_CARVEOUT_HEAP_NAME, } }; +#endif +#ifdef CONFIG_OF #define MAKE_HEAP_TYPE_MAPPING(h) { .name = #h, \ .heap_type = ION_HEAP_TYPE_##h, } @@ -262,6 +265,16 @@ free_heaps: free_pdata(pdata); return ERR_PTR(ret); } +#else +static struct ion_platform_data *msm_ion_parse_dt(struct platform_device *pdev) +{ + return NULL; +} + +static void free_pdata(const struct ion_platform_data *pdata) +{ +} +#endif struct ion_heap *get_ion_heap(int heap_id) { @@ -282,13 +295,19 @@ static int msm_ion_probe(struct platform_device *pdev) { static struct ion_device *new_dev; struct ion_platform_data *pdata; + unsigned int pdata_needs_to_be_freed; int err = -1; int i; - pdata = msm_ion_parse_dt(pdev); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - + if (pdev->dev.of_node) { + pdata = msm_ion_parse_dt(pdev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + pdata_needs_to_be_freed = 1; + } else { + pdata = pdev->dev.platform_data; + pdata_needs_to_be_freed = 0; + } num_heaps = pdata->nr; @@ -331,7 +350,8 @@ static int msm_ion_probe(struct platform_device *pdev) ion_device_add_heap(new_dev, heaps[i]); } - free_pdata(pdata); + if (pdata_needs_to_be_freed) + free_pdata(pdata); platform_set_drvdata(pdev, new_dev); /* @@ -344,66 +364,11 @@ static int msm_ion_probe(struct platform_device *pdev) out: kfree(heaps); - free_pdata(pdata); + if (pdata_needs_to_be_freed) + free_pdata(pdata); return err; } -static int msm_ion_pm_freeze(struct device *dev) -{ - struct ion_device *ion_dev = dev_get_drvdata(dev); - struct ion_heap *heap; - int ret; - - plist_for_each_entry(heap, &ion_dev->heaps, node) { - if (heap->ops->pm.freeze) { - ret = heap->ops->pm.freeze(heap); - if (ret) { - dev_err(dev, "%s freeze callback failed\n", - heap->name); - goto undo; - } - } - } - - return 0; - -undo: - list_for_each_entry_continue_reverse(heap, &ion_dev->heaps.node_list, - node.node_list) - if (heap->ops->pm.restore) - heap->ops->pm.restore(heap); - - return ret; -} - -static int msm_ion_pm_restore(struct device *dev) -{ - struct ion_device *ion_dev = dev_get_drvdata(dev); - struct ion_heap *heap; - int ret = 0; - - plist_for_each_entry(heap, &ion_dev->heaps, node) { - int rc; - - if (heap->ops->pm.restore) { - rc = heap->ops->pm.restore(heap); - if (rc) { - dev_err(dev, "%s restore callback failed.\n", - heap->name); - if (!ret) - ret = rc; - } - } - } - - return ret; -} - -static const struct dev_pm_ops msm_ion_pm_ops = { - .freeze_late = msm_ion_pm_freeze, - .restore_early = msm_ion_pm_restore, -}; - static const struct of_device_id msm_ion_match_table[] = { {.compatible = ION_COMPAT_STR}, {}, @@ -414,7 +379,6 @@ static struct platform_driver msm_ion_driver = { .driver = { .name = "ion-msm", .of_match_table = msm_ion_match_table, - .pm = &msm_ion_pm_ops, .probe_type = PROBE_PREFER_ASYNCHRONOUS, }, }; diff --git a/drivers/staging/android/ion/msm_ion_priv.h b/drivers/staging/android/ion/msm_ion_priv.h index 181ae1cc2c05..11baa424aa6d 100644 --- a/drivers/staging/android/ion/msm_ion_priv.h +++ b/drivers/staging/android/ion/msm_ion_priv.h @@ -40,10 +40,6 @@ int ion_system_secure_heap_drain(struct ion_heap *heap, void *data); struct ion_heap *ion_cma_secure_heap_create(struct ion_platform_heap *heap); void ion_cma_secure_heap_destroy(struct ion_heap *heap); -long msm_ion_custom_ioctl(struct ion_client *client, - unsigned int cmd, - unsigned long arg); - #ifdef CONFIG_CMA struct ion_heap *ion_secure_cma_heap_create(struct ion_platform_heap *heap); void ion_secure_cma_heap_destroy(struct ion_heap *heap); @@ -95,18 +91,5 @@ bool is_secure_vmid_valid(int vmid); int ion_system_secure_heap_unassign_sg(struct sg_table *sgt, int source_vmid); int ion_system_secure_heap_assign_sg(struct sg_table *sgt, int dest_vmid); -/** - * ion_create_chunked_sg_table - helper function to create sg table - * with specified chunk size - * @buffer_base: The starting address used for the sg dma address - * @chunk_size: The size of each entry in the sg table - * @total_size: The total size of the sg table (i.e. the sum of the - * entries). This will be rounded up to the nearest - * multiple of `chunk_size' - */ -struct sg_table *ion_create_chunked_sg_table(phys_addr_t buffer_base, - size_t chunk_size, - size_t total_size); - void show_ion_usage(struct ion_device *dev); #endif /* _MSM_ION_PRIV_H */ diff --git a/drivers/staging/ccree/ssi_sysfs.c b/drivers/staging/ccree/ssi_sysfs.c index 0655658bba4d..f7e0c5024a29 100644 --- a/drivers/staging/ccree/ssi_sysfs.c +++ b/drivers/staging/ccree/ssi_sysfs.c @@ -376,7 +376,7 @@ static int sys_init_dir(struct sys_dir *sys_dir, struct ssi_drvdata *drvdata, return -ENOMEM; /* allocate memory for directory's attributes list */ sys_dir->sys_dir_attr_list = - kzalloc(sizeof(struct attribute *) * (num_of_attrs + 1), + kcalloc(num_of_attrs + 1, sizeof(struct attribute *), GFP_KERNEL); if (!(sys_dir->sys_dir_attr_list)) { diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index b455ff6714eb..f9a4b65485b0 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -108,9 +108,9 @@ static void __comedi_buf_alloc(struct comedi_device *dev, /* Need ref to hardware device to free buffer later. */ bm->dma_hw_dev = get_device(dev->hw_dev); - bm->page_list = vzalloc(sizeof(*buf) * n_pages); + bm->page_list = vzalloc(array_size(n_pages, sizeof(*buf))); if (bm->page_list) - pages = vmalloc(sizeof(struct page *) * n_pages); + pages = vmalloc(array_size(n_pages, sizeof(struct page *))); if (!pages) return; diff --git a/drivers/staging/exfat/Kconfig b/drivers/staging/exfat/Kconfig deleted file mode 100644 index 292a19dfcaf5..000000000000 --- a/drivers/staging/exfat/Kconfig +++ /dev/null @@ -1,41 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -config STAGING_EXFAT_FS - tristate "exFAT fs support" - depends on BLOCK - select NLS - help - This adds support for the exFAT file system. - -config STAGING_EXFAT_DISCARD - bool "enable discard support" - depends on STAGING_EXFAT_FS - default y - -config STAGING_EXFAT_DELAYED_SYNC - bool "enable delayed sync" - depends on STAGING_EXFAT_FS - default n - -config STAGING_EXFAT_KERNEL_DEBUG - bool "enable kernel debug features via ioctl" - depends on STAGING_EXFAT_FS - default n - -config STAGING_EXFAT_DEBUG_MSG - bool "print debug messages" - depends on STAGING_EXFAT_FS - default n - -config STAGING_EXFAT_DEFAULT_CODEPAGE - int "Default codepage for exFAT" - default 437 - depends on STAGING_EXFAT_FS - help - This option should be set to the codepage of your exFAT filesystems. - -config STAGING_EXFAT_DEFAULT_IOCHARSET - string "Default iocharset for exFAT" - default "utf8" - depends on STAGING_EXFAT_FS - help - Set this to the default input/output character set you'd like exFAT to use. diff --git a/drivers/staging/exfat/Makefile b/drivers/staging/exfat/Makefile deleted file mode 100644 index 057556eeca0c..000000000000 --- a/drivers/staging/exfat/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later - -obj-$(CONFIG_STAGING_EXFAT_FS) += exfat.o - -exfat-y := exfat_core.o \ - exfat_super.o \ - exfat_blkdev.o \ - exfat_cache.o \ - exfat_nls.o \ - exfat_upcase.o diff --git a/drivers/staging/exfat/TODO b/drivers/staging/exfat/TODO deleted file mode 100644 index a283ce534cf4..000000000000 --- a/drivers/staging/exfat/TODO +++ /dev/null @@ -1,69 +0,0 @@ -A laundry list of things that need looking at, most of which will -require more work than the average checkpatch cleanup... - -Note that some of these entries may not be bugs - they're things -that need to be looked at, and *possibly* fixed. - -Clean up the ffsCamelCase function names. - -Fix (thing)->flags to not use magic numbers - multiple offenders - -Sort out all the s32/u32/u8 nonsense - most of these should be plain int. - -exfat_core.c - ffsReadFile - the goto err_out seem to leak a brelse(). -same for ffsWriteFile. - -All the calls to fs_sync() need to be looked at, particularly in the -context of EXFAT_DELAYED_SYNC. Currently, if that's defined, we only -flush to disk when sync() gets called. We should be doing at least -metadata flushes at appropriate times. - -ffsTruncateFile - if (old_size <= new_size) { -That doesn't look right. How did it ever work? Are they relying on lazy -block allocation when actual writes happen? If nothing else, it never -does the 'fid->size = new_size' and do the inode update.... - -ffsSetAttr() is just dangling in the breeze, not wired up at all... - -Convert global mutexes to a per-superblock mutex. - -Right now, we load exactly one UTF-8 table. Check to see -if that plays nice with different codepage and iocharset values -for simultanous mounts of different devices - -exfat_rmdir() checks for -EBUSY but ffsRemoveDir() doesn't return it. -In fact, there's a complete lack of -EBUSY testing anywhere. - -There's probably a few missing checks for -EEXIST - -check return codes of sync_dirty_buffer() - -Why is remove_file doing a num_entries++?? - -Double check a lot of can't-happen parameter checks (for null pointers for -things that have only one call site and can't pass a null, etc). - -All the DEBUG stuff can probably be tossed, including the ioctl(). Either -that, or convert to a proper fault-injection system. - -exfat_remount does exactly one thing. Fix to actually deal with remount -options, particularly handling R/O correctly. For that matter, allow -R/O mounts in the first place. - -Figure out why the VFAT code used multi_sector_(read|write) but the -exfat code doesn't use it. The difference matters on SSDs with wear leveling. - -exfat_fat_sync(), exfat_buf_sync(), and sync_alloc_bitmap() -aren't called anyplace.... - -Create helper function for exfat_set_entry_time() and exfat_set_entry_type() -because it's sort of ugly to be calling the same functionn directly and -other code calling through the fs_func struc ponters... - -clean up the remaining vol_type checks, which are of two types: -some are ?: operators with magic numbers, and the rest are places -where we're doing stuff with '.' and '..'. - -Patches to: - Greg Kroah-Hartman - Valdis Kletnieks diff --git a/drivers/staging/exfat/exfat.h b/drivers/staging/exfat/exfat.h deleted file mode 100644 index 341c9192f7e8..000000000000 --- a/drivers/staging/exfat/exfat.h +++ /dev/null @@ -1,760 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. - */ - -#ifndef _EXFAT_H -#define _EXFAT_H - -#include -#include - -#ifdef CONFIG_STAGING_EXFAT_KERNEL_DEBUG - /* For Debugging Purpose */ - /* IOCTL code 'f' used by - * - file systems typically #0~0x1F - * - embedded terminal devices #128~ - * - exts for debugging purpose #99 - * number 100 and 101 is available now but has possible conflicts - */ -#define EXFAT_IOC_GET_DEBUGFLAGS _IOR('f', 100, long) -#define EXFAT_IOC_SET_DEBUGFLAGS _IOW('f', 101, long) - -#define EXFAT_DEBUGFLAGS_INVALID_UMOUNT 0x01 -#define EXFAT_DEBUGFLAGS_ERROR_RW 0x02 -#endif /* CONFIG_STAGING_EXFAT_KERNEL_DEBUG */ - -#ifdef CONFIG_STAGING_EXFAT_DEBUG_MSG -#define DEBUG 1 -#else -#undef DEBUG -#endif - -#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ - -#define DENTRY_SIZE 32 /* dir entry size */ -#define DENTRY_SIZE_BITS 5 - -/* PBR entries */ -#define PBR_SIGNATURE 0xAA55 -#define EXT_SIGNATURE 0xAA550000 -#define VOL_LABEL "NO NAME " /* size should be 11 */ -#define OEM_NAME "MSWIN4.1" /* size should be 8 */ -#define STR_FAT12 "FAT12 " /* size should be 8 */ -#define STR_FAT16 "FAT16 " /* size should be 8 */ -#define STR_FAT32 "FAT32 " /* size should be 8 */ -#define STR_EXFAT "EXFAT " /* size should be 8 */ -#define VOL_CLEAN 0x0000 -#define VOL_DIRTY 0x0002 - -/* max number of clusters */ -#define FAT12_THRESHOLD 4087 /* 2^12 - 1 + 2 (clu 0 & 1) */ -#define FAT16_THRESHOLD 65527 /* 2^16 - 1 + 2 */ -#define FAT32_THRESHOLD 268435457 /* 2^28 - 1 + 2 */ -#define EXFAT_THRESHOLD 268435457 /* 2^28 - 1 + 2 */ - -/* file types */ -#define TYPE_UNUSED 0x0000 -#define TYPE_DELETED 0x0001 -#define TYPE_INVALID 0x0002 -#define TYPE_CRITICAL_PRI 0x0100 -#define TYPE_BITMAP 0x0101 -#define TYPE_UPCASE 0x0102 -#define TYPE_VOLUME 0x0103 -#define TYPE_DIR 0x0104 -#define TYPE_FILE 0x011F -#define TYPE_CRITICAL_SEC 0x0200 -#define TYPE_STREAM 0x0201 -#define TYPE_EXTEND 0x0202 -#define TYPE_ACL 0x0203 -#define TYPE_BENIGN_PRI 0x0400 -#define TYPE_GUID 0x0401 -#define TYPE_PADDING 0x0402 -#define TYPE_ACLTAB 0x0403 -#define TYPE_BENIGN_SEC 0x0800 -#define TYPE_ALL 0x0FFF - -/* time modes */ -#define TM_CREATE 0 -#define TM_MODIFY 1 -#define TM_ACCESS 2 - -/* checksum types */ -#define CS_DIR_ENTRY 0 -#define CS_PBR_SECTOR 1 -#define CS_DEFAULT 2 - -#define CLUSTER_16(x) ((u16)(x)) -#define CLUSTER_32(x) ((u32)(x)) - -#define START_SECTOR(x) \ - ((((sector_t)((x) - 2)) << p_fs->sectors_per_clu_bits) + \ - p_fs->data_start_sector) - -#define IS_LAST_SECTOR_IN_CLUSTER(sec) \ - ((((sec) - p_fs->data_start_sector + 1) & \ - ((1 << p_fs->sectors_per_clu_bits) - 1)) == 0) - -#define GET_CLUSTER_FROM_SECTOR(sec) \ - ((u32)((((sec) - p_fs->data_start_sector) >> \ - p_fs->sectors_per_clu_bits) + 2)) - -#define GET16(p_src) \ - (((u16)(p_src)[0]) | (((u16)(p_src)[1]) << 8)) -#define GET32(p_src) \ - (((u32)(p_src)[0]) | (((u32)(p_src)[1]) << 8) | \ - (((u32)(p_src)[2]) << 16) | (((u32)(p_src)[3]) << 24)) -#define GET64(p_src) \ - (((u64)(p_src)[0]) | (((u64)(p_src)[1]) << 8) | \ - (((u64)(p_src)[2]) << 16) | (((u64)(p_src)[3]) << 24) | \ - (((u64)(p_src)[4]) << 32) | (((u64)(p_src)[5]) << 40) | \ - (((u64)(p_src)[6]) << 48) | (((u64)(p_src)[7]) << 56)) - -#define SET16(p_dst, src) \ - do { \ - (p_dst)[0] = (u8)(src); \ - (p_dst)[1] = (u8)(((u16)(src)) >> 8); \ - } while (0) -#define SET32(p_dst, src) \ - do { \ - (p_dst)[0] = (u8)(src); \ - (p_dst)[1] = (u8)(((u32)(src)) >> 8); \ - (p_dst)[2] = (u8)(((u32)(src)) >> 16); \ - (p_dst)[3] = (u8)(((u32)(src)) >> 24); \ - } while (0) -#define SET64(p_dst, src) \ - do { \ - (p_dst)[0] = (u8)(src); \ - (p_dst)[1] = (u8)(((u64)(src)) >> 8); \ - (p_dst)[2] = (u8)(((u64)(src)) >> 16); \ - (p_dst)[3] = (u8)(((u64)(src)) >> 24); \ - (p_dst)[4] = (u8)(((u64)(src)) >> 32); \ - (p_dst)[5] = (u8)(((u64)(src)) >> 40); \ - (p_dst)[6] = (u8)(((u64)(src)) >> 48); \ - (p_dst)[7] = (u8)(((u64)(src)) >> 56); \ - } while (0) - -#ifdef __LITTLE_ENDIAN -#define GET16_A(p_src) (*((u16 *)(p_src))) -#define GET32_A(p_src) (*((u32 *)(p_src))) -#define GET64_A(p_src) (*((u64 *)(p_src))) -#define SET16_A(p_dst, src) (*((u16 *)(p_dst)) = (u16)(src)) -#define SET32_A(p_dst, src) (*((u32 *)(p_dst)) = (u32)(src)) -#define SET64_A(p_dst, src) (*((u64 *)(p_dst)) = (u64)(src)) -#else /* BIG_ENDIAN */ -#define GET16_A(p_src) GET16(p_src) -#define GET32_A(p_src) GET32(p_src) -#define GET64_A(p_src) GET64(p_src) -#define SET16_A(p_dst, src) SET16(p_dst, src) -#define SET32_A(p_dst, src) SET32(p_dst, src) -#define SET64_A(p_dst, src) SET64(p_dst, src) -#endif - -/* cache size (in number of sectors) */ -/* (should be an exponential value of 2) */ -#define FAT_CACHE_SIZE 128 -#define FAT_CACHE_HASH_SIZE 64 -#define BUF_CACHE_SIZE 256 -#define BUF_CACHE_HASH_SIZE 64 - -/* Upcase table macro */ -#define HIGH_INDEX_BIT (8) -#define HIGH_INDEX_MASK (0xFF00) -#define LOW_INDEX_BIT (16 - HIGH_INDEX_BIT) -#define UTBL_ROW_COUNT BIT(LOW_INDEX_BIT) -#define UTBL_COL_COUNT BIT(HIGH_INDEX_BIT) - -static inline u16 get_col_index(u16 i) -{ - return i >> LOW_INDEX_BIT; -} - -static inline u16 get_row_index(u16 i) -{ - return i & ~HIGH_INDEX_MASK; -} - -#define EXFAT_SUPER_MAGIC (0x2011BAB0L) -#define EXFAT_ROOT_INO 1 - -/* FAT types */ -#define FAT12 0x01 /* FAT12 */ -#define FAT16 0x0E /* Win95 FAT16 (LBA) */ -#define FAT32 0x0C /* Win95 FAT32 (LBA) */ -#define EXFAT 0x07 /* exFAT */ - -/* file name lengths */ -#define MAX_CHARSET_SIZE 3 /* max size of multi-byte character */ -#define MAX_PATH_DEPTH 15 /* max depth of path name */ -#define MAX_NAME_LENGTH 256 /* max len of filename including NULL */ -#define MAX_PATH_LENGTH 260 /* max len of pathname including NULL */ - -/* file attributes */ -#define ATTR_NORMAL 0x0000 -#define ATTR_READONLY 0x0001 -#define ATTR_HIDDEN 0x0002 -#define ATTR_SYSTEM 0x0004 -#define ATTR_VOLUME 0x0008 -#define ATTR_SUBDIR 0x0010 -#define ATTR_ARCHIVE 0x0020 -#define ATTR_EXTEND 0x000F -#define ATTR_RWMASK 0x007E - -#define NUM_UPCASE 2918 - -#ifdef __LITTLE_ENDIAN -#define UNI_CUR_DIR_NAME ".\0" -#define UNI_PAR_DIR_NAME ".\0.\0" -#else -#define UNI_CUR_DIR_NAME "\0." -#define UNI_PAR_DIR_NAME "\0.\0." -#endif - -struct date_time_t { - u16 year; - u16 month; - u16 day; - u16 hour; - u16 minute; - u16 second; - u16 millisecond; -}; - -struct vol_info_t { - u32 FatType; - u32 ClusterSize; - u32 NumClusters; - u32 FreeClusters; - u32 UsedClusters; -}; - -/* directory structure */ -struct chain_t { - u32 dir; - s32 size; - u8 flags; -}; - -struct file_id_t { - struct chain_t dir; - s32 entry; - u32 type; - u32 attr; - u32 start_clu; - u64 size; - u8 flags; - s64 rwoffset; - s32 hint_last_off; - u32 hint_last_clu; -}; - -struct dir_entry_t { - char name[MAX_NAME_LENGTH * MAX_CHARSET_SIZE]; - u32 attr; - u64 Size; - u32 num_subdirs; - struct date_time_t create_timestamp; - struct date_time_t modify_timestamp; - struct date_time_t access_timestamp; -}; - -struct timestamp_t { - u16 sec; /* 0 ~ 59 */ - u16 min; /* 0 ~ 59 */ - u16 hour; /* 0 ~ 23 */ - u16 day; /* 1 ~ 31 */ - u16 mon; /* 1 ~ 12 */ - u16 year; /* 0 ~ 127 (since 1980) */ -}; - -/* MS_DOS FAT partition boot record (512 bytes) */ -struct pbr_sector_t { - u8 jmp_boot[3]; - u8 oem_name[8]; - u8 bpb[109]; - u8 boot_code[390]; - u8 signature[2]; -}; - -/* MS-DOS FAT12/16 BIOS parameter block (51 bytes) */ -struct bpb16_t { - u8 sector_size[2]; - u8 sectors_per_clu; - u8 num_reserved[2]; - u8 num_fats; - u8 num_root_entries[2]; - u8 num_sectors[2]; - u8 media_type; - u8 num_fat_sectors[2]; - u8 sectors_in_track[2]; - u8 num_heads[2]; - u8 num_hid_sectors[4]; - u8 num_huge_sectors[4]; - - u8 phy_drv_no; - u8 reserved; - u8 ext_signature; - u8 vol_serial[4]; - u8 vol_label[11]; - u8 vol_type[8]; -}; - -/* MS-DOS FAT32 BIOS parameter block (79 bytes) */ -struct bpb32_t { - u8 sector_size[2]; - u8 sectors_per_clu; - u8 num_reserved[2]; - u8 num_fats; - u8 num_root_entries[2]; - u8 num_sectors[2]; - u8 media_type; - u8 num_fat_sectors[2]; - u8 sectors_in_track[2]; - u8 num_heads[2]; - u8 num_hid_sectors[4]; - u8 num_huge_sectors[4]; - u8 num_fat32_sectors[4]; - u8 ext_flags[2]; - u8 fs_version[2]; - u8 root_cluster[4]; - u8 fsinfo_sector[2]; - u8 backup_sector[2]; - u8 reserved[12]; - - u8 phy_drv_no; - u8 ext_reserved; - u8 ext_signature; - u8 vol_serial[4]; - u8 vol_label[11]; - u8 vol_type[8]; -}; - -/* MS-DOS EXFAT BIOS parameter block (109 bytes) */ -struct bpbex_t { - u8 reserved1[53]; - u8 vol_offset[8]; - u8 vol_length[8]; - u8 fat_offset[4]; - u8 fat_length[4]; - u8 clu_offset[4]; - u8 clu_count[4]; - u8 root_cluster[4]; - u8 vol_serial[4]; - u8 fs_version[2]; - u8 vol_flags[2]; - u8 sector_size_bits; - u8 sectors_per_clu_bits; - u8 num_fats; - u8 phy_drv_no; - u8 perc_in_use; - u8 reserved2[7]; -}; - -/* MS-DOS FAT file system information sector (512 bytes) */ -struct fsi_sector_t { - u8 signature1[4]; - u8 reserved1[480]; - u8 signature2[4]; - u8 free_cluster[4]; - u8 next_cluster[4]; - u8 reserved2[14]; - u8 signature3[2]; -}; - -/* MS-DOS FAT directory entry (32 bytes) */ -struct dentry_t { - u8 dummy[32]; -}; - -/* MS-DOS EXFAT file directory entry (32 bytes) */ -struct file_dentry_t { - u8 type; - u8 num_ext; - u8 checksum[2]; - u8 attr[2]; - u8 reserved1[2]; - u8 create_time[2]; - u8 create_date[2]; - u8 modify_time[2]; - u8 modify_date[2]; - u8 access_time[2]; - u8 access_date[2]; - u8 create_time_ms; - u8 modify_time_ms; - u8 access_time_ms; - u8 reserved2[9]; -}; - -/* MS-DOS EXFAT stream extension directory entry (32 bytes) */ -struct strm_dentry_t { - u8 type; - u8 flags; - u8 reserved1; - u8 name_len; - u8 name_hash[2]; - u8 reserved2[2]; - u8 valid_size[8]; - u8 reserved3[4]; - u8 start_clu[4]; - u8 size[8]; -}; - -/* MS-DOS EXFAT file name directory entry (32 bytes) */ -struct name_dentry_t { - u8 type; - u8 flags; - u8 unicode_0_14[30]; -}; - -/* MS-DOS EXFAT allocation bitmap directory entry (32 bytes) */ -struct bmap_dentry_t { - u8 type; - u8 flags; - u8 reserved[18]; - u8 start_clu[4]; - u8 size[8]; -}; - -/* MS-DOS EXFAT up-case table directory entry (32 bytes) */ -struct case_dentry_t { - u8 type; - u8 reserved1[3]; - u8 checksum[4]; - u8 reserved2[12]; - u8 start_clu[4]; - u8 size[8]; -}; - -/* MS-DOS EXFAT volume label directory entry (32 bytes) */ -struct volm_dentry_t { - u8 type; - u8 label_len; - u8 unicode_0_10[22]; - u8 reserved[8]; -}; - -/* unused entry hint information */ -struct uentry_t { - u32 dir; - s32 entry; - struct chain_t clu; -}; - -/* unicode name structure */ -struct uni_name_t { - u16 name[MAX_NAME_LENGTH]; - u16 name_hash; - u8 name_len; -}; - -struct buf_cache_t { - struct buf_cache_t *next; - struct buf_cache_t *prev; - struct buf_cache_t *hash_next; - struct buf_cache_t *hash_prev; - s32 drv; - sector_t sec; - bool locked; - struct buffer_head *buf_bh; -}; - -struct fs_info_t { - u32 drv; /* drive ID */ - u32 vol_id; /* volume serial number */ - - u64 num_sectors; /* num of sectors in volume */ - u32 num_clusters; /* num of clusters in volume */ - u32 cluster_size; /* cluster size in bytes */ - u32 cluster_size_bits; - u32 sectors_per_clu; /* cluster size in sectors */ - u32 sectors_per_clu_bits; - - u32 PBR_sector; /* PBR sector */ - u32 FAT1_start_sector; /* FAT1 start sector */ - u32 FAT2_start_sector; /* FAT2 start sector */ - u32 root_start_sector; /* root dir start sector */ - u32 data_start_sector; /* data area start sector */ - u32 num_FAT_sectors; /* num of FAT sectors */ - - u32 root_dir; /* root dir cluster */ - u32 dentries_in_root; /* num of dentries in root dir */ - u32 dentries_per_clu; /* num of dentries per cluster */ - - u32 vol_flag; /* volume dirty flag */ - struct buffer_head *pbr_bh; /* PBR sector */ - - u32 map_clu; /* allocation bitmap start cluster */ - u32 map_sectors; /* num of allocation bitmap sectors */ - struct buffer_head **vol_amap; /* allocation bitmap */ - - u16 **vol_utbl; /* upcase table */ - - u32 clu_srch_ptr; /* cluster search pointer */ - u32 used_clusters; /* number of used clusters */ - struct uentry_t hint_uentry; /* unused entry hint information */ - - u32 dev_ejected; /* block device operation error flag */ - - struct mutex v_mutex; - - /* FAT cache */ - struct buf_cache_t FAT_cache_array[FAT_CACHE_SIZE]; - struct buf_cache_t FAT_cache_lru_list; - struct buf_cache_t FAT_cache_hash_list[FAT_CACHE_HASH_SIZE]; - - /* buf cache */ - struct buf_cache_t buf_cache_array[BUF_CACHE_SIZE]; - struct buf_cache_t buf_cache_lru_list; - struct buf_cache_t buf_cache_hash_list[BUF_CACHE_HASH_SIZE]; -}; - -#define ES_2_ENTRIES 2 -#define ES_3_ENTRIES 3 -#define ES_ALL_ENTRIES 0 - -struct entry_set_cache_t { - /* sector number that contains file_entry */ - sector_t sector; - - /* byte offset in the sector */ - s32 offset; - - /* - * flag in stream entry. - * 01 for cluster chain, - * 03 for contig. clusteres. - */ - s32 alloc_flag; - - u32 num_entries; - - /* __buf should be the last member */ - void *__buf; -}; - -#define EXFAT_ERRORS_CONT 1 /* ignore error and continue */ -#define EXFAT_ERRORS_PANIC 2 /* panic on error */ -#define EXFAT_ERRORS_RO 3 /* remount r/o on error */ - -/* ioctl command */ -#define EXFAT_IOCTL_GET_VOLUME_ID _IOR('r', 0x12, __u32) - -struct exfat_mount_options { - kuid_t fs_uid; - kgid_t fs_gid; - unsigned short fs_fmask; - unsigned short fs_dmask; - - /* permission for setting the [am]time */ - unsigned short allow_utime; - - /* codepage for shortname conversions */ - unsigned short codepage; - - /* charset for filename input/display */ - char *iocharset; - - unsigned char casesensitive; - - /* on error: continue, panic, remount-ro */ - unsigned char errors; -#ifdef CONFIG_STAGING_EXFAT_DISCARD - /* flag on if -o dicard specified and device support discard() */ - unsigned char discard; -#endif /* CONFIG_STAGING_EXFAT_DISCARD */ -}; - -#define EXFAT_HASH_BITS 8 -#define EXFAT_HASH_SIZE BIT(EXFAT_HASH_BITS) - -/* - * EXFAT file system in-core superblock data - */ -struct bd_info_t { - s32 sector_size; /* in bytes */ - s32 sector_size_bits; - s32 sector_size_mask; - - /* total number of sectors in this block device */ - s32 num_sectors; - - /* opened or not */ - bool opened; -}; - -struct exfat_sb_info { - struct fs_info_t fs_info; - struct bd_info_t bd_info; - - struct exfat_mount_options options; - - int s_dirt; - struct mutex s_lock; - struct nls_table *nls_disk; /* Codepage used on disk */ - struct nls_table *nls_io; /* Charset used for input and display */ - - struct inode *fat_inode; - - spinlock_t inode_hash_lock; - struct hlist_head inode_hashtable[EXFAT_HASH_SIZE]; -#ifdef CONFIG_STAGING_EXFAT_KERNEL_DEBUG - long debug_flags; -#endif /* CONFIG_STAGING_EXFAT_KERNEL_DEBUG */ -}; - -/* - * EXFAT file system inode data in memory - */ -struct exfat_inode_info { - struct file_id_t fid; - char *target; - /* NOTE: mmu_private is 64bits, so must hold ->i_mutex to access */ - loff_t mmu_private; /* physically allocated size */ - loff_t i_pos; /* on-disk position of directory entry or 0 */ - struct hlist_node i_hash_fat; /* hash by i_location */ - struct rw_semaphore truncate_lock; - struct inode vfs_inode; - struct rw_semaphore i_alloc_sem; /* protect bmap against truncate */ -}; - -#define EXFAT_SB(sb) ((struct exfat_sb_info *)((sb)->s_fs_info)) - -static inline struct exfat_inode_info *EXFAT_I(struct inode *inode) -{ - return container_of(inode, struct exfat_inode_info, vfs_inode); -} - -/* NLS management function */ -u16 nls_upper(struct super_block *sb, u16 a); -int nls_uniname_cmp(struct super_block *sb, u16 *a, u16 *b); -void nls_uniname_to_cstring(struct super_block *sb, u8 *p_cstring, - struct uni_name_t *p_uniname); -void nls_cstring_to_uniname(struct super_block *sb, - struct uni_name_t *p_uniname, u8 *p_cstring, - bool *p_lossy); - -/* buffer cache management */ -void exfat_buf_init(struct super_block *sb); -void exfat_buf_shutdown(struct super_block *sb); -int exfat_fat_read(struct super_block *sb, u32 loc, u32 *content); -s32 exfat_fat_write(struct super_block *sb, u32 loc, u32 content); -u8 *exfat_fat_getblk(struct super_block *sb, sector_t sec); -void exfat_fat_modify(struct super_block *sb, sector_t sec); -void exfat_fat_release_all(struct super_block *sb); -u8 *exfat_buf_getblk(struct super_block *sb, sector_t sec); -void exfat_buf_modify(struct super_block *sb, sector_t sec); -void exfat_buf_lock(struct super_block *sb, sector_t sec); -void exfat_buf_unlock(struct super_block *sb, sector_t sec); -void exfat_buf_release(struct super_block *sb, sector_t sec); -void exfat_buf_release_all(struct super_block *sb); - -/* fs management functions */ -void fs_set_vol_flags(struct super_block *sb, u32 new_flag); -void fs_error(struct super_block *sb); - -/* cluster management functions */ -s32 count_num_clusters(struct super_block *sb, struct chain_t *dir); -void exfat_chain_cont_cluster(struct super_block *sb, u32 chain, s32 len); - -/* allocation bitmap management functions */ -s32 load_alloc_bitmap(struct super_block *sb); -void free_alloc_bitmap(struct super_block *sb); - -/* upcase table management functions */ -s32 load_upcase_table(struct super_block *sb); -void free_upcase_table(struct super_block *sb); - -/* dir entry management functions */ -struct timestamp_t *tm_current(struct timestamp_t *tm); - -struct dentry_t *get_entry_in_dir(struct super_block *sb, struct chain_t *p_dir, - s32 entry, sector_t *sector); -struct entry_set_cache_t *get_entry_set_in_dir(struct super_block *sb, - struct chain_t *p_dir, s32 entry, - u32 type, - struct dentry_t **file_ep); -void release_entry_set(struct entry_set_cache_t *es); -s32 count_dir_entries(struct super_block *sb, struct chain_t *p_dir); -void update_dir_checksum(struct super_block *sb, struct chain_t *p_dir, - s32 entry); -void update_dir_checksum_with_entry_set(struct super_block *sb, - struct entry_set_cache_t *es); -bool is_dir_empty(struct super_block *sb, struct chain_t *p_dir); - -/* name conversion functions */ -s32 get_num_entries(struct super_block *sb, struct chain_t *p_dir, - struct uni_name_t *p_uniname, s32 *entries); -u16 calc_checksum_2byte(void *data, s32 len, u16 chksum, s32 type); - -/* name resolution functions */ -s32 resolve_path(struct inode *inode, char *path, struct chain_t *p_dir, - struct uni_name_t *p_uniname); - -/* file operation functions */ -s32 exfat_mount(struct super_block *sb, struct pbr_sector_t *p_pbr); -s32 create_dir(struct inode *inode, struct chain_t *p_dir, - struct uni_name_t *p_uniname, struct file_id_t *fid); -s32 create_file(struct inode *inode, struct chain_t *p_dir, - struct uni_name_t *p_uniname, struct file_id_t *fid); -void remove_file(struct inode *inode, struct chain_t *p_dir, s32 entry); -s32 exfat_rename_file(struct inode *inode, struct chain_t *p_dir, s32 old_entry, - struct uni_name_t *p_uniname, struct file_id_t *fid); -s32 move_file(struct inode *inode, struct chain_t *p_olddir, s32 oldentry, - struct chain_t *p_newdir, struct uni_name_t *p_uniname, - struct file_id_t *fid); - -/* sector read/write functions */ -int sector_read(struct super_block *sb, sector_t sec, - struct buffer_head **bh, bool read); -int sector_write(struct super_block *sb, sector_t sec, - struct buffer_head *bh, bool sync); -int multi_sector_read(struct super_block *sb, sector_t sec, - struct buffer_head **bh, s32 num_secs, bool read); -int multi_sector_write(struct super_block *sb, sector_t sec, - struct buffer_head *bh, s32 num_secs, bool sync); - -void exfat_bdev_open(struct super_block *sb); -void exfat_bdev_close(struct super_block *sb); -int exfat_bdev_read(struct super_block *sb, sector_t secno, - struct buffer_head **bh, u32 num_secs, bool read); -int exfat_bdev_write(struct super_block *sb, sector_t secno, - struct buffer_head *bh, u32 num_secs, bool sync); -int exfat_bdev_sync(struct super_block *sb); - -/* cluster operation functions */ -s32 exfat_alloc_cluster(struct super_block *sb, s32 num_alloc, - struct chain_t *p_chain); -void exfat_free_cluster(struct super_block *sb, struct chain_t *p_chain, - s32 do_relse); -s32 exfat_count_used_clusters(struct super_block *sb); - -/* dir operation functions */ -s32 exfat_find_dir_entry(struct super_block *sb, struct chain_t *p_dir, - struct uni_name_t *p_uniname, s32 num_entries, - u32 type); -void exfat_delete_dir_entry(struct super_block *sb, struct chain_t *p_dir, - s32 entry, s32 order, s32 num_entries); -void exfat_get_uni_name_from_ext_entry(struct super_block *sb, - struct chain_t *p_dir, s32 entry, - u16 *uniname); -s32 exfat_count_ext_entries(struct super_block *sb, struct chain_t *p_dir, - s32 entry, struct dentry_t *p_entry); -s32 exfat_calc_num_entries(struct uni_name_t *p_uniname); - -/* dir entry getter/setter */ -u32 exfat_get_entry_type(struct dentry_t *p_entry); -u32 exfat_get_entry_attr(struct dentry_t *p_entry); -void exfat_set_entry_attr(struct dentry_t *p_entry, u32 attr); -u8 exfat_get_entry_flag(struct dentry_t *p_entry); -void exfat_set_entry_flag(struct dentry_t *p_entry, u8 flags); -u32 exfat_get_entry_clu0(struct dentry_t *p_entry); -void exfat_set_entry_clu0(struct dentry_t *p_entry, u32 start_clu); -u64 exfat_get_entry_size(struct dentry_t *p_entry); -void exfat_set_entry_size(struct dentry_t *p_entry, u64 size); -void exfat_get_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp, - u8 mode); -void exfat_set_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp, - u8 mode); - -extern const u8 uni_upcase[]; -#endif /* _EXFAT_H */ diff --git a/drivers/staging/exfat/exfat_blkdev.c b/drivers/staging/exfat/exfat_blkdev.c deleted file mode 100644 index ddff019f2803..000000000000 --- a/drivers/staging/exfat/exfat_blkdev.c +++ /dev/null @@ -1,138 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. - */ - -#include -#include -#include -#include "exfat.h" - -void exfat_bdev_open(struct super_block *sb) -{ - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - - if (p_bd->opened) - return; - - p_bd->sector_size = bdev_logical_block_size(sb->s_bdev); - p_bd->sector_size_bits = ilog2(p_bd->sector_size); - p_bd->sector_size_mask = p_bd->sector_size - 1; - p_bd->num_sectors = i_size_read(sb->s_bdev->bd_inode) >> - p_bd->sector_size_bits; - p_bd->opened = true; -} - -void exfat_bdev_close(struct super_block *sb) -{ - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - - p_bd->opened = false; -} - -int exfat_bdev_read(struct super_block *sb, sector_t secno, - struct buffer_head **bh, u32 num_secs, - bool read) -{ - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); -#ifdef CONFIG_STAGING_EXFAT_KERNEL_DEBUG - struct exfat_sb_info *sbi = EXFAT_SB(sb); - long flags = sbi->debug_flags; - - if (flags & EXFAT_DEBUGFLAGS_ERROR_RW) - return -EIO; -#endif /* CONFIG_STAGING_EXFAT_KERNEL_DEBUG */ - - if (!p_bd->opened) - return -ENODEV; - - if (*bh) - __brelse(*bh); - - if (read) - *bh = __bread(sb->s_bdev, secno, - num_secs << p_bd->sector_size_bits); - else - *bh = __getblk(sb->s_bdev, secno, - num_secs << p_bd->sector_size_bits); - - if (*bh) - return 0; - - WARN(!p_fs->dev_ejected, - "[EXFAT] No bh, device seems wrong or to be ejected.\n"); - - return -EIO; -} - -int exfat_bdev_write(struct super_block *sb, sector_t secno, - struct buffer_head *bh, - u32 num_secs, bool sync) -{ - s32 count; - struct buffer_head *bh2; - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); -#ifdef CONFIG_STAGING_EXFAT_KERNEL_DEBUG - struct exfat_sb_info *sbi = EXFAT_SB(sb); - long flags = sbi->debug_flags; - - if (flags & EXFAT_DEBUGFLAGS_ERROR_RW) - return -EIO; -#endif /* CONFIG_STAGING_EXFAT_KERNEL_DEBUG */ - - if (!p_bd->opened) - return -ENODEV; - - if (secno == bh->b_blocknr) { - lock_buffer(bh); - set_buffer_uptodate(bh); - mark_buffer_dirty(bh); - unlock_buffer(bh); - if (sync && (sync_dirty_buffer(bh) != 0)) - return -EIO; - } else { - count = num_secs << p_bd->sector_size_bits; - - bh2 = __getblk(sb->s_bdev, secno, count); - if (!bh2) - goto no_bh; - - lock_buffer(bh2); - memcpy(bh2->b_data, bh->b_data, count); - set_buffer_uptodate(bh2); - mark_buffer_dirty(bh2); - unlock_buffer(bh2); - if (sync && (sync_dirty_buffer(bh2) != 0)) { - __brelse(bh2); - goto no_bh; - } - __brelse(bh2); - } - - return 0; - -no_bh: - WARN(!p_fs->dev_ejected, - "[EXFAT] No bh, device seems wrong or to be ejected.\n"); - - return -EIO; -} - -int exfat_bdev_sync(struct super_block *sb) -{ - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); -#ifdef CONFIG_STAGING_EXFAT_KERNEL_DEBUG - struct exfat_sb_info *sbi = EXFAT_SB(sb); - long flags = sbi->debug_flags; - - if (flags & EXFAT_DEBUGFLAGS_ERROR_RW) - return -EIO; -#endif /* CONFIG_STAGING_EXFAT_KERNEL_DEBUG */ - - if (!p_bd->opened) - return -ENODEV; - - return sync_blockdev(sb->s_bdev); -} diff --git a/drivers/staging/exfat/exfat_cache.c b/drivers/staging/exfat/exfat_cache.c deleted file mode 100644 index b15203d4e0ae..000000000000 --- a/drivers/staging/exfat/exfat_cache.c +++ /dev/null @@ -1,514 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. - */ - -#include -#include -#include -#include "exfat.h" - -/* Local variables */ -static DEFINE_MUTEX(f_mutex); -static DEFINE_MUTEX(b_mutex); - -static struct buf_cache_t *FAT_cache_find(struct super_block *sb, sector_t sec) -{ - s32 off; - struct buf_cache_t *bp, *hp; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - off = (sec + - (sec >> p_fs->sectors_per_clu_bits)) & (FAT_CACHE_HASH_SIZE - 1); - - hp = &p_fs->FAT_cache_hash_list[off]; - for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) { - if ((bp->drv == p_fs->drv) && (bp->sec == sec)) { - WARN(!bp->buf_bh, - "[EXFAT] FAT_cache has no bh. It will make system panic.\n"); - - touch_buffer(bp->buf_bh); - return bp; - } - } - return NULL; -} - -static void push_to_mru(struct buf_cache_t *bp, struct buf_cache_t *list) -{ - bp->next = list->next; - bp->prev = list; - list->next->prev = bp; - list->next = bp; -} - -static void push_to_lru(struct buf_cache_t *bp, struct buf_cache_t *list) -{ - bp->prev = list->prev; - bp->next = list; - list->prev->next = bp; - list->prev = bp; -} - -static void move_to_mru(struct buf_cache_t *bp, struct buf_cache_t *list) -{ - bp->prev->next = bp->next; - bp->next->prev = bp->prev; - push_to_mru(bp, list); -} - -static void move_to_lru(struct buf_cache_t *bp, struct buf_cache_t *list) -{ - bp->prev->next = bp->next; - bp->next->prev = bp->prev; - push_to_lru(bp, list); -} - -static struct buf_cache_t *FAT_cache_get(struct super_block *sb, sector_t sec) -{ - struct buf_cache_t *bp; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - bp = p_fs->FAT_cache_lru_list.prev; - - move_to_mru(bp, &p_fs->FAT_cache_lru_list); - return bp; -} - -static void FAT_cache_insert_hash(struct super_block *sb, - struct buf_cache_t *bp) -{ - s32 off; - struct buf_cache_t *hp; - struct fs_info_t *p_fs; - - p_fs = &(EXFAT_SB(sb)->fs_info); - off = (bp->sec + - (bp->sec >> p_fs->sectors_per_clu_bits)) & - (FAT_CACHE_HASH_SIZE - 1); - - hp = &p_fs->FAT_cache_hash_list[off]; - bp->hash_next = hp->hash_next; - bp->hash_prev = hp; - hp->hash_next->hash_prev = bp; - hp->hash_next = bp; -} - -static void FAT_cache_remove_hash(struct buf_cache_t *bp) -{ - (bp->hash_prev)->hash_next = bp->hash_next; - (bp->hash_next)->hash_prev = bp->hash_prev; -} - -static void buf_cache_insert_hash(struct super_block *sb, - struct buf_cache_t *bp) -{ - s32 off; - struct buf_cache_t *hp; - struct fs_info_t *p_fs; - - p_fs = &(EXFAT_SB(sb)->fs_info); - off = (bp->sec + - (bp->sec >> p_fs->sectors_per_clu_bits)) & - (BUF_CACHE_HASH_SIZE - 1); - - hp = &p_fs->buf_cache_hash_list[off]; - bp->hash_next = hp->hash_next; - bp->hash_prev = hp; - hp->hash_next->hash_prev = bp; - hp->hash_next = bp; -} - -static void buf_cache_remove_hash(struct buf_cache_t *bp) -{ - (bp->hash_prev)->hash_next = bp->hash_next; - (bp->hash_next)->hash_prev = bp->hash_prev; -} - -void exfat_buf_init(struct super_block *sb) -{ - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - int i; - - /* LRU list */ - p_fs->FAT_cache_lru_list.next = &p_fs->FAT_cache_lru_list; - p_fs->FAT_cache_lru_list.prev = &p_fs->FAT_cache_lru_list; - - for (i = 0; i < FAT_CACHE_SIZE; i++) { - p_fs->FAT_cache_array[i].drv = -1; - p_fs->FAT_cache_array[i].sec = ~0; - p_fs->FAT_cache_array[i].locked = false; - p_fs->FAT_cache_array[i].buf_bh = NULL; - p_fs->FAT_cache_array[i].prev = NULL; - p_fs->FAT_cache_array[i].next = NULL; - push_to_mru(&p_fs->FAT_cache_array[i], - &p_fs->FAT_cache_lru_list); - } - - p_fs->buf_cache_lru_list.next = &p_fs->buf_cache_lru_list; - p_fs->buf_cache_lru_list.prev = &p_fs->buf_cache_lru_list; - - for (i = 0; i < BUF_CACHE_SIZE; i++) { - p_fs->buf_cache_array[i].drv = -1; - p_fs->buf_cache_array[i].sec = ~0; - p_fs->buf_cache_array[i].locked = false; - p_fs->buf_cache_array[i].buf_bh = NULL; - p_fs->buf_cache_array[i].prev = NULL; - p_fs->buf_cache_array[i].next = NULL; - push_to_mru(&p_fs->buf_cache_array[i], - &p_fs->buf_cache_lru_list); - } - - /* HASH list */ - for (i = 0; i < FAT_CACHE_HASH_SIZE; i++) { - p_fs->FAT_cache_hash_list[i].drv = -1; - p_fs->FAT_cache_hash_list[i].sec = ~0; - p_fs->FAT_cache_hash_list[i].hash_next = - &p_fs->FAT_cache_hash_list[i]; - p_fs->FAT_cache_hash_list[i].hash_prev = - &p_fs->FAT_cache_hash_list[i]; - } - - for (i = 0; i < FAT_CACHE_SIZE; i++) - FAT_cache_insert_hash(sb, &p_fs->FAT_cache_array[i]); - - for (i = 0; i < BUF_CACHE_HASH_SIZE; i++) { - p_fs->buf_cache_hash_list[i].drv = -1; - p_fs->buf_cache_hash_list[i].sec = ~0; - p_fs->buf_cache_hash_list[i].hash_next = - &p_fs->buf_cache_hash_list[i]; - p_fs->buf_cache_hash_list[i].hash_prev = - &p_fs->buf_cache_hash_list[i]; - } - - for (i = 0; i < BUF_CACHE_SIZE; i++) - buf_cache_insert_hash(sb, &p_fs->buf_cache_array[i]); -} - -void exfat_buf_shutdown(struct super_block *sb) -{ -} - -static int __exfat_fat_read(struct super_block *sb, u32 loc, u32 *content) -{ - s32 off; - u32 _content; - sector_t sec; - u8 *fat_sector, *fat_entry; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - - sec = p_fs->FAT1_start_sector + - (loc >> (p_bd->sector_size_bits - 2)); - off = (loc << 2) & p_bd->sector_size_mask; - - fat_sector = exfat_fat_getblk(sb, sec); - if (!fat_sector) - return -1; - - fat_entry = &fat_sector[off]; - _content = GET32_A(fat_entry); - - if (_content >= CLUSTER_32(0xFFFFFFF8)) { - *content = CLUSTER_32(~0); - return 0; - } - *content = CLUSTER_32(_content); - return 0; -} - -/* in : sb, loc - * out: content - * returns 0 on success - * -1 on error - */ -int exfat_fat_read(struct super_block *sb, u32 loc, u32 *content) -{ - s32 ret; - - mutex_lock(&f_mutex); - ret = __exfat_fat_read(sb, loc, content); - mutex_unlock(&f_mutex); - - return ret; -} - -static s32 __exfat_fat_write(struct super_block *sb, u32 loc, u32 content) -{ - s32 off; - sector_t sec; - u8 *fat_sector, *fat_entry; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - - sec = p_fs->FAT1_start_sector + (loc >> - (p_bd->sector_size_bits - 2)); - off = (loc << 2) & p_bd->sector_size_mask; - - fat_sector = exfat_fat_getblk(sb, sec); - if (!fat_sector) - return -1; - - fat_entry = &fat_sector[off]; - - SET32_A(fat_entry, content); - - exfat_fat_modify(sb, sec); - return 0; -} - -int exfat_fat_write(struct super_block *sb, u32 loc, u32 content) -{ - s32 ret; - - mutex_lock(&f_mutex); - ret = __exfat_fat_write(sb, loc, content); - mutex_unlock(&f_mutex); - - return ret; -} - -u8 *exfat_fat_getblk(struct super_block *sb, sector_t sec) -{ - struct buf_cache_t *bp; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - bp = FAT_cache_find(sb, sec); - if (bp) { - move_to_mru(bp, &p_fs->FAT_cache_lru_list); - return bp->buf_bh->b_data; - } - - bp = FAT_cache_get(sb, sec); - - FAT_cache_remove_hash(bp); - - bp->drv = p_fs->drv; - bp->sec = sec; - bp->locked = false; - - FAT_cache_insert_hash(sb, bp); - - if (sector_read(sb, sec, &bp->buf_bh, 1) != 0) { - FAT_cache_remove_hash(bp); - bp->drv = -1; - bp->sec = ~0; - bp->locked = false; - bp->buf_bh = NULL; - - move_to_lru(bp, &p_fs->FAT_cache_lru_list); - return NULL; - } - - return bp->buf_bh->b_data; -} - -void exfat_fat_modify(struct super_block *sb, sector_t sec) -{ - struct buf_cache_t *bp; - - bp = FAT_cache_find(sb, sec); - if (bp) - sector_write(sb, sec, bp->buf_bh, 0); -} - -void exfat_fat_release_all(struct super_block *sb) -{ - struct buf_cache_t *bp; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - mutex_lock(&f_mutex); - - bp = p_fs->FAT_cache_lru_list.next; - while (bp != &p_fs->FAT_cache_lru_list) { - if (bp->drv == p_fs->drv) { - bp->drv = -1; - bp->sec = ~0; - bp->locked = false; - - if (bp->buf_bh) { - __brelse(bp->buf_bh); - bp->buf_bh = NULL; - } - } - bp = bp->next; - } - - mutex_unlock(&f_mutex); -} - -static struct buf_cache_t *buf_cache_find(struct super_block *sb, sector_t sec) -{ - s32 off; - struct buf_cache_t *bp, *hp; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - off = (sec + (sec >> p_fs->sectors_per_clu_bits)) & - (BUF_CACHE_HASH_SIZE - 1); - - hp = &p_fs->buf_cache_hash_list[off]; - for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) { - if ((bp->drv == p_fs->drv) && (bp->sec == sec)) { - touch_buffer(bp->buf_bh); - return bp; - } - } - return NULL; -} - -static struct buf_cache_t *buf_cache_get(struct super_block *sb, sector_t sec) -{ - struct buf_cache_t *bp; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - bp = p_fs->buf_cache_lru_list.prev; - while (bp->locked) - bp = bp->prev; - - move_to_mru(bp, &p_fs->buf_cache_lru_list); - return bp; -} - -static u8 *__exfat_buf_getblk(struct super_block *sb, sector_t sec) -{ - struct buf_cache_t *bp; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - bp = buf_cache_find(sb, sec); - if (bp) { - move_to_mru(bp, &p_fs->buf_cache_lru_list); - return bp->buf_bh->b_data; - } - - bp = buf_cache_get(sb, sec); - - buf_cache_remove_hash(bp); - - bp->drv = p_fs->drv; - bp->sec = sec; - bp->locked = false; - - buf_cache_insert_hash(sb, bp); - - if (sector_read(sb, sec, &bp->buf_bh, 1) != 0) { - buf_cache_remove_hash(bp); - bp->drv = -1; - bp->sec = ~0; - bp->locked = false; - bp->buf_bh = NULL; - - move_to_lru(bp, &p_fs->buf_cache_lru_list); - return NULL; - } - - return bp->buf_bh->b_data; -} - -u8 *exfat_buf_getblk(struct super_block *sb, sector_t sec) -{ - u8 *buf; - - mutex_lock(&b_mutex); - buf = __exfat_buf_getblk(sb, sec); - mutex_unlock(&b_mutex); - - return buf; -} - -void exfat_buf_modify(struct super_block *sb, sector_t sec) -{ - struct buf_cache_t *bp; - - mutex_lock(&b_mutex); - - bp = buf_cache_find(sb, sec); - if (likely(bp)) - sector_write(sb, sec, bp->buf_bh, 0); - - WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%llu).\n", - (unsigned long long)sec); - - mutex_unlock(&b_mutex); -} - -void exfat_buf_lock(struct super_block *sb, sector_t sec) -{ - struct buf_cache_t *bp; - - mutex_lock(&b_mutex); - - bp = buf_cache_find(sb, sec); - if (likely(bp)) - bp->locked = true; - - WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%llu).\n", - (unsigned long long)sec); - - mutex_unlock(&b_mutex); -} - -void exfat_buf_unlock(struct super_block *sb, sector_t sec) -{ - struct buf_cache_t *bp; - - mutex_lock(&b_mutex); - - bp = buf_cache_find(sb, sec); - if (likely(bp)) - bp->locked = false; - - WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%llu).\n", - (unsigned long long)sec); - - mutex_unlock(&b_mutex); -} - -void exfat_buf_release(struct super_block *sb, sector_t sec) -{ - struct buf_cache_t *bp; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - mutex_lock(&b_mutex); - - bp = buf_cache_find(sb, sec); - if (likely(bp)) { - bp->drv = -1; - bp->sec = ~0; - bp->locked = false; - - if (bp->buf_bh) { - __brelse(bp->buf_bh); - bp->buf_bh = NULL; - } - - move_to_lru(bp, &p_fs->buf_cache_lru_list); - } - - mutex_unlock(&b_mutex); -} - -void exfat_buf_release_all(struct super_block *sb) -{ - struct buf_cache_t *bp; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - mutex_lock(&b_mutex); - - bp = p_fs->buf_cache_lru_list.next; - while (bp != &p_fs->buf_cache_lru_list) { - if (bp->drv == p_fs->drv) { - bp->drv = -1; - bp->sec = ~0; - bp->locked = false; - - if (bp->buf_bh) { - __brelse(bp->buf_bh); - bp->buf_bh = NULL; - } - } - bp = bp->next; - } - - mutex_unlock(&b_mutex); -} diff --git a/drivers/staging/exfat/exfat_core.c b/drivers/staging/exfat/exfat_core.c deleted file mode 100644 index 374a4fe183f5..000000000000 --- a/drivers/staging/exfat/exfat_core.c +++ /dev/null @@ -1,2529 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. - */ - -#include -#include -#include -#include -#include -#include -#include "exfat.h" - -static void __set_sb_dirty(struct super_block *sb) -{ - struct exfat_sb_info *sbi = EXFAT_SB(sb); - - sbi->s_dirt = 1; -} - -static u8 name_buf[MAX_PATH_LENGTH * MAX_CHARSET_SIZE]; - -static u8 free_bit[] = { - 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, /* 0 ~ 19 */ - 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, /* 20 ~ 39 */ - 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, /* 40 ~ 59 */ - 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, /* 60 ~ 79 */ - 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, /* 80 ~ 99 */ - 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, /* 100 ~ 119 */ - 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, /* 120 ~ 139 */ - 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, /* 140 ~ 159 */ - 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, /* 160 ~ 179 */ - 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, /* 180 ~ 199 */ - 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, /* 200 ~ 219 */ - 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, /* 220 ~ 239 */ - 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 /* 240 ~ 254 */ -}; - -static u8 used_bit[] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, /* 0 ~ 19 */ - 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, /* 20 ~ 39 */ - 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, /* 40 ~ 59 */ - 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, /* 60 ~ 79 */ - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, /* 80 ~ 99 */ - 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, /* 100 ~ 119 */ - 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, /* 120 ~ 139 */ - 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, /* 140 ~ 159 */ - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, /* 160 ~ 179 */ - 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, /* 180 ~ 199 */ - 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, /* 200 ~ 219 */ - 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, /* 220 ~ 239 */ - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 /* 240 ~ 255 */ -}; - -#define BITMAP_LOC(v) ((v) >> 3) -#define BITMAP_SHIFT(v) ((v) & 0x07) - -static inline s32 exfat_bitmap_test(u8 *bitmap, int i) -{ - u8 data; - - data = bitmap[BITMAP_LOC(i)]; - if ((data >> BITMAP_SHIFT(i)) & 0x01) - return 1; - return 0; -} - -static inline void exfat_bitmap_set(u8 *bitmap, int i) -{ - bitmap[BITMAP_LOC(i)] |= (0x01 << BITMAP_SHIFT(i)); -} - -static inline void exfat_bitmap_clear(u8 *bitmap, int i) -{ - bitmap[BITMAP_LOC(i)] &= ~(0x01 << BITMAP_SHIFT(i)); -} - -/* - * File System Management Functions - */ - -void fs_set_vol_flags(struct super_block *sb, u32 new_flag) -{ - struct pbr_sector_t *p_pbr; - struct bpbex_t *p_bpb; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - if (p_fs->vol_flag == new_flag) - return; - - p_fs->vol_flag = new_flag; - - if (!p_fs->pbr_bh) { - if (sector_read(sb, p_fs->PBR_sector, - &p_fs->pbr_bh, 1) != 0) - return; - } - - p_pbr = (struct pbr_sector_t *)p_fs->pbr_bh->b_data; - p_bpb = (struct bpbex_t *)p_pbr->bpb; - SET16(p_bpb->vol_flags, (u16)new_flag); - - /* XXX duyoung - * what can we do here? (cuz fs_set_vol_flags() is void) - */ - if ((new_flag == VOL_DIRTY) && (!buffer_dirty(p_fs->pbr_bh))) - sector_write(sb, p_fs->PBR_sector, p_fs->pbr_bh, 1); - else - sector_write(sb, p_fs->PBR_sector, p_fs->pbr_bh, 0); -} - -void fs_error(struct super_block *sb) -{ - struct exfat_mount_options *opts = &EXFAT_SB(sb)->options; - - if (opts->errors == EXFAT_ERRORS_PANIC) { - panic("[EXFAT] Filesystem panic from previous error\n"); - } else if ((opts->errors == EXFAT_ERRORS_RO) && !sb_rdonly(sb)) { - sb->s_flags |= SB_RDONLY; - pr_err("[EXFAT] Filesystem has been set read-only\n"); - } -} - -/* - * Cluster Management Functions - */ - -static s32 clear_cluster(struct super_block *sb, u32 clu) -{ - sector_t s, n; - s32 ret = 0; - struct buffer_head *tmp_bh = NULL; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - - if (clu == CLUSTER_32(0)) { /* FAT16 root_dir */ - s = p_fs->root_start_sector; - n = p_fs->data_start_sector; - } else { - s = START_SECTOR(clu); - n = s + p_fs->sectors_per_clu; - } - - for (; s < n; s++) { - ret = sector_read(sb, s, &tmp_bh, 0); - if (ret != 0) - return ret; - - memset((char *)tmp_bh->b_data, 0x0, p_bd->sector_size); - ret = sector_write(sb, s, tmp_bh, 0); - if (ret != 0) - break; - } - - brelse(tmp_bh); - return ret; -} - -static s32 set_alloc_bitmap(struct super_block *sb, u32 clu) -{ - int i, b; - sector_t sector; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - - i = clu >> (p_bd->sector_size_bits + 3); - b = clu & ((p_bd->sector_size << 3) - 1); - - sector = START_SECTOR(p_fs->map_clu) + i; - - exfat_bitmap_set((u8 *)p_fs->vol_amap[i]->b_data, b); - - return sector_write(sb, sector, p_fs->vol_amap[i], 0); -} - -static s32 clr_alloc_bitmap(struct super_block *sb, u32 clu) -{ - int i, b; - sector_t sector; -#ifdef CONFIG_STAGING_EXFAT_DISCARD - struct exfat_sb_info *sbi = EXFAT_SB(sb); - struct exfat_mount_options *opts = &sbi->options; - int ret; -#endif /* CONFIG_STAGING_EXFAT_DISCARD */ - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - - i = clu >> (p_bd->sector_size_bits + 3); - b = clu & ((p_bd->sector_size << 3) - 1); - - sector = START_SECTOR(p_fs->map_clu) + i; - - exfat_bitmap_clear((u8 *)p_fs->vol_amap[i]->b_data, b); - -#ifdef CONFIG_STAGING_EXFAT_DISCARD - if (opts->discard) { - ret = sb_issue_discard(sb, START_SECTOR(clu), - (1 << p_fs->sectors_per_clu_bits), - GFP_NOFS, 0); - if (ret == -EOPNOTSUPP) { - pr_warn("discard not supported by device, disabling"); - opts->discard = 0; - } else { - return ret; - } - } -#endif /* CONFIG_STAGING_EXFAT_DISCARD */ - - return sector_write(sb, sector, p_fs->vol_amap[i], 0); -} - -static u32 test_alloc_bitmap(struct super_block *sb, u32 clu) -{ - int i, map_i, map_b; - u32 clu_base, clu_free; - u8 k, clu_mask; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - - clu_base = (clu & ~(0x7)) + 2; - clu_mask = (1 << (clu - clu_base + 2)) - 1; - - map_i = clu >> (p_bd->sector_size_bits + 3); - map_b = (clu >> 3) & p_bd->sector_size_mask; - - for (i = 2; i < p_fs->num_clusters; i += 8) { - k = *(((u8 *)p_fs->vol_amap[map_i]->b_data) + map_b); - if (clu_mask > 0) { - k |= clu_mask; - clu_mask = 0; - } - if (k < 0xFF) { - clu_free = clu_base + free_bit[k]; - if (clu_free < p_fs->num_clusters) - return clu_free; - } - clu_base += 8; - - if (((++map_b) >= p_bd->sector_size) || - (clu_base >= p_fs->num_clusters)) { - if ((++map_i) >= p_fs->map_sectors) { - clu_base = 2; - map_i = 0; - } - map_b = 0; - } - } - - return CLUSTER_32(~0); -} - -s32 exfat_alloc_cluster(struct super_block *sb, s32 num_alloc, - struct chain_t *p_chain) -{ - s32 num_clusters = 0; - u32 hint_clu, new_clu, last_clu = CLUSTER_32(~0); - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - hint_clu = p_chain->dir; - if (hint_clu == CLUSTER_32(~0)) { - hint_clu = test_alloc_bitmap(sb, p_fs->clu_srch_ptr - 2); - if (hint_clu == CLUSTER_32(~0)) - return 0; - } else if (hint_clu >= p_fs->num_clusters) { - hint_clu = 2; - p_chain->flags = 0x01; - } - - __set_sb_dirty(sb); - - p_chain->dir = CLUSTER_32(~0); - - while ((new_clu = test_alloc_bitmap(sb, hint_clu - 2)) != CLUSTER_32(~0)) { - if (new_clu != hint_clu) { - if (p_chain->flags == 0x03) { - exfat_chain_cont_cluster(sb, p_chain->dir, - num_clusters); - p_chain->flags = 0x01; - } - } - - if (set_alloc_bitmap(sb, new_clu - 2) != 0) - return -EIO; - - num_clusters++; - - if (p_chain->flags == 0x01) { - if (exfat_fat_write(sb, new_clu, CLUSTER_32(~0)) < 0) - return -EIO; - } - - if (p_chain->dir == CLUSTER_32(~0)) { - p_chain->dir = new_clu; - } else { - if (p_chain->flags == 0x01) { - if (exfat_fat_write(sb, last_clu, new_clu) < 0) - return -EIO; - } - } - last_clu = new_clu; - - if ((--num_alloc) == 0) { - p_fs->clu_srch_ptr = hint_clu; - if (p_fs->used_clusters != UINT_MAX) - p_fs->used_clusters += num_clusters; - - p_chain->size += num_clusters; - return num_clusters; - } - - hint_clu = new_clu + 1; - if (hint_clu >= p_fs->num_clusters) { - hint_clu = 2; - - if (p_chain->flags == 0x03) { - exfat_chain_cont_cluster(sb, p_chain->dir, - num_clusters); - p_chain->flags = 0x01; - } - } - } - - p_fs->clu_srch_ptr = hint_clu; - if (p_fs->used_clusters != UINT_MAX) - p_fs->used_clusters += num_clusters; - - p_chain->size += num_clusters; - return num_clusters; -} - -void exfat_free_cluster(struct super_block *sb, struct chain_t *p_chain, - s32 do_relse) -{ - s32 num_clusters = 0; - u32 clu; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - int i; - sector_t sector; - - if ((p_chain->dir == CLUSTER_32(0)) || (p_chain->dir == CLUSTER_32(~0))) - return; - - if (p_chain->size <= 0) { - pr_err("[EXFAT] free_cluster : skip free-req clu:%u, because of zero-size truncation\n", - p_chain->dir); - return; - } - - __set_sb_dirty(sb); - clu = p_chain->dir; - - if (p_chain->flags == 0x03) { - do { - if (do_relse) { - sector = START_SECTOR(clu); - for (i = 0; i < p_fs->sectors_per_clu; i++) - exfat_buf_release(sb, sector + i); - } - - if (clr_alloc_bitmap(sb, clu - 2) != 0) - break; - clu++; - - num_clusters++; - } while (num_clusters < p_chain->size); - } else { - do { - if (p_fs->dev_ejected) - break; - - if (do_relse) { - sector = START_SECTOR(clu); - for (i = 0; i < p_fs->sectors_per_clu; i++) - exfat_buf_release(sb, sector + i); - } - - if (clr_alloc_bitmap(sb, clu - 2) != 0) - break; - - if (exfat_fat_read(sb, clu, &clu) == -1) - break; - num_clusters++; - } while ((clu != CLUSTER_32(0)) && (clu != CLUSTER_32(~0))); - } - - if (p_fs->used_clusters != UINT_MAX) - p_fs->used_clusters -= num_clusters; -} - -static u32 find_last_cluster(struct super_block *sb, struct chain_t *p_chain) -{ - u32 clu, next; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - clu = p_chain->dir; - - if (p_chain->flags == 0x03) { - clu += p_chain->size - 1; - } else { - while ((exfat_fat_read(sb, clu, &next) == 0) && - (next != CLUSTER_32(~0))) { - if (p_fs->dev_ejected) - break; - clu = next; - } - } - - return clu; -} - -s32 count_num_clusters(struct super_block *sb, struct chain_t *p_chain) -{ - int i, count = 0; - u32 clu; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - if ((p_chain->dir == CLUSTER_32(0)) || (p_chain->dir == CLUSTER_32(~0))) - return 0; - - clu = p_chain->dir; - - if (p_chain->flags == 0x03) { - count = p_chain->size; - } else { - for (i = 2; i < p_fs->num_clusters; i++) { - count++; - if (exfat_fat_read(sb, clu, &clu) != 0) - return 0; - if (clu == CLUSTER_32(~0)) - break; - } - } - - return count; -} - -s32 exfat_count_used_clusters(struct super_block *sb) -{ - int i, map_i, map_b, count = 0; - u8 k; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - - map_i = 0; - map_b = 0; - - for (i = 2; i < p_fs->num_clusters; i += 8) { - k = *(((u8 *)p_fs->vol_amap[map_i]->b_data) + map_b); - count += used_bit[k]; - - if ((++map_b) >= p_bd->sector_size) { - map_i++; - map_b = 0; - } - } - - return count; -} - -void exfat_chain_cont_cluster(struct super_block *sb, u32 chain, s32 len) -{ - if (len == 0) - return; - - while (len > 1) { - if (exfat_fat_write(sb, chain, chain + 1) < 0) - break; - chain++; - len--; - } - exfat_fat_write(sb, chain, CLUSTER_32(~0)); -} - -/* - * Allocation Bitmap Management Functions - */ - -s32 load_alloc_bitmap(struct super_block *sb) -{ - int i, j, ret; - u32 map_size; - u32 type; - sector_t sector; - struct chain_t clu; - struct bmap_dentry_t *ep; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - - clu.dir = p_fs->root_dir; - clu.flags = 0x01; - - while (clu.dir != CLUSTER_32(~0)) { - if (p_fs->dev_ejected) - break; - - for (i = 0; i < p_fs->dentries_per_clu; i++) { - ep = (struct bmap_dentry_t *)get_entry_in_dir(sb, &clu, - i, NULL); - if (!ep) - return -ENOENT; - - type = exfat_get_entry_type((struct dentry_t *)ep); - - if (type == TYPE_UNUSED) - break; - if (type != TYPE_BITMAP) - continue; - - if (ep->flags == 0x0) { - p_fs->map_clu = GET32_A(ep->start_clu); - map_size = (u32)GET64_A(ep->size); - - p_fs->map_sectors = ((map_size - 1) >> p_bd->sector_size_bits) + 1; - - p_fs->vol_amap = kmalloc_array(p_fs->map_sectors, - sizeof(struct buffer_head *), - GFP_KERNEL); - if (!p_fs->vol_amap) - return -ENOMEM; - - sector = START_SECTOR(p_fs->map_clu); - - for (j = 0; j < p_fs->map_sectors; j++) { - p_fs->vol_amap[j] = NULL; - ret = sector_read(sb, sector + j, &p_fs->vol_amap[j], 1); - if (ret != 0) { - /* release all buffers and free vol_amap */ - i = 0; - while (i < j) - brelse(p_fs->vol_amap[i++]); - - kfree(p_fs->vol_amap); - p_fs->vol_amap = NULL; - return ret; - } - } - - p_fs->pbr_bh = NULL; - return 0; - } - } - - if (exfat_fat_read(sb, clu.dir, &clu.dir) != 0) - return -EIO; - } - - return -EFSCORRUPTED; -} - -void free_alloc_bitmap(struct super_block *sb) -{ - int i; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - brelse(p_fs->pbr_bh); - - for (i = 0; i < p_fs->map_sectors; i++) - __brelse(p_fs->vol_amap[i]); - - kfree(p_fs->vol_amap); - p_fs->vol_amap = NULL; -} - -/* - * Upcase table Management Functions - */ -static s32 __load_upcase_table(struct super_block *sb, sector_t sector, - u32 num_sectors, u32 utbl_checksum) -{ - int i, ret = -EINVAL; - u32 j; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - struct buffer_head *tmp_bh = NULL; - sector_t end_sector = num_sectors + sector; - - bool skip = false; - u32 index = 0; - u16 uni = 0; - u16 **upcase_table; - - u32 checksum = 0; - - upcase_table = kmalloc_array(UTBL_COL_COUNT, sizeof(u16 *), GFP_KERNEL); - p_fs->vol_utbl = upcase_table; - if (!upcase_table) - return -ENOMEM; - memset(upcase_table, 0, UTBL_COL_COUNT * sizeof(u16 *)); - - while (sector < end_sector) { - ret = sector_read(sb, sector, &tmp_bh, 1); - if (ret != 0) { - pr_debug("sector read (0x%llX)fail\n", - (unsigned long long)sector); - goto error; - } - sector++; - - for (i = 0; i < p_bd->sector_size && index <= 0xFFFF; i += 2) { - uni = GET16(((u8 *)tmp_bh->b_data) + i); - - checksum = ((checksum & 1) ? 0x80000000 : 0) + - (checksum >> 1) + *(((u8 *)tmp_bh->b_data) + - i); - checksum = ((checksum & 1) ? 0x80000000 : 0) + - (checksum >> 1) + *(((u8 *)tmp_bh->b_data) + - (i + 1)); - - if (skip) { - pr_debug("skip from 0x%X ", index); - index += uni; - pr_debug("to 0x%X (amount of 0x%X)\n", - index, uni); - skip = false; - } else if (uni == index) { - index++; - } else if (uni == 0xFFFF) { - skip = true; - } else { /* uni != index , uni != 0xFFFF */ - u16 col_index = get_col_index(index); - - if (!upcase_table[col_index]) { - pr_debug("alloc = 0x%X\n", col_index); - upcase_table[col_index] = kmalloc_array(UTBL_ROW_COUNT, - sizeof(u16), GFP_KERNEL); - if (!upcase_table[col_index]) { - ret = -ENOMEM; - goto error; - } - - for (j = 0; j < UTBL_ROW_COUNT; j++) - upcase_table[col_index][j] = (col_index << LOW_INDEX_BIT) | j; - } - - upcase_table[col_index][get_row_index(index)] = uni; - index++; - } - } - } - if (index >= 0xFFFF && utbl_checksum == checksum) { - if (tmp_bh) - brelse(tmp_bh); - return 0; - } - ret = -EINVAL; -error: - if (tmp_bh) - brelse(tmp_bh); - free_upcase_table(sb); - return ret; -} - -static s32 __load_default_upcase_table(struct super_block *sb) -{ - int i, ret = -EINVAL; - u32 j; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - bool skip = false; - u32 index = 0; - u16 uni = 0; - u16 **upcase_table; - - upcase_table = kmalloc_array(UTBL_COL_COUNT, sizeof(u16 *), GFP_KERNEL); - p_fs->vol_utbl = upcase_table; - if (!upcase_table) - return -ENOMEM; - memset(upcase_table, 0, UTBL_COL_COUNT * sizeof(u16 *)); - - for (i = 0; index <= 0xFFFF && i < NUM_UPCASE * 2; i += 2) { - uni = GET16(uni_upcase + i); - if (skip) { - pr_debug("skip from 0x%X ", index); - index += uni; - pr_debug("to 0x%X (amount of 0x%X)\n", index, uni); - skip = false; - } else if (uni == index) { - index++; - } else if (uni == 0xFFFF) { - skip = true; - } else { /* uni != index , uni != 0xFFFF */ - u16 col_index = get_col_index(index); - - if (!upcase_table[col_index]) { - pr_debug("alloc = 0x%X\n", col_index); - upcase_table[col_index] = kmalloc_array(UTBL_ROW_COUNT, - sizeof(u16), - GFP_KERNEL); - if (!upcase_table[col_index]) { - ret = -ENOMEM; - goto error; - } - - for (j = 0; j < UTBL_ROW_COUNT; j++) - upcase_table[col_index][j] = (col_index << LOW_INDEX_BIT) | j; - } - - upcase_table[col_index][get_row_index(index)] = uni; - index++; - } - } - - if (index >= 0xFFFF) - return 0; - -error: - /* FATAL error: default upcase table has error */ - free_upcase_table(sb); - return ret; -} - -s32 load_upcase_table(struct super_block *sb) -{ - int i; - u32 tbl_clu, tbl_size; - sector_t sector; - u32 type, num_sectors; - struct chain_t clu; - struct case_dentry_t *ep; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - - clu.dir = p_fs->root_dir; - clu.flags = 0x01; - - if (p_fs->dev_ejected) - return -EIO; - - while (clu.dir != CLUSTER_32(~0)) { - for (i = 0; i < p_fs->dentries_per_clu; i++) { - ep = (struct case_dentry_t *)get_entry_in_dir(sb, &clu, - i, NULL); - if (!ep) - return -ENOENT; - - type = exfat_get_entry_type((struct dentry_t *)ep); - - if (type == TYPE_UNUSED) - break; - if (type != TYPE_UPCASE) - continue; - - tbl_clu = GET32_A(ep->start_clu); - tbl_size = (u32)GET64_A(ep->size); - - sector = START_SECTOR(tbl_clu); - num_sectors = ((tbl_size - 1) >> p_bd->sector_size_bits) + 1; - if (__load_upcase_table(sb, sector, num_sectors, - GET32_A(ep->checksum)) != 0) - break; - return 0; - } - if (exfat_fat_read(sb, clu.dir, &clu.dir) != 0) - return -EIO; - } - /* load default upcase table */ - return __load_default_upcase_table(sb); -} - -void free_upcase_table(struct super_block *sb) -{ - u32 i; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - u16 **upcase_table; - - upcase_table = p_fs->vol_utbl; - for (i = 0; i < UTBL_COL_COUNT; i++) - kfree(upcase_table[i]); - - kfree(p_fs->vol_utbl); - p_fs->vol_utbl = NULL; -} - -/* - * Directory Entry Management Functions - */ - -u32 exfat_get_entry_type(struct dentry_t *p_entry) -{ - struct file_dentry_t *ep = (struct file_dentry_t *)p_entry; - - if (ep->type == 0x0) { - return TYPE_UNUSED; - } else if (ep->type < 0x80) { - return TYPE_DELETED; - } else if (ep->type == 0x80) { - return TYPE_INVALID; - } else if (ep->type < 0xA0) { - if (ep->type == 0x81) { - return TYPE_BITMAP; - } else if (ep->type == 0x82) { - return TYPE_UPCASE; - } else if (ep->type == 0x83) { - return TYPE_VOLUME; - } else if (ep->type == 0x85) { - if (GET16_A(ep->attr) & ATTR_SUBDIR) - return TYPE_DIR; - else - return TYPE_FILE; - } - return TYPE_CRITICAL_PRI; - } else if (ep->type < 0xC0) { - if (ep->type == 0xA0) - return TYPE_GUID; - else if (ep->type == 0xA1) - return TYPE_PADDING; - else if (ep->type == 0xA2) - return TYPE_ACLTAB; - return TYPE_BENIGN_PRI; - } else if (ep->type < 0xE0) { - if (ep->type == 0xC0) - return TYPE_STREAM; - else if (ep->type == 0xC1) - return TYPE_EXTEND; - else if (ep->type == 0xC2) - return TYPE_ACL; - return TYPE_CRITICAL_SEC; - } - - return TYPE_BENIGN_SEC; -} - -static void exfat_set_entry_type(struct dentry_t *p_entry, u32 type) -{ - struct file_dentry_t *ep = (struct file_dentry_t *)p_entry; - - if (type == TYPE_UNUSED) { - ep->type = 0x0; - } else if (type == TYPE_DELETED) { - ep->type &= ~0x80; - } else if (type == TYPE_STREAM) { - ep->type = 0xC0; - } else if (type == TYPE_EXTEND) { - ep->type = 0xC1; - } else if (type == TYPE_BITMAP) { - ep->type = 0x81; - } else if (type == TYPE_UPCASE) { - ep->type = 0x82; - } else if (type == TYPE_VOLUME) { - ep->type = 0x83; - } else if (type == TYPE_DIR) { - ep->type = 0x85; - SET16_A(ep->attr, ATTR_SUBDIR); - } else if (type == TYPE_FILE) { - ep->type = 0x85; - SET16_A(ep->attr, ATTR_ARCHIVE); - } -} - -u32 exfat_get_entry_attr(struct dentry_t *p_entry) -{ - struct file_dentry_t *ep = (struct file_dentry_t *)p_entry; - - return (u32)GET16_A(ep->attr); -} - -void exfat_set_entry_attr(struct dentry_t *p_entry, u32 attr) -{ - struct file_dentry_t *ep = (struct file_dentry_t *)p_entry; - - SET16_A(ep->attr, (u16)attr); -} - -u8 exfat_get_entry_flag(struct dentry_t *p_entry) -{ - struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry; - - return ep->flags; -} - -void exfat_set_entry_flag(struct dentry_t *p_entry, u8 flags) -{ - struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry; - - ep->flags = flags; -} - -u32 exfat_get_entry_clu0(struct dentry_t *p_entry) -{ - struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry; - - return GET32_A(ep->start_clu); -} - -void exfat_set_entry_clu0(struct dentry_t *p_entry, u32 start_clu) -{ - struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry; - - SET32_A(ep->start_clu, start_clu); -} - -u64 exfat_get_entry_size(struct dentry_t *p_entry) -{ - struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry; - - return GET64_A(ep->valid_size); -} - -void exfat_set_entry_size(struct dentry_t *p_entry, u64 size) -{ - struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry; - - SET64_A(ep->valid_size, size); - SET64_A(ep->size, size); -} - -void exfat_get_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp, - u8 mode) -{ - u16 t = 0x00, d = 0x21; - struct file_dentry_t *ep = (struct file_dentry_t *)p_entry; - - switch (mode) { - case TM_CREATE: - t = GET16_A(ep->create_time); - d = GET16_A(ep->create_date); - break; - case TM_MODIFY: - t = GET16_A(ep->modify_time); - d = GET16_A(ep->modify_date); - break; - case TM_ACCESS: - t = GET16_A(ep->access_time); - d = GET16_A(ep->access_date); - break; - } - - tp->sec = (t & 0x001F) << 1; - tp->min = (t >> 5) & 0x003F; - tp->hour = (t >> 11); - tp->day = (d & 0x001F); - tp->mon = (d >> 5) & 0x000F; - tp->year = (d >> 9); -} - -void exfat_set_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp, - u8 mode) -{ - u16 t, d; - struct file_dentry_t *ep = (struct file_dentry_t *)p_entry; - - t = (tp->hour << 11) | (tp->min << 5) | (tp->sec >> 1); - d = (tp->year << 9) | (tp->mon << 5) | tp->day; - - switch (mode) { - case TM_CREATE: - SET16_A(ep->create_time, t); - SET16_A(ep->create_date, d); - break; - case TM_MODIFY: - SET16_A(ep->modify_time, t); - SET16_A(ep->modify_date, d); - break; - case TM_ACCESS: - SET16_A(ep->access_time, t); - SET16_A(ep->access_date, d); - break; - } -} - -static void init_file_entry(struct file_dentry_t *ep, u32 type) -{ - struct timestamp_t tm, *tp; - - exfat_set_entry_type((struct dentry_t *)ep, type); - - tp = tm_current(&tm); - exfat_set_entry_time((struct dentry_t *)ep, tp, TM_CREATE); - exfat_set_entry_time((struct dentry_t *)ep, tp, TM_MODIFY); - exfat_set_entry_time((struct dentry_t *)ep, tp, TM_ACCESS); - ep->create_time_ms = 0; - ep->modify_time_ms = 0; - ep->access_time_ms = 0; -} - -static void init_strm_entry(struct strm_dentry_t *ep, u8 flags, u32 start_clu, u64 size) -{ - exfat_set_entry_type((struct dentry_t *)ep, TYPE_STREAM); - ep->flags = flags; - SET32_A(ep->start_clu, start_clu); - SET64_A(ep->valid_size, size); - SET64_A(ep->size, size); -} - -static void init_name_entry(struct name_dentry_t *ep, u16 *uniname) -{ - int i; - - exfat_set_entry_type((struct dentry_t *)ep, TYPE_EXTEND); - ep->flags = 0x0; - - for (i = 0; i < 30; i++, i++) { - SET16_A(ep->unicode_0_14 + i, *uniname); - if (*uniname == 0x0) - break; - uniname++; - } -} - -static s32 exfat_init_dir_entry(struct super_block *sb, struct chain_t *p_dir, - s32 entry, u32 type, u32 start_clu, u64 size) -{ - sector_t sector; - u8 flags; - struct file_dentry_t *file_ep; - struct strm_dentry_t *strm_ep; - - flags = (type == TYPE_FILE) ? 0x01 : 0x03; - - /* we cannot use get_entry_set_in_dir here because file ep is not initialized yet */ - file_ep = (struct file_dentry_t *)get_entry_in_dir(sb, p_dir, entry, - §or); - if (!file_ep) - return -ENOENT; - - strm_ep = (struct strm_dentry_t *)get_entry_in_dir(sb, p_dir, entry + 1, - §or); - if (!strm_ep) - return -ENOENT; - - init_file_entry(file_ep, type); - exfat_buf_modify(sb, sector); - - init_strm_entry(strm_ep, flags, start_clu, size); - exfat_buf_modify(sb, sector); - - return 0; -} - -static s32 exfat_init_ext_entry(struct super_block *sb, struct chain_t *p_dir, - s32 entry, s32 num_entries, - struct uni_name_t *p_uniname) -{ - int i; - sector_t sector; - u16 *uniname = p_uniname->name; - struct file_dentry_t *file_ep; - struct strm_dentry_t *strm_ep; - struct name_dentry_t *name_ep; - - file_ep = (struct file_dentry_t *)get_entry_in_dir(sb, p_dir, entry, - §or); - if (!file_ep) - return -ENOENT; - - file_ep->num_ext = (u8)(num_entries - 1); - exfat_buf_modify(sb, sector); - - strm_ep = (struct strm_dentry_t *)get_entry_in_dir(sb, p_dir, entry + 1, - §or); - if (!strm_ep) - return -ENOENT; - - strm_ep->name_len = p_uniname->name_len; - SET16_A(strm_ep->name_hash, p_uniname->name_hash); - exfat_buf_modify(sb, sector); - - for (i = 2; i < num_entries; i++) { - name_ep = (struct name_dentry_t *)get_entry_in_dir(sb, p_dir, - entry + i, - §or); - if (!name_ep) - return -ENOENT; - - init_name_entry(name_ep, uniname); - exfat_buf_modify(sb, sector); - uniname += 15; - } - - update_dir_checksum(sb, p_dir, entry); - - return 0; -} - -void exfat_delete_dir_entry(struct super_block *sb, struct chain_t *p_dir, - s32 entry, s32 order, s32 num_entries) -{ - int i; - sector_t sector; - struct dentry_t *ep; - - for (i = order; i < num_entries; i++) { - ep = get_entry_in_dir(sb, p_dir, entry + i, §or); - if (!ep) - return; - - exfat_set_entry_type(ep, TYPE_DELETED); - exfat_buf_modify(sb, sector); - } -} - -void update_dir_checksum(struct super_block *sb, struct chain_t *p_dir, - s32 entry) -{ - int i, num_entries; - sector_t sector; - u16 chksum; - struct file_dentry_t *file_ep; - struct dentry_t *ep; - - file_ep = (struct file_dentry_t *)get_entry_in_dir(sb, p_dir, entry, - §or); - if (!file_ep) - return; - - exfat_buf_lock(sb, sector); - - num_entries = (s32)file_ep->num_ext + 1; - chksum = calc_checksum_2byte((void *)file_ep, DENTRY_SIZE, 0, - CS_DIR_ENTRY); - - for (i = 1; i < num_entries; i++) { - ep = get_entry_in_dir(sb, p_dir, entry + i, NULL); - if (!ep) { - exfat_buf_unlock(sb, sector); - return; - } - - chksum = calc_checksum_2byte((void *)ep, DENTRY_SIZE, chksum, - CS_DEFAULT); - } - - SET16_A(file_ep->checksum, chksum); - exfat_buf_modify(sb, sector); - exfat_buf_unlock(sb, sector); -} - -static s32 __write_partial_entries_in_entry_set(struct super_block *sb, - struct entry_set_cache_t *es, - sector_t sec, s32 off, u32 count) -{ - s32 num_entries, buf_off = (off - es->offset); - u32 remaining_byte_in_sector, copy_entries; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - u32 clu; - u8 *buf, *esbuf = (u8 *)&es->__buf; - - pr_debug("%s entered es %p sec %llu off %d count %d\n", - __func__, es, (unsigned long long)sec, off, count); - num_entries = count; - - while (num_entries) { - /* white per sector base */ - remaining_byte_in_sector = (1 << p_bd->sector_size_bits) - off; - copy_entries = min_t(s32, - remaining_byte_in_sector >> DENTRY_SIZE_BITS, - num_entries); - buf = exfat_buf_getblk(sb, sec); - if (!buf) - goto err_out; - pr_debug("es->buf %p buf_off %u\n", esbuf, buf_off); - pr_debug("copying %d entries from %p to sector %llu\n", - copy_entries, (esbuf + buf_off), - (unsigned long long)sec); - memcpy(buf + off, esbuf + buf_off, - copy_entries << DENTRY_SIZE_BITS); - exfat_buf_modify(sb, sec); - num_entries -= copy_entries; - - if (num_entries) { - /* get next sector */ - if (IS_LAST_SECTOR_IN_CLUSTER(sec)) { - clu = GET_CLUSTER_FROM_SECTOR(sec); - if (es->alloc_flag == 0x03) { - clu++; - } else { - if (exfat_fat_read(sb, clu, &clu) == -1) - goto err_out; - } - sec = START_SECTOR(clu); - } else { - sec++; - } - off = 0; - buf_off += copy_entries << DENTRY_SIZE_BITS; - } - } - - pr_debug("%s exited successfully\n", __func__); - return 0; -err_out: - pr_debug("%s failed\n", __func__); - return -EINVAL; -} - -/* write back all entries in entry set */ -static s32 write_whole_entry_set(struct super_block *sb, struct entry_set_cache_t *es) -{ - return __write_partial_entries_in_entry_set(sb, es, es->sector, - es->offset, - es->num_entries); -} - -void update_dir_checksum_with_entry_set(struct super_block *sb, - struct entry_set_cache_t *es) -{ - struct dentry_t *ep; - u16 chksum = 0; - s32 chksum_type = CS_DIR_ENTRY, i; - - ep = (struct dentry_t *)&es->__buf; - for (i = 0; i < es->num_entries; i++) { - pr_debug("%s ep %p\n", __func__, ep); - chksum = calc_checksum_2byte((void *)ep, DENTRY_SIZE, chksum, - chksum_type); - ep++; - chksum_type = CS_DEFAULT; - } - - ep = (struct dentry_t *)&es->__buf; - SET16_A(((struct file_dentry_t *)ep)->checksum, chksum); - write_whole_entry_set(sb, es); -} - -static s32 _walk_fat_chain(struct super_block *sb, struct chain_t *p_dir, - s32 byte_offset, u32 *clu) -{ - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - s32 clu_offset; - u32 cur_clu; - - clu_offset = byte_offset >> p_fs->cluster_size_bits; - cur_clu = p_dir->dir; - - if (p_dir->flags == 0x03) { - cur_clu += clu_offset; - } else { - while (clu_offset > 0) { - if (exfat_fat_read(sb, cur_clu, &cur_clu) == -1) - return -EIO; - clu_offset--; - } - } - - if (clu) - *clu = cur_clu; - return 0; -} - -static s32 find_location(struct super_block *sb, struct chain_t *p_dir, s32 entry, - sector_t *sector, s32 *offset) -{ - s32 off, ret; - u32 clu = 0; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - - off = entry << DENTRY_SIZE_BITS; - - if (p_dir->dir == CLUSTER_32(0)) { /* FAT16 root_dir */ - *offset = off & p_bd->sector_size_mask; - *sector = off >> p_bd->sector_size_bits; - *sector += p_fs->root_start_sector; - } else { - ret = _walk_fat_chain(sb, p_dir, off, &clu); - if (ret != 0) - return ret; - - /* byte offset in cluster */ - off &= p_fs->cluster_size - 1; - - /* byte offset in sector */ - *offset = off & p_bd->sector_size_mask; - - /* sector offset in cluster */ - *sector = off >> p_bd->sector_size_bits; - *sector += START_SECTOR(clu); - } - return 0; -} - -struct dentry_t *get_entry_in_dir(struct super_block *sb, struct chain_t *p_dir, - s32 entry, sector_t *sector) -{ - s32 off; - sector_t sec; - u8 *buf; - - if (find_location(sb, p_dir, entry, &sec, &off) != 0) - return NULL; - - buf = exfat_buf_getblk(sb, sec); - - if (!buf) - return NULL; - - if (sector) - *sector = sec; - return (struct dentry_t *)(buf + off); -} - -/* returns a set of dentries for a file or dir. - * Note that this is a copy (dump) of dentries so that user should call write_entry_set() - * to apply changes made in this entry set to the real device. - * in: - * sb+p_dir+entry: indicates a file/dir - * type: specifies how many dentries should be included. - * out: - * file_ep: will point the first dentry(= file dentry) on success - * return: - * pointer of entry set on success, - * NULL on failure. - */ - -#define ES_MODE_STARTED 0 -#define ES_MODE_GET_FILE_ENTRY 1 -#define ES_MODE_GET_STRM_ENTRY 2 -#define ES_MODE_GET_NAME_ENTRY 3 -#define ES_MODE_GET_CRITICAL_SEC_ENTRY 4 -struct entry_set_cache_t *get_entry_set_in_dir(struct super_block *sb, - struct chain_t *p_dir, s32 entry, - u32 type, - struct dentry_t **file_ep) -{ - s32 off, ret, byte_offset; - u32 clu = 0; - sector_t sec; - u32 entry_type; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - struct entry_set_cache_t *es = NULL; - struct dentry_t *ep, *pos; - u8 *buf; - u8 num_entries; - s32 mode = ES_MODE_STARTED; - size_t bufsize; - - pr_debug("%s entered p_dir dir %u flags %x size %d\n", - __func__, p_dir->dir, p_dir->flags, p_dir->size); - - byte_offset = entry << DENTRY_SIZE_BITS; - ret = _walk_fat_chain(sb, p_dir, byte_offset, &clu); - if (ret != 0) - return NULL; - - /* byte offset in cluster */ - byte_offset &= p_fs->cluster_size - 1; - - /* byte offset in sector */ - off = byte_offset & p_bd->sector_size_mask; - - /* sector offset in cluster */ - sec = byte_offset >> p_bd->sector_size_bits; - sec += START_SECTOR(clu); - - buf = exfat_buf_getblk(sb, sec); - if (!buf) - goto err_out; - - ep = (struct dentry_t *)(buf + off); - entry_type = exfat_get_entry_type(ep); - - if ((entry_type != TYPE_FILE) && (entry_type != TYPE_DIR)) - goto err_out; - - if (type == ES_ALL_ENTRIES) - num_entries = ((struct file_dentry_t *)ep)->num_ext + 1; - else - num_entries = type; - - bufsize = offsetof(struct entry_set_cache_t, __buf) + (num_entries) * - sizeof(struct dentry_t); - pr_debug("%s: trying to kmalloc %zx bytes for %d entries\n", __func__, - bufsize, num_entries); - es = kmalloc(bufsize, GFP_KERNEL); - if (!es) - goto err_out; - - es->num_entries = num_entries; - es->sector = sec; - es->offset = off; - es->alloc_flag = p_dir->flags; - - pos = (struct dentry_t *)&es->__buf; - - while (num_entries) { - /* - * instead of copying whole sector, we will check every entry. - * this will provide minimum stablity and consistency. - */ - entry_type = exfat_get_entry_type(ep); - - if ((entry_type == TYPE_UNUSED) || (entry_type == TYPE_DELETED)) - goto err_out; - - switch (mode) { - case ES_MODE_STARTED: - if ((entry_type == TYPE_FILE) || (entry_type == TYPE_DIR)) - mode = ES_MODE_GET_FILE_ENTRY; - else - goto err_out; - break; - case ES_MODE_GET_FILE_ENTRY: - if (entry_type == TYPE_STREAM) - mode = ES_MODE_GET_STRM_ENTRY; - else - goto err_out; - break; - case ES_MODE_GET_STRM_ENTRY: - if (entry_type == TYPE_EXTEND) - mode = ES_MODE_GET_NAME_ENTRY; - else - goto err_out; - break; - case ES_MODE_GET_NAME_ENTRY: - if (entry_type == TYPE_EXTEND) - break; - else if (entry_type == TYPE_STREAM) - goto err_out; - else if (entry_type & TYPE_CRITICAL_SEC) - mode = ES_MODE_GET_CRITICAL_SEC_ENTRY; - else - goto err_out; - break; - case ES_MODE_GET_CRITICAL_SEC_ENTRY: - if ((entry_type == TYPE_EXTEND) || - (entry_type == TYPE_STREAM)) - goto err_out; - else if ((entry_type & TYPE_CRITICAL_SEC) != - TYPE_CRITICAL_SEC) - goto err_out; - break; - } - - memcpy(pos, ep, sizeof(struct dentry_t)); - - if (--num_entries == 0) - break; - - if (((off + DENTRY_SIZE) & p_bd->sector_size_mask) < - (off & p_bd->sector_size_mask)) { - /* get the next sector */ - if (IS_LAST_SECTOR_IN_CLUSTER(sec)) { - if (es->alloc_flag == 0x03) { - clu++; - } else { - if (exfat_fat_read(sb, clu, &clu) == -1) - goto err_out; - } - sec = START_SECTOR(clu); - } else { - sec++; - } - buf = exfat_buf_getblk(sb, sec); - if (!buf) - goto err_out; - off = 0; - ep = (struct dentry_t *)(buf); - } else { - ep++; - off += DENTRY_SIZE; - } - pos++; - } - - if (file_ep) - *file_ep = (struct dentry_t *)&es->__buf; - - pr_debug("%s exiting es %p sec %llu offset %d flags %d, num_entries %u buf ptr %p\n", - __func__, es, (unsigned long long)es->sector, es->offset, - es->alloc_flag, es->num_entries, &es->__buf); - return es; -err_out: - pr_debug("%s exited NULL (es %p)\n", __func__, es); - kfree(es); - return NULL; -} - -void release_entry_set(struct entry_set_cache_t *es) -{ - pr_debug("%s es=%p\n", __func__, es); - kfree(es); -} - -/* search EMPTY CONTINUOUS "num_entries" entries */ -static s32 search_deleted_or_unused_entry(struct super_block *sb, - struct chain_t *p_dir, - s32 num_entries) -{ - int i, dentry, num_empty = 0; - s32 dentries_per_clu; - u32 type; - struct chain_t clu; - struct dentry_t *ep; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */ - dentries_per_clu = p_fs->dentries_in_root; - else - dentries_per_clu = p_fs->dentries_per_clu; - - if (p_fs->hint_uentry.dir == p_dir->dir) { - if (p_fs->hint_uentry.entry == -1) - return -1; - - clu.dir = p_fs->hint_uentry.clu.dir; - clu.size = p_fs->hint_uentry.clu.size; - clu.flags = p_fs->hint_uentry.clu.flags; - - dentry = p_fs->hint_uentry.entry; - } else { - p_fs->hint_uentry.entry = -1; - - clu.dir = p_dir->dir; - clu.size = p_dir->size; - clu.flags = p_dir->flags; - - dentry = 0; - } - - while (clu.dir != CLUSTER_32(~0)) { - if (p_fs->dev_ejected) - break; - - if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */ - i = dentry % dentries_per_clu; - else - i = dentry & (dentries_per_clu - 1); - - for (; i < dentries_per_clu; i++, dentry++) { - ep = get_entry_in_dir(sb, &clu, i, NULL); - if (!ep) - return -1; - - type = exfat_get_entry_type(ep); - - if (type == TYPE_UNUSED) { - num_empty++; - if (p_fs->hint_uentry.entry == -1) { - p_fs->hint_uentry.dir = p_dir->dir; - p_fs->hint_uentry.entry = dentry; - - p_fs->hint_uentry.clu.dir = clu.dir; - p_fs->hint_uentry.clu.size = clu.size; - p_fs->hint_uentry.clu.flags = clu.flags; - } - } else if (type == TYPE_DELETED) { - num_empty++; - } else { - num_empty = 0; - } - - if (num_empty >= num_entries) { - p_fs->hint_uentry.dir = CLUSTER_32(~0); - p_fs->hint_uentry.entry = -1; - return dentry - (num_entries - 1); - } - } - - if (p_dir->dir == CLUSTER_32(0)) - break; /* FAT16 root_dir */ - - if (clu.flags == 0x03) { - if ((--clu.size) > 0) - clu.dir++; - else - clu.dir = CLUSTER_32(~0); - } else { - if (exfat_fat_read(sb, clu.dir, &clu.dir) != 0) - return -1; - } - } - - return -1; -} - -static s32 find_empty_entry(struct inode *inode, struct chain_t *p_dir, s32 num_entries) -{ - s32 ret, dentry; - u32 last_clu; - sector_t sector; - u64 size = 0; - struct chain_t clu; - struct dentry_t *ep = NULL; - struct super_block *sb = inode->i_sb; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct file_id_t *fid = &(EXFAT_I(inode)->fid); - - if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */ - return search_deleted_or_unused_entry(sb, p_dir, num_entries); - - while ((dentry = search_deleted_or_unused_entry(sb, p_dir, num_entries)) < 0) { - if (p_fs->dev_ejected) - break; - - if (p_dir->dir != p_fs->root_dir) - size = i_size_read(inode); - - last_clu = find_last_cluster(sb, p_dir); - clu.dir = last_clu + 1; - clu.size = 0; - clu.flags = p_dir->flags; - - /* (1) allocate a cluster */ - ret = exfat_alloc_cluster(sb, 1, &clu); - if (ret < 1) - return -EIO; - - if (clear_cluster(sb, clu.dir) != 0) - return -EIO; - - /* (2) append to the FAT chain */ - if (clu.flags != p_dir->flags) { - exfat_chain_cont_cluster(sb, p_dir->dir, p_dir->size); - p_dir->flags = 0x01; - p_fs->hint_uentry.clu.flags = 0x01; - } - if (clu.flags == 0x01) - if (exfat_fat_write(sb, last_clu, clu.dir) < 0) - return -EIO; - - if (p_fs->hint_uentry.entry == -1) { - p_fs->hint_uentry.dir = p_dir->dir; - p_fs->hint_uentry.entry = p_dir->size << (p_fs->cluster_size_bits - DENTRY_SIZE_BITS); - - p_fs->hint_uentry.clu.dir = clu.dir; - p_fs->hint_uentry.clu.size = 0; - p_fs->hint_uentry.clu.flags = clu.flags; - } - p_fs->hint_uentry.clu.size++; - p_dir->size++; - - /* (3) update the directory entry */ - if (p_dir->dir != p_fs->root_dir) { - size += p_fs->cluster_size; - - ep = get_entry_in_dir(sb, &fid->dir, - fid->entry + 1, §or); - if (!ep) - return -ENOENT; - exfat_set_entry_size(ep, size); - exfat_set_entry_flag(ep, p_dir->flags); - exfat_buf_modify(sb, sector); - - update_dir_checksum(sb, &fid->dir, - fid->entry); - } - - i_size_write(inode, i_size_read(inode) + p_fs->cluster_size); - EXFAT_I(inode)->mmu_private += p_fs->cluster_size; - EXFAT_I(inode)->fid.size += p_fs->cluster_size; - EXFAT_I(inode)->fid.flags = p_dir->flags; - inode->i_blocks += 1 << (p_fs->cluster_size_bits - 9); - } - - return dentry; -} - -static s32 extract_uni_name_from_name_entry(struct name_dentry_t *ep, u16 *uniname, - s32 order) -{ - int i, len = 0; - - for (i = 0; i < 30; i += 2) { - *uniname = GET16_A(ep->unicode_0_14 + i); - if (*uniname == 0x0) - return len; - uniname++; - len++; - } - - *uniname = 0x0; - return len; -} - -/* return values of exfat_find_dir_entry() - * >= 0 : return dir entiry position with the name in dir - * -1 : (root dir, ".") it is the root dir itself - * -2 : entry with the name does not exist - */ -s32 exfat_find_dir_entry(struct super_block *sb, struct chain_t *p_dir, - struct uni_name_t *p_uniname, s32 num_entries, - u32 type) -{ - int i = 0, dentry = 0, num_ext_entries = 0, len, step; - s32 order = 0; - bool is_feasible_entry = false; - s32 dentries_per_clu, num_empty = 0; - u32 entry_type; - u16 entry_uniname[16], *uniname = NULL, unichar; - struct chain_t clu; - struct dentry_t *ep; - struct file_dentry_t *file_ep; - struct strm_dentry_t *strm_ep; - struct name_dentry_t *name_ep; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - if (p_dir->dir == p_fs->root_dir) { - if ((!nls_uniname_cmp(sb, p_uniname->name, - (u16 *)UNI_CUR_DIR_NAME)) || - (!nls_uniname_cmp(sb, p_uniname->name, - (u16 *)UNI_PAR_DIR_NAME))) - return -1; // special case, root directory itself - } - - if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */ - dentries_per_clu = p_fs->dentries_in_root; - else - dentries_per_clu = p_fs->dentries_per_clu; - - clu.dir = p_dir->dir; - clu.size = p_dir->size; - clu.flags = p_dir->flags; - - p_fs->hint_uentry.dir = p_dir->dir; - p_fs->hint_uentry.entry = -1; - - while (clu.dir != CLUSTER_32(~0)) { - if (p_fs->dev_ejected) - break; - - while (i < dentries_per_clu) { - ep = get_entry_in_dir(sb, &clu, i, NULL); - if (!ep) - return -2; - - entry_type = exfat_get_entry_type(ep); - step = 1; - - if ((entry_type == TYPE_UNUSED) || (entry_type == TYPE_DELETED)) { - is_feasible_entry = false; - - if (p_fs->hint_uentry.entry == -1) { - num_empty++; - - if (num_empty == 1) { - p_fs->hint_uentry.clu.dir = clu.dir; - p_fs->hint_uentry.clu.size = clu.size; - p_fs->hint_uentry.clu.flags = clu.flags; - } - if ((num_empty >= num_entries) || (entry_type == TYPE_UNUSED)) - p_fs->hint_uentry.entry = dentry - (num_empty - 1); - } - - if (entry_type == TYPE_UNUSED) - return -2; - } else { - num_empty = 0; - - if ((entry_type == TYPE_FILE) || (entry_type == TYPE_DIR)) { - file_ep = (struct file_dentry_t *)ep; - if ((type == TYPE_ALL) || (type == entry_type)) { - num_ext_entries = file_ep->num_ext; - is_feasible_entry = true; - } else { - is_feasible_entry = false; - step = file_ep->num_ext + 1; - } - } else if (entry_type == TYPE_STREAM) { - if (is_feasible_entry) { - strm_ep = (struct strm_dentry_t *)ep; - if (p_uniname->name_hash == GET16_A(strm_ep->name_hash) && - p_uniname->name_len == strm_ep->name_len) { - order = 1; - } else { - is_feasible_entry = false; - step = num_ext_entries; - } - } - } else if (entry_type == TYPE_EXTEND) { - if (is_feasible_entry) { - name_ep = (struct name_dentry_t *)ep; - - if ((++order) == 2) - uniname = p_uniname->name; - else - uniname += 15; - - len = extract_uni_name_from_name_entry(name_ep, - entry_uniname, order); - - unichar = *(uniname + len); - *(uniname + len) = 0x0; - - if (nls_uniname_cmp(sb, uniname, entry_uniname)) { - is_feasible_entry = false; - step = num_ext_entries - order + 1; - } else if (order == num_ext_entries) { - p_fs->hint_uentry.dir = CLUSTER_32(~0); - p_fs->hint_uentry.entry = -1; - return dentry - (num_ext_entries); - } - - *(uniname + len) = unichar; - } - } else { - is_feasible_entry = false; - } - } - - i += step; - dentry += step; - } - - i -= dentries_per_clu; - - if (p_dir->dir == CLUSTER_32(0)) - break; /* FAT16 root_dir */ - - if (clu.flags == 0x03) { - if ((--clu.size) > 0) - clu.dir++; - else - clu.dir = CLUSTER_32(~0); - } else { - if (exfat_fat_read(sb, clu.dir, &clu.dir) != 0) - return -2; - } - } - - return -2; -} - -s32 exfat_count_ext_entries(struct super_block *sb, struct chain_t *p_dir, - s32 entry, struct dentry_t *p_entry) -{ - int i, count = 0; - u32 type; - struct file_dentry_t *file_ep = (struct file_dentry_t *)p_entry; - struct dentry_t *ext_ep; - - for (i = 0, entry++; i < file_ep->num_ext; i++, entry++) { - ext_ep = get_entry_in_dir(sb, p_dir, entry, NULL); - if (!ext_ep) - return -1; - - type = exfat_get_entry_type(ext_ep); - if ((type == TYPE_EXTEND) || (type == TYPE_STREAM)) - count++; - else - return count; - } - - return count; -} - -s32 count_dir_entries(struct super_block *sb, struct chain_t *p_dir) -{ - int i, count = 0; - s32 dentries_per_clu; - u32 entry_type; - struct chain_t clu; - struct dentry_t *ep; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */ - dentries_per_clu = p_fs->dentries_in_root; - else - dentries_per_clu = p_fs->dentries_per_clu; - - clu.dir = p_dir->dir; - clu.size = p_dir->size; - clu.flags = p_dir->flags; - - while (clu.dir != CLUSTER_32(~0)) { - if (p_fs->dev_ejected) - break; - - for (i = 0; i < dentries_per_clu; i++) { - ep = get_entry_in_dir(sb, &clu, i, NULL); - if (!ep) - return -ENOENT; - - entry_type = exfat_get_entry_type(ep); - - if (entry_type == TYPE_UNUSED) - return count; - if (entry_type == TYPE_DIR) - count++; - } - - if (p_dir->dir == CLUSTER_32(0)) - break; /* FAT16 root_dir */ - - if (clu.flags == 0x03) { - if ((--clu.size) > 0) - clu.dir++; - else - clu.dir = CLUSTER_32(~0); - } else { - if (exfat_fat_read(sb, clu.dir, &clu.dir) != 0) - return -EIO; - } - } - - return count; -} - -bool is_dir_empty(struct super_block *sb, struct chain_t *p_dir) -{ - int i; - s32 dentries_per_clu; - u32 type; - struct chain_t clu; - struct dentry_t *ep; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */ - dentries_per_clu = p_fs->dentries_in_root; - else - dentries_per_clu = p_fs->dentries_per_clu; - - clu.dir = p_dir->dir; - clu.size = p_dir->size; - clu.flags = p_dir->flags; - - while (clu.dir != CLUSTER_32(~0)) { - if (p_fs->dev_ejected) - break; - - for (i = 0; i < dentries_per_clu; i++) { - ep = get_entry_in_dir(sb, &clu, i, NULL); - if (!ep) - break; - - type = exfat_get_entry_type(ep); - - if (type == TYPE_UNUSED) - return true; - if ((type == TYPE_FILE) || (type == TYPE_DIR)) - return false; - } - - if (p_dir->dir == CLUSTER_32(0)) - break; /* FAT16 root_dir */ - - if (clu.flags == 0x03) { - if ((--clu.size) > 0) - clu.dir++; - else - clu.dir = CLUSTER_32(~0); - } - if (exfat_fat_read(sb, clu.dir, &clu.dir) != 0) - break; - } - - return true; -} - -/* - * Name Conversion Functions - */ - -/* input : dir, uni_name - * output : num_of_entry - */ -s32 get_num_entries(struct super_block *sb, struct chain_t *p_dir, - struct uni_name_t *p_uniname, s32 *entries) -{ - s32 num_entries; - - num_entries = exfat_calc_num_entries(p_uniname); - if (num_entries == 0) - return -EINVAL; - - *entries = num_entries; - - return 0; -} - -void exfat_get_uni_name_from_ext_entry(struct super_block *sb, - struct chain_t *p_dir, s32 entry, - u16 *uniname) -{ - int i; - struct dentry_t *ep; - struct entry_set_cache_t *es; - - es = get_entry_set_in_dir(sb, p_dir, entry, ES_ALL_ENTRIES, &ep); - if (!es || es->num_entries < 3) { - if (es) - release_entry_set(es); - return; - } - - ep += 2; - - /* - * First entry : file entry - * Second entry : stream-extension entry - * Third entry : first file-name entry - * So, the index of first file-name dentry should start from 2. - */ - for (i = 2; i < es->num_entries; i++, ep++) { - if (exfat_get_entry_type(ep) == TYPE_EXTEND) - extract_uni_name_from_name_entry((struct name_dentry_t *) - ep, uniname, i); - else - goto out; - uniname += 15; - } - -out: - release_entry_set(es); -} - -s32 exfat_calc_num_entries(struct uni_name_t *p_uniname) -{ - s32 len; - - len = p_uniname->name_len; - if (len == 0) - return 0; - - /* 1 file entry + 1 stream entry + name entries */ - return (len - 1) / 15 + 3; -} - -u16 calc_checksum_2byte(void *data, s32 len, u16 chksum, s32 type) -{ - int i; - u8 *c = (u8 *)data; - - switch (type) { - case CS_DIR_ENTRY: - for (i = 0; i < len; i++, c++) { - if ((i == 2) || (i == 3)) - continue; - chksum = (((chksum & 1) << 15) | - ((chksum & 0xFFFE) >> 1)) + (u16)*c; - } - break; - default - : - for (i = 0; i < len; i++, c++) - chksum = (((chksum & 1) << 15) | - ((chksum & 0xFFFE) >> 1)) + (u16)*c; - } - - return chksum; -} - -/* - * Name Resolution Functions - */ - -/* return values of resolve_path() - * > 0 : return the length of the path - * < 0 : return error - */ -s32 resolve_path(struct inode *inode, char *path, struct chain_t *p_dir, - struct uni_name_t *p_uniname) -{ - bool lossy = false; - struct super_block *sb = inode->i_sb; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct file_id_t *fid = &(EXFAT_I(inode)->fid); - - if (strscpy(name_buf, path, sizeof(name_buf)) < 0) - return -EINVAL; - - nls_cstring_to_uniname(sb, p_uniname, name_buf, &lossy); - if (lossy) - return -EINVAL; - - fid->size = i_size_read(inode); - - p_dir->dir = fid->start_clu; - p_dir->size = (s32)(fid->size >> p_fs->cluster_size_bits); - p_dir->flags = fid->flags; - - return 0; -} - -s32 exfat_mount(struct super_block *sb, struct pbr_sector_t *p_pbr) -{ - struct bpbex_t *p_bpb = (struct bpbex_t *)p_pbr->bpb; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - - if (p_bpb->num_fats == 0) - return -EFSCORRUPTED; - - p_fs->sectors_per_clu = 1 << p_bpb->sectors_per_clu_bits; - p_fs->sectors_per_clu_bits = p_bpb->sectors_per_clu_bits; - p_fs->cluster_size_bits = p_fs->sectors_per_clu_bits + - p_bd->sector_size_bits; - p_fs->cluster_size = 1 << p_fs->cluster_size_bits; - - p_fs->num_FAT_sectors = GET32(p_bpb->fat_length); - - p_fs->FAT1_start_sector = p_fs->PBR_sector + GET32(p_bpb->fat_offset); - if (p_bpb->num_fats == 1) - p_fs->FAT2_start_sector = p_fs->FAT1_start_sector; - else - p_fs->FAT2_start_sector = p_fs->FAT1_start_sector + - p_fs->num_FAT_sectors; - - p_fs->root_start_sector = p_fs->PBR_sector + GET32(p_bpb->clu_offset); - p_fs->data_start_sector = p_fs->root_start_sector; - - p_fs->num_sectors = GET64(p_bpb->vol_length); - p_fs->num_clusters = GET32(p_bpb->clu_count) + 2; - /* because the cluster index starts with 2 */ - - p_fs->vol_id = GET32(p_bpb->vol_serial); - - p_fs->root_dir = GET32(p_bpb->root_cluster); - p_fs->dentries_in_root = 0; - p_fs->dentries_per_clu = 1 << (p_fs->cluster_size_bits - - DENTRY_SIZE_BITS); - - p_fs->vol_flag = (u32)GET16(p_bpb->vol_flags); - p_fs->clu_srch_ptr = 2; - p_fs->used_clusters = UINT_MAX; - - return 0; -} - -s32 create_dir(struct inode *inode, struct chain_t *p_dir, - struct uni_name_t *p_uniname, struct file_id_t *fid) -{ - s32 ret, dentry, num_entries; - u64 size; - struct chain_t clu; - struct super_block *sb = inode->i_sb; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - ret = get_num_entries(sb, p_dir, p_uniname, &num_entries); - if (ret) - return ret; - - /* find_empty_entry must be called before alloc_cluster */ - dentry = find_empty_entry(inode, p_dir, num_entries); - if (dentry < 0) - return -ENOSPC; - - clu.dir = CLUSTER_32(~0); - clu.size = 0; - clu.flags = 0x03; - - /* (1) allocate a cluster */ - ret = exfat_alloc_cluster(sb, 1, &clu); - if (ret < 0) - return ret; - else if (ret == 0) - return -ENOSPC; - - ret = clear_cluster(sb, clu.dir); - if (ret != 0) - return ret; - - size = p_fs->cluster_size; - - /* (2) update the directory entry */ - /* make sub-dir entry in parent directory */ - ret = exfat_init_dir_entry(sb, p_dir, dentry, TYPE_DIR, clu.dir, - size); - if (ret != 0) - return ret; - - ret = exfat_init_ext_entry(sb, p_dir, dentry, num_entries, p_uniname); - if (ret != 0) - return ret; - - fid->dir.dir = p_dir->dir; - fid->dir.size = p_dir->size; - fid->dir.flags = p_dir->flags; - fid->entry = dentry; - - fid->attr = ATTR_SUBDIR; - fid->flags = 0x03; - fid->size = size; - fid->start_clu = clu.dir; - - fid->type = TYPE_DIR; - fid->rwoffset = 0; - fid->hint_last_off = -1; - - return 0; -} - -s32 create_file(struct inode *inode, struct chain_t *p_dir, - struct uni_name_t *p_uniname, struct file_id_t *fid) -{ - s32 ret, dentry, num_entries; - struct super_block *sb = inode->i_sb; - - ret = get_num_entries(sb, p_dir, p_uniname, &num_entries); - if (ret) - return ret; - - /* find_empty_entry must be called before alloc_cluster() */ - dentry = find_empty_entry(inode, p_dir, num_entries); - if (dentry < 0) - return -ENOSPC; - - /* (1) update the directory entry */ - /* fill the directory entry information of the created file. - * the first cluster is not determined yet. (0) - */ - ret = exfat_init_dir_entry(sb, p_dir, dentry, TYPE_FILE, - CLUSTER_32(0), 0); - if (ret != 0) - return ret; - - ret = exfat_init_ext_entry(sb, p_dir, dentry, num_entries, p_uniname); - if (ret != 0) - return ret; - - fid->dir.dir = p_dir->dir; - fid->dir.size = p_dir->size; - fid->dir.flags = p_dir->flags; - fid->entry = dentry; - - fid->attr = ATTR_ARCHIVE; - fid->flags = 0x03; - fid->size = 0; - fid->start_clu = CLUSTER_32(~0); - - fid->type = TYPE_FILE; - fid->rwoffset = 0; - fid->hint_last_off = -1; - - return 0; -} - -void remove_file(struct inode *inode, struct chain_t *p_dir, s32 entry) -{ - s32 num_entries; - sector_t sector; - struct dentry_t *ep; - struct super_block *sb = inode->i_sb; - - ep = get_entry_in_dir(sb, p_dir, entry, §or); - if (!ep) - return; - - exfat_buf_lock(sb, sector); - - /* exfat_buf_lock() before call count_ext_entries() */ - num_entries = exfat_count_ext_entries(sb, p_dir, entry, ep); - if (num_entries < 0) { - exfat_buf_unlock(sb, sector); - return; - } - num_entries++; - - exfat_buf_unlock(sb, sector); - - /* (1) update the directory entry */ - exfat_delete_dir_entry(sb, p_dir, entry, 0, num_entries); -} - -s32 exfat_rename_file(struct inode *inode, struct chain_t *p_dir, s32 oldentry, - struct uni_name_t *p_uniname, struct file_id_t *fid) -{ - s32 ret, newentry = -1, num_old_entries, num_new_entries; - sector_t sector_old, sector_new; - struct dentry_t *epold, *epnew; - struct super_block *sb = inode->i_sb; - - epold = get_entry_in_dir(sb, p_dir, oldentry, §or_old); - if (!epold) - return -ENOENT; - - exfat_buf_lock(sb, sector_old); - - /* exfat_buf_lock() before call count_ext_entries() */ - num_old_entries = exfat_count_ext_entries(sb, p_dir, oldentry, - epold); - if (num_old_entries < 0) { - exfat_buf_unlock(sb, sector_old); - return -ENOENT; - } - num_old_entries++; - - ret = get_num_entries(sb, p_dir, p_uniname, &num_new_entries); - if (ret) { - exfat_buf_unlock(sb, sector_old); - return ret; - } - - if (num_old_entries < num_new_entries) { - newentry = find_empty_entry(inode, p_dir, num_new_entries); - if (newentry < 0) { - exfat_buf_unlock(sb, sector_old); - return -ENOSPC; - } - - epnew = get_entry_in_dir(sb, p_dir, newentry, §or_new); - if (!epnew) { - exfat_buf_unlock(sb, sector_old); - return -ENOENT; - } - - *epnew = *epold; - if (fid->type == TYPE_FILE) { - fid->attr |= ATTR_ARCHIVE; - exfat_set_entry_attr(epnew, fid->attr); - } - exfat_buf_modify(sb, sector_new); - exfat_buf_unlock(sb, sector_old); - - epold = get_entry_in_dir(sb, p_dir, oldentry + 1, - §or_old); - exfat_buf_lock(sb, sector_old); - epnew = get_entry_in_dir(sb, p_dir, newentry + 1, - §or_new); - - if (!epold || !epnew) { - exfat_buf_unlock(sb, sector_old); - return -ENOENT; - } - - *epnew = *epold; - exfat_buf_modify(sb, sector_new); - exfat_buf_unlock(sb, sector_old); - - ret = exfat_init_ext_entry(sb, p_dir, newentry, - num_new_entries, p_uniname); - if (ret != 0) - return ret; - - exfat_delete_dir_entry(sb, p_dir, oldentry, 0, - num_old_entries); - fid->entry = newentry; - } else { - if (fid->type == TYPE_FILE) { - fid->attr |= ATTR_ARCHIVE; - exfat_set_entry_attr(epold, fid->attr); - } - exfat_buf_modify(sb, sector_old); - exfat_buf_unlock(sb, sector_old); - - ret = exfat_init_ext_entry(sb, p_dir, oldentry, - num_new_entries, p_uniname); - if (ret != 0) - return ret; - - exfat_delete_dir_entry(sb, p_dir, oldentry, num_new_entries, - num_old_entries); - } - - return 0; -} - -s32 move_file(struct inode *inode, struct chain_t *p_olddir, s32 oldentry, - struct chain_t *p_newdir, struct uni_name_t *p_uniname, - struct file_id_t *fid) -{ - s32 ret, newentry, num_new_entries, num_old_entries; - sector_t sector_mov, sector_new; - struct dentry_t *epmov, *epnew; - struct super_block *sb = inode->i_sb; - - epmov = get_entry_in_dir(sb, p_olddir, oldentry, §or_mov); - if (!epmov) - return -ENOENT; - - /* check if the source and target directory is the same */ - if (exfat_get_entry_type(epmov) == TYPE_DIR && - exfat_get_entry_clu0(epmov) == p_newdir->dir) - return -EINVAL; - - exfat_buf_lock(sb, sector_mov); - - /* exfat_buf_lock() before call count_ext_entries() */ - num_old_entries = exfat_count_ext_entries(sb, p_olddir, oldentry, - epmov); - if (num_old_entries < 0) { - exfat_buf_unlock(sb, sector_mov); - return -ENOENT; - } - num_old_entries++; - - ret = get_num_entries(sb, p_newdir, p_uniname, &num_new_entries); - if (ret) { - exfat_buf_unlock(sb, sector_mov); - return ret; - } - - newentry = find_empty_entry(inode, p_newdir, num_new_entries); - if (newentry < 0) { - exfat_buf_unlock(sb, sector_mov); - return -ENOSPC; - } - - epnew = get_entry_in_dir(sb, p_newdir, newentry, §or_new); - if (!epnew) { - exfat_buf_unlock(sb, sector_mov); - return -ENOENT; - } - - *epnew = *epmov; - if (fid->type == TYPE_FILE) { - fid->attr |= ATTR_ARCHIVE; - exfat_set_entry_attr(epnew, fid->attr); - } - exfat_buf_modify(sb, sector_new); - exfat_buf_unlock(sb, sector_mov); - - epmov = get_entry_in_dir(sb, p_olddir, oldentry + 1, - §or_mov); - exfat_buf_lock(sb, sector_mov); - epnew = get_entry_in_dir(sb, p_newdir, newentry + 1, - §or_new); - if (!epmov || !epnew) { - exfat_buf_unlock(sb, sector_mov); - return -ENOENT; - } - - *epnew = *epmov; - exfat_buf_modify(sb, sector_new); - exfat_buf_unlock(sb, sector_mov); - - ret = exfat_init_ext_entry(sb, p_newdir, newentry, num_new_entries, - p_uniname); - if (ret != 0) - return ret; - - exfat_delete_dir_entry(sb, p_olddir, oldentry, 0, num_old_entries); - - fid->dir.dir = p_newdir->dir; - fid->dir.size = p_newdir->size; - fid->dir.flags = p_newdir->flags; - - fid->entry = newentry; - - return 0; -} - -/* - * Sector Read/Write Functions - */ - -int sector_read(struct super_block *sb, sector_t sec, struct buffer_head **bh, - bool read) -{ - s32 ret = -EIO; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - if ((sec >= (p_fs->PBR_sector + p_fs->num_sectors)) && - (p_fs->num_sectors > 0)) { - pr_err("[EXFAT] %s: out of range error! (sec = %llu)\n", - __func__, (unsigned long long)sec); - fs_error(sb); - return ret; - } - - if (!p_fs->dev_ejected) { - ret = exfat_bdev_read(sb, sec, bh, 1, read); - if (ret != 0) - p_fs->dev_ejected = 1; - } - - return ret; -} - -int sector_write(struct super_block *sb, sector_t sec, struct buffer_head *bh, - bool sync) -{ - s32 ret = -EIO; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - if (sec >= (p_fs->PBR_sector + p_fs->num_sectors) && - (p_fs->num_sectors > 0)) { - pr_err("[EXFAT] %s: out of range error! (sec = %llu)\n", - __func__, (unsigned long long)sec); - fs_error(sb); - return ret; - } - - if (!bh) { - pr_err("[EXFAT] %s: bh is NULL!\n", __func__); - fs_error(sb); - return ret; - } - - if (!p_fs->dev_ejected) { - ret = exfat_bdev_write(sb, sec, bh, 1, sync); - if (ret != 0) - p_fs->dev_ejected = 1; - } - - return ret; -} - -int multi_sector_read(struct super_block *sb, sector_t sec, - struct buffer_head **bh, s32 num_secs, bool read) -{ - s32 ret = -EIO; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - if (((sec + num_secs) > (p_fs->PBR_sector + p_fs->num_sectors)) && - (p_fs->num_sectors > 0)) { - pr_err("[EXFAT] %s: out of range error! (sec = %llu, num_secs = %d)\n", - __func__, (unsigned long long)sec, num_secs); - fs_error(sb); - return ret; - } - - if (!p_fs->dev_ejected) { - ret = exfat_bdev_read(sb, sec, bh, num_secs, read); - if (ret != 0) - p_fs->dev_ejected = 1; - } - - return ret; -} - -int multi_sector_write(struct super_block *sb, sector_t sec, - struct buffer_head *bh, s32 num_secs, bool sync) -{ - s32 ret = -EIO; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - if ((sec + num_secs) > (p_fs->PBR_sector + p_fs->num_sectors) && - (p_fs->num_sectors > 0)) { - pr_err("[EXFAT] %s: out of range error! (sec = %llu, num_secs = %d)\n", - __func__, (unsigned long long)sec, num_secs); - fs_error(sb); - return ret; - } - if (!bh) { - pr_err("[EXFAT] %s: bh is NULL!\n", __func__); - fs_error(sb); - return ret; - } - - if (!p_fs->dev_ejected) { - ret = exfat_bdev_write(sb, sec, bh, num_secs, sync); - if (ret != 0) - p_fs->dev_ejected = 1; - } - - return ret; -} diff --git a/drivers/staging/exfat/exfat_nls.c b/drivers/staging/exfat/exfat_nls.c deleted file mode 100644 index 91e8b0c4dce7..000000000000 --- a/drivers/staging/exfat/exfat_nls.c +++ /dev/null @@ -1,212 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. - */ - -#include -#include -#include "exfat.h" - -static u16 bad_uni_chars[] = { - /* " * / : < > ? \ | */ - 0x0022, 0x002A, 0x002F, 0x003A, - 0x003C, 0x003E, 0x003F, 0x005C, 0x007C, - 0 -}; - -static int convert_ch_to_uni(struct nls_table *nls, u16 *uni, u8 *ch, - bool *lossy) -{ - int len; - - *uni = 0x0; - - if (ch[0] < 0x80) { - *uni = (u16)ch[0]; - return 1; - } - - len = nls->char2uni(ch, NLS_MAX_CHARSET_SIZE, uni); - if (len < 0) { - /* conversion failed */ - pr_info("%s: fail to use nls\n", __func__); - if (lossy) - *lossy = true; - *uni = (u16)'_'; - if (!strcmp(nls->charset, "utf8")) - return 1; - else - return 2; - } - - return len; -} - -static int convert_uni_to_ch(struct nls_table *nls, u8 *ch, u16 uni, - bool *lossy) -{ - int len; - - ch[0] = 0x0; - - if (uni < 0x0080) { - ch[0] = (u8)uni; - return 1; - } - - len = nls->uni2char(uni, ch, NLS_MAX_CHARSET_SIZE); - if (len < 0) { - /* conversion failed */ - pr_info("%s: fail to use nls\n", __func__); - if (lossy) - *lossy = true; - ch[0] = '_'; - return 1; - } - - return len; -} - -u16 nls_upper(struct super_block *sb, u16 a) -{ - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - if (EXFAT_SB(sb)->options.casesensitive) - return a; - if (p_fs->vol_utbl && p_fs->vol_utbl[get_col_index(a)]) - return p_fs->vol_utbl[get_col_index(a)][get_row_index(a)]; - else - return a; -} - -static u16 *nls_wstrchr(u16 *str, u16 wchar) -{ - while (*str) { - if (*(str++) == wchar) - return str; - } - - return NULL; -} - -int nls_uniname_cmp(struct super_block *sb, u16 *a, u16 *b) -{ - int i; - - for (i = 0; i < MAX_NAME_LENGTH; i++, a++, b++) { - if (nls_upper(sb, *a) != nls_upper(sb, *b)) - return 1; - if (*a == 0x0) - return 0; - } - return 0; -} - -void nls_uniname_to_cstring(struct super_block *sb, u8 *p_cstring, - struct uni_name_t *p_uniname) -{ - int i, j, len; - u8 buf[MAX_CHARSET_SIZE]; - u16 *uniname = p_uniname->name; - struct nls_table *nls = EXFAT_SB(sb)->nls_io; - - if (!nls) { - len = utf16s_to_utf8s(uniname, MAX_NAME_LENGTH, - UTF16_HOST_ENDIAN, p_cstring, - MAX_NAME_LENGTH); - p_cstring[len] = 0; - return; - } - - i = 0; - while (i < (MAX_NAME_LENGTH - 1)) { - if (*uniname == (u16)'\0') - break; - - len = convert_uni_to_ch(nls, buf, *uniname, NULL); - - if (len > 1) { - for (j = 0; j < len; j++) - *p_cstring++ = (char)*(buf + j); - } else { /* len == 1 */ - *p_cstring++ = (char)*buf; - } - - uniname++; - i++; - } - - *p_cstring = '\0'; -} - -void nls_cstring_to_uniname(struct super_block *sb, - struct uni_name_t *p_uniname, u8 *p_cstring, - bool *p_lossy) -{ - int i, j; - bool lossy = false; - u8 *end_of_name; - u8 upname[MAX_NAME_LENGTH * 2]; - u16 *uniname = p_uniname->name; - struct nls_table *nls = EXFAT_SB(sb)->nls_io; - - /* strip all trailing spaces */ - end_of_name = p_cstring + strlen(p_cstring); - - while (*(--end_of_name) == ' ') { - if (end_of_name < p_cstring) - break; - } - *(++end_of_name) = '\0'; - - if (strcmp(p_cstring, ".") && strcmp(p_cstring, "..")) { - /* strip all trailing periods */ - while (*(--end_of_name) == '.') { - if (end_of_name < p_cstring) - break; - } - *(++end_of_name) = '\0'; - } - - if (*p_cstring == '\0') - lossy = true; - - if (!nls) { - i = utf8s_to_utf16s(p_cstring, MAX_NAME_LENGTH, - UTF16_HOST_ENDIAN, uniname, - MAX_NAME_LENGTH); - for (j = 0; j < i; j++) - SET16_A(upname + j * 2, nls_upper(sb, uniname[j])); - uniname[i] = '\0'; - } else { - i = 0; - j = 0; - while (j < (MAX_NAME_LENGTH - 1)) { - if (*(p_cstring + i) == '\0') - break; - - i += convert_ch_to_uni(nls, uniname, - (u8 *)(p_cstring + i), &lossy); - - if ((*uniname < 0x0020) || - nls_wstrchr(bad_uni_chars, *uniname)) - lossy = true; - - SET16_A(upname + j * 2, nls_upper(sb, *uniname)); - - uniname++; - j++; - } - - if (*(p_cstring + i) != '\0') - lossy = true; - *uniname = (u16)'\0'; - } - - p_uniname->name_len = j; - p_uniname->name_hash = calc_checksum_2byte(upname, j << 1, 0, - CS_DEFAULT); - - if (p_lossy) - *p_lossy = lossy; -} diff --git a/drivers/staging/exfat/exfat_super.c b/drivers/staging/exfat/exfat_super.c deleted file mode 100644 index af97f5a83c5b..000000000000 --- a/drivers/staging/exfat/exfat_super.c +++ /dev/null @@ -1,3296 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define EXFAT_VERSION "1.3.0" - -#include "exfat.h" - -static struct kmem_cache *exfat_inode_cachep; - -static int exfat_default_codepage = CONFIG_STAGING_EXFAT_DEFAULT_CODEPAGE; -static char exfat_default_iocharset[] = CONFIG_STAGING_EXFAT_DEFAULT_IOCHARSET; - -#define INC_IVERSION(x) (inode_inc_iversion(x)) -#define GET_IVERSION(x) (inode_peek_iversion_raw(x)) -#define SET_IVERSION(x, y) (inode_set_iversion(x, y)) - -static struct inode *exfat_iget(struct super_block *sb, loff_t i_pos); -static int exfat_sync_inode(struct inode *inode); -static struct inode *exfat_build_inode(struct super_block *sb, - struct file_id_t *fid, loff_t i_pos); -static int exfat_write_inode(struct inode *inode, - struct writeback_control *wbc); -static void exfat_write_super(struct super_block *sb); - -#define UNIX_SECS_1980 315532800L -#define UNIX_SECS_2108 4354819200L - -/* Convert a FAT time/date pair to a UNIX date (seconds since 1 1 70). */ -static void exfat_time_fat2unix(struct timespec64 *ts, struct date_time_t *tp) -{ - ts->tv_sec = mktime64(tp->year + 1980, tp->month + 1, tp->day, - tp->hour, tp->minute, tp->second); - - ts->tv_nsec = tp->millisecond * NSEC_PER_MSEC; -} - -/* Convert linear UNIX date to a FAT time/date pair. */ -static void exfat_time_unix2fat(struct timespec64 *ts, struct date_time_t *tp) -{ - time64_t second = ts->tv_sec; - struct tm tm; - - time64_to_tm(second, 0, &tm); - - if (second < UNIX_SECS_1980) { - tp->millisecond = 0; - tp->second = 0; - tp->minute = 0; - tp->hour = 0; - tp->day = 1; - tp->month = 1; - tp->year = 0; - return; - } - - if (second >= UNIX_SECS_2108) { - tp->millisecond = 999; - tp->second = 59; - tp->minute = 59; - tp->hour = 23; - tp->day = 31; - tp->month = 12; - tp->year = 127; - return; - } - - tp->millisecond = ts->tv_nsec / NSEC_PER_MSEC; - tp->second = tm.tm_sec; - tp->minute = tm.tm_min; - tp->hour = tm.tm_hour; - tp->day = tm.tm_mday; - tp->month = tm.tm_mon + 1; - tp->year = tm.tm_year + 1900 - 1980; -} - -struct timestamp_t *tm_current(struct timestamp_t *tp) -{ - time64_t second = ktime_get_real_seconds(); - struct tm tm; - - time64_to_tm(second, 0, &tm); - - if (second < UNIX_SECS_1980) { - tp->sec = 0; - tp->min = 0; - tp->hour = 0; - tp->day = 1; - tp->mon = 1; - tp->year = 0; - return tp; - } - - if (second >= UNIX_SECS_2108) { - tp->sec = 59; - tp->min = 59; - tp->hour = 23; - tp->day = 31; - tp->mon = 12; - tp->year = 127; - return tp; - } - - tp->sec = tm.tm_sec; - tp->min = tm.tm_min; - tp->hour = tm.tm_hour; - tp->day = tm.tm_mday; - tp->mon = tm.tm_mon + 1; - tp->year = tm.tm_year + 1900 - 1980; - - return tp; -} - -static void __lock_super(struct super_block *sb) -{ - struct exfat_sb_info *sbi = EXFAT_SB(sb); - - mutex_lock(&sbi->s_lock); -} - -static void __unlock_super(struct super_block *sb) -{ - struct exfat_sb_info *sbi = EXFAT_SB(sb); - - mutex_unlock(&sbi->s_lock); -} - -static int __is_sb_dirty(struct super_block *sb) -{ - struct exfat_sb_info *sbi = EXFAT_SB(sb); - - return sbi->s_dirt; -} - -static void __set_sb_clean(struct super_block *sb) -{ - struct exfat_sb_info *sbi = EXFAT_SB(sb); - - sbi->s_dirt = 0; -} - -static int __exfat_revalidate(struct dentry *dentry) -{ - return 0; -} - -static int exfat_revalidate(struct dentry *dentry, unsigned int flags) -{ - if (flags & LOOKUP_RCU) - return -ECHILD; - - if (dentry->d_inode) - return 1; - return __exfat_revalidate(dentry); -} - -static int exfat_revalidate_ci(struct dentry *dentry, unsigned int flags) -{ - if (flags & LOOKUP_RCU) - return -ECHILD; - - if (dentry->d_inode) - return 1; - - if (!flags) - return 0; - - if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) - return 0; - - return __exfat_revalidate(dentry); -} - -static unsigned int __exfat_striptail_len(unsigned int len, const char *name) -{ - while (len && name[len - 1] == '.') - len--; - return len; -} - -static unsigned int exfat_striptail_len(const struct qstr *qstr) -{ - return __exfat_striptail_len(qstr->len, qstr->name); -} - -static int exfat_d_hash(const struct dentry *dentry, struct qstr *qstr) -{ - qstr->hash = full_name_hash(dentry, qstr->name, - exfat_striptail_len(qstr)); - return 0; -} - -static int exfat_d_hashi(const struct dentry *dentry, struct qstr *qstr) -{ - struct super_block *sb = dentry->d_sb; - const unsigned char *name; - unsigned int len; - unsigned long hash; - - name = qstr->name; - len = exfat_striptail_len(qstr); - - hash = init_name_hash(dentry); - while (len--) - hash = partial_name_hash(nls_upper(sb, *name++), hash); - qstr->hash = end_name_hash(hash); - - return 0; -} - -static int exfat_cmpi(const struct dentry *dentry, unsigned int len, - const char *str, const struct qstr *name) -{ - struct nls_table *t = EXFAT_SB(dentry->d_sb)->nls_io; - unsigned int alen, blen; - - alen = exfat_striptail_len(name); - blen = __exfat_striptail_len(len, str); - if (alen == blen) { - if (!t) { - if (strncasecmp(name->name, str, alen) == 0) - return 0; - } else { - if (nls_strnicmp(t, name->name, str, alen) == 0) - return 0; - } - } - return 1; -} - -static int exfat_cmp(const struct dentry *dentry, unsigned int len, - const char *str, const struct qstr *name) -{ - unsigned int alen, blen; - - alen = exfat_striptail_len(name); - blen = __exfat_striptail_len(len, str); - if (alen == blen) { - if (strncmp(name->name, str, alen) == 0) - return 0; - } - return 1; -} - -static const struct dentry_operations exfat_ci_dentry_ops = { - .d_revalidate = exfat_revalidate_ci, - .d_hash = exfat_d_hashi, - .d_compare = exfat_cmpi, -}; - -static const struct dentry_operations exfat_dentry_ops = { - .d_revalidate = exfat_revalidate, - .d_hash = exfat_d_hash, - .d_compare = exfat_cmp, -}; - -static DEFINE_MUTEX(z_mutex); - -static inline void fs_sync(struct super_block *sb, bool do_sync) -{ - if (do_sync) - exfat_bdev_sync(sb); -} - -/* - * If ->i_mode can't hold S_IWUGO (i.e. ATTR_RO), we use ->i_attrs to - * save ATTR_RO instead of ->i_mode. - * - * If it's directory and !sbi->options.rodir, ATTR_RO isn't read-only - * bit, it's just used as flag for app. - */ -static inline int exfat_mode_can_hold_ro(struct inode *inode) -{ - struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb); - - if (S_ISDIR(inode->i_mode)) - return 0; - - if ((~sbi->options.fs_fmask) & 0222) - return 1; - return 0; -} - -/* Convert attribute bits and a mask to the UNIX mode. */ -static inline mode_t exfat_make_mode(struct exfat_sb_info *sbi, u32 attr, - mode_t mode) -{ - if ((attr & ATTR_READONLY) && !(attr & ATTR_SUBDIR)) - mode &= ~0222; - - if (attr & ATTR_SUBDIR) - return (mode & ~sbi->options.fs_dmask) | S_IFDIR; - else - return (mode & ~sbi->options.fs_fmask) | S_IFREG; -} - -/* Return the FAT attribute byte for this inode */ -static inline u32 exfat_make_attr(struct inode *inode) -{ - if (exfat_mode_can_hold_ro(inode) && !(inode->i_mode & 0222)) - return (EXFAT_I(inode)->fid.attr) | ATTR_READONLY; - else - return EXFAT_I(inode)->fid.attr; -} - -static inline void exfat_save_attr(struct inode *inode, u32 attr) -{ - if (exfat_mode_can_hold_ro(inode)) - EXFAT_I(inode)->fid.attr = attr & ATTR_RWMASK; - else - EXFAT_I(inode)->fid.attr = attr & (ATTR_RWMASK | ATTR_READONLY); -} - -static int ffsMountVol(struct super_block *sb) -{ - int i, ret; - struct pbr_sector_t *p_pbr; - struct buffer_head *tmp_bh = NULL; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - - pr_info("[EXFAT] trying to mount...\n"); - - mutex_lock(&z_mutex); - - exfat_buf_init(sb); - - mutex_init(&p_fs->v_mutex); - p_fs->dev_ejected = 0; - - /* open the block device */ - exfat_bdev_open(sb); - - if (p_bd->sector_size < sb->s_blocksize) { - pr_info("EXFAT: mount failed - sector size %d less than blocksize %ld\n", - p_bd->sector_size, sb->s_blocksize); - ret = -EINVAL; - goto out; - } - if (p_bd->sector_size > sb->s_blocksize) - sb_set_blocksize(sb, p_bd->sector_size); - - /* read Sector 0 */ - if (sector_read(sb, 0, &tmp_bh, 1) != 0) { - ret = -EIO; - goto out; - } - - p_fs->PBR_sector = 0; - - p_pbr = (struct pbr_sector_t *)tmp_bh->b_data; - - /* check the validity of PBR */ - if (GET16_A(p_pbr->signature) != PBR_SIGNATURE) { - brelse(tmp_bh); - exfat_bdev_close(sb); - ret = -EFSCORRUPTED; - goto out; - } - - /* fill fs_struct */ - for (i = 0; i < 53; i++) - if (p_pbr->bpb[i]) - break; - - if (i < 53) { - /* Not sure how we'd get here, but complain if it does */ - ret = -EINVAL; - pr_info("EXFAT: Attempted to mount VFAT filesystem\n"); - goto out; - } else { - ret = exfat_mount(sb, p_pbr); - } - - brelse(tmp_bh); - - if (ret) { - exfat_bdev_close(sb); - goto out; - } - - ret = load_alloc_bitmap(sb); - if (ret) { - exfat_bdev_close(sb); - goto out; - } - ret = load_upcase_table(sb); - if (ret) { - free_alloc_bitmap(sb); - exfat_bdev_close(sb); - goto out; - } - - if (p_fs->dev_ejected) { - free_upcase_table(sb); - free_alloc_bitmap(sb); - exfat_bdev_close(sb); - ret = -EIO; - goto out; - } - - pr_info("[EXFAT] mounted successfully\n"); - -out: - mutex_unlock(&z_mutex); - - return ret; -} - -static int ffsUmountVol(struct super_block *sb) -{ - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - int err = 0; - - pr_info("[EXFAT] trying to unmount...\n"); - - mutex_lock(&z_mutex); - - /* acquire the lock for file system critical section */ - mutex_lock(&p_fs->v_mutex); - - fs_sync(sb, false); - fs_set_vol_flags(sb, VOL_CLEAN); - - free_upcase_table(sb); - free_alloc_bitmap(sb); - - exfat_fat_release_all(sb); - exfat_buf_release_all(sb); - - /* close the block device */ - exfat_bdev_close(sb); - - if (p_fs->dev_ejected) { - pr_info("[EXFAT] unmounted with media errors. Device is already ejected.\n"); - err = -EIO; - } - - exfat_buf_shutdown(sb); - - /* release the lock for file system critical section */ - mutex_unlock(&p_fs->v_mutex); - mutex_unlock(&z_mutex); - - pr_info("[EXFAT] unmounted successfully\n"); - - return err; -} - -static int ffsGetVolInfo(struct super_block *sb, struct vol_info_t *info) -{ - int err = 0; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - /* check the validity of pointer parameters */ - if (!info) - return -EINVAL; - - /* acquire the lock for file system critical section */ - mutex_lock(&p_fs->v_mutex); - - if (p_fs->used_clusters == UINT_MAX) - p_fs->used_clusters = exfat_count_used_clusters(sb); - - info->FatType = EXFAT; - info->ClusterSize = p_fs->cluster_size; - info->NumClusters = p_fs->num_clusters - 2; /* clu 0 & 1 */ - info->UsedClusters = p_fs->used_clusters; - info->FreeClusters = info->NumClusters - info->UsedClusters; - - if (p_fs->dev_ejected) - err = -EIO; - - /* release the lock for file system critical section */ - mutex_unlock(&p_fs->v_mutex); - - return err; -} - -static int ffsSyncVol(struct super_block *sb, bool do_sync) -{ - int err = 0; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - /* acquire the lock for file system critical section */ - mutex_lock(&p_fs->v_mutex); - - /* synchronize the file system */ - fs_sync(sb, do_sync); - fs_set_vol_flags(sb, VOL_CLEAN); - - if (p_fs->dev_ejected) - err = -EIO; - - /* release the lock for file system critical section */ - mutex_unlock(&p_fs->v_mutex); - - return err; -} - -/*----------------------------------------------------------------------*/ -/* File Operation Functions */ -/*----------------------------------------------------------------------*/ - -static int ffsLookupFile(struct inode *inode, char *path, struct file_id_t *fid) -{ - int ret, dentry, num_entries; - struct chain_t dir; - struct uni_name_t uni_name; - struct dentry_t *ep, *ep2; - struct entry_set_cache_t *es = NULL; - struct super_block *sb = inode->i_sb; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - pr_debug("%s entered\n", __func__); - - /* check the validity of pointer parameters */ - if (!fid || !path || (*path == '\0')) - return -EINVAL; - - /* acquire the lock for file system critical section */ - mutex_lock(&p_fs->v_mutex); - - /* check the validity of directory name in the given pathname */ - ret = resolve_path(inode, path, &dir, &uni_name); - if (ret) - goto out; - - ret = get_num_entries(sb, &dir, &uni_name, &num_entries); - if (ret) - goto out; - - /* search the file name for directories */ - dentry = exfat_find_dir_entry(sb, &dir, &uni_name, num_entries, - TYPE_ALL); - if (dentry < -1) { - ret = -ENOENT; - goto out; - } - - fid->dir.dir = dir.dir; - fid->dir.size = dir.size; - fid->dir.flags = dir.flags; - fid->entry = dentry; - - if (dentry == -1) { - fid->type = TYPE_DIR; - fid->rwoffset = 0; - fid->hint_last_off = -1; - - fid->attr = ATTR_SUBDIR; - fid->flags = 0x01; - fid->size = 0; - fid->start_clu = p_fs->root_dir; - } else { - es = get_entry_set_in_dir(sb, &dir, dentry, - ES_2_ENTRIES, &ep); - if (!es) { - ret = -ENOENT; - goto out; - } - ep2 = ep + 1; - - fid->type = exfat_get_entry_type(ep); - fid->rwoffset = 0; - fid->hint_last_off = -1; - fid->attr = exfat_get_entry_attr(ep); - - fid->size = exfat_get_entry_size(ep2); - if ((fid->type == TYPE_FILE) && (fid->size == 0)) { - fid->flags = 0x03; - fid->start_clu = CLUSTER_32(~0); - } else { - fid->flags = exfat_get_entry_flag(ep2); - fid->start_clu = exfat_get_entry_clu0(ep2); - } - - release_entry_set(es); - } - - if (p_fs->dev_ejected) - ret = -EIO; -out: - /* release the lock for file system critical section */ - mutex_unlock(&p_fs->v_mutex); - - return ret; -} - -static int ffsCreateFile(struct inode *inode, char *path, struct file_id_t *fid) -{ - struct chain_t dir; - struct uni_name_t uni_name; - struct super_block *sb = inode->i_sb; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - int ret = 0; - - /* check the validity of pointer parameters */ - if (!fid || !path || (*path == '\0')) - return -EINVAL; - - /* acquire the lock for file system critical section */ - mutex_lock(&p_fs->v_mutex); - - /* check the validity of directory name in the given pathname */ - ret = resolve_path(inode, path, &dir, &uni_name); - if (ret) - goto out; - - fs_set_vol_flags(sb, VOL_DIRTY); - - /* create a new file */ - ret = create_file(inode, &dir, &uni_name, fid); - -#ifndef CONFIG_STAGING_EXFAT_DELAYED_SYNC - fs_sync(sb, true); - fs_set_vol_flags(sb, VOL_CLEAN); -#endif - - if (p_fs->dev_ejected) - ret = -EIO; - -out: - /* release the lock for file system critical section */ - mutex_unlock(&p_fs->v_mutex); - - return ret; -} - -static int ffsTruncateFile(struct inode *inode, u64 old_size, u64 new_size) -{ - s32 num_clusters; - u32 last_clu = CLUSTER_32(0); - int ret = 0; - struct chain_t clu; - struct timestamp_t tm; - struct dentry_t *ep, *ep2; - struct super_block *sb = inode->i_sb; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct file_id_t *fid = &(EXFAT_I(inode)->fid); - struct entry_set_cache_t *es = NULL; - - pr_debug("%s entered (inode %p size %llu)\n", __func__, inode, - new_size); - - /* acquire the lock for file system critical section */ - mutex_lock(&p_fs->v_mutex); - - /* check if the given file ID is opened */ - if (fid->type != TYPE_FILE) { - ret = -EPERM; - goto out; - } - - if (fid->size != old_size) { - pr_err("[EXFAT] truncate : can't skip it because of size-mismatch(old:%lld->fid:%lld).\n", - old_size, fid->size); - } - - if (old_size <= new_size) { - ret = 0; - goto out; - } - - fs_set_vol_flags(sb, VOL_DIRTY); - - clu.dir = fid->start_clu; - clu.size = (s32)((old_size - 1) >> p_fs->cluster_size_bits) + 1; - clu.flags = fid->flags; - - if (new_size > 0) { - num_clusters = (s32)((new_size - 1) >> - p_fs->cluster_size_bits) + 1; - - if (clu.flags == 0x03) { - clu.dir += num_clusters; - } else { - while (num_clusters > 0) { - last_clu = clu.dir; - if (exfat_fat_read(sb, clu.dir, &clu.dir) == -1) { - ret = -EIO; - goto out; - } - num_clusters--; - } - } - - clu.size -= num_clusters; - } - - fid->size = new_size; - fid->attr |= ATTR_ARCHIVE; - if (new_size == 0) { - fid->flags = 0x03; - fid->start_clu = CLUSTER_32(~0); - } - - /* (1) update the directory entry */ - es = get_entry_set_in_dir(sb, &fid->dir, fid->entry, - ES_ALL_ENTRIES, &ep); - if (!es) { - ret = -ENOENT; - goto out; - } - ep2 = ep + 1; - - exfat_set_entry_time(ep, tm_current(&tm), TM_MODIFY); - exfat_set_entry_attr(ep, fid->attr); - - exfat_set_entry_size(ep2, new_size); - if (new_size == 0) { - exfat_set_entry_flag(ep2, 0x01); - exfat_set_entry_clu0(ep2, CLUSTER_32(0)); - } - - update_dir_checksum_with_entry_set(sb, es); - release_entry_set(es); - - /* (2) cut off from the FAT chain */ - if (last_clu != CLUSTER_32(0)) { - if (fid->flags == 0x01) - exfat_fat_write(sb, last_clu, CLUSTER_32(~0)); - } - - /* (3) free the clusters */ - exfat_free_cluster(sb, &clu, 0); - - /* hint information */ - fid->hint_last_off = -1; - if (fid->rwoffset > fid->size) - fid->rwoffset = fid->size; - -#ifndef CONFIG_STAGING_EXFAT_DELAYED_SYNC - fs_sync(sb, true); - fs_set_vol_flags(sb, VOL_CLEAN); -#endif - - if (p_fs->dev_ejected) - ret = -EIO; - -out: - pr_debug("%s exited (%d)\n", __func__, ret); - /* release the lock for file system critical section */ - mutex_unlock(&p_fs->v_mutex); - - return ret; -} - -static void update_parent_info(struct file_id_t *fid, - struct inode *parent_inode) -{ - struct fs_info_t *p_fs = &(EXFAT_SB(parent_inode->i_sb)->fs_info); - struct file_id_t *parent_fid = &(EXFAT_I(parent_inode)->fid); - - if (unlikely((parent_fid->flags != fid->dir.flags) || - (parent_fid->size != - (fid->dir.size << p_fs->cluster_size_bits)) || - (parent_fid->start_clu != fid->dir.dir))) { - fid->dir.dir = parent_fid->start_clu; - fid->dir.flags = parent_fid->flags; - fid->dir.size = ((parent_fid->size + (p_fs->cluster_size - 1)) - >> p_fs->cluster_size_bits); - } -} - -static int ffsMoveFile(struct inode *old_parent_inode, struct file_id_t *fid, - struct inode *new_parent_inode, struct dentry *new_dentry) -{ - s32 ret; - s32 dentry; - struct chain_t olddir, newdir; - struct chain_t *p_dir = NULL; - struct uni_name_t uni_name; - struct dentry_t *ep; - struct super_block *sb = old_parent_inode->i_sb; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - u8 *new_path = (u8 *)new_dentry->d_name.name; - struct inode *new_inode = new_dentry->d_inode; - int num_entries; - struct file_id_t *new_fid = NULL; - s32 new_entry = 0; - - /* check the validity of the given file id */ - if (!fid) - return -EINVAL; - - /* check the validity of pointer parameters */ - if (!new_path || (*new_path == '\0')) - return -EINVAL; - - /* acquire the lock for file system critical section */ - mutex_lock(&p_fs->v_mutex); - - update_parent_info(fid, old_parent_inode); - - olddir.dir = fid->dir.dir; - olddir.size = fid->dir.size; - olddir.flags = fid->dir.flags; - - dentry = fid->entry; - - ep = get_entry_in_dir(sb, &olddir, dentry, NULL); - if (!ep) { - ret = -ENOENT; - goto out2; - } - - if (exfat_get_entry_attr(ep) & ATTR_READONLY) { - ret = -EPERM; - goto out2; - } - - /* check whether new dir is existing directory and empty */ - if (new_inode) { - u32 entry_type; - - ret = -ENOENT; - new_fid = &EXFAT_I(new_inode)->fid; - - update_parent_info(new_fid, new_parent_inode); - - p_dir = &new_fid->dir; - new_entry = new_fid->entry; - ep = get_entry_in_dir(sb, p_dir, new_entry, NULL); - if (!ep) - goto out; - - entry_type = exfat_get_entry_type(ep); - - if (entry_type == TYPE_DIR) { - struct chain_t new_clu; - - new_clu.dir = new_fid->start_clu; - new_clu.size = (s32)((new_fid->size - 1) >> - p_fs->cluster_size_bits) + 1; - new_clu.flags = new_fid->flags; - - if (!is_dir_empty(sb, &new_clu)) { - ret = -EEXIST; - goto out; - } - } - } - - /* check the validity of directory name in the given new pathname */ - ret = resolve_path(new_parent_inode, new_path, &newdir, &uni_name); - if (ret) - goto out2; - - fs_set_vol_flags(sb, VOL_DIRTY); - - if (olddir.dir == newdir.dir) - ret = exfat_rename_file(new_parent_inode, &olddir, dentry, - &uni_name, fid); - else - ret = move_file(new_parent_inode, &olddir, dentry, &newdir, - &uni_name, fid); - - if ((ret == 0) && new_inode) { - /* delete entries of new_dir */ - ep = get_entry_in_dir(sb, p_dir, new_entry, NULL); - if (!ep) - goto out; - - num_entries = exfat_count_ext_entries(sb, p_dir, - new_entry, ep); - if (num_entries < 0) - goto out; - exfat_delete_dir_entry(sb, p_dir, new_entry, 0, - num_entries + 1); - } -out: -#ifndef CONFIG_STAGING_EXFAT_DELAYED_SYNC - fs_sync(sb, true); - fs_set_vol_flags(sb, VOL_CLEAN); -#endif - - if (p_fs->dev_ejected) - ret = -EIO; -out2: - /* release the lock for file system critical section */ - mutex_unlock(&p_fs->v_mutex); - - return ret; -} - -static int ffsRemoveFile(struct inode *inode, struct file_id_t *fid) -{ - s32 dentry; - int ret = 0; - struct chain_t dir, clu_to_free; - struct dentry_t *ep; - struct super_block *sb = inode->i_sb; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - /* check the validity of the given file id */ - if (!fid) - return -EINVAL; - - /* acquire the lock for file system critical section */ - mutex_lock(&p_fs->v_mutex); - - dir.dir = fid->dir.dir; - dir.size = fid->dir.size; - dir.flags = fid->dir.flags; - - dentry = fid->entry; - - ep = get_entry_in_dir(sb, &dir, dentry, NULL); - if (!ep) { - ret = -ENOENT; - goto out; - } - - if (exfat_get_entry_attr(ep) & ATTR_READONLY) { - ret = -EPERM; - goto out; - } - fs_set_vol_flags(sb, VOL_DIRTY); - - /* (1) update the directory entry */ - remove_file(inode, &dir, dentry); - - clu_to_free.dir = fid->start_clu; - clu_to_free.size = (s32)((fid->size - 1) >> p_fs->cluster_size_bits) + 1; - clu_to_free.flags = fid->flags; - - /* (2) free the clusters */ - exfat_free_cluster(sb, &clu_to_free, 0); - - fid->size = 0; - fid->start_clu = CLUSTER_32(~0); - fid->flags = 0x03; - -#ifndef CONFIG_STAGING_EXFAT_DELAYED_SYNC - fs_sync(sb, true); - fs_set_vol_flags(sb, VOL_CLEAN); -#endif - - if (p_fs->dev_ejected) - ret = -EIO; -out: - /* release the lock for file system critical section */ - mutex_unlock(&p_fs->v_mutex); - - return ret; -} - -static int ffsReadStat(struct inode *inode, struct dir_entry_t *info) -{ - s32 count; - int ret = 0; - struct chain_t dir; - struct uni_name_t uni_name; - struct timestamp_t tm; - struct dentry_t *ep, *ep2; - struct super_block *sb = inode->i_sb; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct file_id_t *fid = &(EXFAT_I(inode)->fid); - struct entry_set_cache_t *es = NULL; - u8 is_dir = (fid->type == TYPE_DIR) ? 1 : 0; - - pr_debug("%s entered\n", __func__); - - /* acquire the lock for file system critical section */ - mutex_lock(&p_fs->v_mutex); - - if (is_dir) { - if ((fid->dir.dir == p_fs->root_dir) && - (fid->entry == -1)) { - info->attr = ATTR_SUBDIR; - memset((char *)&info->create_timestamp, 0, - sizeof(struct date_time_t)); - memset((char *)&info->modify_timestamp, 0, - sizeof(struct date_time_t)); - memset((char *)&info->access_timestamp, 0, - sizeof(struct date_time_t)); - strcpy(info->name, "."); - - dir.dir = p_fs->root_dir; - dir.flags = 0x01; - - if (p_fs->root_dir == CLUSTER_32(0)) { - /* FAT16 root_dir */ - info->Size = p_fs->dentries_in_root << - DENTRY_SIZE_BITS; - } else { - info->Size = count_num_clusters(sb, &dir) << - p_fs->cluster_size_bits; - } - - count = count_dir_entries(sb, &dir); - if (count < 0) { - ret = count; /* propagate error upward */ - goto out; - } - info->num_subdirs = count; - - if (p_fs->dev_ejected) - ret = -EIO; - goto out; - } - } - - /* get the directory entry of given file or directory */ - es = get_entry_set_in_dir(sb, &fid->dir, fid->entry, - ES_2_ENTRIES, &ep); - if (!es) { - ret = -ENOENT; - goto out; - } - ep2 = ep + 1; - - /* set FILE_INFO structure using the acquired struct dentry_t */ - info->attr = exfat_get_entry_attr(ep); - - exfat_get_entry_time(ep, &tm, TM_CREATE); - info->create_timestamp.year = tm.year; - info->create_timestamp.month = tm.mon; - info->create_timestamp.day = tm.day; - info->create_timestamp.hour = tm.hour; - info->create_timestamp.minute = tm.min; - info->create_timestamp.second = tm.sec; - info->create_timestamp.millisecond = 0; - - exfat_get_entry_time(ep, &tm, TM_MODIFY); - info->modify_timestamp.year = tm.year; - info->modify_timestamp.month = tm.mon; - info->modify_timestamp.day = tm.day; - info->modify_timestamp.hour = tm.hour; - info->modify_timestamp.minute = tm.min; - info->modify_timestamp.second = tm.sec; - info->modify_timestamp.millisecond = 0; - - memset((char *)&info->access_timestamp, 0, sizeof(struct date_time_t)); - - *uni_name.name = 0x0; - /* XXX this is very bad for exfat cuz name is already included in es. - * API should be revised - */ - exfat_get_uni_name_from_ext_entry(sb, &fid->dir, fid->entry, - uni_name.name); - nls_uniname_to_cstring(sb, info->name, &uni_name); - - info->num_subdirs = 2; - - info->Size = exfat_get_entry_size(ep2); - - release_entry_set(es); - - if (is_dir) { - dir.dir = fid->start_clu; - dir.flags = 0x01; - - if (info->Size == 0) - info->Size = (u64)count_num_clusters(sb, &dir) << - p_fs->cluster_size_bits; - - count = count_dir_entries(sb, &dir); - if (count < 0) { - ret = count; /* propagate error upward */ - goto out; - } - info->num_subdirs += count; - } - - if (p_fs->dev_ejected) - ret = -EIO; - -out: - /* release the lock for file system critical section */ - mutex_unlock(&p_fs->v_mutex); - - pr_debug("%s exited successfully\n", __func__); - return ret; -} - -static int ffsWriteStat(struct inode *inode, struct dir_entry_t *info) -{ - int ret = 0; - struct timestamp_t tm; - struct dentry_t *ep, *ep2; - struct entry_set_cache_t *es = NULL; - struct super_block *sb = inode->i_sb; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct file_id_t *fid = &(EXFAT_I(inode)->fid); - u8 is_dir = (fid->type == TYPE_DIR) ? 1 : 0; - - pr_debug("%s entered (inode %p info %p\n", __func__, inode, info); - - /* acquire the lock for file system critical section */ - mutex_lock(&p_fs->v_mutex); - - if (is_dir) { - if ((fid->dir.dir == p_fs->root_dir) && - (fid->entry == -1)) { - if (p_fs->dev_ejected) - ret = -EIO; - ret = 0; - goto out; - } - } - - fs_set_vol_flags(sb, VOL_DIRTY); - - /* get the directory entry of given file or directory */ - es = get_entry_set_in_dir(sb, &fid->dir, fid->entry, - ES_ALL_ENTRIES, &ep); - if (!es) { - ret = -ENOENT; - goto out; - } - ep2 = ep + 1; - - exfat_set_entry_attr(ep, info->attr); - - /* set FILE_INFO structure using the acquired struct dentry_t */ - tm.sec = info->create_timestamp.second; - tm.min = info->create_timestamp.minute; - tm.hour = info->create_timestamp.hour; - tm.day = info->create_timestamp.day; - tm.mon = info->create_timestamp.month; - tm.year = info->create_timestamp.year; - exfat_set_entry_time(ep, &tm, TM_CREATE); - - tm.sec = info->modify_timestamp.second; - tm.min = info->modify_timestamp.minute; - tm.hour = info->modify_timestamp.hour; - tm.day = info->modify_timestamp.day; - tm.mon = info->modify_timestamp.month; - tm.year = info->modify_timestamp.year; - exfat_set_entry_time(ep, &tm, TM_MODIFY); - - exfat_set_entry_size(ep2, info->Size); - - update_dir_checksum_with_entry_set(sb, es); - release_entry_set(es); - - if (p_fs->dev_ejected) - ret = -EIO; - -out: - /* release the lock for file system critical section */ - mutex_unlock(&p_fs->v_mutex); - - pr_debug("%s exited (%d)\n", __func__, ret); - - return ret; -} - -static int ffsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu) -{ - s32 num_clusters, num_alloced; - bool modified = false; - u32 last_clu; - int ret = 0; - struct chain_t new_clu; - struct dentry_t *ep; - struct entry_set_cache_t *es = NULL; - struct super_block *sb = inode->i_sb; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct file_id_t *fid = &(EXFAT_I(inode)->fid); - - /* check the validity of pointer parameters */ - if (!clu) - return -EINVAL; - - /* acquire the lock for file system critical section */ - mutex_lock(&p_fs->v_mutex); - - fid->rwoffset = (s64)(clu_offset) << p_fs->cluster_size_bits; - - if (EXFAT_I(inode)->mmu_private == 0) - num_clusters = 0; - else - num_clusters = (s32)((EXFAT_I(inode)->mmu_private - 1) >> - p_fs->cluster_size_bits) + 1; - - *clu = last_clu = fid->start_clu; - - if (fid->flags == 0x03) { - if ((clu_offset > 0) && (*clu != CLUSTER_32(~0))) { - last_clu += clu_offset - 1; - - if (clu_offset == num_clusters) - *clu = CLUSTER_32(~0); - else - *clu += clu_offset; - } - } else { - /* hint information */ - if ((clu_offset > 0) && (fid->hint_last_off > 0) && - (clu_offset >= fid->hint_last_off)) { - clu_offset -= fid->hint_last_off; - *clu = fid->hint_last_clu; - } - - while ((clu_offset > 0) && (*clu != CLUSTER_32(~0))) { - last_clu = *clu; - if (exfat_fat_read(sb, *clu, clu) == -1) { - ret = -EIO; - goto out; - } - clu_offset--; - } - } - - if (*clu == CLUSTER_32(~0)) { - fs_set_vol_flags(sb, VOL_DIRTY); - - new_clu.dir = (last_clu == CLUSTER_32(~0)) ? CLUSTER_32(~0) : - last_clu + 1; - new_clu.size = 0; - new_clu.flags = fid->flags; - - /* (1) allocate a cluster */ - num_alloced = exfat_alloc_cluster(sb, 1, &new_clu); - if (num_alloced < 0) { - ret = -EIO; - goto out; - } else if (num_alloced == 0) { - ret = -ENOSPC; - goto out; - } - - /* (2) append to the FAT chain */ - if (last_clu == CLUSTER_32(~0)) { - if (new_clu.flags == 0x01) - fid->flags = 0x01; - fid->start_clu = new_clu.dir; - modified = true; - } else { - if (new_clu.flags != fid->flags) { - exfat_chain_cont_cluster(sb, fid->start_clu, - num_clusters); - fid->flags = 0x01; - modified = true; - } - if (new_clu.flags == 0x01) - exfat_fat_write(sb, last_clu, new_clu.dir); - } - - num_clusters += num_alloced; - *clu = new_clu.dir; - - es = get_entry_set_in_dir(sb, &fid->dir, fid->entry, - ES_ALL_ENTRIES, &ep); - if (!es) { - ret = -ENOENT; - goto out; - } - /* get stream entry */ - ep++; - - /* (3) update directory entry */ - if (modified) { - exfat_set_entry_flag(ep, fid->flags); - exfat_set_entry_clu0(ep, fid->start_clu); - } - - update_dir_checksum_with_entry_set(sb, es); - release_entry_set(es); - - /* add number of new blocks to inode */ - inode->i_blocks += num_alloced << (p_fs->cluster_size_bits - 9); - } - - /* hint information */ - fid->hint_last_off = (s32)(fid->rwoffset >> p_fs->cluster_size_bits); - fid->hint_last_clu = *clu; - - if (p_fs->dev_ejected) - ret = -EIO; - -out: - /* release the lock for file system critical section */ - mutex_unlock(&p_fs->v_mutex); - - return ret; -} - -/*----------------------------------------------------------------------*/ -/* Directory Operation Functions */ -/*----------------------------------------------------------------------*/ - -static int ffsCreateDir(struct inode *inode, char *path, struct file_id_t *fid) -{ - int ret = 0; - struct chain_t dir; - struct uni_name_t uni_name; - struct super_block *sb = inode->i_sb; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - pr_debug("%s entered\n", __func__); - - /* check the validity of pointer parameters */ - if (!fid || !path || (*path == '\0')) - return -EINVAL; - - /* acquire the lock for file system critical section */ - mutex_lock(&p_fs->v_mutex); - - /* check the validity of directory name in the given old pathname */ - ret = resolve_path(inode, path, &dir, &uni_name); - if (ret) - goto out; - - fs_set_vol_flags(sb, VOL_DIRTY); - - ret = create_dir(inode, &dir, &uni_name, fid); - -#ifndef CONFIG_STAGING_EXFAT_DELAYED_SYNC - fs_sync(sb, true); - fs_set_vol_flags(sb, VOL_CLEAN); -#endif - - if (p_fs->dev_ejected) - ret = -EIO; -out: - /* release the lock for file system critical section */ - mutex_unlock(&p_fs->v_mutex); - - return ret; -} - -static int ffsReadDir(struct inode *inode, struct dir_entry_t *dir_entry) -{ - int i, dentry, clu_offset; - int ret = 0; - s32 dentries_per_clu, dentries_per_clu_bits = 0; - u32 type; - sector_t sector; - struct chain_t dir, clu; - struct uni_name_t uni_name; - struct timestamp_t tm; - struct dentry_t *ep; - struct super_block *sb = inode->i_sb; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct file_id_t *fid = &(EXFAT_I(inode)->fid); - - /* check the validity of pointer parameters */ - if (!dir_entry) - return -EINVAL; - - /* check if the given file ID is opened */ - if (fid->type != TYPE_DIR) - return -ENOTDIR; - - /* acquire the lock for file system critical section */ - mutex_lock(&p_fs->v_mutex); - - if (fid->entry == -1) { - dir.dir = p_fs->root_dir; - dir.flags = 0x01; - } else { - dir.dir = fid->start_clu; - dir.size = (s32)(fid->size >> p_fs->cluster_size_bits); - dir.flags = fid->flags; - } - - dentry = (s32)fid->rwoffset; - - if (dir.dir == CLUSTER_32(0)) { - /* FAT16 root_dir */ - dentries_per_clu = p_fs->dentries_in_root; - - if (dentry == dentries_per_clu) { - clu.dir = CLUSTER_32(~0); - } else { - clu.dir = dir.dir; - clu.size = dir.size; - clu.flags = dir.flags; - } - } else { - dentries_per_clu = p_fs->dentries_per_clu; - dentries_per_clu_bits = ilog2(dentries_per_clu); - - clu_offset = dentry >> dentries_per_clu_bits; - clu.dir = dir.dir; - clu.size = dir.size; - clu.flags = dir.flags; - - if (clu.flags == 0x03) { - clu.dir += clu_offset; - clu.size -= clu_offset; - } else { - /* hint_information */ - if ((clu_offset > 0) && (fid->hint_last_off > 0) && - (clu_offset >= fid->hint_last_off)) { - clu_offset -= fid->hint_last_off; - clu.dir = fid->hint_last_clu; - } - - while (clu_offset > 0) { - /* clu.dir = exfat_fat_read(sb, clu.dir); */ - if (exfat_fat_read(sb, clu.dir, &clu.dir) == -1) { - ret = -EIO; - goto out; - } - clu_offset--; - } - } - } - - while (clu.dir != CLUSTER_32(~0)) { - if (p_fs->dev_ejected) - break; - - if (dir.dir == CLUSTER_32(0)) /* FAT16 root_dir */ - i = dentry % dentries_per_clu; - else - i = dentry & (dentries_per_clu - 1); - - for ( ; i < dentries_per_clu; i++, dentry++) { - ep = get_entry_in_dir(sb, &clu, i, §or); - if (!ep) { - ret = -ENOENT; - goto out; - } - type = exfat_get_entry_type(ep); - - if (type == TYPE_UNUSED) - break; - - if ((type != TYPE_FILE) && (type != TYPE_DIR)) - continue; - - exfat_buf_lock(sb, sector); - dir_entry->attr = exfat_get_entry_attr(ep); - - exfat_get_entry_time(ep, &tm, TM_CREATE); - dir_entry->create_timestamp.year = tm.year; - dir_entry->create_timestamp.month = tm.mon; - dir_entry->create_timestamp.day = tm.day; - dir_entry->create_timestamp.hour = tm.hour; - dir_entry->create_timestamp.minute = tm.min; - dir_entry->create_timestamp.second = tm.sec; - dir_entry->create_timestamp.millisecond = 0; - - exfat_get_entry_time(ep, &tm, TM_MODIFY); - dir_entry->modify_timestamp.year = tm.year; - dir_entry->modify_timestamp.month = tm.mon; - dir_entry->modify_timestamp.day = tm.day; - dir_entry->modify_timestamp.hour = tm.hour; - dir_entry->modify_timestamp.minute = tm.min; - dir_entry->modify_timestamp.second = tm.sec; - dir_entry->modify_timestamp.millisecond = 0; - - memset((char *)&dir_entry->access_timestamp, 0, - sizeof(struct date_time_t)); - - *uni_name.name = 0x0; - exfat_get_uni_name_from_ext_entry(sb, &dir, dentry, - uni_name.name); - nls_uniname_to_cstring(sb, dir_entry->name, &uni_name); - exfat_buf_unlock(sb, sector); - - ep = get_entry_in_dir(sb, &clu, i + 1, NULL); - if (!ep) { - ret = -ENOENT; - goto out; - } - - dir_entry->Size = exfat_get_entry_size(ep); - - /* hint information */ - if (dir.dir == CLUSTER_32(0)) { /* FAT16 root_dir */ - } else { - fid->hint_last_off = dentry >> - dentries_per_clu_bits; - fid->hint_last_clu = clu.dir; - } - - fid->rwoffset = (s64)(++dentry); - - if (p_fs->dev_ejected) - ret = -EIO; - goto out; - } - - if (dir.dir == CLUSTER_32(0)) - break; /* FAT16 root_dir */ - - if (clu.flags == 0x03) { - if ((--clu.size) > 0) - clu.dir++; - else - clu.dir = CLUSTER_32(~0); - } else { - /* clu.dir = exfat_fat_read(sb, clu.dir); */ - if (exfat_fat_read(sb, clu.dir, &clu.dir) == -1) { - ret = -EIO; - goto out; - } - } - } - - *dir_entry->name = '\0'; - - fid->rwoffset = (s64)(++dentry); - - if (p_fs->dev_ejected) - ret = -EIO; - -out: - /* release the lock for file system critical section */ - mutex_unlock(&p_fs->v_mutex); - - return ret; -} - -static int ffsRemoveDir(struct inode *inode, struct file_id_t *fid) -{ - s32 dentry; - int ret = 0; - struct chain_t dir, clu_to_free; - struct super_block *sb = inode->i_sb; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - /* check the validity of the given file id */ - if (!fid) - return -EINVAL; - - dir.dir = fid->dir.dir; - dir.size = fid->dir.size; - dir.flags = fid->dir.flags; - - dentry = fid->entry; - - /* acquire the lock for file system critical section */ - mutex_lock(&p_fs->v_mutex); - - clu_to_free.dir = fid->start_clu; - clu_to_free.size = (s32)((fid->size - 1) >> p_fs->cluster_size_bits) + 1; - clu_to_free.flags = fid->flags; - - if (!is_dir_empty(sb, &clu_to_free)) { - ret = -ENOTEMPTY; - goto out; - } - - fs_set_vol_flags(sb, VOL_DIRTY); - - /* (1) update the directory entry */ - remove_file(inode, &dir, dentry); - - /* (2) free the clusters */ - exfat_free_cluster(sb, &clu_to_free, 1); - - fid->size = 0; - fid->start_clu = CLUSTER_32(~0); - fid->flags = 0x03; - -#ifndef CONFIG_STAGING_EXFAT_DELAYED_SYNC - fs_sync(sb, true); - fs_set_vol_flags(sb, VOL_CLEAN); -#endif - - if (p_fs->dev_ejected) - ret = -EIO; - -out: - /* release the lock for file system critical section */ - mutex_unlock(&p_fs->v_mutex); - - return ret; -} - -/*======================================================================*/ -/* Directory Entry Operations */ -/*======================================================================*/ - -static int exfat_readdir(struct file *filp, struct dir_context *ctx) -{ - struct inode *inode = file_inode(filp); - struct super_block *sb = inode->i_sb; - struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); - struct dir_entry_t de; - struct inode *tmp; - unsigned long inum; - loff_t cpos, i_pos; - int err = 0; - - __lock_super(sb); - - cpos = ctx->pos; - /* Fake . and .. for any directory. */ - while (cpos < 2) { - if (inode->i_ino == EXFAT_ROOT_INO) - inum = EXFAT_ROOT_INO; - else if (cpos == 0) - inum = inode->i_ino; - else /* (cpos == 1) */ - inum = parent_ino(filp->f_path.dentry); - - if (!dir_emit_dots(filp, ctx)) - goto out; - cpos++; - ctx->pos++; - } - if (cpos == 2) - cpos = 0; - if (cpos & (DENTRY_SIZE - 1)) { - err = -ENOENT; - goto out; - } - -get_new: - EXFAT_I(inode)->fid.size = i_size_read(inode); - EXFAT_I(inode)->fid.rwoffset = cpos >> DENTRY_SIZE_BITS; - - err = ffsReadDir(inode, &de); - if (err) { - /* at least we tried to read a sector - * move cpos to next sector position (should be aligned) - */ - if (err == -EIO) { - cpos += 1 << p_bd->sector_size_bits; - cpos &= ~((1 << p_bd->sector_size_bits) - 1); - } - - goto end_of_dir; - } - - cpos = EXFAT_I(inode)->fid.rwoffset << DENTRY_SIZE_BITS; - - if (!de.name[0]) - goto end_of_dir; - - i_pos = ((loff_t)EXFAT_I(inode)->fid.start_clu << 32) | - ((EXFAT_I(inode)->fid.rwoffset - 1) & 0xffffffff); - tmp = exfat_iget(sb, i_pos); - if (tmp) { - inum = tmp->i_ino; - iput(tmp); - } else { - inum = iunique(sb, EXFAT_ROOT_INO); - } - - if (!dir_emit(ctx, de.name, strlen(de.name), inum, - (de.attr & ATTR_SUBDIR) ? DT_DIR : DT_REG)) - goto out; - - ctx->pos = cpos; - goto get_new; - -end_of_dir: - ctx->pos = cpos; -out: - __unlock_super(sb); - return err; -} - -static int exfat_ioctl_volume_id(struct inode *dir) -{ - struct super_block *sb = dir->i_sb; - struct exfat_sb_info *sbi = EXFAT_SB(sb); - struct fs_info_t *p_fs = &sbi->fs_info; - - return p_fs->vol_id; -} - -static long exfat_generic_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) -{ - struct inode *inode = filp->f_path.dentry->d_inode; -#ifdef CONFIG_STAGING_EXFAT_KERNEL_DEBUG - unsigned int flags; -#endif /* CONFIG_STAGING_EXFAT_KERNEL_DEBUG */ - - switch (cmd) { - case EXFAT_IOCTL_GET_VOLUME_ID: - return exfat_ioctl_volume_id(inode); -#ifdef CONFIG_STAGING_EXFAT_KERNEL_DEBUG - case EXFAT_IOC_GET_DEBUGFLAGS: { - struct super_block *sb = inode->i_sb; - struct exfat_sb_info *sbi = EXFAT_SB(sb); - - flags = sbi->debug_flags; - return put_user(flags, (int __user *)arg); - } - case EXFAT_IOC_SET_DEBUGFLAGS: { - struct super_block *sb = inode->i_sb; - struct exfat_sb_info *sbi = EXFAT_SB(sb); - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (get_user(flags, (int __user *)arg)) - return -EFAULT; - - __lock_super(sb); - sbi->debug_flags = flags; - __unlock_super(sb); - - return 0; - } -#endif /* CONFIG_STAGING_EXFAT_KERNEL_DEBUG */ - default: - return -ENOTTY; /* Inappropriate ioctl for device */ - } -} - -static const struct file_operations exfat_dir_operations = { - .llseek = generic_file_llseek, - .read = generic_read_dir, - .iterate = exfat_readdir, - .unlocked_ioctl = exfat_generic_ioctl, - .fsync = generic_file_fsync, -}; - -static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode, - bool excl) -{ - struct super_block *sb = dir->i_sb; - struct timespec64 curtime; - struct inode *inode; - struct file_id_t fid; - loff_t i_pos; - int err; - - __lock_super(sb); - - pr_debug("%s entered\n", __func__); - - err = ffsCreateFile(dir, (u8 *)dentry->d_name.name, &fid); - if (err) - goto out; - - INC_IVERSION(dir); - curtime = current_time(dir); - dir->i_ctime = curtime; - dir->i_mtime = curtime; - dir->i_atime = curtime; - if (IS_DIRSYNC(dir)) - (void)exfat_sync_inode(dir); - else - mark_inode_dirty(dir); - - i_pos = ((loff_t)fid.dir.dir << 32) | (fid.entry & 0xffffffff); - - inode = exfat_build_inode(sb, &fid, i_pos); - if (IS_ERR(inode)) { - err = PTR_ERR(inode); - goto out; - } - INC_IVERSION(inode); - curtime = current_time(inode); - inode->i_mtime = curtime; - inode->i_atime = curtime; - inode->i_ctime = curtime; - /* - * timestamp is already written, so mark_inode_dirty() is unnecessary. - */ - - dentry->d_time = GET_IVERSION(dentry->d_parent->d_inode); - d_instantiate(dentry, inode); - -out: - __unlock_super(sb); - pr_debug("%s exited\n", __func__); - return err; -} - -static int exfat_find(struct inode *dir, struct qstr *qname, - struct file_id_t *fid) -{ - int err; - - if (qname->len == 0) - return -ENOENT; - - err = ffsLookupFile(dir, (u8 *)qname->name, fid); - if (err) - return -ENOENT; - - return 0; -} - -static int exfat_d_anon_disconn(struct dentry *dentry) -{ - return IS_ROOT(dentry) && (dentry->d_flags & DCACHE_DISCONNECTED); -} - -static struct dentry *exfat_lookup(struct inode *dir, struct dentry *dentry, - unsigned int flags) -{ - struct super_block *sb = dir->i_sb; - struct inode *inode; - struct dentry *alias; - int err; - struct file_id_t fid; - loff_t i_pos; - mode_t i_mode; - - __lock_super(sb); - pr_debug("%s entered\n", __func__); - err = exfat_find(dir, &dentry->d_name, &fid); - if (err) { - if (err == -ENOENT) { - inode = NULL; - goto out; - } - goto error; - } - - i_pos = ((loff_t)fid.dir.dir << 32) | (fid.entry & 0xffffffff); - inode = exfat_build_inode(sb, &fid, i_pos); - if (IS_ERR(inode)) { - err = PTR_ERR(inode); - goto error; - } - - i_mode = inode->i_mode; - alias = d_find_alias(inode); - if (alias && !exfat_d_anon_disconn(alias)) { - BUG_ON(d_unhashed(alias)); - if (!S_ISDIR(i_mode)) - d_move(alias, dentry); - iput(inode); - __unlock_super(sb); - pr_debug("%s exited 1\n", __func__); - return alias; - } - dput(alias); -out: - __unlock_super(sb); - dentry->d_time = GET_IVERSION(dentry->d_parent->d_inode); - dentry = d_splice_alias(inode, dentry); - if (dentry) - dentry->d_time = GET_IVERSION(dentry->d_parent->d_inode); - pr_debug("%s exited 2\n", __func__); - return dentry; - -error: - __unlock_super(sb); - pr_debug("%s exited 3\n", __func__); - return ERR_PTR(err); -} - -static inline unsigned long exfat_hash(loff_t i_pos) -{ - return hash_32(i_pos, EXFAT_HASH_BITS); -} - -static void exfat_attach(struct inode *inode, loff_t i_pos) -{ - struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb); - struct hlist_head *head = sbi->inode_hashtable + exfat_hash(i_pos); - - spin_lock(&sbi->inode_hash_lock); - EXFAT_I(inode)->i_pos = i_pos; - hlist_add_head(&EXFAT_I(inode)->i_hash_fat, head); - spin_unlock(&sbi->inode_hash_lock); -} - -static void exfat_detach(struct inode *inode) -{ - struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb); - - spin_lock(&sbi->inode_hash_lock); - hlist_del_init(&EXFAT_I(inode)->i_hash_fat); - EXFAT_I(inode)->i_pos = 0; - spin_unlock(&sbi->inode_hash_lock); -} - -static int exfat_unlink(struct inode *dir, struct dentry *dentry) -{ - struct inode *inode = dentry->d_inode; - struct super_block *sb = dir->i_sb; - struct timespec64 curtime; - int err; - - __lock_super(sb); - - pr_debug("%s entered\n", __func__); - - EXFAT_I(inode)->fid.size = i_size_read(inode); - - err = ffsRemoveFile(dir, &(EXFAT_I(inode)->fid)); - if (err) - goto out; - - INC_IVERSION(dir); - curtime = current_time(dir); - dir->i_mtime = curtime; - dir->i_atime = curtime; - if (IS_DIRSYNC(dir)) - (void)exfat_sync_inode(dir); - else - mark_inode_dirty(dir); - - clear_nlink(inode); - curtime = current_time(inode); - inode->i_mtime = curtime; - inode->i_atime = curtime; - exfat_detach(inode); - remove_inode_hash(inode); - -out: - __unlock_super(sb); - pr_debug("%s exited\n", __func__); - return err; -} - -static int exfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) -{ - struct super_block *sb = dir->i_sb; - struct timespec64 curtime; - struct inode *inode; - struct file_id_t fid; - loff_t i_pos; - int err; - - __lock_super(sb); - - pr_debug("%s entered\n", __func__); - - err = ffsCreateDir(dir, (u8 *)dentry->d_name.name, &fid); - if (err) - goto out; - - INC_IVERSION(dir); - curtime = current_time(dir); - dir->i_ctime = curtime; - dir->i_mtime = curtime; - dir->i_atime = curtime; - if (IS_DIRSYNC(dir)) - (void)exfat_sync_inode(dir); - else - mark_inode_dirty(dir); - inc_nlink(dir); - - i_pos = ((loff_t)fid.dir.dir << 32) | (fid.entry & 0xffffffff); - - inode = exfat_build_inode(sb, &fid, i_pos); - if (IS_ERR(inode)) { - err = PTR_ERR(inode); - goto out; - } - INC_IVERSION(inode); - curtime = current_time(inode); - inode->i_mtime = curtime; - inode->i_atime = curtime; - inode->i_ctime = curtime; - /* timestamp is already written, so mark_inode_dirty() is unneeded. */ - - dentry->d_time = GET_IVERSION(dentry->d_parent->d_inode); - d_instantiate(dentry, inode); - -out: - __unlock_super(sb); - pr_debug("%s exited\n", __func__); - return err; -} - -static int exfat_rmdir(struct inode *dir, struct dentry *dentry) -{ - struct inode *inode = dentry->d_inode; - struct super_block *sb = dir->i_sb; - struct timespec64 curtime; - int err; - - __lock_super(sb); - - pr_debug("%s entered\n", __func__); - - EXFAT_I(inode)->fid.size = i_size_read(inode); - - err = ffsRemoveDir(dir, &(EXFAT_I(inode)->fid)); - if (err) - goto out; - - INC_IVERSION(dir); - curtime = current_time(dir); - dir->i_mtime = curtime; - dir->i_atime = curtime; - if (IS_DIRSYNC(dir)) - (void)exfat_sync_inode(dir); - else - mark_inode_dirty(dir); - drop_nlink(dir); - - clear_nlink(inode); - curtime = current_time(inode); - inode->i_mtime = curtime; - inode->i_atime = curtime; - exfat_detach(inode); - remove_inode_hash(inode); - -out: - __unlock_super(sb); - pr_debug("%s exited\n", __func__); - return err; -} - -static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - unsigned int flags) -{ - struct inode *old_inode, *new_inode; - struct super_block *sb = old_dir->i_sb; - struct timespec64 curtime; - loff_t i_pos; - int err; - - if (flags) - return -EINVAL; - - __lock_super(sb); - - pr_debug("%s entered\n", __func__); - - old_inode = old_dentry->d_inode; - new_inode = new_dentry->d_inode; - - EXFAT_I(old_inode)->fid.size = i_size_read(old_inode); - - err = ffsMoveFile(old_dir, &(EXFAT_I(old_inode)->fid), new_dir, - new_dentry); - if (err) - goto out; - - INC_IVERSION(new_dir); - curtime = current_time(new_dir); - new_dir->i_ctime = curtime; - new_dir->i_mtime = curtime; - new_dir->i_atime = curtime; - - if (IS_DIRSYNC(new_dir)) - (void)exfat_sync_inode(new_dir); - else - mark_inode_dirty(new_dir); - - i_pos = ((loff_t)EXFAT_I(old_inode)->fid.dir.dir << 32) | - (EXFAT_I(old_inode)->fid.entry & 0xffffffff); - - exfat_detach(old_inode); - exfat_attach(old_inode, i_pos); - if (IS_DIRSYNC(new_dir)) - (void)exfat_sync_inode(old_inode); - else - mark_inode_dirty(old_inode); - - if ((S_ISDIR(old_inode->i_mode)) && (old_dir != new_dir)) { - drop_nlink(old_dir); - if (!new_inode) - inc_nlink(new_dir); - } - INC_IVERSION(old_dir); - curtime = current_time(old_dir); - old_dir->i_ctime = curtime; - old_dir->i_mtime = curtime; - if (IS_DIRSYNC(old_dir)) - (void)exfat_sync_inode(old_dir); - else - mark_inode_dirty(old_dir); - - if (new_inode) { - exfat_detach(new_inode); - drop_nlink(new_inode); - if (S_ISDIR(new_inode->i_mode)) - drop_nlink(new_inode); - new_inode->i_ctime = current_time(new_inode); - } - -out: - __unlock_super(sb); - pr_debug("%s exited\n", __func__); - return err; -} - -static int exfat_cont_expand(struct inode *inode, loff_t size) -{ - struct address_space *mapping = inode->i_mapping; - loff_t start = i_size_read(inode), count = size - i_size_read(inode); - struct timespec64 curtime; - int err, err2; - - err = generic_cont_expand_simple(inode, size); - if (err != 0) - return err; - - curtime = current_time(inode); - inode->i_ctime = curtime; - inode->i_mtime = curtime; - mark_inode_dirty(inode); - - if (IS_SYNC(inode)) { - err = filemap_fdatawrite_range(mapping, start, - start + count - 1); - err2 = sync_mapping_buffers(mapping); - err = (err) ? (err) : (err2); - err2 = write_inode_now(inode, 1); - err = (err) ? (err) : (err2); - if (!err) - err = filemap_fdatawait_range(mapping, start, - start + count - 1); - } - return err; -} - -static int exfat_allow_set_time(struct exfat_sb_info *sbi, struct inode *inode) -{ - mode_t allow_utime = sbi->options.allow_utime; - - if (!uid_eq(current_fsuid(), inode->i_uid)) { - if (in_group_p(inode->i_gid)) - allow_utime >>= 3; - if (allow_utime & MAY_WRITE) - return 1; - } - - /* use a default check */ - return 0; -} - -static int exfat_sanitize_mode(const struct exfat_sb_info *sbi, - struct inode *inode, umode_t *mode_ptr) -{ - mode_t i_mode, mask, perm; - - i_mode = inode->i_mode; - - if (S_ISREG(i_mode) || S_ISLNK(i_mode)) - mask = sbi->options.fs_fmask; - else - mask = sbi->options.fs_dmask; - - perm = *mode_ptr & ~(S_IFMT | mask); - - /* Of the r and x bits, all (subject to umask) must be present.*/ - if ((perm & 0555) != (i_mode & 0555)) - return -EPERM; - - if (exfat_mode_can_hold_ro(inode)) { - /* - * Of the w bits, either all (subject to umask) or none must be - * present. - */ - if ((perm & 0222) && ((perm & 0222) != (0222 & ~mask))) - return -EPERM; - } else { - /* - * If exfat_mode_can_hold_ro(inode) is false, can't change w - * bits. - */ - if ((perm & 0222) != (0222 & ~mask)) - return -EPERM; - } - - *mode_ptr &= S_IFMT | perm; - - return 0; -} - -static void exfat_truncate(struct inode *inode, loff_t old_size) -{ - struct super_block *sb = inode->i_sb; - struct exfat_sb_info *sbi = EXFAT_SB(sb); - struct fs_info_t *p_fs = &sbi->fs_info; - struct timespec64 curtime; - int err; - - __lock_super(sb); - - /* - * This protects against truncating a file bigger than it was then - * trying to write into the hole. - */ - if (EXFAT_I(inode)->mmu_private > i_size_read(inode)) - EXFAT_I(inode)->mmu_private = i_size_read(inode); - - if (EXFAT_I(inode)->fid.start_clu == 0) - goto out; - - err = ffsTruncateFile(inode, old_size, i_size_read(inode)); - if (err) - goto out; - - curtime = current_time(inode); - inode->i_ctime = curtime; - inode->i_mtime = curtime; - if (IS_DIRSYNC(inode)) - (void)exfat_sync_inode(inode); - else - mark_inode_dirty(inode); - - inode->i_blocks = ((i_size_read(inode) + (p_fs->cluster_size - 1)) & - ~((loff_t)p_fs->cluster_size - 1)) >> 9; -out: - __unlock_super(sb); -} - -static int exfat_setattr(struct dentry *dentry, struct iattr *attr) -{ - struct exfat_sb_info *sbi = EXFAT_SB(dentry->d_sb); - struct inode *inode = dentry->d_inode; - unsigned int ia_valid; - int error; - loff_t old_size; - - pr_debug("%s entered\n", __func__); - - if ((attr->ia_valid & ATTR_SIZE) && - attr->ia_size > i_size_read(inode)) { - error = exfat_cont_expand(inode, attr->ia_size); - if (error || attr->ia_valid == ATTR_SIZE) - return error; - attr->ia_valid &= ~ATTR_SIZE; - } - - ia_valid = attr->ia_valid; - - if ((ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) && - exfat_allow_set_time(sbi, inode)) { - attr->ia_valid &= ~(ATTR_MTIME_SET | - ATTR_ATIME_SET | - ATTR_TIMES_SET); - } - - error = setattr_prepare(dentry, attr); - attr->ia_valid = ia_valid; - if (error) - return error; - - if (((attr->ia_valid & ATTR_UID) && - (!uid_eq(attr->ia_uid, sbi->options.fs_uid))) || - ((attr->ia_valid & ATTR_GID) && - (!gid_eq(attr->ia_gid, sbi->options.fs_gid))) || - ((attr->ia_valid & ATTR_MODE) && - (attr->ia_mode & ~(S_IFREG | S_IFLNK | S_IFDIR | 0777)))) { - return -EPERM; - } - - /* - * We don't return -EPERM here. Yes, strange, but this is too - * old behavior. - */ - if (attr->ia_valid & ATTR_MODE) { - if (exfat_sanitize_mode(sbi, inode, &attr->ia_mode) < 0) - attr->ia_valid &= ~ATTR_MODE; - } - - EXFAT_I(inode)->fid.size = i_size_read(inode); - - if (attr->ia_valid & ATTR_SIZE) { - old_size = i_size_read(inode); - down_write(&EXFAT_I(inode)->truncate_lock); - truncate_setsize(inode, attr->ia_size); - exfat_truncate(inode, old_size); - up_write(&EXFAT_I(inode)->truncate_lock); - } - setattr_copy(inode, attr); - mark_inode_dirty(inode); - - pr_debug("%s exited\n", __func__); - return error; -} - -static int exfat_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int flags) -{ - struct inode *inode = path->dentry->d_inode; - - pr_debug("%s entered\n", __func__); - - generic_fillattr(inode, stat); - stat->blksize = EXFAT_SB(inode->i_sb)->fs_info.cluster_size; - - pr_debug("%s exited\n", __func__); - return 0; -} - -static const struct inode_operations exfat_dir_inode_operations = { - .create = exfat_create, - .lookup = exfat_lookup, - .unlink = exfat_unlink, - .mkdir = exfat_mkdir, - .rmdir = exfat_rmdir, - .rename = exfat_rename, - .setattr = exfat_setattr, - .getattr = exfat_getattr, -}; - -/*======================================================================*/ -/* File Operations */ -/*======================================================================*/ -static int exfat_file_release(struct inode *inode, struct file *filp) -{ - struct super_block *sb = inode->i_sb; - - EXFAT_I(inode)->fid.size = i_size_read(inode); - ffsSyncVol(sb, false); - return 0; -} - -static const struct file_operations exfat_file_operations = { - .llseek = generic_file_llseek, - .read_iter = generic_file_read_iter, - .write_iter = generic_file_write_iter, - .mmap = generic_file_mmap, - .release = exfat_file_release, - .unlocked_ioctl = exfat_generic_ioctl, - .fsync = generic_file_fsync, - .splice_read = generic_file_splice_read, -}; - -static const struct inode_operations exfat_file_inode_operations = { - .setattr = exfat_setattr, - .getattr = exfat_getattr, -}; - -/*======================================================================*/ -/* Address Space Operations */ -/*======================================================================*/ - -static int exfat_bmap(struct inode *inode, sector_t sector, sector_t *phys, - unsigned long *mapped_blocks, int *create) -{ - struct super_block *sb = inode->i_sb; - struct exfat_sb_info *sbi = EXFAT_SB(sb); - struct fs_info_t *p_fs = &sbi->fs_info; - const unsigned long blocksize = sb->s_blocksize; - const unsigned char blocksize_bits = sb->s_blocksize_bits; - sector_t last_block; - int err, clu_offset, sec_offset; - unsigned int cluster; - - *phys = 0; - *mapped_blocks = 0; - - last_block = (i_size_read(inode) + (blocksize - 1)) >> blocksize_bits; - if (sector >= last_block) { - if (*create == 0) - return 0; - } else { - *create = 0; - } - - /* cluster offset */ - clu_offset = sector >> p_fs->sectors_per_clu_bits; - - /* sector offset in cluster */ - sec_offset = sector & (p_fs->sectors_per_clu - 1); - - EXFAT_I(inode)->fid.size = i_size_read(inode); - - err = ffsMapCluster(inode, clu_offset, &cluster); - - if (!err && (cluster != CLUSTER_32(~0))) { - *phys = START_SECTOR(cluster) + sec_offset; - *mapped_blocks = p_fs->sectors_per_clu - sec_offset; - } - - return 0; -} - -static int exfat_get_block(struct inode *inode, sector_t iblock, - struct buffer_head *bh_result, int create) -{ - struct super_block *sb = inode->i_sb; - unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits; - int err; - unsigned long mapped_blocks; - sector_t phys; - - __lock_super(sb); - - err = exfat_bmap(inode, iblock, &phys, &mapped_blocks, &create); - if (err) { - __unlock_super(sb); - return err; - } - - if (phys) { - max_blocks = min(mapped_blocks, max_blocks); - if (create) { - EXFAT_I(inode)->mmu_private += max_blocks << - sb->s_blocksize_bits; - set_buffer_new(bh_result); - } - map_bh(bh_result, sb, phys); - } - - bh_result->b_size = max_blocks << sb->s_blocksize_bits; - __unlock_super(sb); - - return 0; -} - -static int exfat_readpage(struct file *file, struct page *page) -{ - return mpage_readpage(page, exfat_get_block); -} - -static int exfat_readpages(struct file *file, struct address_space *mapping, - struct list_head *pages, unsigned int nr_pages) -{ - return mpage_readpages(mapping, pages, nr_pages, exfat_get_block); -} - -static int exfat_writepage(struct page *page, struct writeback_control *wbc) -{ - return block_write_full_page(page, exfat_get_block, wbc); -} - -static int exfat_writepages(struct address_space *mapping, - struct writeback_control *wbc) -{ - return mpage_writepages(mapping, wbc, exfat_get_block); -} - -static void exfat_write_failed(struct address_space *mapping, loff_t to) -{ - struct inode *inode = mapping->host; - - if (to > i_size_read(inode)) { - truncate_pagecache(inode, i_size_read(inode)); - EXFAT_I(inode)->fid.size = i_size_read(inode); - exfat_truncate(inode, i_size_read(inode)); - } -} - -static int exfat_write_begin(struct file *file, struct address_space *mapping, - loff_t pos, unsigned int len, unsigned int flags, - struct page **pagep, void **fsdata) -{ - int ret; - - *pagep = NULL; - ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata, - exfat_get_block, - &EXFAT_I(mapping->host)->mmu_private); - - if (ret < 0) - exfat_write_failed(mapping, pos + len); - return ret; -} - -static int exfat_write_end(struct file *file, struct address_space *mapping, - loff_t pos, unsigned int len, unsigned int copied, - struct page *pagep, void *fsdata) -{ - struct inode *inode = mapping->host; - struct file_id_t *fid = &(EXFAT_I(inode)->fid); - struct timespec64 curtime; - int err; - - err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata); - - if (err < len) - exfat_write_failed(mapping, pos + len); - - if (!(err < 0) && !(fid->attr & ATTR_ARCHIVE)) { - curtime = current_time(inode); - inode->i_mtime = curtime; - inode->i_ctime = curtime; - fid->attr |= ATTR_ARCHIVE; - mark_inode_dirty(inode); - } - return err; -} - -static ssize_t exfat_direct_IO(struct kiocb *iocb, struct iov_iter *iter) -{ - struct inode *inode = iocb->ki_filp->f_mapping->host; - struct address_space *mapping = iocb->ki_filp->f_mapping; - ssize_t ret; - int rw; - - rw = iov_iter_rw(iter); - - if (rw == WRITE) { - if (EXFAT_I(inode)->mmu_private < iov_iter_count(iter)) - return 0; - } - ret = blockdev_direct_IO(iocb, inode, iter, exfat_get_block); - - if ((ret < 0) && (rw & WRITE)) - exfat_write_failed(mapping, iov_iter_count(iter)); - return ret; -} - -static sector_t _exfat_bmap(struct address_space *mapping, sector_t block) -{ - sector_t blocknr; - - /* exfat_get_cluster() assumes the requested blocknr isn't truncated. */ - down_read(&EXFAT_I(mapping->host)->truncate_lock); - blocknr = generic_block_bmap(mapping, block, exfat_get_block); - up_read(&EXFAT_I(mapping->host)->truncate_lock); - - return blocknr; -} - -static const struct address_space_operations exfat_aops = { - .readpage = exfat_readpage, - .readpages = exfat_readpages, - .writepage = exfat_writepage, - .writepages = exfat_writepages, - .write_begin = exfat_write_begin, - .write_end = exfat_write_end, - .direct_IO = exfat_direct_IO, - .bmap = _exfat_bmap -}; - -/*======================================================================*/ -/* Super Operations */ -/*======================================================================*/ - -static struct inode *exfat_iget(struct super_block *sb, loff_t i_pos) -{ - struct exfat_sb_info *sbi = EXFAT_SB(sb); - struct exfat_inode_info *info; - struct hlist_head *head = sbi->inode_hashtable + exfat_hash(i_pos); - struct inode *inode = NULL; - - spin_lock(&sbi->inode_hash_lock); - hlist_for_each_entry(info, head, i_hash_fat) { - BUG_ON(info->vfs_inode.i_sb != sb); - - if (i_pos != info->i_pos) - continue; - inode = igrab(&info->vfs_inode); - if (inode) - break; - } - spin_unlock(&sbi->inode_hash_lock); - return inode; -} - -/* doesn't deal with root inode */ -static int exfat_fill_inode(struct inode *inode, struct file_id_t *fid) -{ - struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb); - struct fs_info_t *p_fs = &sbi->fs_info; - struct dir_entry_t info; - - memcpy(&(EXFAT_I(inode)->fid), fid, sizeof(struct file_id_t)); - - ffsReadStat(inode, &info); - - EXFAT_I(inode)->i_pos = 0; - EXFAT_I(inode)->target = NULL; - inode->i_uid = sbi->options.fs_uid; - inode->i_gid = sbi->options.fs_gid; - INC_IVERSION(inode); - inode->i_generation = prandom_u32(); - - if (info.attr & ATTR_SUBDIR) { /* directory */ - inode->i_generation &= ~1; - inode->i_mode = exfat_make_mode(sbi, info.attr, 0777); - inode->i_op = &exfat_dir_inode_operations; - inode->i_fop = &exfat_dir_operations; - - i_size_write(inode, info.Size); - EXFAT_I(inode)->mmu_private = i_size_read(inode); - set_nlink(inode, info.num_subdirs); - } else { /* regular file */ - inode->i_generation |= 1; - inode->i_mode = exfat_make_mode(sbi, info.attr, 0777); - inode->i_op = &exfat_file_inode_operations; - inode->i_fop = &exfat_file_operations; - inode->i_mapping->a_ops = &exfat_aops; - inode->i_mapping->nrpages = 0; - - i_size_write(inode, info.Size); - EXFAT_I(inode)->mmu_private = i_size_read(inode); - } - exfat_save_attr(inode, info.attr); - - inode->i_blocks = ((i_size_read(inode) + (p_fs->cluster_size - 1)) - & ~((loff_t)p_fs->cluster_size - 1)) >> 9; - - exfat_time_fat2unix(&inode->i_mtime, &info.modify_timestamp); - exfat_time_fat2unix(&inode->i_ctime, &info.create_timestamp); - exfat_time_fat2unix(&inode->i_atime, &info.access_timestamp); - - return 0; -} - -static struct inode *exfat_build_inode(struct super_block *sb, - struct file_id_t *fid, loff_t i_pos) -{ - struct inode *inode; - int err; - - inode = exfat_iget(sb, i_pos); - if (inode) - goto out; - inode = new_inode(sb); - if (!inode) { - inode = ERR_PTR(-ENOMEM); - goto out; - } - inode->i_ino = iunique(sb, EXFAT_ROOT_INO); - SET_IVERSION(inode, 1); - err = exfat_fill_inode(inode, fid); - if (err) { - iput(inode); - inode = ERR_PTR(err); - goto out; - } - exfat_attach(inode, i_pos); - insert_inode_hash(inode); -out: - return inode; -} - -static int exfat_sync_inode(struct inode *inode) -{ - return exfat_write_inode(inode, NULL); -} - -static struct inode *exfat_alloc_inode(struct super_block *sb) -{ - struct exfat_inode_info *ei; - - ei = kmem_cache_alloc(exfat_inode_cachep, GFP_NOFS); - if (!ei) - return NULL; - - init_rwsem(&ei->truncate_lock); - - return &ei->vfs_inode; -} - -static void exfat_destroy_inode(struct inode *inode) -{ - kfree(EXFAT_I(inode)->target); - EXFAT_I(inode)->target = NULL; - - kmem_cache_free(exfat_inode_cachep, EXFAT_I(inode)); -} - -static int exfat_write_inode(struct inode *inode, struct writeback_control *wbc) -{ - struct dir_entry_t info; - - if (inode->i_ino == EXFAT_ROOT_INO) - return 0; - - info.attr = exfat_make_attr(inode); - info.Size = i_size_read(inode); - - exfat_time_unix2fat(&inode->i_mtime, &info.modify_timestamp); - exfat_time_unix2fat(&inode->i_ctime, &info.create_timestamp); - exfat_time_unix2fat(&inode->i_atime, &info.access_timestamp); - - ffsWriteStat(inode, &info); - - return 0; -} - -static void exfat_evict_inode(struct inode *inode) -{ - truncate_inode_pages(&inode->i_data, 0); - - if (!inode->i_nlink) - i_size_write(inode, 0); - invalidate_inode_buffers(inode); - clear_inode(inode); - exfat_detach(inode); - - remove_inode_hash(inode); -} - -static void exfat_free_super(struct exfat_sb_info *sbi) -{ - if (sbi->nls_disk) - unload_nls(sbi->nls_disk); - if (sbi->nls_io) - unload_nls(sbi->nls_io); - if (sbi->options.iocharset != exfat_default_iocharset) - kfree(sbi->options.iocharset); - /* mutex_init is in exfat_fill_super function. only for 3.7+ */ - mutex_destroy(&sbi->s_lock); - kvfree(sbi); -} - -static void exfat_put_super(struct super_block *sb) -{ - struct exfat_sb_info *sbi = EXFAT_SB(sb); - - if (__is_sb_dirty(sb)) - exfat_write_super(sb); - - ffsUmountVol(sb); - - sb->s_fs_info = NULL; - exfat_free_super(sbi); -} - -static void exfat_write_super(struct super_block *sb) -{ - __lock_super(sb); - - __set_sb_clean(sb); - - if (!sb_rdonly(sb)) - ffsSyncVol(sb, true); - - __unlock_super(sb); -} - -static int exfat_sync_fs(struct super_block *sb, int wait) -{ - int err = 0; - - if (__is_sb_dirty(sb)) { - __lock_super(sb); - __set_sb_clean(sb); - err = ffsSyncVol(sb, true); - __unlock_super(sb); - } - - return err; -} - -static int exfat_statfs(struct dentry *dentry, struct kstatfs *buf) -{ - struct super_block *sb = dentry->d_sb; - u64 id = huge_encode_dev(sb->s_bdev->bd_dev); - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - struct vol_info_t info; - - if (p_fs->used_clusters == UINT_MAX) { - if (ffsGetVolInfo(sb, &info) == -EIO) - return -EIO; - - } else { - info.FatType = EXFAT; - info.ClusterSize = p_fs->cluster_size; - info.NumClusters = p_fs->num_clusters - 2; - info.UsedClusters = p_fs->used_clusters; - info.FreeClusters = info.NumClusters - info.UsedClusters; - - if (p_fs->dev_ejected) - pr_info("[EXFAT] statfs on device that is ejected\n"); - } - - buf->f_type = sb->s_magic; - buf->f_bsize = info.ClusterSize; - buf->f_blocks = info.NumClusters; - buf->f_bfree = info.FreeClusters; - buf->f_bavail = info.FreeClusters; - buf->f_fsid.val[0] = (u32)id; - buf->f_fsid.val[1] = (u32)(id >> 32); - buf->f_namelen = 260; - - return 0; -} - -static int exfat_remount(struct super_block *sb, int *flags, char *data) -{ - *flags |= SB_NODIRATIME; - return 0; -} - -static int exfat_show_options(struct seq_file *m, struct dentry *root) -{ - struct exfat_sb_info *sbi = EXFAT_SB(root->d_sb); - struct exfat_mount_options *opts = &sbi->options; - - if (__kuid_val(opts->fs_uid)) - seq_printf(m, ",uid=%u", __kuid_val(opts->fs_uid)); - if (__kgid_val(opts->fs_gid)) - seq_printf(m, ",gid=%u", __kgid_val(opts->fs_gid)); - seq_printf(m, ",fmask=%04o", opts->fs_fmask); - seq_printf(m, ",dmask=%04o", opts->fs_dmask); - if (opts->allow_utime) - seq_printf(m, ",allow_utime=%04o", opts->allow_utime); - if (sbi->nls_disk) - seq_printf(m, ",codepage=%s", sbi->nls_disk->charset); - if (sbi->nls_io) - seq_printf(m, ",iocharset=%s", sbi->nls_io->charset); - seq_printf(m, ",namecase=%u", opts->casesensitive); - if (opts->errors == EXFAT_ERRORS_CONT) - seq_puts(m, ",errors=continue"); - else if (opts->errors == EXFAT_ERRORS_PANIC) - seq_puts(m, ",errors=panic"); - else - seq_puts(m, ",errors=remount-ro"); -#ifdef CONFIG_STAGING_EXFAT_DISCARD - if (opts->discard) - seq_puts(m, ",discard"); -#endif - return 0; -} - -static const struct super_operations exfat_sops = { - .alloc_inode = exfat_alloc_inode, - .destroy_inode = exfat_destroy_inode, - .write_inode = exfat_write_inode, - .evict_inode = exfat_evict_inode, - .put_super = exfat_put_super, - .sync_fs = exfat_sync_fs, - .statfs = exfat_statfs, - .remount_fs = exfat_remount, - .show_options = exfat_show_options, -}; - -/*======================================================================*/ -/* Export Operations */ -/*======================================================================*/ - -static struct inode *exfat_nfs_get_inode(struct super_block *sb, u64 ino, - u32 generation) -{ - struct inode *inode = NULL; - - if (ino < EXFAT_ROOT_INO) - return inode; - inode = ilookup(sb, ino); - - if (inode && generation && (inode->i_generation != generation)) { - iput(inode); - inode = NULL; - } - - return inode; -} - -static struct dentry *exfat_fh_to_dentry(struct super_block *sb, - struct fid *fid, int fh_len, - int fh_type) -{ - return generic_fh_to_dentry(sb, fid, fh_len, fh_type, - exfat_nfs_get_inode); -} - -static struct dentry *exfat_fh_to_parent(struct super_block *sb, - struct fid *fid, int fh_len, - int fh_type) -{ - return generic_fh_to_parent(sb, fid, fh_len, fh_type, - exfat_nfs_get_inode); -} - -static const struct export_operations exfat_export_ops = { - .fh_to_dentry = exfat_fh_to_dentry, - .fh_to_parent = exfat_fh_to_parent, -}; - -/*======================================================================*/ -/* Super Block Read Operations */ -/*======================================================================*/ - -enum { - Opt_uid, - Opt_gid, - Opt_umask, - Opt_dmask, - Opt_fmask, - Opt_allow_utime, - Opt_codepage, - Opt_charset, - Opt_namecase, - Opt_debug, - Opt_err_cont, - Opt_err_panic, - Opt_err_ro, - Opt_utf8_hack, - Opt_err, -#ifdef CONFIG_STAGING_EXFAT_DISCARD - Opt_discard, -#endif /* EXFAT_CONFIG_DISCARD */ -}; - -static const match_table_t exfat_tokens = { - {Opt_uid, "uid=%u"}, - {Opt_gid, "gid=%u"}, - {Opt_umask, "umask=%o"}, - {Opt_dmask, "dmask=%o"}, - {Opt_fmask, "fmask=%o"}, - {Opt_allow_utime, "allow_utime=%o"}, - {Opt_codepage, "codepage=%u"}, - {Opt_charset, "iocharset=%s"}, - {Opt_namecase, "namecase=%u"}, - {Opt_debug, "debug"}, - {Opt_err_cont, "errors=continue"}, - {Opt_err_panic, "errors=panic"}, - {Opt_err_ro, "errors=remount-ro"}, - {Opt_utf8_hack, "utf8"}, -#ifdef CONFIG_STAGING_EXFAT_DISCARD - {Opt_discard, "discard"}, -#endif /* CONFIG_STAGING_EXFAT_DISCARD */ - {Opt_err, NULL} -}; - -static int parse_options(char *options, int silent, int *debug, - struct exfat_mount_options *opts) -{ - char *p; - substring_t args[MAX_OPT_ARGS]; - int option; - char *iocharset; - - opts->fs_uid = current_uid(); - opts->fs_gid = current_gid(); - opts->fs_fmask = current->fs->umask; - opts->fs_dmask = current->fs->umask; - opts->allow_utime = U16_MAX; - opts->codepage = exfat_default_codepage; - opts->iocharset = exfat_default_iocharset; - opts->casesensitive = 0; - opts->errors = EXFAT_ERRORS_RO; -#ifdef CONFIG_STAGING_EXFAT_DISCARD - opts->discard = 0; -#endif - *debug = 0; - - if (!options) - goto out; - - while ((p = strsep(&options, ","))) { - int token; - - if (!*p) - continue; - - token = match_token(p, exfat_tokens, args); - switch (token) { - case Opt_uid: - if (match_int(&args[0], &option)) - return 0; - opts->fs_uid = KUIDT_INIT(option); - break; - case Opt_gid: - if (match_int(&args[0], &option)) - return 0; - opts->fs_gid = KGIDT_INIT(option); - break; - case Opt_umask: - case Opt_dmask: - case Opt_fmask: - if (match_octal(&args[0], &option)) - return 0; - if (token != Opt_dmask) - opts->fs_fmask = option; - if (token != Opt_fmask) - opts->fs_dmask = option; - break; - case Opt_allow_utime: - if (match_octal(&args[0], &option)) - return 0; - opts->allow_utime = option & 0022; - break; - case Opt_codepage: - if (match_int(&args[0], &option)) - return 0; - opts->codepage = option; - break; - case Opt_charset: - if (opts->iocharset != exfat_default_iocharset) - kfree(opts->iocharset); - iocharset = match_strdup(&args[0]); - if (!iocharset) - return -ENOMEM; - opts->iocharset = iocharset; - break; - case Opt_namecase: - if (match_int(&args[0], &option)) - return 0; - opts->casesensitive = option; - break; - case Opt_err_cont: - opts->errors = EXFAT_ERRORS_CONT; - break; - case Opt_err_panic: - opts->errors = EXFAT_ERRORS_PANIC; - break; - case Opt_err_ro: - opts->errors = EXFAT_ERRORS_RO; - break; - case Opt_debug: - *debug = 1; - break; -#ifdef CONFIG_STAGING_EXFAT_DISCARD - case Opt_discard: - opts->discard = 1; - break; -#endif /* CONFIG_STAGING_EXFAT_DISCARD */ - case Opt_utf8_hack: - break; - default: - if (!silent) - pr_err("[EXFAT] Unrecognized mount option %s or missing value\n", - p); - return -EINVAL; - } - } - -out: - if (opts->allow_utime == U16_MAX) - opts->allow_utime = ~opts->fs_dmask & 0022; - - return 0; -} - -static void exfat_hash_init(struct super_block *sb) -{ - struct exfat_sb_info *sbi = EXFAT_SB(sb); - int i; - - spin_lock_init(&sbi->inode_hash_lock); - for (i = 0; i < EXFAT_HASH_SIZE; i++) - INIT_HLIST_HEAD(&sbi->inode_hashtable[i]); -} - -static int exfat_read_root(struct inode *inode) -{ - struct super_block *sb = inode->i_sb; - struct exfat_sb_info *sbi = EXFAT_SB(sb); - struct fs_info_t *p_fs = &sbi->fs_info; - struct timespec64 curtime; - struct dir_entry_t info; - - EXFAT_I(inode)->fid.dir.dir = p_fs->root_dir; - EXFAT_I(inode)->fid.dir.flags = 0x01; - EXFAT_I(inode)->fid.entry = -1; - EXFAT_I(inode)->fid.start_clu = p_fs->root_dir; - EXFAT_I(inode)->fid.flags = 0x01; - EXFAT_I(inode)->fid.type = TYPE_DIR; - EXFAT_I(inode)->fid.rwoffset = 0; - EXFAT_I(inode)->fid.hint_last_off = -1; - - EXFAT_I(inode)->target = NULL; - - ffsReadStat(inode, &info); - - inode->i_uid = sbi->options.fs_uid; - inode->i_gid = sbi->options.fs_gid; - INC_IVERSION(inode); - inode->i_generation = 0; - inode->i_mode = exfat_make_mode(sbi, ATTR_SUBDIR, 0777); - inode->i_op = &exfat_dir_inode_operations; - inode->i_fop = &exfat_dir_operations; - - i_size_write(inode, info.Size); - inode->i_blocks = ((i_size_read(inode) + (p_fs->cluster_size - 1)) - & ~((loff_t)p_fs->cluster_size - 1)) >> 9; - EXFAT_I(inode)->i_pos = ((loff_t)p_fs->root_dir << 32) | 0xffffffff; - EXFAT_I(inode)->mmu_private = i_size_read(inode); - - exfat_save_attr(inode, ATTR_SUBDIR); - curtime = current_time(inode); - inode->i_mtime = curtime; - inode->i_atime = curtime; - inode->i_ctime = curtime; - set_nlink(inode, info.num_subdirs + 2); - - return 0; -} - -static void setup_dops(struct super_block *sb) -{ - if (EXFAT_SB(sb)->options.casesensitive == 0) - sb->s_d_op = &exfat_ci_dentry_ops; - else - sb->s_d_op = &exfat_dentry_ops; -} - -static int exfat_fill_super(struct super_block *sb, void *data, int silent) -{ - struct inode *root_inode = NULL; - struct exfat_sb_info *sbi; - int debug, ret; - long error; - - /* - * GFP_KERNEL is ok here, because while we do hold the - * supeblock lock, memory pressure can't call back into - * the filesystem, since we're only just about to mount - * it and have no inodes etc active! - */ - sbi = kvzalloc(sizeof(*sbi), GFP_KERNEL); - if (!sbi) - return -ENOMEM; - mutex_init(&sbi->s_lock); - sb->s_fs_info = sbi; - sb->s_flags |= SB_NODIRATIME; - sb->s_magic = EXFAT_SUPER_MAGIC; - sb->s_op = &exfat_sops; - sb->s_export_op = &exfat_export_ops; - - error = parse_options(data, silent, &debug, &sbi->options); - if (error) - goto out_fail; - - setup_dops(sb); - - error = -EIO; - sb_min_blocksize(sb, 512); - sb->s_maxbytes = 0x7fffffffffffffffLL; /* maximum file size */ - - ret = ffsMountVol(sb); - if (ret) { - if (!silent) - pr_err("[EXFAT] ffsMountVol failed\n"); - - goto out_fail; - } - - /* set up enough so that it can read an inode */ - exfat_hash_init(sb); - - /* - * The low byte of FAT's first entry must have same value with - * media-field. But in real world, too many devices is - * writing wrong value. So, removed that validity check. - * - * if (FAT_FIRST_ENT(sb, media) != first) - */ - - sbi->nls_io = load_nls(sbi->options.iocharset); - - error = -ENOMEM; - root_inode = new_inode(sb); - if (!root_inode) - goto out_fail2; - root_inode->i_ino = EXFAT_ROOT_INO; - SET_IVERSION(root_inode, 1); - - error = exfat_read_root(root_inode); - if (error < 0) - goto out_fail2; - error = -ENOMEM; - exfat_attach(root_inode, EXFAT_I(root_inode)->i_pos); - insert_inode_hash(root_inode); - sb->s_root = d_make_root(root_inode); - if (!sb->s_root) { - pr_err("[EXFAT] Getting the root inode failed\n"); - goto out_fail2; - } - - return 0; - -out_fail2: - ffsUmountVol(sb); -out_fail: - if (root_inode) - iput(root_inode); - sb->s_fs_info = NULL; - exfat_free_super(sbi); - return error; -} - -static struct dentry *exfat_fs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, - void *data) -{ - return mount_bdev(fs_type, flags, dev_name, data, exfat_fill_super); -} - -static void init_once(void *foo) -{ - struct exfat_inode_info *ei = (struct exfat_inode_info *)foo; - - INIT_HLIST_NODE(&ei->i_hash_fat); - inode_init_once(&ei->vfs_inode); -} - -static int __init exfat_init_inodecache(void) -{ - exfat_inode_cachep = kmem_cache_create("exfat_inode_cache", - sizeof(struct exfat_inode_info), - 0, - (SLAB_RECLAIM_ACCOUNT | - SLAB_MEM_SPREAD), - init_once); - if (!exfat_inode_cachep) - return -ENOMEM; - return 0; -} - -static void __exit exfat_destroy_inodecache(void) -{ - /* - * Make sure all delayed rcu free inodes are flushed before we - * destroy cache. - */ - rcu_barrier(); - kmem_cache_destroy(exfat_inode_cachep); -} - -#ifdef CONFIG_STAGING_EXFAT_KERNEL_DEBUG -static void exfat_debug_kill_sb(struct super_block *sb) -{ - struct exfat_sb_info *sbi = EXFAT_SB(sb); - struct block_device *bdev = sb->s_bdev; - struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); - - long flags; - - if (sbi) { - flags = sbi->debug_flags; - - if (flags & EXFAT_DEBUGFLAGS_INVALID_UMOUNT) { - /* - * invalidate_bdev drops all device cache include - * dirty. We use this to simulate device removal. - */ - mutex_lock(&p_fs->v_mutex); - exfat_fat_release_all(sb); - exfat_buf_release_all(sb); - mutex_unlock(&p_fs->v_mutex); - - invalidate_bdev(bdev); - } - } - - kill_block_super(sb); -} -#endif /* CONFIG_STAGING_EXFAT_KERNEL_DEBUG */ - -static struct file_system_type exfat_fs_type = { - .owner = THIS_MODULE, - .name = "exfat", - .mount = exfat_fs_mount, -#ifdef CONFIG_STAGING_EXFAT_KERNEL_DEBUG - .kill_sb = exfat_debug_kill_sb, -#else - .kill_sb = kill_block_super, -#endif /* CONFIG_STAGING_EXFAT_KERNEL_DEBUG */ - .fs_flags = FS_REQUIRES_DEV, -}; - -static int __init init_exfat(void) -{ - int err; - - BUILD_BUG_ON(sizeof(struct dentry_t) != DENTRY_SIZE); - BUILD_BUG_ON(sizeof(struct file_dentry_t) != DENTRY_SIZE); - BUILD_BUG_ON(sizeof(struct strm_dentry_t) != DENTRY_SIZE); - BUILD_BUG_ON(sizeof(struct name_dentry_t) != DENTRY_SIZE); - BUILD_BUG_ON(sizeof(struct bmap_dentry_t) != DENTRY_SIZE); - BUILD_BUG_ON(sizeof(struct case_dentry_t) != DENTRY_SIZE); - BUILD_BUG_ON(sizeof(struct volm_dentry_t) != DENTRY_SIZE); - - pr_info("exFAT: Version %s\n", EXFAT_VERSION); - - err = exfat_init_inodecache(); - if (err) - return err; - - err = register_filesystem(&exfat_fs_type); - if (err) - return err; - - return 0; -} - -static void __exit exit_exfat(void) -{ - exfat_destroy_inodecache(); - unregister_filesystem(&exfat_fs_type); -} - -module_init(init_exfat); -module_exit(exit_exfat); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("exFAT Filesystem Driver"); -MODULE_ALIAS_FS("exfat"); diff --git a/drivers/staging/exfat/exfat_upcase.c b/drivers/staging/exfat/exfat_upcase.c deleted file mode 100644 index b91a1faa0e50..000000000000 --- a/drivers/staging/exfat/exfat_upcase.c +++ /dev/null @@ -1,740 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. - */ - -#include -#include "exfat.h" - -const u8 uni_upcase[NUM_UPCASE << 1] = { - 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, - 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, - 0x08, 0x00, 0x09, 0x00, 0x0A, 0x00, 0x0B, 0x00, - 0x0C, 0x00, 0x0D, 0x00, 0x0E, 0x00, 0x0F, 0x00, - 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, - 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, - 0x18, 0x00, 0x19, 0x00, 0x1A, 0x00, 0x1B, 0x00, - 0x1C, 0x00, 0x1D, 0x00, 0x1E, 0x00, 0x1F, 0x00, - 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, - 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, - 0x28, 0x00, 0x29, 0x00, 0x2A, 0x00, 0x2B, 0x00, - 0x2C, 0x00, 0x2D, 0x00, 0x2E, 0x00, 0x2F, 0x00, - 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, - 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, - 0x38, 0x00, 0x39, 0x00, 0x3A, 0x00, 0x3B, 0x00, - 0x3C, 0x00, 0x3D, 0x00, 0x3E, 0x00, 0x3F, 0x00, - 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, - 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, - 0x48, 0x00, 0x49, 0x00, 0x4A, 0x00, 0x4B, 0x00, - 0x4C, 0x00, 0x4D, 0x00, 0x4E, 0x00, 0x4F, 0x00, - 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, - 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, - 0x58, 0x00, 0x59, 0x00, 0x5A, 0x00, 0x5B, 0x00, - 0x5C, 0x00, 0x5D, 0x00, 0x5E, 0x00, 0x5F, 0x00, - 0x60, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, - 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, - 0x48, 0x00, 0x49, 0x00, 0x4A, 0x00, 0x4B, 0x00, - 0x4C, 0x00, 0x4D, 0x00, 0x4E, 0x00, 0x4F, 0x00, - 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, - 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, - 0x58, 0x00, 0x59, 0x00, 0x5A, 0x00, 0x7B, 0x00, - 0x7C, 0x00, 0x7D, 0x00, 0x7E, 0x00, 0x7F, 0x00, - 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, - 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, - 0x88, 0x00, 0x89, 0x00, 0x8A, 0x00, 0x8B, 0x00, - 0x8C, 0x00, 0x8D, 0x00, 0x8E, 0x00, 0x8F, 0x00, - 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, - 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, - 0x98, 0x00, 0x99, 0x00, 0x9A, 0x00, 0x9B, 0x00, - 0x9C, 0x00, 0x9D, 0x00, 0x9E, 0x00, 0x9F, 0x00, - 0xA0, 0x00, 0xA1, 0x00, 0xA2, 0x00, 0xA3, 0x00, - 0xA4, 0x00, 0xA5, 0x00, 0xA6, 0x00, 0xA7, 0x00, - 0xA8, 0x00, 0xA9, 0x00, 0xAA, 0x00, 0xAB, 0x00, - 0xAC, 0x00, 0xAD, 0x00, 0xAE, 0x00, 0xAF, 0x00, - 0xB0, 0x00, 0xB1, 0x00, 0xB2, 0x00, 0xB3, 0x00, - 0xB4, 0x00, 0xB5, 0x00, 0xB6, 0x00, 0xB7, 0x00, - 0xB8, 0x00, 0xB9, 0x00, 0xBA, 0x00, 0xBB, 0x00, - 0xBC, 0x00, 0xBD, 0x00, 0xBE, 0x00, 0xBF, 0x00, - 0xC0, 0x00, 0xC1, 0x00, 0xC2, 0x00, 0xC3, 0x00, - 0xC4, 0x00, 0xC5, 0x00, 0xC6, 0x00, 0xC7, 0x00, - 0xC8, 0x00, 0xC9, 0x00, 0xCA, 0x00, 0xCB, 0x00, - 0xCC, 0x00, 0xCD, 0x00, 0xCE, 0x00, 0xCF, 0x00, - 0xD0, 0x00, 0xD1, 0x00, 0xD2, 0x00, 0xD3, 0x00, - 0xD4, 0x00, 0xD5, 0x00, 0xD6, 0x00, 0xD7, 0x00, - 0xD8, 0x00, 0xD9, 0x00, 0xDA, 0x00, 0xDB, 0x00, - 0xDC, 0x00, 0xDD, 0x00, 0xDE, 0x00, 0xDF, 0x00, - 0xC0, 0x00, 0xC1, 0x00, 0xC2, 0x00, 0xC3, 0x00, - 0xC4, 0x00, 0xC5, 0x00, 0xC6, 0x00, 0xC7, 0x00, - 0xC8, 0x00, 0xC9, 0x00, 0xCA, 0x00, 0xCB, 0x00, - 0xCC, 0x00, 0xCD, 0x00, 0xCE, 0x00, 0xCF, 0x00, - 0xD0, 0x00, 0xD1, 0x00, 0xD2, 0x00, 0xD3, 0x00, - 0xD4, 0x00, 0xD5, 0x00, 0xD6, 0x00, 0xF7, 0x00, - 0xD8, 0x00, 0xD9, 0x00, 0xDA, 0x00, 0xDB, 0x00, - 0xDC, 0x00, 0xDD, 0x00, 0xDE, 0x00, 0x78, 0x01, - 0x00, 0x01, 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, - 0x04, 0x01, 0x04, 0x01, 0x06, 0x01, 0x06, 0x01, - 0x08, 0x01, 0x08, 0x01, 0x0A, 0x01, 0x0A, 0x01, - 0x0C, 0x01, 0x0C, 0x01, 0x0E, 0x01, 0x0E, 0x01, - 0x10, 0x01, 0x10, 0x01, 0x12, 0x01, 0x12, 0x01, - 0x14, 0x01, 0x14, 0x01, 0x16, 0x01, 0x16, 0x01, - 0x18, 0x01, 0x18, 0x01, 0x1A, 0x01, 0x1A, 0x01, - 0x1C, 0x01, 0x1C, 0x01, 0x1E, 0x01, 0x1E, 0x01, - 0x20, 0x01, 0x20, 0x01, 0x22, 0x01, 0x22, 0x01, - 0x24, 0x01, 0x24, 0x01, 0x26, 0x01, 0x26, 0x01, - 0x28, 0x01, 0x28, 0x01, 0x2A, 0x01, 0x2A, 0x01, - 0x2C, 0x01, 0x2C, 0x01, 0x2E, 0x01, 0x2E, 0x01, - 0x30, 0x01, 0x31, 0x01, 0x32, 0x01, 0x32, 0x01, - 0x34, 0x01, 0x34, 0x01, 0x36, 0x01, 0x36, 0x01, - 0x38, 0x01, 0x39, 0x01, 0x39, 0x01, 0x3B, 0x01, - 0x3B, 0x01, 0x3D, 0x01, 0x3D, 0x01, 0x3F, 0x01, - 0x3F, 0x01, 0x41, 0x01, 0x41, 0x01, 0x43, 0x01, - 0x43, 0x01, 0x45, 0x01, 0x45, 0x01, 0x47, 0x01, - 0x47, 0x01, 0x49, 0x01, 0x4A, 0x01, 0x4A, 0x01, - 0x4C, 0x01, 0x4C, 0x01, 0x4E, 0x01, 0x4E, 0x01, - 0x50, 0x01, 0x50, 0x01, 0x52, 0x01, 0x52, 0x01, - 0x54, 0x01, 0x54, 0x01, 0x56, 0x01, 0x56, 0x01, - 0x58, 0x01, 0x58, 0x01, 0x5A, 0x01, 0x5A, 0x01, - 0x5C, 0x01, 0x5C, 0x01, 0x5E, 0x01, 0x5E, 0x01, - 0x60, 0x01, 0x60, 0x01, 0x62, 0x01, 0x62, 0x01, - 0x64, 0x01, 0x64, 0x01, 0x66, 0x01, 0x66, 0x01, - 0x68, 0x01, 0x68, 0x01, 0x6A, 0x01, 0x6A, 0x01, - 0x6C, 0x01, 0x6C, 0x01, 0x6E, 0x01, 0x6E, 0x01, - 0x70, 0x01, 0x70, 0x01, 0x72, 0x01, 0x72, 0x01, - 0x74, 0x01, 0x74, 0x01, 0x76, 0x01, 0x76, 0x01, - 0x78, 0x01, 0x79, 0x01, 0x79, 0x01, 0x7B, 0x01, - 0x7B, 0x01, 0x7D, 0x01, 0x7D, 0x01, 0x7F, 0x01, - 0x43, 0x02, 0x81, 0x01, 0x82, 0x01, 0x82, 0x01, - 0x84, 0x01, 0x84, 0x01, 0x86, 0x01, 0x87, 0x01, - 0x87, 0x01, 0x89, 0x01, 0x8A, 0x01, 0x8B, 0x01, - 0x8B, 0x01, 0x8D, 0x01, 0x8E, 0x01, 0x8F, 0x01, - 0x90, 0x01, 0x91, 0x01, 0x91, 0x01, 0x93, 0x01, - 0x94, 0x01, 0xF6, 0x01, 0x96, 0x01, 0x97, 0x01, - 0x98, 0x01, 0x98, 0x01, 0x3D, 0x02, 0x9B, 0x01, - 0x9C, 0x01, 0x9D, 0x01, 0x20, 0x02, 0x9F, 0x01, - 0xA0, 0x01, 0xA0, 0x01, 0xA2, 0x01, 0xA2, 0x01, - 0xA4, 0x01, 0xA4, 0x01, 0xA6, 0x01, 0xA7, 0x01, - 0xA7, 0x01, 0xA9, 0x01, 0xAA, 0x01, 0xAB, 0x01, - 0xAC, 0x01, 0xAC, 0x01, 0xAE, 0x01, 0xAF, 0x01, - 0xAF, 0x01, 0xB1, 0x01, 0xB2, 0x01, 0xB3, 0x01, - 0xB3, 0x01, 0xB5, 0x01, 0xB5, 0x01, 0xB7, 0x01, - 0xB8, 0x01, 0xB8, 0x01, 0xBA, 0x01, 0xBB, 0x01, - 0xBC, 0x01, 0xBC, 0x01, 0xBE, 0x01, 0xF7, 0x01, - 0xC0, 0x01, 0xC1, 0x01, 0xC2, 0x01, 0xC3, 0x01, - 0xC4, 0x01, 0xC5, 0x01, 0xC4, 0x01, 0xC7, 0x01, - 0xC8, 0x01, 0xC7, 0x01, 0xCA, 0x01, 0xCB, 0x01, - 0xCA, 0x01, 0xCD, 0x01, 0xCD, 0x01, 0xCF, 0x01, - 0xCF, 0x01, 0xD1, 0x01, 0xD1, 0x01, 0xD3, 0x01, - 0xD3, 0x01, 0xD5, 0x01, 0xD5, 0x01, 0xD7, 0x01, - 0xD7, 0x01, 0xD9, 0x01, 0xD9, 0x01, 0xDB, 0x01, - 0xDB, 0x01, 0x8E, 0x01, 0xDE, 0x01, 0xDE, 0x01, - 0xE0, 0x01, 0xE0, 0x01, 0xE2, 0x01, 0xE2, 0x01, - 0xE4, 0x01, 0xE4, 0x01, 0xE6, 0x01, 0xE6, 0x01, - 0xE8, 0x01, 0xE8, 0x01, 0xEA, 0x01, 0xEA, 0x01, - 0xEC, 0x01, 0xEC, 0x01, 0xEE, 0x01, 0xEE, 0x01, - 0xF0, 0x01, 0xF1, 0x01, 0xF2, 0x01, 0xF1, 0x01, - 0xF4, 0x01, 0xF4, 0x01, 0xF6, 0x01, 0xF7, 0x01, - 0xF8, 0x01, 0xF8, 0x01, 0xFA, 0x01, 0xFA, 0x01, - 0xFC, 0x01, 0xFC, 0x01, 0xFE, 0x01, 0xFE, 0x01, - 0x00, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x04, 0x02, 0x04, 0x02, 0x06, 0x02, 0x06, 0x02, - 0x08, 0x02, 0x08, 0x02, 0x0A, 0x02, 0x0A, 0x02, - 0x0C, 0x02, 0x0C, 0x02, 0x0E, 0x02, 0x0E, 0x02, - 0x10, 0x02, 0x10, 0x02, 0x12, 0x02, 0x12, 0x02, - 0x14, 0x02, 0x14, 0x02, 0x16, 0x02, 0x16, 0x02, - 0x18, 0x02, 0x18, 0x02, 0x1A, 0x02, 0x1A, 0x02, - 0x1C, 0x02, 0x1C, 0x02, 0x1E, 0x02, 0x1E, 0x02, - 0x20, 0x02, 0x21, 0x02, 0x22, 0x02, 0x22, 0x02, - 0x24, 0x02, 0x24, 0x02, 0x26, 0x02, 0x26, 0x02, - 0x28, 0x02, 0x28, 0x02, 0x2A, 0x02, 0x2A, 0x02, - 0x2C, 0x02, 0x2C, 0x02, 0x2E, 0x02, 0x2E, 0x02, - 0x30, 0x02, 0x30, 0x02, 0x32, 0x02, 0x32, 0x02, - 0x34, 0x02, 0x35, 0x02, 0x36, 0x02, 0x37, 0x02, - 0x38, 0x02, 0x39, 0x02, 0x65, 0x2C, 0x3B, 0x02, - 0x3B, 0x02, 0x3D, 0x02, 0x66, 0x2C, 0x3F, 0x02, - 0x40, 0x02, 0x41, 0x02, 0x41, 0x02, 0x43, 0x02, - 0x44, 0x02, 0x45, 0x02, 0x46, 0x02, 0x46, 0x02, - 0x48, 0x02, 0x48, 0x02, 0x4A, 0x02, 0x4A, 0x02, - 0x4C, 0x02, 0x4C, 0x02, 0x4E, 0x02, 0x4E, 0x02, - 0x50, 0x02, 0x51, 0x02, 0x52, 0x02, 0x81, 0x01, - 0x86, 0x01, 0x55, 0x02, 0x89, 0x01, 0x8A, 0x01, - 0x58, 0x02, 0x8F, 0x01, 0x5A, 0x02, 0x90, 0x01, - 0x5C, 0x02, 0x5D, 0x02, 0x5E, 0x02, 0x5F, 0x02, - 0x93, 0x01, 0x61, 0x02, 0x62, 0x02, 0x94, 0x01, - 0x64, 0x02, 0x65, 0x02, 0x66, 0x02, 0x67, 0x02, - 0x97, 0x01, 0x96, 0x01, 0x6A, 0x02, 0x62, 0x2C, - 0x6C, 0x02, 0x6D, 0x02, 0x6E, 0x02, 0x9C, 0x01, - 0x70, 0x02, 0x71, 0x02, 0x9D, 0x01, 0x73, 0x02, - 0x74, 0x02, 0x9F, 0x01, 0x76, 0x02, 0x77, 0x02, - 0x78, 0x02, 0x79, 0x02, 0x7A, 0x02, 0x7B, 0x02, - 0x7C, 0x02, 0x64, 0x2C, 0x7E, 0x02, 0x7F, 0x02, - 0xA6, 0x01, 0x81, 0x02, 0x82, 0x02, 0xA9, 0x01, - 0x84, 0x02, 0x85, 0x02, 0x86, 0x02, 0x87, 0x02, - 0xAE, 0x01, 0x44, 0x02, 0xB1, 0x01, 0xB2, 0x01, - 0x45, 0x02, 0x8D, 0x02, 0x8E, 0x02, 0x8F, 0x02, - 0x90, 0x02, 0x91, 0x02, 0xB7, 0x01, 0x93, 0x02, - 0x94, 0x02, 0x95, 0x02, 0x96, 0x02, 0x97, 0x02, - 0x98, 0x02, 0x99, 0x02, 0x9A, 0x02, 0x9B, 0x02, - 0x9C, 0x02, 0x9D, 0x02, 0x9E, 0x02, 0x9F, 0x02, - 0xA0, 0x02, 0xA1, 0x02, 0xA2, 0x02, 0xA3, 0x02, - 0xA4, 0x02, 0xA5, 0x02, 0xA6, 0x02, 0xA7, 0x02, - 0xA8, 0x02, 0xA9, 0x02, 0xAA, 0x02, 0xAB, 0x02, - 0xAC, 0x02, 0xAD, 0x02, 0xAE, 0x02, 0xAF, 0x02, - 0xB0, 0x02, 0xB1, 0x02, 0xB2, 0x02, 0xB3, 0x02, - 0xB4, 0x02, 0xB5, 0x02, 0xB6, 0x02, 0xB7, 0x02, - 0xB8, 0x02, 0xB9, 0x02, 0xBA, 0x02, 0xBB, 0x02, - 0xBC, 0x02, 0xBD, 0x02, 0xBE, 0x02, 0xBF, 0x02, - 0xC0, 0x02, 0xC1, 0x02, 0xC2, 0x02, 0xC3, 0x02, - 0xC4, 0x02, 0xC5, 0x02, 0xC6, 0x02, 0xC7, 0x02, - 0xC8, 0x02, 0xC9, 0x02, 0xCA, 0x02, 0xCB, 0x02, - 0xCC, 0x02, 0xCD, 0x02, 0xCE, 0x02, 0xCF, 0x02, - 0xD0, 0x02, 0xD1, 0x02, 0xD2, 0x02, 0xD3, 0x02, - 0xD4, 0x02, 0xD5, 0x02, 0xD6, 0x02, 0xD7, 0x02, - 0xD8, 0x02, 0xD9, 0x02, 0xDA, 0x02, 0xDB, 0x02, - 0xDC, 0x02, 0xDD, 0x02, 0xDE, 0x02, 0xDF, 0x02, - 0xE0, 0x02, 0xE1, 0x02, 0xE2, 0x02, 0xE3, 0x02, - 0xE4, 0x02, 0xE5, 0x02, 0xE6, 0x02, 0xE7, 0x02, - 0xE8, 0x02, 0xE9, 0x02, 0xEA, 0x02, 0xEB, 0x02, - 0xEC, 0x02, 0xED, 0x02, 0xEE, 0x02, 0xEF, 0x02, - 0xF0, 0x02, 0xF1, 0x02, 0xF2, 0x02, 0xF3, 0x02, - 0xF4, 0x02, 0xF5, 0x02, 0xF6, 0x02, 0xF7, 0x02, - 0xF8, 0x02, 0xF9, 0x02, 0xFA, 0x02, 0xFB, 0x02, - 0xFC, 0x02, 0xFD, 0x02, 0xFE, 0x02, 0xFF, 0x02, - 0x00, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x03, - 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x07, 0x03, - 0x08, 0x03, 0x09, 0x03, 0x0A, 0x03, 0x0B, 0x03, - 0x0C, 0x03, 0x0D, 0x03, 0x0E, 0x03, 0x0F, 0x03, - 0x10, 0x03, 0x11, 0x03, 0x12, 0x03, 0x13, 0x03, - 0x14, 0x03, 0x15, 0x03, 0x16, 0x03, 0x17, 0x03, - 0x18, 0x03, 0x19, 0x03, 0x1A, 0x03, 0x1B, 0x03, - 0x1C, 0x03, 0x1D, 0x03, 0x1E, 0x03, 0x1F, 0x03, - 0x20, 0x03, 0x21, 0x03, 0x22, 0x03, 0x23, 0x03, - 0x24, 0x03, 0x25, 0x03, 0x26, 0x03, 0x27, 0x03, - 0x28, 0x03, 0x29, 0x03, 0x2A, 0x03, 0x2B, 0x03, - 0x2C, 0x03, 0x2D, 0x03, 0x2E, 0x03, 0x2F, 0x03, - 0x30, 0x03, 0x31, 0x03, 0x32, 0x03, 0x33, 0x03, - 0x34, 0x03, 0x35, 0x03, 0x36, 0x03, 0x37, 0x03, - 0x38, 0x03, 0x39, 0x03, 0x3A, 0x03, 0x3B, 0x03, - 0x3C, 0x03, 0x3D, 0x03, 0x3E, 0x03, 0x3F, 0x03, - 0x40, 0x03, 0x41, 0x03, 0x42, 0x03, 0x43, 0x03, - 0x44, 0x03, 0x45, 0x03, 0x46, 0x03, 0x47, 0x03, - 0x48, 0x03, 0x49, 0x03, 0x4A, 0x03, 0x4B, 0x03, - 0x4C, 0x03, 0x4D, 0x03, 0x4E, 0x03, 0x4F, 0x03, - 0x50, 0x03, 0x51, 0x03, 0x52, 0x03, 0x53, 0x03, - 0x54, 0x03, 0x55, 0x03, 0x56, 0x03, 0x57, 0x03, - 0x58, 0x03, 0x59, 0x03, 0x5A, 0x03, 0x5B, 0x03, - 0x5C, 0x03, 0x5D, 0x03, 0x5E, 0x03, 0x5F, 0x03, - 0x60, 0x03, 0x61, 0x03, 0x62, 0x03, 0x63, 0x03, - 0x64, 0x03, 0x65, 0x03, 0x66, 0x03, 0x67, 0x03, - 0x68, 0x03, 0x69, 0x03, 0x6A, 0x03, 0x6B, 0x03, - 0x6C, 0x03, 0x6D, 0x03, 0x6E, 0x03, 0x6F, 0x03, - 0x70, 0x03, 0x71, 0x03, 0x72, 0x03, 0x73, 0x03, - 0x74, 0x03, 0x75, 0x03, 0x76, 0x03, 0x77, 0x03, - 0x78, 0x03, 0x79, 0x03, 0x7A, 0x03, 0xFD, 0x03, - 0xFE, 0x03, 0xFF, 0x03, 0x7E, 0x03, 0x7F, 0x03, - 0x80, 0x03, 0x81, 0x03, 0x82, 0x03, 0x83, 0x03, - 0x84, 0x03, 0x85, 0x03, 0x86, 0x03, 0x87, 0x03, - 0x88, 0x03, 0x89, 0x03, 0x8A, 0x03, 0x8B, 0x03, - 0x8C, 0x03, 0x8D, 0x03, 0x8E, 0x03, 0x8F, 0x03, - 0x90, 0x03, 0x91, 0x03, 0x92, 0x03, 0x93, 0x03, - 0x94, 0x03, 0x95, 0x03, 0x96, 0x03, 0x97, 0x03, - 0x98, 0x03, 0x99, 0x03, 0x9A, 0x03, 0x9B, 0x03, - 0x9C, 0x03, 0x9D, 0x03, 0x9E, 0x03, 0x9F, 0x03, - 0xA0, 0x03, 0xA1, 0x03, 0xA2, 0x03, 0xA3, 0x03, - 0xA4, 0x03, 0xA5, 0x03, 0xA6, 0x03, 0xA7, 0x03, - 0xA8, 0x03, 0xA9, 0x03, 0xAA, 0x03, 0xAB, 0x03, - 0x86, 0x03, 0x88, 0x03, 0x89, 0x03, 0x8A, 0x03, - 0xB0, 0x03, 0x91, 0x03, 0x92, 0x03, 0x93, 0x03, - 0x94, 0x03, 0x95, 0x03, 0x96, 0x03, 0x97, 0x03, - 0x98, 0x03, 0x99, 0x03, 0x9A, 0x03, 0x9B, 0x03, - 0x9C, 0x03, 0x9D, 0x03, 0x9E, 0x03, 0x9F, 0x03, - 0xA0, 0x03, 0xA1, 0x03, 0xA3, 0x03, 0xA3, 0x03, - 0xA4, 0x03, 0xA5, 0x03, 0xA6, 0x03, 0xA7, 0x03, - 0xA8, 0x03, 0xA9, 0x03, 0xAA, 0x03, 0xAB, 0x03, - 0x8C, 0x03, 0x8E, 0x03, 0x8F, 0x03, 0xCF, 0x03, - 0xD0, 0x03, 0xD1, 0x03, 0xD2, 0x03, 0xD3, 0x03, - 0xD4, 0x03, 0xD5, 0x03, 0xD6, 0x03, 0xD7, 0x03, - 0xD8, 0x03, 0xD8, 0x03, 0xDA, 0x03, 0xDA, 0x03, - 0xDC, 0x03, 0xDC, 0x03, 0xDE, 0x03, 0xDE, 0x03, - 0xE0, 0x03, 0xE0, 0x03, 0xE2, 0x03, 0xE2, 0x03, - 0xE4, 0x03, 0xE4, 0x03, 0xE6, 0x03, 0xE6, 0x03, - 0xE8, 0x03, 0xE8, 0x03, 0xEA, 0x03, 0xEA, 0x03, - 0xEC, 0x03, 0xEC, 0x03, 0xEE, 0x03, 0xEE, 0x03, - 0xF0, 0x03, 0xF1, 0x03, 0xF9, 0x03, 0xF3, 0x03, - 0xF4, 0x03, 0xF5, 0x03, 0xF6, 0x03, 0xF7, 0x03, - 0xF7, 0x03, 0xF9, 0x03, 0xFA, 0x03, 0xFA, 0x03, - 0xFC, 0x03, 0xFD, 0x03, 0xFE, 0x03, 0xFF, 0x03, - 0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x04, - 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, 0x04, - 0x08, 0x04, 0x09, 0x04, 0x0A, 0x04, 0x0B, 0x04, - 0x0C, 0x04, 0x0D, 0x04, 0x0E, 0x04, 0x0F, 0x04, - 0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04, - 0x14, 0x04, 0x15, 0x04, 0x16, 0x04, 0x17, 0x04, - 0x18, 0x04, 0x19, 0x04, 0x1A, 0x04, 0x1B, 0x04, - 0x1C, 0x04, 0x1D, 0x04, 0x1E, 0x04, 0x1F, 0x04, - 0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04, - 0x24, 0x04, 0x25, 0x04, 0x26, 0x04, 0x27, 0x04, - 0x28, 0x04, 0x29, 0x04, 0x2A, 0x04, 0x2B, 0x04, - 0x2C, 0x04, 0x2D, 0x04, 0x2E, 0x04, 0x2F, 0x04, - 0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04, - 0x14, 0x04, 0x15, 0x04, 0x16, 0x04, 0x17, 0x04, - 0x18, 0x04, 0x19, 0x04, 0x1A, 0x04, 0x1B, 0x04, - 0x1C, 0x04, 0x1D, 0x04, 0x1E, 0x04, 0x1F, 0x04, - 0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04, - 0x24, 0x04, 0x25, 0x04, 0x26, 0x04, 0x27, 0x04, - 0x28, 0x04, 0x29, 0x04, 0x2A, 0x04, 0x2B, 0x04, - 0x2C, 0x04, 0x2D, 0x04, 0x2E, 0x04, 0x2F, 0x04, - 0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x04, - 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, 0x04, - 0x08, 0x04, 0x09, 0x04, 0x0A, 0x04, 0x0B, 0x04, - 0x0C, 0x04, 0x0D, 0x04, 0x0E, 0x04, 0x0F, 0x04, - 0x60, 0x04, 0x60, 0x04, 0x62, 0x04, 0x62, 0x04, - 0x64, 0x04, 0x64, 0x04, 0x66, 0x04, 0x66, 0x04, - 0x68, 0x04, 0x68, 0x04, 0x6A, 0x04, 0x6A, 0x04, - 0x6C, 0x04, 0x6C, 0x04, 0x6E, 0x04, 0x6E, 0x04, - 0x70, 0x04, 0x70, 0x04, 0x72, 0x04, 0x72, 0x04, - 0x74, 0x04, 0x74, 0x04, 0x76, 0x04, 0x76, 0x04, - 0x78, 0x04, 0x78, 0x04, 0x7A, 0x04, 0x7A, 0x04, - 0x7C, 0x04, 0x7C, 0x04, 0x7E, 0x04, 0x7E, 0x04, - 0x80, 0x04, 0x80, 0x04, 0x82, 0x04, 0x83, 0x04, - 0x84, 0x04, 0x85, 0x04, 0x86, 0x04, 0x87, 0x04, - 0x88, 0x04, 0x89, 0x04, 0x8A, 0x04, 0x8A, 0x04, - 0x8C, 0x04, 0x8C, 0x04, 0x8E, 0x04, 0x8E, 0x04, - 0x90, 0x04, 0x90, 0x04, 0x92, 0x04, 0x92, 0x04, - 0x94, 0x04, 0x94, 0x04, 0x96, 0x04, 0x96, 0x04, - 0x98, 0x04, 0x98, 0x04, 0x9A, 0x04, 0x9A, 0x04, - 0x9C, 0x04, 0x9C, 0x04, 0x9E, 0x04, 0x9E, 0x04, - 0xA0, 0x04, 0xA0, 0x04, 0xA2, 0x04, 0xA2, 0x04, - 0xA4, 0x04, 0xA4, 0x04, 0xA6, 0x04, 0xA6, 0x04, - 0xA8, 0x04, 0xA8, 0x04, 0xAA, 0x04, 0xAA, 0x04, - 0xAC, 0x04, 0xAC, 0x04, 0xAE, 0x04, 0xAE, 0x04, - 0xB0, 0x04, 0xB0, 0x04, 0xB2, 0x04, 0xB2, 0x04, - 0xB4, 0x04, 0xB4, 0x04, 0xB6, 0x04, 0xB6, 0x04, - 0xB8, 0x04, 0xB8, 0x04, 0xBA, 0x04, 0xBA, 0x04, - 0xBC, 0x04, 0xBC, 0x04, 0xBE, 0x04, 0xBE, 0x04, - 0xC0, 0x04, 0xC1, 0x04, 0xC1, 0x04, 0xC3, 0x04, - 0xC3, 0x04, 0xC5, 0x04, 0xC5, 0x04, 0xC7, 0x04, - 0xC7, 0x04, 0xC9, 0x04, 0xC9, 0x04, 0xCB, 0x04, - 0xCB, 0x04, 0xCD, 0x04, 0xCD, 0x04, 0xC0, 0x04, - 0xD0, 0x04, 0xD0, 0x04, 0xD2, 0x04, 0xD2, 0x04, - 0xD4, 0x04, 0xD4, 0x04, 0xD6, 0x04, 0xD6, 0x04, - 0xD8, 0x04, 0xD8, 0x04, 0xDA, 0x04, 0xDA, 0x04, - 0xDC, 0x04, 0xDC, 0x04, 0xDE, 0x04, 0xDE, 0x04, - 0xE0, 0x04, 0xE0, 0x04, 0xE2, 0x04, 0xE2, 0x04, - 0xE4, 0x04, 0xE4, 0x04, 0xE6, 0x04, 0xE6, 0x04, - 0xE8, 0x04, 0xE8, 0x04, 0xEA, 0x04, 0xEA, 0x04, - 0xEC, 0x04, 0xEC, 0x04, 0xEE, 0x04, 0xEE, 0x04, - 0xF0, 0x04, 0xF0, 0x04, 0xF2, 0x04, 0xF2, 0x04, - 0xF4, 0x04, 0xF4, 0x04, 0xF6, 0x04, 0xF6, 0x04, - 0xF8, 0x04, 0xF8, 0x04, 0xFA, 0x04, 0xFA, 0x04, - 0xFC, 0x04, 0xFC, 0x04, 0xFE, 0x04, 0xFE, 0x04, - 0x00, 0x05, 0x00, 0x05, 0x02, 0x05, 0x02, 0x05, - 0x04, 0x05, 0x04, 0x05, 0x06, 0x05, 0x06, 0x05, - 0x08, 0x05, 0x08, 0x05, 0x0A, 0x05, 0x0A, 0x05, - 0x0C, 0x05, 0x0C, 0x05, 0x0E, 0x05, 0x0E, 0x05, - 0x10, 0x05, 0x10, 0x05, 0x12, 0x05, 0x12, 0x05, - 0x14, 0x05, 0x15, 0x05, 0x16, 0x05, 0x17, 0x05, - 0x18, 0x05, 0x19, 0x05, 0x1A, 0x05, 0x1B, 0x05, - 0x1C, 0x05, 0x1D, 0x05, 0x1E, 0x05, 0x1F, 0x05, - 0x20, 0x05, 0x21, 0x05, 0x22, 0x05, 0x23, 0x05, - 0x24, 0x05, 0x25, 0x05, 0x26, 0x05, 0x27, 0x05, - 0x28, 0x05, 0x29, 0x05, 0x2A, 0x05, 0x2B, 0x05, - 0x2C, 0x05, 0x2D, 0x05, 0x2E, 0x05, 0x2F, 0x05, - 0x30, 0x05, 0x31, 0x05, 0x32, 0x05, 0x33, 0x05, - 0x34, 0x05, 0x35, 0x05, 0x36, 0x05, 0x37, 0x05, - 0x38, 0x05, 0x39, 0x05, 0x3A, 0x05, 0x3B, 0x05, - 0x3C, 0x05, 0x3D, 0x05, 0x3E, 0x05, 0x3F, 0x05, - 0x40, 0x05, 0x41, 0x05, 0x42, 0x05, 0x43, 0x05, - 0x44, 0x05, 0x45, 0x05, 0x46, 0x05, 0x47, 0x05, - 0x48, 0x05, 0x49, 0x05, 0x4A, 0x05, 0x4B, 0x05, - 0x4C, 0x05, 0x4D, 0x05, 0x4E, 0x05, 0x4F, 0x05, - 0x50, 0x05, 0x51, 0x05, 0x52, 0x05, 0x53, 0x05, - 0x54, 0x05, 0x55, 0x05, 0x56, 0x05, 0x57, 0x05, - 0x58, 0x05, 0x59, 0x05, 0x5A, 0x05, 0x5B, 0x05, - 0x5C, 0x05, 0x5D, 0x05, 0x5E, 0x05, 0x5F, 0x05, - 0x60, 0x05, 0x31, 0x05, 0x32, 0x05, 0x33, 0x05, - 0x34, 0x05, 0x35, 0x05, 0x36, 0x05, 0x37, 0x05, - 0x38, 0x05, 0x39, 0x05, 0x3A, 0x05, 0x3B, 0x05, - 0x3C, 0x05, 0x3D, 0x05, 0x3E, 0x05, 0x3F, 0x05, - 0x40, 0x05, 0x41, 0x05, 0x42, 0x05, 0x43, 0x05, - 0x44, 0x05, 0x45, 0x05, 0x46, 0x05, 0x47, 0x05, - 0x48, 0x05, 0x49, 0x05, 0x4A, 0x05, 0x4B, 0x05, - 0x4C, 0x05, 0x4D, 0x05, 0x4E, 0x05, 0x4F, 0x05, - 0x50, 0x05, 0x51, 0x05, 0x52, 0x05, 0x53, 0x05, - 0x54, 0x05, 0x55, 0x05, 0x56, 0x05, 0xFF, 0xFF, - 0xF6, 0x17, 0x63, 0x2C, 0x7E, 0x1D, 0x7F, 0x1D, - 0x80, 0x1D, 0x81, 0x1D, 0x82, 0x1D, 0x83, 0x1D, - 0x84, 0x1D, 0x85, 0x1D, 0x86, 0x1D, 0x87, 0x1D, - 0x88, 0x1D, 0x89, 0x1D, 0x8A, 0x1D, 0x8B, 0x1D, - 0x8C, 0x1D, 0x8D, 0x1D, 0x8E, 0x1D, 0x8F, 0x1D, - 0x90, 0x1D, 0x91, 0x1D, 0x92, 0x1D, 0x93, 0x1D, - 0x94, 0x1D, 0x95, 0x1D, 0x96, 0x1D, 0x97, 0x1D, - 0x98, 0x1D, 0x99, 0x1D, 0x9A, 0x1D, 0x9B, 0x1D, - 0x9C, 0x1D, 0x9D, 0x1D, 0x9E, 0x1D, 0x9F, 0x1D, - 0xA0, 0x1D, 0xA1, 0x1D, 0xA2, 0x1D, 0xA3, 0x1D, - 0xA4, 0x1D, 0xA5, 0x1D, 0xA6, 0x1D, 0xA7, 0x1D, - 0xA8, 0x1D, 0xA9, 0x1D, 0xAA, 0x1D, 0xAB, 0x1D, - 0xAC, 0x1D, 0xAD, 0x1D, 0xAE, 0x1D, 0xAF, 0x1D, - 0xB0, 0x1D, 0xB1, 0x1D, 0xB2, 0x1D, 0xB3, 0x1D, - 0xB4, 0x1D, 0xB5, 0x1D, 0xB6, 0x1D, 0xB7, 0x1D, - 0xB8, 0x1D, 0xB9, 0x1D, 0xBA, 0x1D, 0xBB, 0x1D, - 0xBC, 0x1D, 0xBD, 0x1D, 0xBE, 0x1D, 0xBF, 0x1D, - 0xC0, 0x1D, 0xC1, 0x1D, 0xC2, 0x1D, 0xC3, 0x1D, - 0xC4, 0x1D, 0xC5, 0x1D, 0xC6, 0x1D, 0xC7, 0x1D, - 0xC8, 0x1D, 0xC9, 0x1D, 0xCA, 0x1D, 0xCB, 0x1D, - 0xCC, 0x1D, 0xCD, 0x1D, 0xCE, 0x1D, 0xCF, 0x1D, - 0xD0, 0x1D, 0xD1, 0x1D, 0xD2, 0x1D, 0xD3, 0x1D, - 0xD4, 0x1D, 0xD5, 0x1D, 0xD6, 0x1D, 0xD7, 0x1D, - 0xD8, 0x1D, 0xD9, 0x1D, 0xDA, 0x1D, 0xDB, 0x1D, - 0xDC, 0x1D, 0xDD, 0x1D, 0xDE, 0x1D, 0xDF, 0x1D, - 0xE0, 0x1D, 0xE1, 0x1D, 0xE2, 0x1D, 0xE3, 0x1D, - 0xE4, 0x1D, 0xE5, 0x1D, 0xE6, 0x1D, 0xE7, 0x1D, - 0xE8, 0x1D, 0xE9, 0x1D, 0xEA, 0x1D, 0xEB, 0x1D, - 0xEC, 0x1D, 0xED, 0x1D, 0xEE, 0x1D, 0xEF, 0x1D, - 0xF0, 0x1D, 0xF1, 0x1D, 0xF2, 0x1D, 0xF3, 0x1D, - 0xF4, 0x1D, 0xF5, 0x1D, 0xF6, 0x1D, 0xF7, 0x1D, - 0xF8, 0x1D, 0xF9, 0x1D, 0xFA, 0x1D, 0xFB, 0x1D, - 0xFC, 0x1D, 0xFD, 0x1D, 0xFE, 0x1D, 0xFF, 0x1D, - 0x00, 0x1E, 0x00, 0x1E, 0x02, 0x1E, 0x02, 0x1E, - 0x04, 0x1E, 0x04, 0x1E, 0x06, 0x1E, 0x06, 0x1E, - 0x08, 0x1E, 0x08, 0x1E, 0x0A, 0x1E, 0x0A, 0x1E, - 0x0C, 0x1E, 0x0C, 0x1E, 0x0E, 0x1E, 0x0E, 0x1E, - 0x10, 0x1E, 0x10, 0x1E, 0x12, 0x1E, 0x12, 0x1E, - 0x14, 0x1E, 0x14, 0x1E, 0x16, 0x1E, 0x16, 0x1E, - 0x18, 0x1E, 0x18, 0x1E, 0x1A, 0x1E, 0x1A, 0x1E, - 0x1C, 0x1E, 0x1C, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, - 0x20, 0x1E, 0x20, 0x1E, 0x22, 0x1E, 0x22, 0x1E, - 0x24, 0x1E, 0x24, 0x1E, 0x26, 0x1E, 0x26, 0x1E, - 0x28, 0x1E, 0x28, 0x1E, 0x2A, 0x1E, 0x2A, 0x1E, - 0x2C, 0x1E, 0x2C, 0x1E, 0x2E, 0x1E, 0x2E, 0x1E, - 0x30, 0x1E, 0x30, 0x1E, 0x32, 0x1E, 0x32, 0x1E, - 0x34, 0x1E, 0x34, 0x1E, 0x36, 0x1E, 0x36, 0x1E, - 0x38, 0x1E, 0x38, 0x1E, 0x3A, 0x1E, 0x3A, 0x1E, - 0x3C, 0x1E, 0x3C, 0x1E, 0x3E, 0x1E, 0x3E, 0x1E, - 0x40, 0x1E, 0x40, 0x1E, 0x42, 0x1E, 0x42, 0x1E, - 0x44, 0x1E, 0x44, 0x1E, 0x46, 0x1E, 0x46, 0x1E, - 0x48, 0x1E, 0x48, 0x1E, 0x4A, 0x1E, 0x4A, 0x1E, - 0x4C, 0x1E, 0x4C, 0x1E, 0x4E, 0x1E, 0x4E, 0x1E, - 0x50, 0x1E, 0x50, 0x1E, 0x52, 0x1E, 0x52, 0x1E, - 0x54, 0x1E, 0x54, 0x1E, 0x56, 0x1E, 0x56, 0x1E, - 0x58, 0x1E, 0x58, 0x1E, 0x5A, 0x1E, 0x5A, 0x1E, - 0x5C, 0x1E, 0x5C, 0x1E, 0x5E, 0x1E, 0x5E, 0x1E, - 0x60, 0x1E, 0x60, 0x1E, 0x62, 0x1E, 0x62, 0x1E, - 0x64, 0x1E, 0x64, 0x1E, 0x66, 0x1E, 0x66, 0x1E, - 0x68, 0x1E, 0x68, 0x1E, 0x6A, 0x1E, 0x6A, 0x1E, - 0x6C, 0x1E, 0x6C, 0x1E, 0x6E, 0x1E, 0x6E, 0x1E, - 0x70, 0x1E, 0x70, 0x1E, 0x72, 0x1E, 0x72, 0x1E, - 0x74, 0x1E, 0x74, 0x1E, 0x76, 0x1E, 0x76, 0x1E, - 0x78, 0x1E, 0x78, 0x1E, 0x7A, 0x1E, 0x7A, 0x1E, - 0x7C, 0x1E, 0x7C, 0x1E, 0x7E, 0x1E, 0x7E, 0x1E, - 0x80, 0x1E, 0x80, 0x1E, 0x82, 0x1E, 0x82, 0x1E, - 0x84, 0x1E, 0x84, 0x1E, 0x86, 0x1E, 0x86, 0x1E, - 0x88, 0x1E, 0x88, 0x1E, 0x8A, 0x1E, 0x8A, 0x1E, - 0x8C, 0x1E, 0x8C, 0x1E, 0x8E, 0x1E, 0x8E, 0x1E, - 0x90, 0x1E, 0x90, 0x1E, 0x92, 0x1E, 0x92, 0x1E, - 0x94, 0x1E, 0x94, 0x1E, 0x96, 0x1E, 0x97, 0x1E, - 0x98, 0x1E, 0x99, 0x1E, 0x9A, 0x1E, 0x9B, 0x1E, - 0x9C, 0x1E, 0x9D, 0x1E, 0x9E, 0x1E, 0x9F, 0x1E, - 0xA0, 0x1E, 0xA0, 0x1E, 0xA2, 0x1E, 0xA2, 0x1E, - 0xA4, 0x1E, 0xA4, 0x1E, 0xA6, 0x1E, 0xA6, 0x1E, - 0xA8, 0x1E, 0xA8, 0x1E, 0xAA, 0x1E, 0xAA, 0x1E, - 0xAC, 0x1E, 0xAC, 0x1E, 0xAE, 0x1E, 0xAE, 0x1E, - 0xB0, 0x1E, 0xB0, 0x1E, 0xB2, 0x1E, 0xB2, 0x1E, - 0xB4, 0x1E, 0xB4, 0x1E, 0xB6, 0x1E, 0xB6, 0x1E, - 0xB8, 0x1E, 0xB8, 0x1E, 0xBA, 0x1E, 0xBA, 0x1E, - 0xBC, 0x1E, 0xBC, 0x1E, 0xBE, 0x1E, 0xBE, 0x1E, - 0xC0, 0x1E, 0xC0, 0x1E, 0xC2, 0x1E, 0xC2, 0x1E, - 0xC4, 0x1E, 0xC4, 0x1E, 0xC6, 0x1E, 0xC6, 0x1E, - 0xC8, 0x1E, 0xC8, 0x1E, 0xCA, 0x1E, 0xCA, 0x1E, - 0xCC, 0x1E, 0xCC, 0x1E, 0xCE, 0x1E, 0xCE, 0x1E, - 0xD0, 0x1E, 0xD0, 0x1E, 0xD2, 0x1E, 0xD2, 0x1E, - 0xD4, 0x1E, 0xD4, 0x1E, 0xD6, 0x1E, 0xD6, 0x1E, - 0xD8, 0x1E, 0xD8, 0x1E, 0xDA, 0x1E, 0xDA, 0x1E, - 0xDC, 0x1E, 0xDC, 0x1E, 0xDE, 0x1E, 0xDE, 0x1E, - 0xE0, 0x1E, 0xE0, 0x1E, 0xE2, 0x1E, 0xE2, 0x1E, - 0xE4, 0x1E, 0xE4, 0x1E, 0xE6, 0x1E, 0xE6, 0x1E, - 0xE8, 0x1E, 0xE8, 0x1E, 0xEA, 0x1E, 0xEA, 0x1E, - 0xEC, 0x1E, 0xEC, 0x1E, 0xEE, 0x1E, 0xEE, 0x1E, - 0xF0, 0x1E, 0xF0, 0x1E, 0xF2, 0x1E, 0xF2, 0x1E, - 0xF4, 0x1E, 0xF4, 0x1E, 0xF6, 0x1E, 0xF6, 0x1E, - 0xF8, 0x1E, 0xF8, 0x1E, 0xFA, 0x1E, 0xFB, 0x1E, - 0xFC, 0x1E, 0xFD, 0x1E, 0xFE, 0x1E, 0xFF, 0x1E, - 0x08, 0x1F, 0x09, 0x1F, 0x0A, 0x1F, 0x0B, 0x1F, - 0x0C, 0x1F, 0x0D, 0x1F, 0x0E, 0x1F, 0x0F, 0x1F, - 0x08, 0x1F, 0x09, 0x1F, 0x0A, 0x1F, 0x0B, 0x1F, - 0x0C, 0x1F, 0x0D, 0x1F, 0x0E, 0x1F, 0x0F, 0x1F, - 0x18, 0x1F, 0x19, 0x1F, 0x1A, 0x1F, 0x1B, 0x1F, - 0x1C, 0x1F, 0x1D, 0x1F, 0x16, 0x1F, 0x17, 0x1F, - 0x18, 0x1F, 0x19, 0x1F, 0x1A, 0x1F, 0x1B, 0x1F, - 0x1C, 0x1F, 0x1D, 0x1F, 0x1E, 0x1F, 0x1F, 0x1F, - 0x28, 0x1F, 0x29, 0x1F, 0x2A, 0x1F, 0x2B, 0x1F, - 0x2C, 0x1F, 0x2D, 0x1F, 0x2E, 0x1F, 0x2F, 0x1F, - 0x28, 0x1F, 0x29, 0x1F, 0x2A, 0x1F, 0x2B, 0x1F, - 0x2C, 0x1F, 0x2D, 0x1F, 0x2E, 0x1F, 0x2F, 0x1F, - 0x38, 0x1F, 0x39, 0x1F, 0x3A, 0x1F, 0x3B, 0x1F, - 0x3C, 0x1F, 0x3D, 0x1F, 0x3E, 0x1F, 0x3F, 0x1F, - 0x38, 0x1F, 0x39, 0x1F, 0x3A, 0x1F, 0x3B, 0x1F, - 0x3C, 0x1F, 0x3D, 0x1F, 0x3E, 0x1F, 0x3F, 0x1F, - 0x48, 0x1F, 0x49, 0x1F, 0x4A, 0x1F, 0x4B, 0x1F, - 0x4C, 0x1F, 0x4D, 0x1F, 0x46, 0x1F, 0x47, 0x1F, - 0x48, 0x1F, 0x49, 0x1F, 0x4A, 0x1F, 0x4B, 0x1F, - 0x4C, 0x1F, 0x4D, 0x1F, 0x4E, 0x1F, 0x4F, 0x1F, - 0x50, 0x1F, 0x59, 0x1F, 0x52, 0x1F, 0x5B, 0x1F, - 0x54, 0x1F, 0x5D, 0x1F, 0x56, 0x1F, 0x5F, 0x1F, - 0x58, 0x1F, 0x59, 0x1F, 0x5A, 0x1F, 0x5B, 0x1F, - 0x5C, 0x1F, 0x5D, 0x1F, 0x5E, 0x1F, 0x5F, 0x1F, - 0x68, 0x1F, 0x69, 0x1F, 0x6A, 0x1F, 0x6B, 0x1F, - 0x6C, 0x1F, 0x6D, 0x1F, 0x6E, 0x1F, 0x6F, 0x1F, - 0x68, 0x1F, 0x69, 0x1F, 0x6A, 0x1F, 0x6B, 0x1F, - 0x6C, 0x1F, 0x6D, 0x1F, 0x6E, 0x1F, 0x6F, 0x1F, - 0xBA, 0x1F, 0xBB, 0x1F, 0xC8, 0x1F, 0xC9, 0x1F, - 0xCA, 0x1F, 0xCB, 0x1F, 0xDA, 0x1F, 0xDB, 0x1F, - 0xF8, 0x1F, 0xF9, 0x1F, 0xEA, 0x1F, 0xEB, 0x1F, - 0xFA, 0x1F, 0xFB, 0x1F, 0x7E, 0x1F, 0x7F, 0x1F, - 0x88, 0x1F, 0x89, 0x1F, 0x8A, 0x1F, 0x8B, 0x1F, - 0x8C, 0x1F, 0x8D, 0x1F, 0x8E, 0x1F, 0x8F, 0x1F, - 0x88, 0x1F, 0x89, 0x1F, 0x8A, 0x1F, 0x8B, 0x1F, - 0x8C, 0x1F, 0x8D, 0x1F, 0x8E, 0x1F, 0x8F, 0x1F, - 0x98, 0x1F, 0x99, 0x1F, 0x9A, 0x1F, 0x9B, 0x1F, - 0x9C, 0x1F, 0x9D, 0x1F, 0x9E, 0x1F, 0x9F, 0x1F, - 0x98, 0x1F, 0x99, 0x1F, 0x9A, 0x1F, 0x9B, 0x1F, - 0x9C, 0x1F, 0x9D, 0x1F, 0x9E, 0x1F, 0x9F, 0x1F, - 0xA8, 0x1F, 0xA9, 0x1F, 0xAA, 0x1F, 0xAB, 0x1F, - 0xAC, 0x1F, 0xAD, 0x1F, 0xAE, 0x1F, 0xAF, 0x1F, - 0xA8, 0x1F, 0xA9, 0x1F, 0xAA, 0x1F, 0xAB, 0x1F, - 0xAC, 0x1F, 0xAD, 0x1F, 0xAE, 0x1F, 0xAF, 0x1F, - 0xB8, 0x1F, 0xB9, 0x1F, 0xB2, 0x1F, 0xBC, 0x1F, - 0xB4, 0x1F, 0xB5, 0x1F, 0xB6, 0x1F, 0xB7, 0x1F, - 0xB8, 0x1F, 0xB9, 0x1F, 0xBA, 0x1F, 0xBB, 0x1F, - 0xBC, 0x1F, 0xBD, 0x1F, 0xBE, 0x1F, 0xBF, 0x1F, - 0xC0, 0x1F, 0xC1, 0x1F, 0xC2, 0x1F, 0xC3, 0x1F, - 0xC4, 0x1F, 0xC5, 0x1F, 0xC6, 0x1F, 0xC7, 0x1F, - 0xC8, 0x1F, 0xC9, 0x1F, 0xCA, 0x1F, 0xCB, 0x1F, - 0xC3, 0x1F, 0xCD, 0x1F, 0xCE, 0x1F, 0xCF, 0x1F, - 0xD8, 0x1F, 0xD9, 0x1F, 0xD2, 0x1F, 0xD3, 0x1F, - 0xD4, 0x1F, 0xD5, 0x1F, 0xD6, 0x1F, 0xD7, 0x1F, - 0xD8, 0x1F, 0xD9, 0x1F, 0xDA, 0x1F, 0xDB, 0x1F, - 0xDC, 0x1F, 0xDD, 0x1F, 0xDE, 0x1F, 0xDF, 0x1F, - 0xE8, 0x1F, 0xE9, 0x1F, 0xE2, 0x1F, 0xE3, 0x1F, - 0xE4, 0x1F, 0xEC, 0x1F, 0xE6, 0x1F, 0xE7, 0x1F, - 0xE8, 0x1F, 0xE9, 0x1F, 0xEA, 0x1F, 0xEB, 0x1F, - 0xEC, 0x1F, 0xED, 0x1F, 0xEE, 0x1F, 0xEF, 0x1F, - 0xF0, 0x1F, 0xF1, 0x1F, 0xF2, 0x1F, 0xF3, 0x1F, - 0xF4, 0x1F, 0xF5, 0x1F, 0xF6, 0x1F, 0xF7, 0x1F, - 0xF8, 0x1F, 0xF9, 0x1F, 0xFA, 0x1F, 0xFB, 0x1F, - 0xF3, 0x1F, 0xFD, 0x1F, 0xFE, 0x1F, 0xFF, 0x1F, - 0x00, 0x20, 0x01, 0x20, 0x02, 0x20, 0x03, 0x20, - 0x04, 0x20, 0x05, 0x20, 0x06, 0x20, 0x07, 0x20, - 0x08, 0x20, 0x09, 0x20, 0x0A, 0x20, 0x0B, 0x20, - 0x0C, 0x20, 0x0D, 0x20, 0x0E, 0x20, 0x0F, 0x20, - 0x10, 0x20, 0x11, 0x20, 0x12, 0x20, 0x13, 0x20, - 0x14, 0x20, 0x15, 0x20, 0x16, 0x20, 0x17, 0x20, - 0x18, 0x20, 0x19, 0x20, 0x1A, 0x20, 0x1B, 0x20, - 0x1C, 0x20, 0x1D, 0x20, 0x1E, 0x20, 0x1F, 0x20, - 0x20, 0x20, 0x21, 0x20, 0x22, 0x20, 0x23, 0x20, - 0x24, 0x20, 0x25, 0x20, 0x26, 0x20, 0x27, 0x20, - 0x28, 0x20, 0x29, 0x20, 0x2A, 0x20, 0x2B, 0x20, - 0x2C, 0x20, 0x2D, 0x20, 0x2E, 0x20, 0x2F, 0x20, - 0x30, 0x20, 0x31, 0x20, 0x32, 0x20, 0x33, 0x20, - 0x34, 0x20, 0x35, 0x20, 0x36, 0x20, 0x37, 0x20, - 0x38, 0x20, 0x39, 0x20, 0x3A, 0x20, 0x3B, 0x20, - 0x3C, 0x20, 0x3D, 0x20, 0x3E, 0x20, 0x3F, 0x20, - 0x40, 0x20, 0x41, 0x20, 0x42, 0x20, 0x43, 0x20, - 0x44, 0x20, 0x45, 0x20, 0x46, 0x20, 0x47, 0x20, - 0x48, 0x20, 0x49, 0x20, 0x4A, 0x20, 0x4B, 0x20, - 0x4C, 0x20, 0x4D, 0x20, 0x4E, 0x20, 0x4F, 0x20, - 0x50, 0x20, 0x51, 0x20, 0x52, 0x20, 0x53, 0x20, - 0x54, 0x20, 0x55, 0x20, 0x56, 0x20, 0x57, 0x20, - 0x58, 0x20, 0x59, 0x20, 0x5A, 0x20, 0x5B, 0x20, - 0x5C, 0x20, 0x5D, 0x20, 0x5E, 0x20, 0x5F, 0x20, - 0x60, 0x20, 0x61, 0x20, 0x62, 0x20, 0x63, 0x20, - 0x64, 0x20, 0x65, 0x20, 0x66, 0x20, 0x67, 0x20, - 0x68, 0x20, 0x69, 0x20, 0x6A, 0x20, 0x6B, 0x20, - 0x6C, 0x20, 0x6D, 0x20, 0x6E, 0x20, 0x6F, 0x20, - 0x70, 0x20, 0x71, 0x20, 0x72, 0x20, 0x73, 0x20, - 0x74, 0x20, 0x75, 0x20, 0x76, 0x20, 0x77, 0x20, - 0x78, 0x20, 0x79, 0x20, 0x7A, 0x20, 0x7B, 0x20, - 0x7C, 0x20, 0x7D, 0x20, 0x7E, 0x20, 0x7F, 0x20, - 0x80, 0x20, 0x81, 0x20, 0x82, 0x20, 0x83, 0x20, - 0x84, 0x20, 0x85, 0x20, 0x86, 0x20, 0x87, 0x20, - 0x88, 0x20, 0x89, 0x20, 0x8A, 0x20, 0x8B, 0x20, - 0x8C, 0x20, 0x8D, 0x20, 0x8E, 0x20, 0x8F, 0x20, - 0x90, 0x20, 0x91, 0x20, 0x92, 0x20, 0x93, 0x20, - 0x94, 0x20, 0x95, 0x20, 0x96, 0x20, 0x97, 0x20, - 0x98, 0x20, 0x99, 0x20, 0x9A, 0x20, 0x9B, 0x20, - 0x9C, 0x20, 0x9D, 0x20, 0x9E, 0x20, 0x9F, 0x20, - 0xA0, 0x20, 0xA1, 0x20, 0xA2, 0x20, 0xA3, 0x20, - 0xA4, 0x20, 0xA5, 0x20, 0xA6, 0x20, 0xA7, 0x20, - 0xA8, 0x20, 0xA9, 0x20, 0xAA, 0x20, 0xAB, 0x20, - 0xAC, 0x20, 0xAD, 0x20, 0xAE, 0x20, 0xAF, 0x20, - 0xB0, 0x20, 0xB1, 0x20, 0xB2, 0x20, 0xB3, 0x20, - 0xB4, 0x20, 0xB5, 0x20, 0xB6, 0x20, 0xB7, 0x20, - 0xB8, 0x20, 0xB9, 0x20, 0xBA, 0x20, 0xBB, 0x20, - 0xBC, 0x20, 0xBD, 0x20, 0xBE, 0x20, 0xBF, 0x20, - 0xC0, 0x20, 0xC1, 0x20, 0xC2, 0x20, 0xC3, 0x20, - 0xC4, 0x20, 0xC5, 0x20, 0xC6, 0x20, 0xC7, 0x20, - 0xC8, 0x20, 0xC9, 0x20, 0xCA, 0x20, 0xCB, 0x20, - 0xCC, 0x20, 0xCD, 0x20, 0xCE, 0x20, 0xCF, 0x20, - 0xD0, 0x20, 0xD1, 0x20, 0xD2, 0x20, 0xD3, 0x20, - 0xD4, 0x20, 0xD5, 0x20, 0xD6, 0x20, 0xD7, 0x20, - 0xD8, 0x20, 0xD9, 0x20, 0xDA, 0x20, 0xDB, 0x20, - 0xDC, 0x20, 0xDD, 0x20, 0xDE, 0x20, 0xDF, 0x20, - 0xE0, 0x20, 0xE1, 0x20, 0xE2, 0x20, 0xE3, 0x20, - 0xE4, 0x20, 0xE5, 0x20, 0xE6, 0x20, 0xE7, 0x20, - 0xE8, 0x20, 0xE9, 0x20, 0xEA, 0x20, 0xEB, 0x20, - 0xEC, 0x20, 0xED, 0x20, 0xEE, 0x20, 0xEF, 0x20, - 0xF0, 0x20, 0xF1, 0x20, 0xF2, 0x20, 0xF3, 0x20, - 0xF4, 0x20, 0xF5, 0x20, 0xF6, 0x20, 0xF7, 0x20, - 0xF8, 0x20, 0xF9, 0x20, 0xFA, 0x20, 0xFB, 0x20, - 0xFC, 0x20, 0xFD, 0x20, 0xFE, 0x20, 0xFF, 0x20, - 0x00, 0x21, 0x01, 0x21, 0x02, 0x21, 0x03, 0x21, - 0x04, 0x21, 0x05, 0x21, 0x06, 0x21, 0x07, 0x21, - 0x08, 0x21, 0x09, 0x21, 0x0A, 0x21, 0x0B, 0x21, - 0x0C, 0x21, 0x0D, 0x21, 0x0E, 0x21, 0x0F, 0x21, - 0x10, 0x21, 0x11, 0x21, 0x12, 0x21, 0x13, 0x21, - 0x14, 0x21, 0x15, 0x21, 0x16, 0x21, 0x17, 0x21, - 0x18, 0x21, 0x19, 0x21, 0x1A, 0x21, 0x1B, 0x21, - 0x1C, 0x21, 0x1D, 0x21, 0x1E, 0x21, 0x1F, 0x21, - 0x20, 0x21, 0x21, 0x21, 0x22, 0x21, 0x23, 0x21, - 0x24, 0x21, 0x25, 0x21, 0x26, 0x21, 0x27, 0x21, - 0x28, 0x21, 0x29, 0x21, 0x2A, 0x21, 0x2B, 0x21, - 0x2C, 0x21, 0x2D, 0x21, 0x2E, 0x21, 0x2F, 0x21, - 0x30, 0x21, 0x31, 0x21, 0x32, 0x21, 0x33, 0x21, - 0x34, 0x21, 0x35, 0x21, 0x36, 0x21, 0x37, 0x21, - 0x38, 0x21, 0x39, 0x21, 0x3A, 0x21, 0x3B, 0x21, - 0x3C, 0x21, 0x3D, 0x21, 0x3E, 0x21, 0x3F, 0x21, - 0x40, 0x21, 0x41, 0x21, 0x42, 0x21, 0x43, 0x21, - 0x44, 0x21, 0x45, 0x21, 0x46, 0x21, 0x47, 0x21, - 0x48, 0x21, 0x49, 0x21, 0x4A, 0x21, 0x4B, 0x21, - 0x4C, 0x21, 0x4D, 0x21, 0x32, 0x21, 0x4F, 0x21, - 0x50, 0x21, 0x51, 0x21, 0x52, 0x21, 0x53, 0x21, - 0x54, 0x21, 0x55, 0x21, 0x56, 0x21, 0x57, 0x21, - 0x58, 0x21, 0x59, 0x21, 0x5A, 0x21, 0x5B, 0x21, - 0x5C, 0x21, 0x5D, 0x21, 0x5E, 0x21, 0x5F, 0x21, - 0x60, 0x21, 0x61, 0x21, 0x62, 0x21, 0x63, 0x21, - 0x64, 0x21, 0x65, 0x21, 0x66, 0x21, 0x67, 0x21, - 0x68, 0x21, 0x69, 0x21, 0x6A, 0x21, 0x6B, 0x21, - 0x6C, 0x21, 0x6D, 0x21, 0x6E, 0x21, 0x6F, 0x21, - 0x60, 0x21, 0x61, 0x21, 0x62, 0x21, 0x63, 0x21, - 0x64, 0x21, 0x65, 0x21, 0x66, 0x21, 0x67, 0x21, - 0x68, 0x21, 0x69, 0x21, 0x6A, 0x21, 0x6B, 0x21, - 0x6C, 0x21, 0x6D, 0x21, 0x6E, 0x21, 0x6F, 0x21, - 0x80, 0x21, 0x81, 0x21, 0x82, 0x21, 0x83, 0x21, - 0x83, 0x21, 0xFF, 0xFF, 0x4B, 0x03, 0xB6, 0x24, - 0xB7, 0x24, 0xB8, 0x24, 0xB9, 0x24, 0xBA, 0x24, - 0xBB, 0x24, 0xBC, 0x24, 0xBD, 0x24, 0xBE, 0x24, - 0xBF, 0x24, 0xC0, 0x24, 0xC1, 0x24, 0xC2, 0x24, - 0xC3, 0x24, 0xC4, 0x24, 0xC5, 0x24, 0xC6, 0x24, - 0xC7, 0x24, 0xC8, 0x24, 0xC9, 0x24, 0xCA, 0x24, - 0xCB, 0x24, 0xCC, 0x24, 0xCD, 0x24, 0xCE, 0x24, - 0xCF, 0x24, 0xFF, 0xFF, 0x46, 0x07, 0x00, 0x2C, - 0x01, 0x2C, 0x02, 0x2C, 0x03, 0x2C, 0x04, 0x2C, - 0x05, 0x2C, 0x06, 0x2C, 0x07, 0x2C, 0x08, 0x2C, - 0x09, 0x2C, 0x0A, 0x2C, 0x0B, 0x2C, 0x0C, 0x2C, - 0x0D, 0x2C, 0x0E, 0x2C, 0x0F, 0x2C, 0x10, 0x2C, - 0x11, 0x2C, 0x12, 0x2C, 0x13, 0x2C, 0x14, 0x2C, - 0x15, 0x2C, 0x16, 0x2C, 0x17, 0x2C, 0x18, 0x2C, - 0x19, 0x2C, 0x1A, 0x2C, 0x1B, 0x2C, 0x1C, 0x2C, - 0x1D, 0x2C, 0x1E, 0x2C, 0x1F, 0x2C, 0x20, 0x2C, - 0x21, 0x2C, 0x22, 0x2C, 0x23, 0x2C, 0x24, 0x2C, - 0x25, 0x2C, 0x26, 0x2C, 0x27, 0x2C, 0x28, 0x2C, - 0x29, 0x2C, 0x2A, 0x2C, 0x2B, 0x2C, 0x2C, 0x2C, - 0x2D, 0x2C, 0x2E, 0x2C, 0x5F, 0x2C, 0x60, 0x2C, - 0x60, 0x2C, 0x62, 0x2C, 0x63, 0x2C, 0x64, 0x2C, - 0x65, 0x2C, 0x66, 0x2C, 0x67, 0x2C, 0x67, 0x2C, - 0x69, 0x2C, 0x69, 0x2C, 0x6B, 0x2C, 0x6B, 0x2C, - 0x6D, 0x2C, 0x6E, 0x2C, 0x6F, 0x2C, 0x70, 0x2C, - 0x71, 0x2C, 0x72, 0x2C, 0x73, 0x2C, 0x74, 0x2C, - 0x75, 0x2C, 0x75, 0x2C, 0x77, 0x2C, 0x78, 0x2C, - 0x79, 0x2C, 0x7A, 0x2C, 0x7B, 0x2C, 0x7C, 0x2C, - 0x7D, 0x2C, 0x7E, 0x2C, 0x7F, 0x2C, 0x80, 0x2C, - 0x80, 0x2C, 0x82, 0x2C, 0x82, 0x2C, 0x84, 0x2C, - 0x84, 0x2C, 0x86, 0x2C, 0x86, 0x2C, 0x88, 0x2C, - 0x88, 0x2C, 0x8A, 0x2C, 0x8A, 0x2C, 0x8C, 0x2C, - 0x8C, 0x2C, 0x8E, 0x2C, 0x8E, 0x2C, 0x90, 0x2C, - 0x90, 0x2C, 0x92, 0x2C, 0x92, 0x2C, 0x94, 0x2C, - 0x94, 0x2C, 0x96, 0x2C, 0x96, 0x2C, 0x98, 0x2C, - 0x98, 0x2C, 0x9A, 0x2C, 0x9A, 0x2C, 0x9C, 0x2C, - 0x9C, 0x2C, 0x9E, 0x2C, 0x9E, 0x2C, 0xA0, 0x2C, - 0xA0, 0x2C, 0xA2, 0x2C, 0xA2, 0x2C, 0xA4, 0x2C, - 0xA4, 0x2C, 0xA6, 0x2C, 0xA6, 0x2C, 0xA8, 0x2C, - 0xA8, 0x2C, 0xAA, 0x2C, 0xAA, 0x2C, 0xAC, 0x2C, - 0xAC, 0x2C, 0xAE, 0x2C, 0xAE, 0x2C, 0xB0, 0x2C, - 0xB0, 0x2C, 0xB2, 0x2C, 0xB2, 0x2C, 0xB4, 0x2C, - 0xB4, 0x2C, 0xB6, 0x2C, 0xB6, 0x2C, 0xB8, 0x2C, - 0xB8, 0x2C, 0xBA, 0x2C, 0xBA, 0x2C, 0xBC, 0x2C, - 0xBC, 0x2C, 0xBE, 0x2C, 0xBE, 0x2C, 0xC0, 0x2C, - 0xC0, 0x2C, 0xC2, 0x2C, 0xC2, 0x2C, 0xC4, 0x2C, - 0xC4, 0x2C, 0xC6, 0x2C, 0xC6, 0x2C, 0xC8, 0x2C, - 0xC8, 0x2C, 0xCA, 0x2C, 0xCA, 0x2C, 0xCC, 0x2C, - 0xCC, 0x2C, 0xCE, 0x2C, 0xCE, 0x2C, 0xD0, 0x2C, - 0xD0, 0x2C, 0xD2, 0x2C, 0xD2, 0x2C, 0xD4, 0x2C, - 0xD4, 0x2C, 0xD6, 0x2C, 0xD6, 0x2C, 0xD8, 0x2C, - 0xD8, 0x2C, 0xDA, 0x2C, 0xDA, 0x2C, 0xDC, 0x2C, - 0xDC, 0x2C, 0xDE, 0x2C, 0xDE, 0x2C, 0xE0, 0x2C, - 0xE0, 0x2C, 0xE2, 0x2C, 0xE2, 0x2C, 0xE4, 0x2C, - 0xE5, 0x2C, 0xE6, 0x2C, 0xE7, 0x2C, 0xE8, 0x2C, - 0xE9, 0x2C, 0xEA, 0x2C, 0xEB, 0x2C, 0xEC, 0x2C, - 0xED, 0x2C, 0xEE, 0x2C, 0xEF, 0x2C, 0xF0, 0x2C, - 0xF1, 0x2C, 0xF2, 0x2C, 0xF3, 0x2C, 0xF4, 0x2C, - 0xF5, 0x2C, 0xF6, 0x2C, 0xF7, 0x2C, 0xF8, 0x2C, - 0xF9, 0x2C, 0xFA, 0x2C, 0xFB, 0x2C, 0xFC, 0x2C, - 0xFD, 0x2C, 0xFE, 0x2C, 0xFF, 0x2C, 0xA0, 0x10, - 0xA1, 0x10, 0xA2, 0x10, 0xA3, 0x10, 0xA4, 0x10, - 0xA5, 0x10, 0xA6, 0x10, 0xA7, 0x10, 0xA8, 0x10, - 0xA9, 0x10, 0xAA, 0x10, 0xAB, 0x10, 0xAC, 0x10, - 0xAD, 0x10, 0xAE, 0x10, 0xAF, 0x10, 0xB0, 0x10, - 0xB1, 0x10, 0xB2, 0x10, 0xB3, 0x10, 0xB4, 0x10, - 0xB5, 0x10, 0xB6, 0x10, 0xB7, 0x10, 0xB8, 0x10, - 0xB9, 0x10, 0xBA, 0x10, 0xBB, 0x10, 0xBC, 0x10, - 0xBD, 0x10, 0xBE, 0x10, 0xBF, 0x10, 0xC0, 0x10, - 0xC1, 0x10, 0xC2, 0x10, 0xC3, 0x10, 0xC4, 0x10, - 0xC5, 0x10, 0xFF, 0xFF, 0x1B, 0xD2, 0x21, 0xFF, - 0x22, 0xFF, 0x23, 0xFF, 0x24, 0xFF, 0x25, 0xFF, - 0x26, 0xFF, 0x27, 0xFF, 0x28, 0xFF, 0x29, 0xFF, - 0x2A, 0xFF, 0x2B, 0xFF, 0x2C, 0xFF, 0x2D, 0xFF, - 0x2E, 0xFF, 0x2F, 0xFF, 0x30, 0xFF, 0x31, 0xFF, - 0x32, 0xFF, 0x33, 0xFF, 0x34, 0xFF, 0x35, 0xFF, - 0x36, 0xFF, 0x37, 0xFF, 0x38, 0xFF, 0x39, 0xFF, - 0x3A, 0xFF, 0x5B, 0xFF, 0x5C, 0xFF, 0x5D, 0xFF, - 0x5E, 0xFF, 0x5F, 0xFF, 0x60, 0xFF, 0x61, 0xFF, - 0x62, 0xFF, 0x63, 0xFF, 0x64, 0xFF, 0x65, 0xFF, - 0x66, 0xFF, 0x67, 0xFF, 0x68, 0xFF, 0x69, 0xFF, - 0x6A, 0xFF, 0x6B, 0xFF, 0x6C, 0xFF, 0x6D, 0xFF, - 0x6E, 0xFF, 0x6F, 0xFF, 0x70, 0xFF, 0x71, 0xFF, - 0x72, 0xFF, 0x73, 0xFF, 0x74, 0xFF, 0x75, 0xFF, - 0x76, 0xFF, 0x77, 0xFF, 0x78, 0xFF, 0x79, 0xFF, - 0x7A, 0xFF, 0x7B, 0xFF, 0x7C, 0xFF, 0x7D, 0xFF, - 0x7E, 0xFF, 0x7F, 0xFF, 0x80, 0xFF, 0x81, 0xFF, - 0x82, 0xFF, 0x83, 0xFF, 0x84, 0xFF, 0x85, 0xFF, - 0x86, 0xFF, 0x87, 0xFF, 0x88, 0xFF, 0x89, 0xFF, - 0x8A, 0xFF, 0x8B, 0xFF, 0x8C, 0xFF, 0x8D, 0xFF, - 0x8E, 0xFF, 0x8F, 0xFF, 0x90, 0xFF, 0x91, 0xFF, - 0x92, 0xFF, 0x93, 0xFF, 0x94, 0xFF, 0x95, 0xFF, - 0x96, 0xFF, 0x97, 0xFF, 0x98, 0xFF, 0x99, 0xFF, - 0x9A, 0xFF, 0x9B, 0xFF, 0x9C, 0xFF, 0x9D, 0xFF, - 0x9E, 0xFF, 0x9F, 0xFF, 0xA0, 0xFF, 0xA1, 0xFF, - 0xA2, 0xFF, 0xA3, 0xFF, 0xA4, 0xFF, 0xA5, 0xFF, - 0xA6, 0xFF, 0xA7, 0xFF, 0xA8, 0xFF, 0xA9, 0xFF, - 0xAA, 0xFF, 0xAB, 0xFF, 0xAC, 0xFF, 0xAD, 0xFF, - 0xAE, 0xFF, 0xAF, 0xFF, 0xB0, 0xFF, 0xB1, 0xFF, - 0xB2, 0xFF, 0xB3, 0xFF, 0xB4, 0xFF, 0xB5, 0xFF, - 0xB6, 0xFF, 0xB7, 0xFF, 0xB8, 0xFF, 0xB9, 0xFF, - 0xBA, 0xFF, 0xBB, 0xFF, 0xBC, 0xFF, 0xBD, 0xFF, - 0xBE, 0xFF, 0xBF, 0xFF, 0xC0, 0xFF, 0xC1, 0xFF, - 0xC2, 0xFF, 0xC3, 0xFF, 0xC4, 0xFF, 0xC5, 0xFF, - 0xC6, 0xFF, 0xC7, 0xFF, 0xC8, 0xFF, 0xC9, 0xFF, - 0xCA, 0xFF, 0xCB, 0xFF, 0xCC, 0xFF, 0xCD, 0xFF, - 0xCE, 0xFF, 0xCF, 0xFF, 0xD0, 0xFF, 0xD1, 0xFF, - 0xD2, 0xFF, 0xD3, 0xFF, 0xD4, 0xFF, 0xD5, 0xFF, - 0xD6, 0xFF, 0xD7, 0xFF, 0xD8, 0xFF, 0xD9, 0xFF, - 0xDA, 0xFF, 0xDB, 0xFF, 0xDC, 0xFF, 0xDD, 0xFF, - 0xDE, 0xFF, 0xDF, 0xFF, 0xE0, 0xFF, 0xE1, 0xFF, - 0xE2, 0xFF, 0xE3, 0xFF, 0xE4, 0xFF, 0xE5, 0xFF, - 0xE6, 0xFF, 0xE7, 0xFF, 0xE8, 0xFF, 0xE9, 0xFF, - 0xEA, 0xFF, 0xEB, 0xFF, 0xEC, 0xFF, 0xED, 0xFF, - 0xEE, 0xFF, 0xEF, 0xFF, 0xF0, 0xFF, 0xF1, 0xFF, - 0xF2, 0xFF, 0xF3, 0xFF, 0xF4, 0xFF, 0xF5, 0xFF, - 0xF6, 0xFF, 0xF7, 0xFF, 0xF8, 0xFF, 0xF9, 0xFF, - 0xFA, 0xFF, 0xFB, 0xFF, 0xFC, 0xFF, 0xFD, 0xFF, - 0xFE, 0xFF, 0xFF, 0xFF -}; diff --git a/drivers/staging/fsl-mc/bus/fsl-mc-allocator.c b/drivers/staging/fsl-mc/bus/fsl-mc-allocator.c index 8ea3920400a0..db39daef4cbe 100644 --- a/drivers/staging/fsl-mc/bus/fsl-mc-allocator.c +++ b/drivers/staging/fsl-mc/bus/fsl-mc-allocator.c @@ -357,8 +357,8 @@ int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus, if (error < 0) return error; - irq_resources = devm_kzalloc(&mc_bus_dev->dev, - sizeof(*irq_resources) * irq_count, + irq_resources = devm_kcalloc(&mc_bus_dev->dev, + irq_count, sizeof(*irq_resources), GFP_KERNEL); if (!irq_resources) { error = -ENOMEM; @@ -458,7 +458,7 @@ int __must_check fsl_mc_allocate_irqs(struct fsl_mc_device *mc_dev) return -ENOSPC; } - irqs = devm_kzalloc(&mc_dev->dev, irq_count * sizeof(irqs[0]), + irqs = devm_kcalloc(&mc_dev->dev, irq_count, sizeof(irqs[0]), GFP_KERNEL); if (!irqs) return -ENOMEM; diff --git a/drivers/staging/fw-api/fw/htt_ppdu_stats.h b/drivers/staging/fw-api/fw/htt_ppdu_stats.h index 1f70b5a8f42d..a9f25643a649 100644 --- a/drivers/staging/fw-api/fw/htt_ppdu_stats.h +++ b/drivers/staging/fw-api/fw/htt_ppdu_stats.h @@ -719,9 +719,11 @@ typedef struct { * BIT [15: 8] - RSSI of the aborted OBSS frame (in dB w.r.t. noise floor) * by which SRG/Non-SRG based spatial reuse opportunity * was created. - * BIT [31:16] - reserved + * BIT [16:16] - PPDU transmitted using PSR opportunity + * BIT [31:17] - reserved */ union { + A_UINT32 reserved__psr_tx__aborted_obss_rssi__srg_tx__non_srg_tx___bss_color_id; A_UINT32 reserved__aborted_obss_rssi__srg_tx__non_srg_tx___bss_color_id; A_UINT32 reserved__bss_color_id; struct { @@ -729,7 +731,8 @@ typedef struct { non_srg_tx: 1, srg_tx: 1, aborted_obss_rssi: 8, - reserved2: 16; + psr_tx: 1, + reserved2: 15; }; }; } htt_ppdu_stats_common_tlv; diff --git a/drivers/staging/fw-api/fw/htt_stats.h b/drivers/staging/fw-api/fw/htt_stats.h index d0cb8ccc836a..68945063ec52 100644 --- a/drivers/staging/fw-api/fw/htt_stats.h +++ b/drivers/staging/fw-api/fw/htt_stats.h @@ -367,6 +367,14 @@ enum htt_dbg_ext_stats_type { */ HTT_DBG_EXT_VDEV_RTT_RESP_STATS = 34, + /* HTT_DBG_EXT_PKTLOG_AND_HTT_RING_STATS + * PARAMS: + * - No Params + * RESP MSG: + * - htt_pktlog_and_htt_ring_stats_t + */ + HTT_DBG_EXT_PKTLOG_AND_HTT_RING_STATS = 35, + /* keep this last */ HTT_DBG_NUM_EXT_STATS = 256, @@ -511,6 +519,7 @@ typedef enum { HTT_STATS_TXBF_OFDMA_STEER_STATS_TAG = 116, /* htt_txbf_ofdma_steer_stats_tlv */ HTT_STATS_STA_UL_OFDMA_STATS_TAG = 117, /* htt_sta_ul_ofdma_stats_tlv */ HTT_STATS_VDEV_RTT_RESP_STATS_TAG = 118, /* htt_vdev_rtt_resp_stats_tlv */ + HTT_STATS_PKTLOG_AND_HTT_RING_STATS_TAG = 119, /* htt_pktlog_and_htt_ring_stats_tlv */ HTT_STATS_MAX_TAG, } htt_tlv_tag_t; @@ -5113,5 +5122,28 @@ typedef struct { htt_vdev_rtt_resp_stats_tlv vdev_rtt_resp_stats; } htt_vdev_rtt_resp_stats_t; +/* STATS_TYPE : HTT_DBG_EXT_PKTLOG_AND_HTT_RING_STATS + * TLV_TAGS: + * - HTT_STATS_PKTLOG_AND_HTT_RING_STATS_TAG + */ +/* NOTE: + * This structure is for documentation, and cannot be safely used directly. + * Instead, use the constituent TLV structures to fill/parse. + */ +typedef struct { + htt_tlv_hdr_t tlv_hdr; + + /* No of pktlog payloads that were dropped in htt_ppdu_stats path */ + A_UINT32 pktlog_lite_drop_cnt; + /* No of pktlog payloads that were dropped in TQM path */ + A_UINT32 pktlog_tqm_drop_cnt; + /* No of pktlog ppdu stats payloads that were dropped */ + A_UINT32 pktlog_ppdu_stats_drop_cnt; + /* No of pktlog ppdu ctrl payloads that were dropped */ + A_UINT32 pktlog_ppdu_ctrl_drop_cnt; + /* No of pktlog sw events payloads that were dropped */ + A_UINT32 pktlog_sw_events_drop_cnt; +} htt_pktlog_and_htt_ring_stats_tlv; + #endif /* __HTT_STATS_H__ */ diff --git a/drivers/staging/fw-api/fw/wlan_module_ids.h b/drivers/staging/fw-api/fw/wlan_module_ids.h index 13f5b1d9a38f..4e701bc241e9 100644 --- a/drivers/staging/fw-api/fw/wlan_module_ids.h +++ b/drivers/staging/fw-api/fw/wlan_module_ids.h @@ -116,6 +116,7 @@ typedef enum { WLAN_MODULE_QUIET_IE, /* 0x52 */ WLAN_MODULE_SHMEM_MGR, /* 0x53 */ WLAN_MODULE_CFIR, /* 0x54 */ /* Channel Capture */ + WLAN_MODULE_CODE_COVER, /* 0x55 */ /* code coverage */ WLAN_MODULE_ID_MAX, WLAN_MODULE_ID_INVALID = WLAN_MODULE_ID_MAX, diff --git a/drivers/staging/fw-api/fw/wmi_services.h b/drivers/staging/fw-api/fw/wmi_services.h index 6d9e867d5aa1..9b6d51c7f688 100644 --- a/drivers/staging/fw-api/fw/wmi_services.h +++ b/drivers/staging/fw-api/fw/wmi_services.h @@ -445,6 +445,9 @@ typedef enum { WMI_REQUEST_CTRL_PATH_STATS_REQUEST = 250, /* FW supports control path stats */ WMI_SERVICE_TPC_STATS_EVENT = 251, /* FW support to dump the TPC tables */ WMI_SERVICE_NO_INTERBAND_MCC_SUPPORT = 252, /* Indicates FW doesn't support interband MCC */ + WMI_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT = 253, /* FW supports VDEV's MBSS param exchange in VDEV start command */ + WMI_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT = 254, /* FW supports ROAM trigger configuration param TLV */ + WMI_SERVICE_CFR_TA_RA_AS_FP_SUPPORT = 255, /* indicates FW support to program CFR TA/RA filtered packets as Filter pass */ /******* ADD NEW SERVICES UP TO 256 HERE *******/ @@ -470,6 +473,9 @@ typedef enum { /******* ADD NEW SERVICES 256 AND BEYOND HERE *******/ + WMI_SERVICE_CFR_CAPTURE_COUNT_SUPPORT = 256, /* indicates FW support to program CFR capture mode and capture count */ + WMI_SERVICE_OCV_SUPPORT = 257, /* FW supports OCV (Operating Channel Validation) */ + WMI_MAX_EXT2_SERVICE diff --git a/drivers/staging/fw-api/fw/wmi_tlv_defs.h b/drivers/staging/fw-api/fw/wmi_tlv_defs.h index e85d2481edc9..1a8ea2273fa0 100644 --- a/drivers/staging/fw-api/fw/wmi_tlv_defs.h +++ b/drivers/staging/fw-api/fw/wmi_tlv_defs.h @@ -1095,6 +1095,11 @@ typedef enum { WMITLV_TAG_STRUC_wmi_vdev_disconnect_event_fixed_param, WMITLV_TAG_STRUC_wmi_roam_btm_response_info_tlv_param, WMITLV_TAG_STRUC_wmi_roam_initial_info_tlv_param, + WMITLV_TAG_STRUC_wmi_pdev_twt_session_stats_event_fixed_param, + WMITLV_TAG_STRUC_wmi_twt_session_stats_info, + WMITLV_TAG_STRUC_wmi_configure_roam_trigger_parameters, + WMITLV_TAG_STRUC_wmi_vdev_extd_stats, + WMITLV_TAG_STRUC_wmi_twt_add_dialog_additional_params, } WMITLV_TAG_ID; /* @@ -1798,6 +1803,7 @@ typedef enum { OP(WMI_VDEV_BCN_LATENCY_EVENTID) \ OP(WMI_AUDIO_AGGR_SCHED_METHOD_EVENTID) \ OP(WMI_VDEV_DISCONNECT_EVENTID) \ + OP(WMI_TWT_SESSION_STATS_EVENTID) \ /* add new EVT_LIST elements above this line */ @@ -3284,7 +3290,8 @@ WMITLV_CREATE_PARAM_STRUC(WMI_IDLE_TRIGGER_MONITOR_CMDID); /* Enable or disable roaming trigger reason */ #define WMITLV_TABLE_WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID(id,op,buf,len) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_roam_enable_disable_trigger_reason_fixed_param, wmi_roam_enable_disable_trigger_reason_fixed_param, fixed_param, WMITLV_SIZE_FIX) + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_roam_enable_disable_trigger_reason_fixed_param, wmi_roam_enable_disable_trigger_reason_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_configure_roam_trigger_parameters, config_roam_trigger_param, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID); /* DSM filter parameters */ @@ -4974,7 +4981,8 @@ WMITLV_CREATE_PARAM_STRUC(WMI_HOST_SWFDA_EVENTID); WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_rssi_stats, rssi_stats, WMITLV_SIZE_VAR) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_congestion_stats, congestion_stats, WMITLV_SIZE_VAR) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_peer_extd2_stats, peer_extd2_stats, WMITLV_SIZE_VAR) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_pmf_bcn_protect_stats, pmf_bcn_protect_stats, WMITLV_SIZE_VAR) + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_pmf_bcn_protect_stats, pmf_bcn_protect_stats, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_vdev_extd_stats, vdev_extd_stats, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_UPDATE_STATS_EVENTID); /* Update PN response Event */ @@ -5782,7 +5790,8 @@ WMITLV_CREATE_PARAM_STRUC(WMI_PEER_STATS_INFO_EVENTID); /* Update Control Path stats event */ #define WMITLV_TABLE_WMI_CTRL_PATH_STATS_EVENTID(id, op, buf, len) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_ctrl_path_stats_event_fixed_param, wmi_ctrl_path_stats_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_ctrl_path_pdev_stats_struct, ctrl_path_pdev_stats, WMITLV_SIZE_VAR) + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_ctrl_path_pdev_stats_struct, ctrl_path_pdev_stats, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_vdev_extd_stats, vdev_extd_stats, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_CTRL_PATH_STATS_EVENTID); #define WMITLV_TABLE_WMI_RADIO_CHAN_STATS_EVENTID(id, op, buf, len) \ @@ -5866,7 +5875,8 @@ WMITLV_CREATE_PARAM_STRUC(WMI_TWT_DISABLE_COMPLETE_EVENTID); /* adding TWT dialog complete Event */ #define WMITLV_TABLE_WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID(id,op,buf,len) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_twt_add_dialog_complete_event_fixed_param, wmi_twt_add_dialog_complete_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_twt_add_dialog_complete_event_fixed_param, wmi_twt_add_dialog_complete_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_twt_add_dialog_additional_params, twt_params, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID); /* deleting TWT dialog complete Event */ @@ -6025,6 +6035,13 @@ WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_GET_TPC_STATS_EVENTID); WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_bcn_latency_fixed_param, wmi_vdev_bcn_latency_fixed_param, fixed_param, WMITLV_SIZE_FIX) WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_BCN_LATENCY_EVENTID); +/* TWT Stats session event */ +#define WMITLV_TABLE_WMI_TWT_SESSION_STATS_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_twt_session_stats_event_fixed_param, wmi_pdev_twt_session_stats_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_twt_session_stats_info, twt_sessions, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_TWT_SESSION_STATS_EVENTID); + + #ifdef __cplusplus } #endif diff --git a/drivers/staging/fw-api/fw/wmi_unified.h b/drivers/staging/fw-api/fw/wmi_unified.h index f16457b42283..d7f1ec7b3946 100644 --- a/drivers/staging/fw-api/fw/wmi_unified.h +++ b/drivers/staging/fw-api/fw/wmi_unified.h @@ -1991,6 +1991,7 @@ typedef enum { WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID, WMI_TWT_BTWT_INVITE_STA_COMPLETE_EVENTID, WMI_TWT_BTWT_REMOVE_STA_COMPLETE_EVENTID, + WMI_TWT_SESSION_STATS_EVENTID, /** Events in Prototyping phase */ WMI_NDI_CAP_RSP_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_PROTOTYPE), @@ -3695,6 +3696,13 @@ typedef struct { * specified by the host's ini configuration. */ A_UINT32 max_ndi_interfaces; + + /** @brief max_ap_vaps + * Maximum number of AP mode vdevs created at any time. + * This value is minimum of the number of AP vdevs supported by + * the target and host. + */ + A_UINT32 max_ap_vaps; } wmi_resource_config; #define WMI_MSDU_FLOW_AST_ENABLE_GET(msdu_flow_config0, ast_x) \ @@ -4343,6 +4351,9 @@ typedef enum { /* Force broadcast address in RA even though specified bssid */ #define WMI_SCAN_FLAG_EXT_FORCE_BRCAST_RA 0x00000200 +/* Extend 6ghz channel measure time */ +#define WMI_SCAN_FLAG_EXT_6GHZ_EXTEND_MEASURE_TIME 0x00000400 + /** * new 6 GHz flags per chan (short ssid or bssid) in struct * wmi_hint_freq_short_ssid or wmi_hint_freq_bssid @@ -6843,6 +6854,13 @@ typedef enum { */ WMI_PDEV_PARAM_SET_PREAM_PUNCT_BW, + /* + * Parameter used to set the Margin dB value to be included for calculating + * the spatial reuse value in common info field of the UL Trigger frame. + * Accepted value as per Spec are 0 to 5 dB (inclusive). + */ + WMI_PDEV_PARAM_SR_TRIGGER_MARGIN, + } WMI_PDEV_PARAM; #define WMI_PDEV_ONLY_BSR_TRIG_IS_ENABLED(trig_type) WMI_GET_BITS(trig_type, 0, 1) @@ -7759,22 +7777,23 @@ typedef struct { } wmi_pdev_set_wmm_params_cmd_fixed_param; typedef enum { - WMI_REQUEST_PEER_STAT = 0x0001, - WMI_REQUEST_AP_STAT = 0x0002, - WMI_REQUEST_PDEV_STAT = 0x0004, - WMI_REQUEST_VDEV_STAT = 0x0008, - WMI_REQUEST_BCNFLT_STAT = 0x0010, - WMI_REQUEST_VDEV_RATE_STAT = 0x0020, - WMI_REQUEST_INST_STAT = 0x0040, - WMI_REQUEST_MIB_STAT = 0x0080, - WMI_REQUEST_RSSI_PER_CHAIN_STAT = 0x0100, - WMI_REQUEST_CONGESTION_STAT = 0x0200, - WMI_REQUEST_PEER_EXTD_STAT = 0x0400, - WMI_REQUEST_BCN_STAT = 0x0800, - WMI_REQUEST_BCN_STAT_RESET = 0x1000, - WMI_REQUEST_PEER_EXTD2_STAT = 0x2000, - WMI_REQUEST_MIB_EXTD_STAT = 0x4000, - WMI_REQUEST_PMF_BCN_PROTECT_STAT = 0x8000, + WMI_REQUEST_PEER_STAT = 0x00001, + WMI_REQUEST_AP_STAT = 0x00002, + WMI_REQUEST_PDEV_STAT = 0x00004, + WMI_REQUEST_VDEV_STAT = 0x00008, + WMI_REQUEST_BCNFLT_STAT = 0x00010, + WMI_REQUEST_VDEV_RATE_STAT = 0x00020, + WMI_REQUEST_INST_STAT = 0x00040, + WMI_REQUEST_MIB_STAT = 0x00080, + WMI_REQUEST_RSSI_PER_CHAIN_STAT = 0x00100, + WMI_REQUEST_CONGESTION_STAT = 0x00200, + WMI_REQUEST_PEER_EXTD_STAT = 0x00400, + WMI_REQUEST_BCN_STAT = 0x00800, + WMI_REQUEST_BCN_STAT_RESET = 0x01000, + WMI_REQUEST_PEER_EXTD2_STAT = 0x02000, + WMI_REQUEST_MIB_EXTD_STAT = 0x04000, + WMI_REQUEST_PMF_BCN_PROTECT_STAT = 0x08000, + WMI_REQUEST_VDEV_EXTD_STAT = 0x10000, } wmi_stats_id; /* @@ -8499,6 +8518,10 @@ typedef struct { * wmi_pmf_bcn_protect_stats pmf_bcn_protect_stats[] * follows the other TLVs */ +/* If WMI_REQUEST_VDEV_EXTD_STAT is set in stats_id, then TLV + * wmi_vdev_extd_stats wmi_vdev_extd_stats[] + * follows the other TLVs + */ } wmi_stats_event_fixed_param; /* WLAN channel CCA stats bitmap */ @@ -9123,6 +9146,8 @@ typedef struct { * different types of stats: * 1. wmi_ctrl_path_pdev_stats_struct ctrl_path_pdev_stats[]; * This TLV array contains zero or more pdev stats instances. + * 2. wmi_vdev_extd_stats vdev_extd_stats[]; + * This TLV array contains zero or more vdev_extd_stats instances. */ } wmi_ctrl_path_stats_event_fixed_param; @@ -9272,6 +9297,23 @@ typedef struct { A_UINT32 tx_bcn_outage_cnt; /* Total number of failed beacons */ } wmi_bcn_stats; +/** + * vdev extension statistics + */ +typedef struct { + A_UINT32 tlv_header; + /* vdev id */ + A_UINT32 vdev_id; + /* Total number of Fils Discovery frames transmitted successfully */ + A_UINT32 fd_succ_cnt; + /* Total number of Fils Discovery frames failed */ + A_UINT32 fd_fail_cnt; + /* Total number of unsolicited probe response frames transmitted successfully */ + A_UINT32 unsolicited_prb_succ_cnt; + /* Total number of unsolicited probe response frames failed */ + A_UINT32 unsolicited_prb_fail_cnt; +} wmi_vdev_extd_stats; + /** * peer statistics. */ @@ -9485,9 +9527,13 @@ typedef struct { * See macros starting with WMI_PDEV_ID_ for values. */ A_UINT32 pdev_id; - /** control flags for this vdev */ + /** control flags for this vdev (DEPRECATED) + * Use @mbss_capability_flags in vdev start instead. + */ A_UINT32 flags; - /** vdevid of transmitted AP (mbssid case) */ + /** vdevid of transmitted AP (mbssid case) (DEPRECATED) + * Use @vdevid_trans in vdev start instead. + */ A_UINT32 vdevid_trans; /* This TLV is followed by another TLV of array of structures * wmi_vdev_txrx_streams cfg_txrx_streams[]; @@ -10248,6 +10294,19 @@ typedef struct { A_UINT32 regdomain; /* min data rate to be used in BSS in Mbps */ A_UINT32 min_data_rate; + + /** @mbss_capability_flags: Bitmap of vdev's MBSS/EMA capability. + * Capabilities are combination of below flags: + * VDEV_FLAGS_NON_MBSSID_AP + * VDEV_FLAGS_TRANSMIT_AP + * VDEV_FLAGS_NON_TRANSMIT_AP + * VDEV_FLAGS_EMA_MODE + */ + A_UINT32 mbss_capability_flags; + + /** vdevid of transmitting VAP (mbssid case). Ignored for non mbssid case */ + A_UINT32 vdevid_trans; + /* The TLVs follows this structure: * wmi_channel chan; <-- WMI channel * wmi_p2p_noa_descriptor noa_descriptors[]; <-- actual p2p NOA descriptor from scan entry @@ -10434,6 +10493,11 @@ typedef enum { */ #define WMI_VDEV_ROAM_11KV_CTRL_DONOT_SEND_DISASSOC_ON_BTM_DI_SET 0x4 + +/** NAN vdev config Feature flags */ +#define WMI_VDEV_NAN_ALLOW_DW_CONFIG_CHANGE_IN_SYNC_ROLE 0x1 + + /** the definition of different VDEV parameters */ typedef enum { /** RTS Threshold */ @@ -11281,6 +11345,12 @@ typedef enum { */ WMI_VDEV_PARAM_ROAM_11KV_CTRL, /* 0xA2 */ + /* vdev param to enable or disable various NAN config features + * param value bitmap set to 1 for enable and 0 for disable respectively + */ + WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES, /* 0xA3 */ + + /*=== ADD NEW VDEV PARAM TYPES ABOVE THIS LINE === * The below vdev param types are used for prototyping, and are * prone to change. @@ -13164,6 +13234,22 @@ typedef struct { #define WMI_RC_TS_FLAG 0x200 /* Three stream flag */ #define WMI_RC_UAPSD_FLAG 0x400 /* UAPSD Rate Control */ +enum WMI_PEER_STA_TYPE { + WMI_PEER_STA_TYPE_INVALID = 0, /* Invalid type*/ + WMI_PEER_STA_TYPE_ONLY_STAVDEV = 1, /* AP has only STAVDEV and APVDEV is not present on any radio */ + WMI_PEER_STA_TYPE_APVDEV_ON_OTHER_RADIO = 2, /* AP has STAVDEV on one radio and APVDEV on other radios */ + WMI_PEER_STA_TYPE_FH_APVDEV_ON_SAME_RADIO = 3, /* AP has STAVDEV and APVDEV on same radio. During STAVDEV connection, + * no repeater client is connected with this repeater APVDEV + */ + WMI_PEER_STA_TYPE_BH_APVDEV_ON_SAME_RADIO = 4, /* AP has STAVDEV and APVDEV on same radio. During STAVDEV connection, + * at least one repeater client is connected with this repeater APVDEV + * (daisy chain config) + */ +}; + +#define WMI_PEER_STA_TYPE_GET(dword) WMI_GET_BITS(dword, 0, 8) +#define WMI_PEER_STA_TYPE_SET(dword, value) WMI_SET_BITS(dword, 0, 8, value) + typedef struct { A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param */ /** peer MAC address */ @@ -13254,6 +13340,13 @@ typedef struct { */ A_UINT32 peer_he_caps_6ghz; + /* bit[0-7] : sta_type + * bit[8-31]: reserved + * Refer to enum WMI_PEER_STA_TYPE for sta_type values. + * Refer to WMI_PEER_STA_TYPE_GET/SET macros. + */ + A_UINT32 sta_type; + /* Following this struct are the TLV's: * A_UINT8 peer_legacy_rates[]; * A_UINT8 peer_ht_rates[]; @@ -14825,6 +14918,43 @@ typedef struct { **/ } wmi_roam_subnet_change_config_fixed_param; +typedef enum { + /** No change in scan mode, use legacy modes */ + ROAM_TRIGGER_SCAN_MODE_NONE = 0, + /** Trigger only partial roam scan */ + ROAM_TRIGGER_SCAN_MODE_PARTIAL, + /** Trigger only FULL roam scan */ + ROAM_TRIGGER_SCAN_MODE_FULL, + /** Don't trigger any roam scan and disconnect from AP */ + ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION, +} WMI_ROAM_TRIGGER_SCAN_MODE; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_configure_roam_trigger_parameters */ + A_UINT32 trigger_reason; /** Roam trigger reason from WMI_ROAM_TRIGGER_REASON_ID */ + A_UINT32 enable; /** 0 - Disable, non-zero - enable */ + A_UINT32 scan_mode; /** Scan mode from WMI_ROAM_TRIGGER_SCAN_MODE */ + /** consider roam trigger if connected AP rssi is worse than trigger_rssi_threshold */ + A_INT32 trigger_rssi_threshold; /* Units in dbm*/ + /* + * Consider AP as roam candidate only if AP rssi is better than + * cand_ap_min_rssi_threshold + */ + A_INT32 cand_ap_min_rssi_threshold; /* Units in dbm */ + /* Roam score delta in %. + * Consider AP as roam candidate only if AP score is at least + * roam_score_delta % better than connected AP score. + * Ex: roam_score_delta = 20, and connected AP score is 4000, + * then consider candidate AP only if its score is at least + * 4800 (= 4000 * 120%) + */ + A_UINT32 roam_score_delta_percentage; + /* Reason code to be filled in the response frame from STA. + Ex: Reason code in the BTM response frame + Valid values are 0 - 255 */ + A_UINT32 reason_code; +} wmi_configure_roam_trigger_parameters; + /** * WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON: * Enable or disable roaming triggers in FW. @@ -14840,6 +14970,15 @@ typedef struct { * bit value equal 0x0. */ A_UINT32 trigger_reason_bitmask; + +/** + * The following TLVs will follow this fixed_param TLV: + * + * wmi_configure_roam_trigger_parameters config_roam_trigger_param[] + * Roam trigger configuration per roam trigger. + * The number of elements in this TLV array is limited to + * WMI_ROAM_TRIGGER_EXT_REASON_MAX + */ } wmi_roam_enable_disable_trigger_reason_fixed_param; /** WMI_PROFILE_MATCH_EVENT: offload scan @@ -16039,6 +16178,10 @@ typedef enum { * due to CSA in OCV enabled case. */ WLAN_DISCONNECT_REASON_CSA_SA_QUERY_TIMEOUT = 1, + /* MOVE_TO_CELLULAR: + * Disconnect from WiFi to move to cellular + */ + WLAN_DISCONNECT_REASON_MOVE_TO_CELLULAR, } WMI_VDEV_DISCONNECT_REASON_ID; typedef struct { @@ -27362,6 +27505,10 @@ typedef enum _WMI_TWT_COMMAND_T { #define TWT_FLAGS_GET_BTWT_ID0(flag) WMI_GET_BITS(flag, 12, 1) #define TWT_FLAGS_SET_BTWT_ID0(flag, val) WMI_SET_BITS(flag, 12, 1, val) +/* 0 means TWT Information frame is enabled, 1 means TWT Information frame is disabled */ +#define TWT_FLAGS_GET_TWT_INFO_FRAME_DISABLED(flag) WMI_GET_BITS(flag, 13, 1) +#define TWT_FLAGS_SET_TWT_INFO_FRAME_DISABLED(flag, val) WMI_SET_BITS(flag, 13, 1, val) + typedef struct { A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_twt_add_dialog_cmd_fixed_param */ A_UINT32 vdev_id; /* VDEV identifier */ @@ -27410,12 +27557,27 @@ typedef enum _WMI_ADD_TWT_STATUS_T { WMI_ADD_TWT_STATUS_UNKNOWN_ERROR, /* adding TWT dialog failed with an unknown reason */ } WMI_ADD_TWT_STATUS_T; +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_twt_add_dialog_additional_params */ + A_UINT32 flags; /* TWT flags, refer to MACROs TWT_FLAGS_*(TWT_FLAGS_GET_CMD etc) */ + A_UINT32 wake_dur_us; /* Wake duration in uS */ + A_UINT32 wake_intvl_us; /* Wake Interval in uS */ + A_UINT32 sp_offset_us; /* SP Starting Offset */ + A_UINT32 sp_tsf_us_lo; /* SP start TSF bits 31:0 */ + A_UINT32 sp_tsf_us_hi; /* SP start TSF bits 63:32 */ +} wmi_twt_add_dialog_additional_params; + typedef struct { A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_twt_add_dialog_complete_event_fixed_param */ A_UINT32 vdev_id; /* VDEV identifier */ wmi_mac_addr peer_macaddr; /* peer MAC address */ A_UINT32 dialog_id; /* TWT dialog ID */ A_UINT32 status; /* refer to WMI_ADD_TWT_STATUS_T */ +/* + * This fixed_param TLV is followed by the below TLVs: + * wmi_twt_add_dialog_additional_params twt_params[]; // TWT params received + * // from peer + */ } wmi_twt_add_dialog_complete_event_fixed_param; typedef struct { @@ -28117,6 +28279,9 @@ typedef struct { typedef enum { WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER = 1, /* Roam scan triggered due to periodic timer expiry */ WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER, /* Roam scan triggered due to inactivity detection */ + /* INACTIVITY_TIMER_LOW_RSSI - alias for INACTIVITY_TIMER */ + WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI = + WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER, WMI_ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER, /* Roam scan triggered due to BTM Disassoc Imminent timeout */ WMI_ROAM_TRIGGER_SUB_REASON_FULL_SCAN, /* Roam scan triggered due to partial scan failure */ WMI_ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC, /* Roam scan triggered due to Low rssi periodic timer */ @@ -28127,6 +28292,16 @@ typedef enum { * This timer is enabled/used for roaming in a vendor-specific manner. */ WMI_ROAM_TRIGGER_SUB_REASCON_PERIODIC_TIMER_AFTER_INACTIVITY, + WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY = + WMI_ROAM_TRIGGER_SUB_REASCON_PERIODIC_TIMER_AFTER_INACTIVITY, + /* + * PERIODIC_TIMER_AFTER_INACTIVITY_LOW_RSSI - alias for + * PERIODIC_TIMER_AFTER_INACTIVITY + */ + WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_LOW_RSSI = + WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY, + WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU, + WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU, } WMI_ROAM_TRIGGER_SUB_REASON_ID; typedef enum wmi_roam_invoke_status_error { @@ -28359,6 +28534,12 @@ typedef struct { * 0x08-0xFF TBD */ A_UINT32 vsie_reason; + /* + * timestamp is the absolute time w.r.t host timer which is synchronized + * between the host and target. + * This timestamp indicates the time when btm response is sent. + */ + A_UINT32 timestamp; /* milli second units */ } wmi_roam_btm_response_info; typedef struct { @@ -30580,6 +30761,7 @@ typedef struct { #define WMI_CFR_NDPA_NDP_ALL_EN_BIT_POS 3 #define WMI_CFR_TA_RA_TYPE_FILTER_EN_BIT_POS 4 #define WMI_CFR_ALL_PACKET_EN_BIT_POS 5 +#define WMI_CFR_FILTER_IN_AS_FP_TA_RA_TYPE_BIT_POS 6 #define WMI_CFR_CAPTURE_INTERVAL_NUM_BITS 24 #define WMI_CFR_CAPTURE_INTERVAL_BIT_POS 0 @@ -30599,6 +30781,14 @@ typedef struct { #define WMI_CFR_FREEZE_DELAY_CNT_THR_NUM_BITS 8 #define WMI_CFR_FREEZE_DELAY_CNT_THR_BIT_POS 1 + +#define WMI_CFR_CAPTURE_COUNT_NUM_BITS 16 +#define WMI_CFR_CAPTURE_COUNT_BIT_POS 0 + +#define WMI_CFR_CAPTURE_INTERVAL_MODE_SEL_NUM_BITS 1 +#define WMI_CFR_CAPTURE_INTERVAL_MODE_SEL_BIT_POS 16 + + #define WMI_CFR_DIRECTED_FTM_ACK_EN_SET(param, value) \ WMI_SET_BITS(param, WMI_CFR_DIRECTED_FTM_ACK_EN_BIT_POS, 1, value) @@ -30637,6 +30827,12 @@ typedef struct { #define WMI_CFR_ALL_PACKET_EN_GET(param) \ WMI_GET_BITS(param, WMI_CFR_ALL_PACKET_EN_BIT_POS, 1) +#define WMI_CFR_FILTER_IN_AS_FP_TA_RA_TYPE_SET(param, value) \ + WMI_SET_BITS(param, WMI_CFR_FILTER_IN_AS_FP_TA_RA_TYPE_BIT_POS, 1, value) + +#define WMI_CFR_FILTER_IN_AS_FP_TA_RA_TYPE_GET(param) \ + WMI_GET_BITS(param, WMI_CFR_FILTER_IN_AS_FP_TA_RA_TYPE_BIT_POS, 1) + #define WMI_CFR_CAPTURE_INTERVAL_SET(param, value) \ WMI_SET_BITS(param, WMI_CFR_CAPTURE_INTERVAL_BIT_POS, WMI_CFR_CAPTURE_INTERVAL_NUM_BITS, value) @@ -30673,6 +30869,18 @@ typedef struct { #define WMI_CFR_FREEZE_DELAY_CNT_THR_GET(param) \ WMI_GET_BITS(param, WMI_CFR_FREEZE_DELAY_CNT_THR_BIT_POS, WMI_CFR_FREEZE_DELAY_CNT_THR_NUM_BITS) +#define WMI_CFR_CAPTURE_COUNT_SET(param, value) \ + WMI_SET_BITS(param, WMI_CFR_CAPTURE_COUNT_BIT_POS, WMI_CFR_CAPTURE_COUNT_NUM_BITS, value) + +#define WMI_CFR_CAPTURE_COUNT_GET(param) \ + WMI_GET_BITS(param, WMI_CFR_CAPTURE_COUNT_BIT_POS, WMI_CFR_CAPTURE_COUNT_NUM_BITS) + +#define WMI_CFR_CAPTURE_INTERVAL_MODE_SEL_SET(param, value) \ + WMI_SET_BITS(param, WMI_CFR_CAPTURE_INTERVAL_MODE_SEL_BIT_POS, WMI_CFR_CAPTURE_INTERVAL_MODE_SEL_NUM_BITS, value) + +#define WMI_CFR_CAPTURE_INTERVAL_MODE_SEL_GET(param) \ + WMI_GET_BITS(param, WMI_CFR_CAPTURE_INTERVAL_MODE_SEL_BIT_POS, WMI_CFR_CAPTURE_INTERVAL_MODE_SEL_NUM_BITS) + typedef struct { /** TLV tag and len; tag equals * WMITLV_TAG_STRUC_wmi_peer_cfr_capture_filter_cmd_fixed_param */ @@ -30687,10 +30895,12 @@ typedef struct { * Bit 0: Filter Directed FTM ACK frames for CFR capture * Bit 1: Filter All FTM ACK frames for CFR capture * Bit 2: Filter NDPA NDP Directed Frames for CFR capture - * Bit 3: Filter Frames based on TA/RA/Subtype as provided + * Bit 3: Filter NDPA NDP All Frames for CFR capture + * Bit 4: Filter Frames based on TA/RA/Subtype as provided * in CFR Group config - * Bit 4: Filter in All packets for CFR Capture - * Bits 31:5 Reserved for future use + * Bit 5: Filter in All packets for CFR Capture + * Bit 6: Filter in TA/RA frames as FP if this bit is set else as MO + * Bits 31:7 Reserved for future use */ A_UINT32 filter_type; /* capture_interval: @@ -30738,6 +30948,25 @@ typedef struct { * Bits 31:9 Reserved for future use */ A_UINT32 freeze_tlv_delay_cnt; + + /* capture_count: + * Indicates the number of consecutive packets for which CFR capture + * is to be enabled. + * Interpretation of capture_interval_mode_select (bit 16): + * Value 0: capture_interval + capture_duration fields are used + * to capture CFR for capture_duration after every + * capture_interval. + * Value 1: capture_interval + capture_count fields are used to + * capture CFR for capture_count+1 number of packets + * after every capture interval + * Bit 15:0 : capture_count + * Refer to WMI_CFR_CAPTURE_COUNT_GET/SET macros. + * Bit 16 : capture_interval_mode_select + * Refer to WMI_CFR_CAPTURE_INTERVAL_MODE_SEL_GET/SET macros. + * Bits 31:17 : Reserved + */ + A_UINT32 capture_count; + /* * A variable-length TLV array of wmi_cfr_filter_group_config will * follow this fixed_param TLV @@ -31205,6 +31434,65 @@ typedef struct { */ } wmi_simulation_test_cmd_fixed_param; +#define WMI_TWT_SESSION_FLAG_FLOW_ID_GET(_var) WMI_GET_BITS(_var, 0, 16) +#define WMI_TWT_SESSION_FLAG_FLOW_ID_SET(_var, _val) WMI_SET_BITS(_var, 0, 16, _val) + +#define WMI_TWT_SESSION_FLAG_BCAST_TWT_GET(_var) WMI_GET_BITS(_var, 16, 1) +#define WMI_TWT_SESSION_FLAG_BCAST_TWT_SET(_var, _val) WMI_SET_BITS(_var, 16, 1, _val) + +#define WMI_TWT_SESSION_FLAG_TRIGGER_TWT_GET(_var) WMI_GET_BITS(_var, 17, 1) +#define WMI_TWT_SESSION_FLAG_TRIGGER_TWT_SET(_var, _val) WMI_SET_BITS(_var, 17, 1, _val) + +#define WMI_TWT_SESSION_FLAG_ANNOUN_TWT_GET(_var) WMI_GET_BITS(_var, 18, 1) +#define WMI_TWT_SESSION_FLAG_ANNOUN_TWT_SET(_var, _val) WMI_SET_BITS(_var, 18, 1, _val) + +#define WMI_TWT_SESSION_FLAG_TWT_PROTECTION_GET(_var) WMI_GET_BITS(_var, 19, 1) +#define WMI_TWT_SESSION_FLAG_TWT_PROTECTION_SET(_var, _val) WMI_SET_BITS(_var, 19, 1, _val) + +#define WMI_TWT_SESSION_FLAG_TWT_INFO_FRAME_DISABLED_GET(_var) WMI_GET_BITS(_var, 20, 1) +#define WMI_TWT_SESSION_FLAG_TWT_INFO_FRAME_DISABLED_SET(_var, _val) WMI_SET_BITS(_var, 20, 1, _val) + +typedef struct { + /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_twt_session_stats_info */ + A_UINT32 tlv_hdr; + + A_UINT32 vdev_id; + wmi_mac_addr peer_mac; + A_UINT32 event_type; /* event type - defined in enum wmi_twt_session_stats_type */ + /* + * Flags to provide information on TWT session and session types. + * This field is filled with the bitwise combination of the flag values + * defined by WMI_TWT_SESSION_FLAG_xxx + */ + A_UINT32 flow_id_flags; + A_UINT32 dialog_id; + A_UINT32 wake_dura_us; + A_UINT32 wake_intvl_us; + /* this long time after TWT resumed the 1st Service Period will start */ + A_UINT32 sp_offset_us; + /* service period start TSF */ + A_UINT32 sp_tsf_us_lo; /* bits 31:0 */ + A_UINT32 sp_tsf_us_hi; /* bits 63:32 */ +} wmi_twt_session_stats_info; + +enum wmi_twt_session_stats_type { + WMI_TWT_SESSION_SETUP = 1, + WMI_TWT_SESSION_TEARDOWN = 2, + WMI_TWT_SESSION_UPDATE = 3, +}; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_pdev_twt_session_stats_event_fixed_param */ + A_UINT32 tlv_header; + + A_UINT32 pdev_id; /* ID of the pdev this response belongs to */ + + /* The TLVs follows this structure: + * wmi_twt_session_stats_info twt_sessions[]; <--- Array of twt_session. + */ +} wmi_pdev_twt_session_stats_event_fixed_param; + /* ADD NEW DEFS HERE */ diff --git a/drivers/staging/fw-api/fw/wmi_version.h b/drivers/staging/fw-api/fw/wmi_version.h index 9c7c836fc990..6be23827697f 100644 --- a/drivers/staging/fw-api/fw/wmi_version.h +++ b/drivers/staging/fw-api/fw/wmi_version.h @@ -36,7 +36,7 @@ #define __WMI_VER_MINOR_ 0 /** WMI revision number has to be incremented when there is a * change that may or may not break compatibility. */ -#define __WMI_REVISION_ 854 +#define __WMI_REVISION_ 869 /** The Version Namespace should not be normally changed. Only * host and firmware of the same WMI namespace will work diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c index 07fac3948f3a..cc35037ace59 100644 --- a/drivers/staging/greybus/audio_topology.c +++ b/drivers/staging/greybus/audio_topology.c @@ -145,7 +145,7 @@ static const char **gb_generate_enum_strings(struct gbaudio_module_info *gb, __u8 *data; items = le32_to_cpu(gbenum->items); - strings = devm_kzalloc(gb->dev, sizeof(char *) * items, GFP_KERNEL); + strings = devm_kcalloc(gb->dev, items, sizeof(char *), GFP_KERNEL); data = gbenum->names; for (i = 0; i < items; i++) { diff --git a/drivers/staging/greybus/camera.c b/drivers/staging/greybus/camera.c index a64517eabff4..4931fdd59a84 100644 --- a/drivers/staging/greybus/camera.c +++ b/drivers/staging/greybus/camera.c @@ -1181,8 +1181,7 @@ static int gb_camera_debugfs_init(struct gb_camera *gcam) return PTR_ERR(gcam->debugfs.root); } - gcam->debugfs.buffers = vmalloc(sizeof(*gcam->debugfs.buffers) * - GB_CAMERA_DEBUGFS_BUFFER_MAX); + gcam->debugfs.buffers = vmalloc(array_size(GB_CAMERA_DEBUGFS_BUFFER_MAX, sizeof(*gcam->debugfs.buffers))); if (!gcam->debugfs.buffers) return -ENOMEM; diff --git a/drivers/staging/irda/net/discovery.c b/drivers/staging/irda/net/discovery.c index 364d70aed068..d48e9a839831 100644 --- a/drivers/staging/irda/net/discovery.c +++ b/drivers/staging/irda/net/discovery.c @@ -178,7 +178,9 @@ void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force) if(buffer == NULL) { /* Create the client specific buffer */ n = HASHBIN_GET_SIZE(log); - buffer = kmalloc(n * sizeof(struct irda_device_info), GFP_ATOMIC); + buffer = kmalloc_array(n, + sizeof(struct irda_device_info), + GFP_ATOMIC); if (buffer == NULL) { spin_unlock_irqrestore(&log->hb_spinlock, flags); return; @@ -290,7 +292,9 @@ struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn, if(buffer == NULL) { /* Create the client specific buffer */ n = HASHBIN_GET_SIZE(log); - buffer = kmalloc(n * sizeof(struct irda_device_info), GFP_ATOMIC); + buffer = kmalloc_array(n, + sizeof(struct irda_device_info), + GFP_ATOMIC); if (buffer == NULL) { spin_unlock_irqrestore(&log->hb_spinlock, flags); return NULL; diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 8c97acd79211..1a0ee7578d7f 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -1151,7 +1151,7 @@ static int mdc_read_page_remote(struct file *data, struct page *page0) } for (npages = 1; npages < max_pages; npages++) { - page = page_cache_alloc_cold(inode->i_mapping); + page = page_cache_alloc(inode->i_mapping); if (!page) break; page_pool[npages] = page; diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c index 95c7fa3b532c..28cb84890614 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c @@ -1016,7 +1016,7 @@ int cl_global_init(void) { int result; - cl_envs = kzalloc(sizeof(*cl_envs) * num_possible_cpus(), GFP_KERNEL); + cl_envs = kcalloc(num_possible_cpus(), sizeof(*cl_envs), GFP_KERNEL); if (!cl_envs) { result = -ENOMEM; goto out; diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c index 155f6a45cc8b..e1fffc76be02 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/service.c +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c @@ -491,7 +491,7 @@ ptlrpc_service_part_init(struct ptlrpc_service *svc, /* allocate memory for scp_at_array (ptlrpc_at_array) */ array->paa_reqs_array = - kzalloc_node(sizeof(struct list_head) * size, GFP_NOFS, + kcalloc_node(size, sizeof(struct list_head), GFP_NOFS, cfs_cpt_spread_node(svc->srv_cptable, cpt)); if (!array->paa_reqs_array) return -ENOMEM; @@ -500,7 +500,7 @@ ptlrpc_service_part_init(struct ptlrpc_service *svc, INIT_LIST_HEAD(&array->paa_reqs_array[index]); array->paa_reqs_count = - kzalloc_node(sizeof(__u32) * size, GFP_NOFS, + kcalloc_node(size, sizeof(__u32), GFP_NOFS, cfs_cpt_spread_node(svc->srv_cptable, cpt)); if (!array->paa_reqs_count) goto free_reqs_array; @@ -2540,7 +2540,7 @@ int ptlrpc_hr_init(void) hrp->hrp_nthrs = 1; hrp->hrp_thrs = - kzalloc_node(hrp->hrp_nthrs * sizeof(*hrt), GFP_NOFS, + kcalloc_node(hrp->hrp_nthrs, sizeof(*hrt), GFP_NOFS, cfs_cpt_spread_node(ptlrpc_hr.hr_cpt_table, i)); if (!hrp->hrp_thrs) { diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c index 05897b747349..7ae2478fecc8 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c @@ -4331,8 +4331,8 @@ int atomisp_css_create_acc_pipe(struct atomisp_sub_device *asd) pipe_config = &stream_env->pipe_configs[CSS_PIPE_ID_ACC]; ia_css_pipe_config_defaults(pipe_config); - asd->acc.acc_stages = kzalloc(MAX_ACC_STAGES * - sizeof(void *), GFP_KERNEL); + asd->acc.acc_stages = kcalloc(MAX_ACC_STAGES, sizeof(void *), + GFP_KERNEL); if (!asd->acc.acc_stages) return -ENOMEM; pipe_config->acc_stages = asd->acc.acc_stages; diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c index f1d8cc5a2730..f28ea9a2604b 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c @@ -1136,7 +1136,7 @@ static int remove_pad_from_frame(struct atomisp_device *isp, ia_css_ptr load = in_frame->data; ia_css_ptr store = load; - buffer = kmalloc(width*sizeof(load), GFP_KERNEL); + buffer = kmalloc_array(width, sizeof(load), GFP_KERNEL); if (!buffer) { dev_err(isp->dev, "out of memory.\n"); return -ENOMEM; diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c index 744ab6eb42a0..e5bf60601d92 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c @@ -1414,8 +1414,10 @@ int atomisp_subdev_init(struct atomisp_device *isp) * multiple streams */ isp->num_of_streams = 2; - isp->asd = devm_kzalloc(isp->dev, sizeof(struct atomisp_sub_device) * - isp->num_of_streams, GFP_KERNEL); + isp->asd = devm_kcalloc(isp->dev, + isp->num_of_streams, + sizeof(struct atomisp_sub_device), + GFP_KERNEL); if (!isp->asd) return -ENOMEM; for (i = 0; i < isp->num_of_streams; i++) { diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_firmware.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_firmware.c index 63582161050a..2150a650aa84 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_firmware.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_firmware.c @@ -226,16 +226,17 @@ sh_css_load_firmware(const char *fw_data, sh_css_num_binaries = file_header->binary_nr; /* Only allocate memory for ISP blob info */ if (sh_css_num_binaries > NUM_OF_SPS) { - sh_css_blob_info = kmalloc( - (sh_css_num_binaries - NUM_OF_SPS) * - sizeof(*sh_css_blob_info), GFP_KERNEL); + sh_css_blob_info = kmalloc_array(sh_css_num_binaries - NUM_OF_SPS, + sizeof(*sh_css_blob_info), + GFP_KERNEL); if (sh_css_blob_info == NULL) return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; } else { sh_css_blob_info = NULL; } - fw_minibuffer = kzalloc(sh_css_num_binaries * sizeof(struct fw_param), GFP_KERNEL); + fw_minibuffer = kcalloc(sh_css_num_binaries, sizeof(struct fw_param), + GFP_KERNEL); if (fw_minibuffer == NULL) return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; diff --git a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_bo.c b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_bo.c index 11162f595fc7..929597713261 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_bo.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_bo.c @@ -725,8 +725,8 @@ static int alloc_private_pages(struct hmm_buffer_object *bo, pgnr = bo->pgnr; - bo->page_obj = kmalloc(sizeof(struct hmm_page_object) * pgnr, - GFP_KERNEL); + bo->page_obj = kmalloc_array(pgnr, sizeof(struct hmm_page_object), + GFP_KERNEL); if (unlikely(!bo->page_obj)) { dev_err(atomisp_dev, "out of memory for bo->page_obj\n"); return -ENOMEM; @@ -990,14 +990,14 @@ static int alloc_user_pages(struct hmm_buffer_object *bo, struct vm_area_struct *vma; struct page **pages; - pages = kmalloc(sizeof(struct page *) * bo->pgnr, GFP_KERNEL); + pages = kmalloc_array(bo->pgnr, sizeof(struct page *), GFP_KERNEL); if (unlikely(!pages)) { dev_err(atomisp_dev, "out of memory for pages...\n"); return -ENOMEM; } - bo->page_obj = kmalloc(sizeof(struct hmm_page_object) * bo->pgnr, - GFP_KERNEL); + bo->page_obj = kmalloc_array(bo->pgnr, sizeof(struct hmm_page_object), + GFP_KERNEL); if (unlikely(!bo->page_obj)) { dev_err(atomisp_dev, "out of memory for bo->page_obj...\n"); kfree(pages); @@ -1363,7 +1363,7 @@ void *hmm_bo_vmap(struct hmm_buffer_object *bo, bool cached) bo->status &= ~(HMM_BO_VMAPED | HMM_BO_VMAPED_CACHED); } - pages = kmalloc(sizeof(*pages) * bo->pgnr, GFP_KERNEL); + pages = kmalloc_array(bo->pgnr, sizeof(*pages), GFP_KERNEL); if (unlikely(!pages)) { mutex_unlock(&bo->mutex); dev_err(atomisp_dev, "out of memory for pages...\n"); diff --git a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_reserved_pool.c b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_reserved_pool.c index bf6586805f7f..8bcef2445b48 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_reserved_pool.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_reserved_pool.c @@ -97,8 +97,8 @@ static int hmm_reserved_pool_setup(struct hmm_reserved_pool_info **repool_info, return -ENOMEM; } - pool_info->pages = kmalloc(sizeof(struct page *) * pool_size, - GFP_KERNEL); + pool_info->pages = kmalloc_array(pool_size, sizeof(struct page *), + GFP_KERNEL); if (unlikely(!pool_info->pages)) { dev_err(atomisp_dev, "out of memory for repool_info->pages.\n"); kfree(pool_info); diff --git a/drivers/staging/media/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c index e35e1b2160e3..3939409fcf5d 100644 --- a/drivers/staging/media/lirc/lirc_zilog.c +++ b/drivers/staging/media/lirc/lirc_zilog.c @@ -807,8 +807,7 @@ static int fw_load(struct IR_tx *tx) dev_dbg(tx->ir->l.dev, "%u IR blaster codesets loaded\n", tx_data->num_code_sets); - tx_data->code_sets = vmalloc( - tx_data->num_code_sets * sizeof(char *)); + tx_data->code_sets = vmalloc(array_size(sizeof(char *), tx_data->num_code_sets)); if (!tx_data->code_sets) { fw_unload_locked(); ret = -ENOMEM; diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_threads.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_threads.h index 82c0fcccfb84..da598a5ea08a 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_threads.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_threads.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -111,4 +111,39 @@ void qdf_print_thread_trace(qdf_thread_t *thread); * Return: pointer to task struct */ qdf_thread_t *qdf_get_current_task(void); + +/** + * qdf_thread_set_cpus_allowed_mask() - set cpu mask for a particular thread + * @thread: thread for which new cpu mask is set + * @new_mask: new cpu mask to be set for the thread + * + * Return: None + */ +void +qdf_thread_set_cpus_allowed_mask(qdf_thread_t *thread, qdf_cpu_mask *new_mask); + +/** + * qdf_cpumask_clear() - clear all cpus in a cpumask + * @dstp: cpumask pointer + * + * Return: None + */ +void qdf_cpumask_clear(qdf_cpu_mask *dstp); + +/** + * qdf_cpumask_set_cpu() - set a cpu in a cpumask + * @cpu: cpu number + * @dstp: cpumask pointer + * + * Return: None + */ +void qdf_cpumask_set_cpu(unsigned int cpu, qdf_cpu_mask *dstp); + +/** + * qdf_cpumask_setall - set all cpus + * @dstp: cpumask pointer + * + * Return: None + */ +void qdf_cpumask_setall(qdf_cpu_mask *dstp); #endif /* __QDF_THREADS_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_types.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_types.h index c06f86e27312..6d0f98523d96 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_types.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_types.h @@ -155,6 +155,11 @@ typedef __qdf_dma_context_t qdf_dma_context_t; typedef __qdf_mem_info_t qdf_mem_info_t; typedef __sgtable_t sgtable_t; +/** + * typepdef qdf_cpu_mask - CPU Mask + */ +typedef __qdf_cpu_mask qdf_cpu_mask; + /** * pointer to net device */ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_types.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_types.h index eb0044ff0faa..5e1cce58cdf3 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_types.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_types.h @@ -156,6 +156,7 @@ typedef dma_addr_t __qdf_dma_addr_t; typedef size_t __qdf_dma_size_t; typedef dma_addr_t __qdf_dma_context_t; typedef struct net_device *__qdf_netdev_t; +typedef struct cpumask __qdf_cpu_mask; typedef __le16 __qdf_le16_t; typedef __le32 __qdf_le32_t; typedef __le64 __qdf_le64_t; diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_threads.c b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_threads.c index 842d6bc5f9f6..7ae3606a813d 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_threads.c +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_threads.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -197,3 +197,32 @@ qdf_thread_t *qdf_get_current_task(void) return current; } qdf_export_symbol(qdf_get_current_task); + +void +qdf_thread_set_cpus_allowed_mask(qdf_thread_t *thread, qdf_cpu_mask *new_mask) +{ + set_cpus_allowed_ptr(thread, new_mask); +} + +qdf_export_symbol(qdf_thread_set_cpus_allowed_mask); + +void qdf_cpumask_clear(qdf_cpu_mask *dstp) +{ + cpumask_clear(dstp); +} + +qdf_export_symbol(qdf_cpumask_clear); + +void qdf_cpumask_set_cpu(unsigned int cpu, qdf_cpu_mask *dstp) +{ + cpumask_set_cpu(cpu, dstp); +} + +qdf_export_symbol(qdf_cpumask_set_cpu); + +void qdf_cpumask_setall(qdf_cpu_mask *dstp) +{ + cpumask_setall(dstp); +} + +qdf_export_symbol(qdf_cpumask_setall); diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_trace.c b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_trace.c index d03438bad0e9..c76ffb13b93e 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_trace.c +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_trace.c @@ -2783,26 +2783,27 @@ QDF_STATUS qdf_dpt_dump_stats_debugfs(qdf_debugfs_file_t file, break; case QDF_DP_TRACE_HDD_TX_TIMEOUT: - qdf_debugfs_printf(file, "DPT: %04d: %s %s\n", - i, p_record.time, - qdf_dp_code_to_string(p_record.code)); - qdf_debugfs_printf(file, "%s: HDD TX Timeout\n"); + qdf_debugfs_printf( + file, "DPT: %04d: %llu %s\n", + i, p_record.time, + qdf_dp_code_to_string(p_record.code)); + qdf_debugfs_printf(file, "HDD TX Timeout\n"); break; case QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT: - qdf_debugfs_printf(file, "%04d: %s %s\n", - i, p_record.time, - qdf_dp_code_to_string(p_record.code)); - qdf_debugfs_printf(file, - "%s: HDD SoftAP TX Timeout\n"); + qdf_debugfs_printf( + file, "DPT: %04d: %llu %s\n", + i, p_record.time, + qdf_dp_code_to_string(p_record.code)); + qdf_debugfs_printf(file, "HDD SoftAP TX Timeout\n"); break; case QDF_DP_TRACE_CE_FAST_PACKET_ERR_RECORD: - qdf_debugfs_printf(file, "DPT: %04d: %s %s\n", - i, p_record.time, - qdf_dp_code_to_string(p_record.code)); - qdf_debugfs_printf(file, - "%s: CE Fast Packet Error\n"); + qdf_debugfs_printf( + file, "DPT: %04d: %llu %s\n", + i, p_record.time, + qdf_dp_code_to_string(p_record.code)); + qdf_debugfs_printf(file, "CE Fast Packet Error\n"); break; case QDF_DP_TRACE_MAX: diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/nan/inc/target_if_nan.h b/drivers/staging/qca-wifi-host-cmn/target_if/nan/inc/target_if_nan.h index 2563efae7d0e..1ddc2676b158 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/nan/inc/target_if_nan.h +++ b/drivers/staging/qca-wifi-host-cmn/target_if/nan/inc/target_if_nan.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017, 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h index c10b9d604009..448bf9c67000 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h @@ -1510,7 +1510,8 @@ static inline QDF_STATUS wlan_parse_rsn_ie(uint8_t *rsn_ie, rsn->pmkid_count = LE_READ_2(ie); ie += 2; rem_len -= 2; - if (rsn->pmkid_count > (unsigned int) rem_len / PMKID_LEN) { + if (rsn->pmkid_count > MAX_PMKID || + rsn->pmkid_count > (unsigned int)rem_len / PMKID_LEN) { rsn->pmkid_count = 0; return QDF_STATUS_E_INVAL; } diff --git a/drivers/staging/qca-wifi-host-cmn/umac/nan/dispatcher/inc/nan_ucfg_api.h b/drivers/staging/qca-wifi-host-cmn/umac/nan/dispatcher/inc/nan_ucfg_api.h index fa2d990e1aed..13f9af872c74 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/nan/dispatcher/inc/nan_ucfg_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/nan/dispatcher/inc/nan_ucfg_api.h @@ -279,4 +279,3 @@ QDF_STATUS ucfg_nan_get_callbacks(struct wlan_objmgr_psoc *psoc, struct nan_callbacks *cb_obj); #endif /* _NAN_UCFG_API_H_ */ - diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services.c b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services.c index eb64ab629874..f1551c36f80f 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services.c @@ -1854,24 +1854,124 @@ uint32_t reg_freq_to_chan(struct wlan_objmgr_pdev *pdev, struct regulatory_channel *chan_list; struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + if (freq == 0) { + reg_err("Invalid freq %d", freq); + return 0; + } + pdev_priv_obj = reg_get_pdev_obj(pdev); if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { reg_err("reg pdev priv obj is NULL"); - return QDF_STATUS_E_FAILURE; + return 0; } - chan_list = pdev_priv_obj->cur_chan_list; + chan_list = pdev_priv_obj->mas_chan_list; + for (count = 0; count < NUM_CHANNELS; count++) { + if (chan_list[count].center_freq >= freq) + break; + } - for (count = 0; count < NUM_CHANNELS; count++) - if (chan_list[count].center_freq == freq) - return chan_list[count].chan_num; + if (count == NUM_CHANNELS) + goto end; + if (chan_list[count].center_freq == freq) + return chan_list[count].chan_num; + + if (count == 0) + goto end; + + if ((chan_list[count - 1].chan_num == INVALID_CHANNEL_NUM) || + (chan_list[count].chan_num == INVALID_CHANNEL_NUM)) { + reg_err("Frequency %d invalid in current reg domain", freq); + return 0; + } + + return (chan_list[count - 1].chan_num + + (freq - chan_list[count - 1].center_freq) / 5); + +end: reg_err("invalid frequency %d", freq); - return 0; } +static uint16_t reg_compute_chan_to_freq(struct wlan_objmgr_pdev *pdev, + uint8_t chan_num, + enum channel_enum min_chan_range, + enum channel_enum max_chan_range) +{ + uint16_t count; + struct regulatory_channel *chan_list; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + + pdev_priv_obj = reg_get_pdev_obj(pdev); + + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("reg pdev priv obj is NULL"); + return 0; + } + + chan_list = pdev_priv_obj->mas_chan_list; + + for (count = min_chan_range; count <= max_chan_range; count++) { + if (reg_chan_is_49ghz(pdev, chan_list[count].chan_num)) { + if (chan_list[count].chan_num == chan_num) + break; + continue; + } else if ((chan_list[count].chan_num >= chan_num) && + (chan_list[count].state != CHANNEL_STATE_DISABLE) && + !(chan_list[count].chan_flags & + REGULATORY_CHAN_DISABLED) && + (chan_list[count].chan_num != INVALID_CHANNEL_NUM)) + break; + } + + if (count == max_chan_range + 1) + goto end; + + if (chan_list[count].chan_num == chan_num) { + if (chan_list[count].chan_flags & REGULATORY_CHAN_DISABLED) + reg_err("Channel %d disabled in current reg domain", + chan_num); + return chan_list[count].center_freq; + } + + if (count == min_chan_range) + goto end; + + if ((chan_list[count - 1].chan_num == INVALID_CHANNEL_NUM) || + reg_chan_is_49ghz(pdev, chan_list[count - 1].chan_num) || + (chan_list[count].chan_num == INVALID_CHANNEL_NUM)) { + reg_err("Channel %d invalid in current reg domain", + chan_num); + return 0; + } + + return (chan_list[count - 1].center_freq + + (chan_num - chan_list[count - 1].chan_num) * 5); + +end: + + reg_debug_rl("Invalid channel %d", chan_num); + return 0; +} + +uint16_t reg_legacy_chan_to_freq(struct wlan_objmgr_pdev *pdev, + uint8_t chan_num) +{ + uint16_t min_chan_range = MIN_24GHZ_CHANNEL; + uint16_t max_chan_range = MAX_5GHZ_CHANNEL; + + if (chan_num == 0) { + reg_err("Invalid channel %d", chan_num); + return 0; + } + + return reg_compute_chan_to_freq(pdev, chan_num, + min_chan_range, + max_chan_range); +} + uint32_t reg_chan_to_freq(struct wlan_objmgr_pdev *pdev, uint32_t chan_num) { diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services.h b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services.h index 1b4440902198..b7a7e220eeff 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services.h @@ -461,6 +461,16 @@ uint32_t reg_freq_to_chan(struct wlan_objmgr_pdev *pdev, uint32_t freq); uint32_t reg_chan_to_freq(struct wlan_objmgr_pdev *pdev, uint32_t chan_num); +/** + * reg_legacy_chan_to_freq() - Get freq from chan noumber, for 2G and 5G + * @pdev: Pointer to pdev + * @chan_num: Channel number + * + * Return: Channel frequency if success, otherwise 0 + */ +uint16_t reg_legacy_chan_to_freq(struct wlan_objmgr_pdev *pdev, + uint8_t chan_num); + /** * reg_chan_is_49ghz() - Check if the input channel number is 4.9GHz * @pdev: Pdev pointer diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h index 42174be1976c..93056b2d344d 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h @@ -447,6 +447,16 @@ uint32_t wlan_reg_chan_to_freq(struct wlan_objmgr_pdev *pdev, * * Return: true or false */ + +/** + * wlan_reg_legacy_chan_to_freq () - convert chan to freq, for 2G and 5G + * @chan: channel number + * + * Return: frequency + */ +uint16_t wlan_reg_legacy_chan_to_freq(struct wlan_objmgr_pdev *pdev, + uint8_t chan); + bool wlan_reg_is_world(uint8_t *country); /** diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/src/wlan_reg_services_api.c b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/src/wlan_reg_services_api.c index 8166292c7c30..9569f6f08e35 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/src/wlan_reg_services_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/src/wlan_reg_services_api.c @@ -469,6 +469,12 @@ uint32_t wlan_reg_chan_to_freq(struct wlan_objmgr_pdev *pdev, return reg_chan_to_freq(pdev, chan_num); } +uint16_t wlan_reg_legacy_chan_to_freq(struct wlan_objmgr_pdev *pdev, + uint8_t chan_num) +{ + return reg_legacy_chan_to_freq(pdev, chan_num); +} + bool wlan_reg_chan_is_49ghz(struct wlan_objmgr_pdev *pdev, uint8_t chan_num) { diff --git a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_main.c b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_main.c index 086321d7e117..1434fea3207b 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_main.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_main.c @@ -233,8 +233,9 @@ static void wifi_update_channel_bw_info(struct wlan_objmgr_psoc *psoc, wlan_reg_set_channel_params(pdev, chan, sec_ch_2g, &ch_params); if (ch_params.center_freq_seg0) chan_info->band_center_freq1 = - wlan_reg_get_channel_freq(pdev, - ch_params.center_freq_seg0); + wlan_reg_legacy_chan_to_freq( + pdev, + ch_params.center_freq_seg0); wifi_pos_psoc->wifi_pos_get_phy_mode(chan, ch_params.ch_width, &phy_mode); diff --git a/drivers/staging/qca-wifi-host-cmn/utils/fwlog/dbglog_host.c b/drivers/staging/qca-wifi-host-cmn/utils/fwlog/dbglog_host.c index ea3c6fc4f75b..d0debea6fff2 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/fwlog/dbglog_host.c +++ b/drivers/staging/qca-wifi-host-cmn/utils/fwlog/dbglog_host.c @@ -741,7 +741,7 @@ char *DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] = { }, {"" /* HOST */ }, - {"" /* BEACON */ + { /* BEACON */ "BEACON_EVENT_SWBA_SEND_FAILED", "BEACON_EVENT_EARLY_RX_BMISS_STATUS", "BEACON_EVENT_EARLY_RX_SLEEP_SLOP", diff --git a/drivers/staging/qca-wifi-host-cmn/utils/logging/src/wlan_logging_sock_svc.c b/drivers/staging/qca-wifi-host-cmn/utils/logging/src/wlan_logging_sock_svc.c index 7220ebf08019..dd0b59281232 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/logging/src/wlan_logging_sock_svc.c +++ b/drivers/staging/qca-wifi-host-cmn/utils/logging/src/wlan_logging_sock_svc.c @@ -798,7 +798,7 @@ int wlan_logging_sock_init_svc(void) /* Initialize the pktStats data structure here */ pkt_stats_size = sizeof(struct pkt_stats_msg); - gpkt_stats_buffers = vmalloc(MAX_PKTSTATS_BUFF * pkt_stats_size); + gpkt_stats_buffers = vmalloc(array_size(pkt_stats_size, MAX_PKTSTATS_BUFF)); if (!gpkt_stats_buffers) { pr_err("%s: Could not allocate memory for Pkt stats\n", __func__); diff --git a/drivers/staging/qca-wifi-host-cmn/utils/pktlog/linux_ac.c b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/linux_ac.c index 0bbb9df0ecad..6cf9640d3025 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/pktlog/linux_ac.c +++ b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/linux_ac.c @@ -120,7 +120,7 @@ int pktlog_alloc_buf(struct hif_opaque_softc *scn) } qdf_spin_unlock_bh(&pl_info->log_lock); - buffer = vmalloc((page_cnt + 2) * PAGE_SIZE); + buffer = vmalloc(array_size((page_cnt + 2), PAGE_SIZE)); if (buffer == NULL) { printk(PKTLOG_TAG "%s: Unable to allocate buffer " diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_param.h b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_param.h index f5a54a46e1d8..d307f96796fa 100644 --- a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_param.h +++ b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_param.h @@ -5790,6 +5790,7 @@ typedef enum { #endif wmi_roam_stats_event_id, wmi_roam_scan_chan_list_id, + wmi_vdev_bcn_latency_event_id, wmi_events_max, } wmi_conv_event_id; @@ -6054,6 +6055,7 @@ typedef enum { wmi_vdev_param_set_ba_mode, wmi_vdev_param_autorate_misc_cfg, wmi_vdev_param_amsdu_subframe_size_per_ac, + wmi_vdev_param_nan_config_features, wmi_vdev_param_max, } wmi_conv_vdev_param_id; diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/src/wmi_unified_non_tlv.c b/drivers/staging/qca-wifi-host-cmn/wmi/src/wmi_unified_non_tlv.c index c18bb20a5394..35b14b3fef2a 100644 --- a/drivers/staging/qca-wifi-host-cmn/wmi/src/wmi_unified_non_tlv.c +++ b/drivers/staging/qca-wifi-host-cmn/wmi/src/wmi_unified_non_tlv.c @@ -9413,6 +9413,8 @@ static void populate_vdev_param_non_tlv(uint32_t *vdev_param) WMI_VDEV_PARAM_DISABLE_CABQ; vdev_param[wmi_vdev_param_amsdu_subframe_size_per_ac] = WMI_VDEV_PARAM_AMSDU_SUBFRAME_SIZE_PER_AC; + vdev_param[wmi_vdev_param_nan_config_features] = + WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES; } #endif diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/src/wmi_unified_tlv.c b/drivers/staging/qca-wifi-host-cmn/wmi/src/wmi_unified_tlv.c index bbc976ce8500..015484e47c06 100644 --- a/drivers/staging/qca-wifi-host-cmn/wmi/src/wmi_unified_tlv.c +++ b/drivers/staging/qca-wifi-host-cmn/wmi/src/wmi_unified_tlv.c @@ -24991,6 +24991,8 @@ static void populate_tlv_events_id(uint32_t *event_ids) event_ids[wmi_roam_scan_chan_list_id] = WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID; + event_ids[wmi_vdev_bcn_latency_event_id] = + WMI_VDEV_BCN_LATENCY_EVENTID; } /** @@ -25664,6 +25666,8 @@ static void populate_vdev_param_tlv(uint32_t *vdev_param) WMI_VDEV_PARAM_CAPABILITIES; vdev_param[wmi_vdev_param_autorate_misc_cfg] = WMI_VDEV_PARAM_AUTORATE_MISC_CFG; + vdev_param[wmi_vdev_param_nan_config_features] = + WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES; } #endif diff --git a/drivers/staging/qcacld-3.0/Kbuild b/drivers/staging/qcacld-3.0/Kbuild index 07e0f3d61a9a..340a2faa5a01 100644 --- a/drivers/staging/qcacld-3.0/Kbuild +++ b/drivers/staging/qcacld-3.0/Kbuild @@ -1983,6 +1983,14 @@ ifeq ($(CONFIG_ARCH_SDX20), y) cppflags-y += -DSYNC_IPA_READY endif +ifeq ($(CONFIG_ARCH_MSM8996), y) +CONFIG_RX_THREAD_PRIORITY := y +endif + +ifeq ($(CONFIG_RX_THREAD_PRIORITY), y) +cppflags-y += -DRX_THREAD_PRIORITY +endif + #Enable wbuff cppflags-$(CONFIG_WLAN_WBUFF) += -DWLAN_FEATURE_WBUFF diff --git a/drivers/staging/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c b/drivers/staging/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c index 0c427ff61cb3..96aa113fe3b1 100644 --- a/drivers/staging/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c +++ b/drivers/staging/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c @@ -435,19 +435,25 @@ pkt_capture_mgmt_rx_data_cb(struct wlan_objmgr_psoc *psoc, qdf_nbuf_t nbuf; int buf_len; - if (!(pkt_capture_get_pktcap_mode() & PACKET_CAPTURE_MODE_MGMT_ONLY)) + if (!(pkt_capture_get_pktcap_mode() & PACKET_CAPTURE_MODE_MGMT_ONLY)) { + qdf_nbuf_free(wbuf); return QDF_STATUS_E_FAILURE; + } buf_len = qdf_nbuf_len(wbuf); nbuf = qdf_nbuf_alloc(NULL, roundup( buf_len + RESERVE_BYTES, 4), RESERVE_BYTES, 4, false); - if (!nbuf) + if (!nbuf) { + qdf_nbuf_free(wbuf); return QDF_STATUS_E_FAILURE; + } qdf_nbuf_put_tail(nbuf, buf_len); qdf_mem_copy(qdf_nbuf_data(nbuf), qdf_nbuf_data(wbuf), buf_len); + qdf_nbuf_free(wbuf); + wh = (struct ieee80211_frame *)qdf_nbuf_data(nbuf); type = (wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK; sub_type = (wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; diff --git a/drivers/staging/qcacld-3.0/configs/default_defconfig b/drivers/staging/qcacld-3.0/configs/default_defconfig index ef153325d613..e6e4a3a15a4a 100644 --- a/drivers/staging/qcacld-3.0/configs/default_defconfig +++ b/drivers/staging/qcacld-3.0/configs/default_defconfig @@ -75,6 +75,7 @@ ifeq ($(CONFIG_ARCH_QCS40X), y) CONFIG_MULTI_IF_LOG := y CONFIG_DFS_PRI_MULTIPLIER := y CONFIG_DFS_OVERRIDE_RF_THRESHOLD := y + CONFIG_RX_THREAD_PRIORITY := y endif #Flag to enable Legacy Fast Roaming2(LFR2) diff --git a/drivers/staging/qcacld-3.0/configs/qcs40x.snoc.perf_defconfig b/drivers/staging/qcacld-3.0/configs/qcs40x.snoc.perf_defconfig index 0452f8be72be..b5b63f68a79c 100644 --- a/drivers/staging/qcacld-3.0/configs/qcs40x.snoc.perf_defconfig +++ b/drivers/staging/qcacld-3.0/configs/qcs40x.snoc.perf_defconfig @@ -195,5 +195,5 @@ CONFIG_CFG_NUM_WMI_MGMT_EVENT_HISTORY := 16 CONFIG_CFG_NUM_TX_RX_HISTOGRAM := 16 # CONFIG_CFG_NUM_RX_IND_RECORD := 1024 - +CONFIG_RX_THREAD_PRIORITY := y ################################### diff --git a/drivers/staging/qcacld-3.0/core/cds/src/cds_regdomain.c b/drivers/staging/qcacld-3.0/core/cds/src/cds_regdomain.c index f8f55d2a4c8c..b66e62b8c740 100644 --- a/drivers/staging/qcacld-3.0/core/cds/src/cds_regdomain.c +++ b/drivers/staging/qcacld-3.0/core/cds/src/cds_regdomain.c @@ -281,7 +281,7 @@ static const struct country_code_to_reg_dmn g_all_countries[] = { {CTRY_TRINIDAD_Y_TOBAGO, FCC3_WORLD, "TT", "TRINIDAD AND TOBAGO"}, {CTRY_TUNISIA, ETSI3_WORLD, "TN", "TUNISIA"}, {CTRY_TURKEY, ETSI1_WORLD, "TR", "TURKEY"}, - {CTRY_TURKS_AND_CAICOS, FCC3_WORLD, "TC" "TURKS AND CAICOS"}, + {CTRY_TURKS_AND_CAICOS, FCC3_WORLD, "TC", "TURKS AND CAICOS"}, {CTRY_UGANDA, FCC3_WORLD, "UG", "UGANDA"}, {CTRY_UKRAINE, ETSI9_WORLD, "UA", "UKRAINE"}, {CTRY_UAE, FCC3_WORLD, "AE", "UNITED ARAB EMIRATES"}, @@ -293,7 +293,7 @@ static const struct country_code_to_reg_dmn g_all_countries[] = { {CTRY_VENEZUELA, FCC2_ETSIC, "VE", "VENEZUELA"}, {CTRY_VIET_NAM, FCC3_WORLD, "VN", "VIETNAM"}, {CTRY_VIRGIN_ISLANDS, FCC3_FCCA, "VI", "VIRGIN ISLANDS"}, - {CTRY_WALLIS_AND_FUTUNA, ETSI1_WORLD, "WF" "WALLIS"}, + {CTRY_WALLIS_AND_FUTUNA, ETSI1_WORLD, "WF", "WALLIS"}, {CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN"}, {CTRY_ZIMBABWE, ETSI1_WORLD, "ZW", "ZIMBABWE"}, {CTRY_JAPAN15, MKK5_MKKC, "JP", "JAPAN"}, diff --git a/drivers/staging/qcacld-3.0/core/cds/src/cds_sched.c b/drivers/staging/qcacld-3.0/core/cds/src/cds_sched.c index 99f89c4621f8..0da486925705 100644 --- a/drivers/staging/qcacld-3.0/core/cds/src/cds_sched.c +++ b/drivers/staging/qcacld-3.0/core/cds/src/cds_sched.c @@ -795,7 +795,15 @@ static int cds_ol_rx_thread(void *arg) bool shutdown = false; int status; +#ifdef RX_THREAD_PRIORITY + struct sched_param scheduler_params = {0}; + + scheduler_params.sched_priority = 1; + sched_setscheduler(current, SCHED_FIFO, &scheduler_params); +#else set_user_nice(current, -1); +#endif + #ifdef MSM_PLATFORM set_wake_up_idle(true); #endif diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.c index c53d00b4aa41..bc83a452b27e 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.c @@ -138,7 +138,7 @@ int ol_peer_recovery_notifier_cb(struct notifier_block *block, struct qdf_notifer_data *notif_data = data; qdf_notif_block *notif_block; struct ol_txrx_peer_t *peer; - struct peer_hang_data hang_data; + struct peer_hang_data hang_data = {0}; enum peer_debug_id_type dbg_id; if (!data || !block) diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_cfg.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_cfg.h index 269b2a7ede66..29aa08e1e0b5 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_cfg.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_cfg.h @@ -8512,6 +8512,35 @@ enum hdd_link_speed_rpt_type { #define CFG_NDP_KEEP_ALIVE_PERIOD_MAX (30) #define CFG_NDP_KEEP_ALIVE_PERIOD_DEFAULT (20) +/* + * + * nan_feature_config - Bitmap to enable/disable a particular NAN/NDP feature + * + * @Min: 0 + * @Max: 0xFFFF + * @Default: 0x1 + * + * This parameter helps to enable/disable a particular feature config by setting + * corresponding bit and send to firmware through the VDEV param + * WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES + * Acceptable values for this: + * BIT(0): Allow DW configuration from framework in sync role. + * If this is not set, firmware shall follow the spec/default behavior. + * BIT(1) to BIT(31): Reserved + * + * Related: None + * + * Supported Feature: NAN + * + * Usage: External + * + * + */ +#define CFG_NAN_FEATURE_CONFIG "nan_feature_config" +#define CFG_NAN_FEATURE_CONFIG_MIN (0) +#define CFG_NAN_FEATURE_CONFIG_MAX (0xFFFF) +#define CFG_NAN_FEATURE_CONFIG_DEFAULT (1) + /* * * gSupportMp0Discovery - To support discovery of NAN cluster with @@ -17571,6 +17600,28 @@ enum hdd_external_acs_policy { #define CFG_DISABLE_4WAY_HS_OFFLOAD_MAX (1) #define CFG_DISABLE_4WAY_HS_OFFLOAD_DEFAULT (0) +/* + * + * nb_commands_interval - Used to rate limit nb commands from userspace + * + * @Min: 0 + * @Max: 10 + * Default: 3 + * + * This ini is used to specify the duration in which any supp. nb command from + * userspace will not be processed completely in driver. For ex, the default + * value of 3 seconds signifies that consecutive commands within that + * time will not be processed fully. + * + * Usage: Internal + * + * + */ +#define CFG_NB_COMMANDS_RATE_LIMIT "nb_commands_interval" +#define CFG_NB_COMMANDS_RATE_LIMIT_MIN (0) +#define CFG_NB_COMMANDS_RATE_LIMIT_MAX (10) +#define CFG_NB_COMMANDS_RATE_LIMIT_DEFAULT (3) + /* * * enable_time_sync_ftm - Time Sync FTM feature support @@ -18294,6 +18345,7 @@ struct hdd_config { bool nan_separate_iface_support; uint16_t ndp_keep_alive_period; bool support_mp0_discovery; + uint32_t nan_feature_config; #endif bool enableSelfRecovery; #ifdef FEATURE_WLAN_FORCE_SAP_SCC @@ -18780,6 +18832,7 @@ struct hdd_config { bool ShortGI160MhzEnable; uint32_t vendor_roam_score_algorithm; uint32_t dp_proto_event_bitmap; + uint8_t nb_commands_interval; #ifdef SAR_SAFETY_FEATURE uint32_t sar_safety_timeout; diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_main.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_main.h index 9cb53096766e..3e0274993f95 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_main.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_main.h @@ -138,6 +138,29 @@ struct hdd_apf_context { #define NUM_TX_QUEUES 4 #endif +/* HDD_IS_RATE_LIMIT_REQ: Macro helper to implement rate limiting + * @flag: The flag to determine if limiting is required or not + * @rate: The number of seconds within which if multiple commands come, the + * flag will be set to true + * + * If the function in which this macro is used is called multiple times within + * "rate" number of seconds, the "flag" will be set to true which can be used + * to reject/take appropriate action. + */ +#define HDD_IS_RATE_LIMIT_REQ(flag, rate)\ + do {\ + static ulong __last_ticks;\ + ulong __ticks = jiffies;\ + flag = false; \ + if (!time_after(__ticks,\ + __last_ticks + rate * HZ)) {\ + flag = true; \ + } \ + else { \ + __last_ticks = __ticks;\ + } \ + } while (0) + /* * API in_compat_syscall() is introduced in 4.6 kernel to check whether we're * in a compat syscall or not. It is a new way to query the syscall type, which @@ -4131,4 +4154,18 @@ static inline void hdd_send_update_owe_info_event(struct hdd_adapter *adapter, } #endif +#if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) +/** + * hdd_beacon_latency_event_cb() - Callback function to get latency level + * @latency_level: latency level received from firmware + * + * Return: None + */ +void hdd_beacon_latency_event_cb(uint32_t latency_level); +#else +static inline void hdd_beacon_latency_event_cb(uint32_t latency_level) +{ +} +#endif + #endif /* end #if !defined(WLAN_HDD_MAIN_H) */ diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg.c index 4053b29a7713..f9c5e772667e 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg.c @@ -3295,6 +3295,13 @@ struct reg_table_entry g_registry_table[] = { CFG_SUPPORT_MP0_DISCOVERY_DEFAULT, CFG_SUPPORT_MP0_DISCOVERY_MIN, CFG_SUPPORT_MP0_DISCOVERY_MAX), + + REG_VARIABLE(CFG_NAN_FEATURE_CONFIG, WLAN_PARAM_Integer, + struct hdd_config, nan_feature_config, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NAN_FEATURE_CONFIG_DEFAULT, + CFG_NAN_FEATURE_CONFIG_MIN, + CFG_NAN_FEATURE_CONFIG_MAX), #endif REG_VARIABLE(CFG_ENABLE_SELF_RECOVERY, WLAN_PARAM_Integer, @@ -6355,6 +6362,14 @@ struct reg_table_entry g_registry_table[] = { CFG_DISABLE_4WAY_HS_OFFLOAD_DEFAULT, CFG_DISABLE_4WAY_HS_OFFLOAD_MIN, CFG_DISABLE_4WAY_HS_OFFLOAD_MAX), + + REG_VARIABLE(CFG_NB_COMMANDS_RATE_LIMIT, WLAN_PARAM_Integer, + struct hdd_config, nb_commands_interval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NB_COMMANDS_RATE_LIMIT_DEFAULT, + CFG_NB_COMMANDS_RATE_LIMIT_MIN, + CFG_NB_COMMANDS_RATE_LIMIT_MAX), + #ifdef FEATURE_WLAN_TIME_SYNC_FTM REG_VARIABLE(CFG_ENABLE_TIME_SYNC_FTM, WLAN_PARAM_Integer, struct hdd_config, time_sync_ftm_enable, diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c index f64be7ccd1fa..492ba06ea00a 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c @@ -4725,12 +4725,19 @@ hdd_store_nss_chains_cfg_in_vdev(struct hdd_adapter *adapter) { struct mlme_nss_chains vdev_ini_cfg; struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct wlan_objmgr_vdev *vdev; /* Populate the nss chain params from ini for this vdev type */ hdd_fill_nss_chain_params(hdd_ctx, &vdev_ini_cfg, adapter->device_mode); + vdev = hdd_objmgr_get_vdev(adapter); /* Store the nss chain config into the vdev */ - sme_store_nss_chains_cfg_in_vdev(adapter->vdev, &vdev_ini_cfg); + if (vdev) { + sme_store_nss_chains_cfg_in_vdev(adapter->vdev, &vdev_ini_cfg); + hdd_objmgr_put_vdev(vdev); + } else { + hdd_err("Vdev is NULL"); + } } #ifdef WLAN_FEATURE_NAN @@ -4746,11 +4753,32 @@ static void hdd_configure_nan_support_mp0_discovery(struct hdd_adapter *adapter) VDEV_CMD); } } + +static void hdd_set_nan_feature_config(struct hdd_adapter *adapter) +{ + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + + if (!wlan_hdd_nan_is_supported(hdd_ctx)) + return; + + if (QDF_NAN_DISC_MODE == adapter->device_mode || + (QDF_STA_MODE == adapter->device_mode && + (!hdd_ctx->nan_seperate_vdev_supported || + !wlan_hdd_nan_separate_iface_supported(hdd_ctx)))) + sme_cli_set_command(adapter->session_id, + WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES, + hdd_ctx->config->nan_feature_config, + VDEV_CMD); +} #else static inline void hdd_configure_nan_support_mp0_discovery( struct hdd_adapter *adapter) { } + +static inline void hdd_set_nan_feature_config(struct hdd_adapter *adapter) +{ +} #endif int hdd_vdev_create(struct hdd_adapter *adapter, @@ -4855,6 +4883,7 @@ int hdd_vdev_create(struct hdd_adapter *adapter, hdd_nofl_debug("vdev %d created successfully", adapter->session_id); hdd_configure_nan_support_mp0_discovery(adapter); + hdd_set_nan_feature_config(adapter); return 0; @@ -6260,6 +6289,14 @@ QDF_STATUS hdd_stop_adapter_ext(struct hdd_context *hdd_ctx, /* Diassociate with all the peers before stop ap post */ if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) wlan_hdd_del_station(adapter); + + qdf_ret_status = + sme_roam_del_pmkid_from_cache(hdd_ctx->mac_handle, + adapter->session_id, + NULL, true); + if (QDF_IS_STATUS_ERROR(qdf_ret_status)) + hdd_err("Cannot flush PMKSA Cache"); + /* Flush IPA exception path packets */ sap_config = &adapter->session.ap.sap_config; if (sap_config) @@ -8640,8 +8677,13 @@ static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, cpumask_t *pm_qos_cpu_mask) { cpumask_copy(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask); + /* Latency value to be read from INI */ - pm_qos_update_request(&hdd_ctx->pm_qos_req, 1); + if (cpumask_empty(pm_qos_cpu_mask)) + pm_qos_update_request(&hdd_ctx->pm_qos_req, + PM_QOS_DEFAULT_VALUE); + else + pm_qos_update_request(&hdd_ctx->pm_qos_req, 1); } #ifdef CONFIG_SMP @@ -8654,6 +8696,8 @@ static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, static inline void hdd_update_pm_qos_affine_cores(struct hdd_context *hdd_ctx) { hdd_ctx->pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; + qdf_cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine); + hdd_pm_qos_update_cpu_mask(&hdd_ctx->pm_qos_req.cpus_affine, false); } #else static inline void hdd_update_pm_qos_affine_cores(struct hdd_context *hdd_ctx) @@ -8665,6 +8709,8 @@ static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx) hdd_update_pm_qos_affine_cores(hdd_ctx); pm_qos_add_request(&hdd_ctx->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); + hdd_info("Set cpu_mask %*pb for affine_cores", + cpumask_pr_args(&hdd_ctx->pm_qos_req.cpus_affine)); } static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx) @@ -8899,13 +8945,13 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx, hdd_ctx->hdd_txrx_hist[index].qtime = qdf_get_log_timestamp(); hdd_ctx->hdd_txrx_hist_idx++; hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK; - } /* Clear all the mask if no silver/gold vote is required */ if (next_vote_level < PLD_BUS_WIDTH_MEDIUM) cpumask_clear(&pm_qos_cpu_mask); hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask); + } hdd_display_periodic_stats(hdd_ctx, (total_pkts > 0) ? true : false); @@ -13163,6 +13209,12 @@ int hdd_register_cb(struct hdd_context *hdd_ctx) sme_set_roam_scan_ch_event_cb(mac_handle, hdd_get_roam_scan_ch_cb); + status = sme_set_beacon_latency_event_cb(mac_handle, + hdd_beacon_latency_event_cb); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err_rl("Register beacon latency event callback failed"); + + hdd_exit(); return ret; @@ -16326,6 +16378,20 @@ void hdd_hidden_ssid_enable_roaming(hdd_handle_t hdd_handle, uint8_t vdev_id) wlan_hdd_enable_roaming(adapter); } +#if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) +void hdd_beacon_latency_event_cb(uint32_t latency_level) +{ + struct hdd_context *hdd_ctx; + + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + if (!hdd_ctx) { + hdd_err_rl("Invalid HDD_CTX"); + return; + } + wlan_hdd_set_wlm_mode(hdd_ctx, latency_level); +} +#endif + #ifdef WLAN_FEATURE_PKT_CAPTURE /** diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_power.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_power.c index c87e6ccdb4ce..07a130261daa 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_power.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_power.c @@ -2332,6 +2332,7 @@ static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev); int status; struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + static bool is_rate_limited; hdd_enter_dev(ndev); @@ -2356,10 +2357,14 @@ static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, return -EINVAL; } + HDD_IS_RATE_LIMIT_REQ(is_rate_limited, + hdd_ctx->config->nb_commands_interval); + mutex_lock(&hdd_ctx->iface_change_lock); - if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) { + if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED || + is_rate_limited) { mutex_unlock(&hdd_ctx->iface_change_lock); - hdd_debug("Driver Module not enabled return success"); + hdd_debug("Modules not enabled/rate limited, use cached stats"); /* Send cached data to upperlayer*/ *dbm = adapter->hdd_stats.class_a_stat.max_pwr; return 0; diff --git a/drivers/staging/qcacld-3.0/core/mac/inc/qwlan_version.h b/drivers/staging/qcacld-3.0/core/mac/inc/qwlan_version.h index 80b3729ec5ab..cf9473de94f2 100644 --- a/drivers/staging/qcacld-3.0/core/mac/inc/qwlan_version.h +++ b/drivers/staging/qcacld-3.0/core/mac/inc/qwlan_version.h @@ -32,9 +32,9 @@ #define QWLAN_VERSION_MAJOR 5 #define QWLAN_VERSION_MINOR 2 #define QWLAN_VERSION_PATCH 03 -#define QWLAN_VERSION_EXTRA "V" -#define QWLAN_VERSION_BUILD 28 +#define QWLAN_VERSION_EXTRA "I" +#define QWLAN_VERSION_BUILD 29 -#define QWLAN_VERSIONSTR "5.2.03.28V" +#define QWLAN_VERSIONSTR "5.2.03.29I" #endif /* QWLAN_VERSION_H */ diff --git a/drivers/staging/qcacld-3.0/core/sme/inc/sme_api.h b/drivers/staging/qcacld-3.0/core/sme/inc/sme_api.h index c1c5da5ef686..61add962964c 100644 --- a/drivers/staging/qcacld-3.0/core/sme/inc/sme_api.h +++ b/drivers/staging/qcacld-3.0/core/sme/inc/sme_api.h @@ -3238,4 +3238,27 @@ QDF_STATUS sme_handle_peer_cleanup(tHalHandle hal, uint8_t vdev_id); */ QDF_STATUS sme_update_owe_info(tpAniSirGlobal mac, tSirSmeAssocInd *assoc_ind); + +#if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) +/** + * sme_set_beacon_latency_event_cb() - Register beacon latency IE callback + * @mac_handle: Opaque handle to the MAC context + * @beacon_latency_event_cb: callback to be registered + * + * Return: QDF_STATUS + */ +QDF_STATUS +sme_set_beacon_latency_event_cb(mac_handle_t mac_handle, + void (*beacon_latency_event_cb) + (uint32_t latency_level)); +#else +static inline QDF_STATUS +sme_set_beacon_latency_event_cb(mac_handle_t mac_handle, + void (*beacon_latency_event_cb) + (uint32_t latency_level)) +{ + return QDF_STATUS_SUCCESS; +} +#endif + #endif /* #if !defined( __SME_API_H ) */ diff --git a/drivers/staging/qcacld-3.0/core/sme/inc/sme_internal.h b/drivers/staging/qcacld-3.0/core/sme/inc/sme_internal.h index bf7f34f3eada..d82b2630d774 100644 --- a/drivers/staging/qcacld-3.0/core/sme/inc/sme_internal.h +++ b/drivers/staging/qcacld-3.0/core/sme/inc/sme_internal.h @@ -355,6 +355,9 @@ typedef struct tagSmeStruct { sme_get_raom_scan_ch_Callback roam_scan_ch_callback; void *roam_scan_ch_get_context; #endif +#if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) + void (*beacon_latency_event_cb)(uint32_t latency_level); +#endif } tSmeStruct, *tpSmeStruct; #endif /* #if !defined( __SMEINTERNAL_H ) */ diff --git a/drivers/staging/qcacld-3.0/core/sme/src/common/sme_api.c b/drivers/staging/qcacld-3.0/core/sme/src/common/sme_api.c index 8721e9cfa1e5..d1c4ebafab6f 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/common/sme_api.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/common/sme_api.c @@ -17289,3 +17289,24 @@ QDF_STATUS sme_update_owe_info(tpAniSirGlobal mac, { return csr_update_owe_info(mac, assoc_ind); } + +#if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) +QDF_STATUS +sme_set_beacon_latency_event_cb(mac_handle_t mac_handle, + void (*beacon_latency_event_cb) + (uint32_t latency_level)) +{ + QDF_STATUS qdf_status; + struct sAniSirGlobal *mac = MAC_CONTEXT(mac_handle); + + qdf_status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_ERROR(qdf_status)) { + sme_err("Failed to acquire sme lock; status: %d", qdf_status); + return qdf_status; + } + mac->sme.beacon_latency_event_cb = beacon_latency_event_cb; + sme_release_global_lock(&mac->sme); + + return qdf_status; +} +#endif diff --git a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_roam.c b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_roam.c index 4f4965a99352..eb55076d5c07 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_roam.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_roam.c @@ -7573,16 +7573,37 @@ bool csr_roam_is_fast_roam_enabled(tpAniSirGlobal pMac, uint32_t sessionId) } } -static void csr_update_scan_entry_associnfo(tpAniSirGlobal mac_ctx, - struct bss_info *bss, enum scan_entry_connection_state state) +static +void csr_update_scan_entry_associnfo(tpAniSirGlobal mac_ctx, + struct csr_roam_session *session, + enum scan_entry_connection_state state) { QDF_STATUS status; struct mlme_info mlme; + struct bss_info bss; + tCsrRoamConnectedProfile *conn_profile; - sme_debug("Update MLME info in scan database. bssid %pM state: %d", - bss->bssid.bytes, state); + if (!session) { + sme_debug("session is NULL"); + return; + } + conn_profile = &session->connectedProfile; + if (!CSR_IS_INFRASTRUCTURE(conn_profile)) { + sme_debug("not infra return"); + return; + } + + qdf_copy_macaddr(&bss.bssid, &conn_profile->bssid); + bss.chan = conn_profile->operationChannel; + bss.ssid.length = conn_profile->SSID.length; + qdf_mem_copy(&bss.ssid.ssid, &conn_profile->SSID.ssId, + bss.ssid.length); + + sme_debug("Update MLME info in scan database. bssid %pM ssid:%.*s chan %d state: %d", + bss.bssid.bytes, bss.ssid.length, bss.ssid.ssid, bss.chan, + state); mlme.assoc_state = state; - status = ucfg_scan_update_mlme_by_bssinfo(mac_ctx->pdev, bss, &mlme); + status = ucfg_scan_update_mlme_by_bssinfo(mac_ctx->pdev, &bss, &mlme); if (QDF_IS_STATUS_ERROR(status)) sme_debug("Failed to update the MLME info in scan entry"); } @@ -7736,7 +7757,6 @@ static void csr_roam_process_results_default(tpAniSirGlobal mac_ctx, struct csr_roam_session *session; struct csr_roam_info *roam_info; QDF_STATUS status; - struct bss_info bss_info; struct csr_roam_connectedinfo *prev_connect_info = NULL; if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { @@ -7752,14 +7772,17 @@ static void csr_roam_process_results_default(tpAniSirGlobal mac_ctx, sme_debug("Assoc ref count: %d", session->bRefAssocStartCnt); - if (CSR_IS_INFRASTRUCTURE(&session->connectedProfile)) { - qdf_copy_macaddr(&bss_info.bssid, - &session->connectedProfile.bssid); - bss_info.chan = session->connectedProfile.operationChannel; - bss_info.ssid.length = session->connectedProfile.SSID.length; - qdf_mem_copy(&bss_info.ssid.ssid, - &session->connectedProfile.SSID.ssId, - bss_info.ssid.length); + /* Update AP's assoc info in scan before removing connectedProfile */ + switch (cmd->u.roamCmd.roamReason) { + case eCsrSmeIssuedDisassocForHandoff: + case eCsrForcedDisassoc: + case eCsrForcedDeauth: + case eCsrForcedDisassocMICFailure: + csr_update_scan_entry_associnfo(mac_ctx, session, + SCAN_ENTRY_CON_STATE_NONE); + break; + default: + break; } if (CSR_IS_INFRASTRUCTURE(&session->connectedProfile) || CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(mac_ctx, session_id)) { @@ -7878,8 +7901,6 @@ static void csr_roam_process_results_default(tpAniSirGlobal mac_ctx, SME_QOS_CSR_DISCONNECT_IND, NULL); #endif - csr_update_scan_entry_associnfo(mac_ctx, &bss_info, - SCAN_ENTRY_CON_STATE_NONE); csr_roam_link_down(mac_ctx, session_id); if (mac_ctx->roam.deauthRspStatus == eSIR_SME_DEAUTH_STATUS) { @@ -8351,7 +8372,6 @@ static void csr_roam_process_join_res(tpAniSirGlobal mac_ctx, struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info; tSirSmeJoinRsp *join_rsp = (tSirSmeJoinRsp *) context; uint32_t len; - struct bss_info bss_info; if (!join_rsp) { sme_err("join_rsp is NULL"); @@ -8703,15 +8723,8 @@ static void csr_roam_process_join_res(tpAniSirGlobal mac_ctx, eCSR_ROAM_RESULT_ASSOCIATED); } - qdf_copy_macaddr(&bss_info.bssid, &conn_profile->bssid); - bss_info.chan = conn_profile->operationChannel; - bss_info.ssid.length = - conn_profile->SSID.length; - qdf_mem_copy(&bss_info.ssid.ssid, - &conn_profile->SSID.ssId, - bss_info.ssid.length); - csr_update_scan_entry_associnfo(mac_ctx, - &bss_info, SCAN_ENTRY_CON_STATE_ASSOC); + csr_update_scan_entry_associnfo(mac_ctx, session, + SCAN_ENTRY_CON_STATE_ASSOC); csr_roam_completion(mac_ctx, session_id, NULL, cmd, eCSR_ROAM_RESULT_NONE, true); csr_reset_pmkid_candidate_list(mac_ctx, session_id); @@ -12940,7 +12953,10 @@ csr_roam_chk_lnk_disassoc_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr) return; } - /* Update the disconnect stats */ + csr_update_scan_entry_associnfo(mac_ctx, + session, SCAN_ENTRY_CON_STATE_NONE); + + /* Update the disconnect stats */ session->disconnect_stats.disconnection_cnt++; session->disconnect_stats.disassoc_by_peer++; @@ -13015,6 +13031,8 @@ csr_roam_chk_lnk_deauth_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr) return; } + csr_update_scan_entry_associnfo(mac_ctx, + session, SCAN_ENTRY_CON_STATE_NONE); /* Update the disconnect stats */ switch (pDeauthInd->reasonCode) { case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON: @@ -24207,6 +24225,10 @@ static QDF_STATUS csr_process_roam_sync_callback(tpAniSirGlobal mac_ctx, bss_desc, ies_local); ps_global_info->remain_in_power_active_till_dhcp = false; session->connectState = eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED; + + /* Remove old BSSID mlme info from scan cache */ + csr_update_scan_entry_associnfo(mac_ctx, session, + SCAN_ENTRY_CON_STATE_NONE); roam_info = qdf_mem_malloc(sizeof(struct csr_roam_info)); if (NULL == roam_info) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, @@ -24227,6 +24249,9 @@ static QDF_STATUS csr_process_roam_sync_callback(tpAniSirGlobal mac_ctx, session->pCurRoamProfile, bss_desc, ies_local); + /* Add new mlme info to new BSSID after upting connectedProfile */ + csr_update_scan_entry_associnfo(mac_ctx, session, + SCAN_ENTRY_CON_STATE_ASSOC); csr_roam_save_security_rsp_ie(mac_ctx, session_id, session->pCurRoamProfile->negotiatedAuthType, bss_desc, ies_local); diff --git a/drivers/staging/qcacld-3.0/core/wma/inc/wma_internal.h b/drivers/staging/qcacld-3.0/core/wma/inc/wma_internal.h index 30e2a4af8636..8a88e68f6696 100644 --- a/drivers/staging/qcacld-3.0/core/wma/inc/wma_internal.h +++ b/drivers/staging/qcacld-3.0/core/wma/inc/wma_internal.h @@ -1308,6 +1308,26 @@ int wma_unified_beacon_debug_stats_event_handler(void *handle, uint8_t *cmd_param_info, uint32_t len); +#if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) +/** + * wma_vdev_bcn_latency_event_handler() - Get the latency info received in bcn + * @handle: WMA handle + * @event: data in event + * @len: length + * + * Return: 0 for success or error code + */ +int wma_vdev_bcn_latency_event_handler(void *handle, uint8_t *event, + uint32_t len); +#else +static inline int wma_vdev_bcn_latency_event_handler(void *handle, + uint8_t *event, + uint32_t len) +{ + return 0; +} +#endif + #ifdef FEATURE_WLAN_DIAG_SUPPORT /** * wma_sta_kickout_event()- send sta kickout event diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_features.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_features.c index c760ea33d6f5..49f2c64a8d48 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_features.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_features.c @@ -5837,6 +5837,46 @@ int wma_unified_beacon_debug_stats_event_handler(void *handle, } #endif +#if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) +int +wma_vdev_bcn_latency_event_handler(void *handle, + uint8_t *event_info, + uint32_t len) +{ + WMI_VDEV_BCN_LATENCY_EVENTID_param_tlvs *param_buf = NULL; + wmi_vdev_bcn_latency_fixed_param *bcn_latency = NULL; + tpAniSirGlobal mac = + (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE); + uint32_t latency_level; + + param_buf = (WMI_VDEV_BCN_LATENCY_EVENTID_param_tlvs *)event_info; + if (!param_buf) { + wma_err("Invalid bcn latency event"); + return -EINVAL; + } + + bcn_latency = param_buf->fixed_param; + if (!bcn_latency) { + wma_debug("beacon latency event fixed param is NULL"); + return -EINVAL; + } + + /* Map the latency value to the level which host expects + * 1 - normal, 2 - moderate, 3 - low, 4 - ultralow + */ + latency_level = bcn_latency->latency_level + 1; + if (latency_level < 1 || latency_level > 4) { + wma_debug("invalid beacon latency level value"); + return -EINVAL; + } + + /* Call the registered sme callback */ + mac->sme.beacon_latency_event_cb(latency_level); + + return 0; +} +#endif + int wma_chan_info_event_handler(void *handle, uint8_t *event_buf, uint32_t len) { diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_main.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_main.c index 38f025e5bb21..fcfd6a4ec347 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_main.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_main.c @@ -3566,6 +3566,12 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, WMA_RX_SERIALIZER_CTX); #endif +#if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) + wmi_unified_register_event_handler(wma_handle->wmi_handle, + wmi_vdev_bcn_latency_event_id, + wma_vdev_bcn_latency_event_handler, + WMA_RX_SERIALIZER_CTX); +#endif /* register for linkspeed response event */ wmi_unified_register_event_handler(wma_handle->wmi_handle, wmi_peer_estimated_linkspeed_event_id, diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c index f6d71587b803..02f286a580c3 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c @@ -53,7 +53,7 @@ int rtw_init_mlme_priv(struct adapter *padapter) memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid)); - pbuf = vzalloc(MAX_BSS_CNT * (sizeof(struct wlan_network))); + pbuf = vzalloc(array_size(MAX_BSS_CNT, sizeof(struct wlan_network))); if (!pbuf) { res = _FAIL; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index cbf8eb4a049d..afdd79d9dd93 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -597,8 +597,9 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee, bool bMatchWinStart = false, bPktInBuf = false; IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): Seq is %d,pTS->RxIndicateSeq is %d, WinSize is %d\n",__func__,SeqNum,pTS->RxIndicateSeq,WinSize); - prxbIndicateArray = kmalloc(sizeof(struct ieee80211_rxb *) * - REORDER_WIN_SIZE, GFP_KERNEL); + prxbIndicateArray = kmalloc_array(REORDER_WIN_SIZE, + sizeof(struct ieee80211_rxb *), + GFP_KERNEL); if (!prxbIndicateArray) return; diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index fbbd1b59dc11..bbc2fadf65f5 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -1686,8 +1686,8 @@ static short rtl8192_usb_initendpoints(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); - priv->rx_urb = kmalloc(sizeof(struct urb *) * (MAX_RX_URB + 1), - GFP_KERNEL); + priv->rx_urb = kmalloc_array(MAX_RX_URB + 1, sizeof(struct urb *), + GFP_KERNEL); if (!priv->rx_urb) return -ENOMEM; diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme.c b/drivers/staging/rtl8723bs/core/rtw_mlme.c index cb8a95aabd6c..278edf4a93dd 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c @@ -47,7 +47,7 @@ sint _rtw_init_mlme_priv(struct adapter *padapter) memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid)); - pbuf = vzalloc(MAX_BSS_CNT * (sizeof(struct wlan_network))); + pbuf = vzalloc(array_size(MAX_BSS_CNT, sizeof(struct wlan_network))); if (pbuf == NULL) { res = _FAIL; diff --git a/drivers/staging/rtlwifi/efuse.c b/drivers/staging/rtlwifi/efuse.c index 6d5e657017c6..711d9ef8908b 100644 --- a/drivers/staging/rtlwifi/efuse.c +++ b/drivers/staging/rtlwifi/efuse.c @@ -248,15 +248,15 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) } /* allocate memory for efuse_tbl and efuse_word */ - efuse_tbl = kzalloc(rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE] * - sizeof(u8), GFP_ATOMIC); + efuse_tbl = kzalloc(rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE], + GFP_ATOMIC); if (!efuse_tbl) return; - efuse_word = kzalloc(EFUSE_MAX_WORD_UNIT * sizeof(u16 *), GFP_ATOMIC); + efuse_word = kcalloc(EFUSE_MAX_WORD_UNIT, sizeof(u16 *), GFP_ATOMIC); if (!efuse_word) goto out; for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { - efuse_word[i] = kzalloc(efuse_max_section * sizeof(u16), + efuse_word[i] = kcalloc(efuse_max_section, sizeof(u16), GFP_ATOMIC); if (!efuse_word[i]) goto done; diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c index 7cdce87f3051..3a19e43ed341 100644 --- a/drivers/staging/rts5208/ms.c +++ b/drivers/staging/rts5208/ms.c @@ -2618,7 +2618,7 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no) segment = &ms_card->segment[seg_no]; if (!segment->l2p_table) { - segment->l2p_table = vmalloc(table_size * 2); + segment->l2p_table = vmalloc(array_size(table_size, 2)); if (!segment->l2p_table) { rtsx_trace(chip); goto BUILD_FAIL; diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c index 4ad472dd9daf..8a823466ca2b 100644 --- a/drivers/staging/rts5208/rtsx_chip.c +++ b/drivers/staging/rts5208/rtsx_chip.c @@ -1660,13 +1660,13 @@ int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, dev_dbg(rtsx_dev(chip), "dw_len = %d\n", dw_len); - data = vzalloc(dw_len * 4); + data = vzalloc(array_size(dw_len, 4)); if (!data) { rtsx_trace(chip); return STATUS_NOMEM; } - mask = vzalloc(dw_len * 4); + mask = vzalloc(array_size(dw_len, 4)); if (!mask) { vfree(data); rtsx_trace(chip); @@ -1721,7 +1721,7 @@ int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, dev_dbg(rtsx_dev(chip), "dw_len = %d\n", dw_len); - data = vmalloc(dw_len * 4); + data = vmalloc(array_size(dw_len, 4)); if (!data) { rtsx_trace(chip); return STATUS_NOMEM; diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c index 419dba89af06..6eb3ba56937d 100644 --- a/drivers/staging/unisys/visorhba/visorhba_main.c +++ b/drivers/staging/unisys/visorhba/visorhba_main.c @@ -873,7 +873,7 @@ static void do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, if (cmdrsp->scsi.no_disk_result == 0) return; - buf = kzalloc(sizeof(char) * 36, GFP_KERNEL); + buf = kzalloc(36, GFP_KERNEL); if (!buf) return; diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c index f05e9af4fe81..77f1f4c91acc 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c @@ -2086,7 +2086,7 @@ dump_phys_mem(void *virt_addr, u32 num_bytes) num_pages = DIV_ROUND_UP(offset + num_bytes, PAGE_SIZE); - pages = kmalloc(sizeof(struct page *) * num_pages, GFP_KERNEL); + pages = kmalloc_array(num_pages, sizeof(struct page *), GFP_KERNEL); if (!pages) { vchiq_log_error(vchiq_arm_log_level, "Unable to allocation memory for %d pages\n", diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 0d0be7d8b9d6..b88d086c709a 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -251,10 +251,10 @@ int transport_alloc_session_tags(struct se_session *se_sess, { int rc; - se_sess->sess_cmd_map = kzalloc(tag_num * tag_size, + se_sess->sess_cmd_map = kcalloc(tag_size, tag_num, GFP_KERNEL | __GFP_NOWARN | __GFP_RETRY_MAYFAIL); if (!se_sess->sess_cmd_map) { - se_sess->sess_cmd_map = vzalloc(tag_num * tag_size); + se_sess->sess_cmd_map = vzalloc(array_size(tag_size, tag_num)); if (!se_sess->sess_cmd_map) { pr_err("Unable to allocate se_sess->sess_cmd_map\n"); return -ENOMEM; diff --git a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c index c719167e9f28..45e7e5cbdffb 100644 --- a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c +++ b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c @@ -96,7 +96,7 @@ int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp, } *trt_count = p->package.count; - trts = kzalloc(*trt_count * sizeof(struct trt), GFP_KERNEL); + trts = kcalloc(*trt_count, sizeof(struct trt), GFP_KERNEL); if (!trts) { result = -ENOMEM; goto end; @@ -178,7 +178,7 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp, /* ignore p->package.elements[0], as this is _ART Revision field */ *art_count = p->package.count - 1; - arts = kzalloc(*art_count * sizeof(struct art), GFP_KERNEL); + arts = kcalloc(*art_count, sizeof(struct art), GFP_KERNEL); if (!arts) { result = -ENOMEM; goto end; diff --git a/drivers/thermal/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/int340x_thermal/int340x_thermal_zone.c index 145a5c53ff5c..8a11162eab2a 100644 --- a/drivers/thermal/int340x_thermal/int340x_thermal_zone.c +++ b/drivers/thermal/int340x_thermal/int340x_thermal_zone.c @@ -239,9 +239,9 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, if (ACPI_FAILURE(status)) trip_cnt = 0; else { - int34x_thermal_zone->aux_trips = kzalloc( - sizeof(*int34x_thermal_zone->aux_trips) * - trip_cnt, GFP_KERNEL); + int34x_thermal_zone->aux_trips = kcalloc(trip_cnt, + sizeof(*int34x_thermal_zone->aux_trips), + GFP_KERNEL); if (!int34x_thermal_zone->aux_trips) { ret = -ENOMEM; goto err_trip_alloc; diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index 6925765f0e2c..f7fc624933e9 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c @@ -1360,7 +1360,7 @@ __init *thermal_of_build_thermal_zone(struct device_node *np) if (tz->ntrips == 0) /* must have at least one child */ goto finish; - tz->trips = kzalloc(tz->ntrips * sizeof(*tz->trips), GFP_KERNEL); + tz->trips = kcalloc(tz->ntrips, sizeof(*tz->trips), GFP_KERNEL); if (!tz->trips) { ret = -ENOMEM; goto free_tz; @@ -1386,7 +1386,7 @@ __init *thermal_of_build_thermal_zone(struct device_node *np) if (tz->num_tbps == 0) goto finish; - tz->tbps = kzalloc(tz->num_tbps * sizeof(*tz->tbps), GFP_KERNEL); + tz->tbps = kcalloc(tz->num_tbps, sizeof(*tz->tbps), GFP_KERNEL); if (!tz->tbps) { ret = -ENOMEM; goto free_trips; diff --git a/drivers/thermal/qcom/lmh_dbg.c b/drivers/thermal/qcom/lmh_dbg.c index 00e32c235eac..0fd8b36f4315 100644 --- a/drivers/thermal/qcom/lmh_dbg.c +++ b/drivers/thermal/qcom/lmh_dbg.c @@ -198,8 +198,8 @@ static int lmh_parse_and_extract(const char __user *user_buf, size_t count, ret = -EINVAL; goto dfs_cfg_write_exit; } - config_buf = kzalloc((++data_ct) * sizeof(uint32_t), - GFP_KERNEL); + config_buf = kcalloc(++data_ct, sizeof(uint32_t), + GFP_KERNEL); if (!config_buf) { ret = -ENOMEM; goto dfs_cfg_write_exit; diff --git a/drivers/thermal/qcom/qmi_cooling.c b/drivers/thermal/qcom/qmi_cooling.c index 2309f029c859..a9e0d73784ff 100644 --- a/drivers/thermal/qcom/qmi_cooling.c +++ b/drivers/thermal/qcom/qmi_cooling.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -133,6 +133,10 @@ static struct qmi_dev_info device_clients[] = { .dev_name = "mmw_skin3", .type = QMI_CDEV_MAX_LIMIT_TYPE, }, + { + .dev_name = "modem_v2x", + .type = QMI_CDEV_MAX_LIMIT_TYPE, + }, { .dev_name = "cdsp_sw", .type = QMI_CDEV_MAX_LIMIT_TYPE, diff --git a/drivers/thermal/qcom/qti_virtual_sensor.c b/drivers/thermal/qcom/qti_virtual_sensor.c index 747c59c9858f..956173d33d98 100644 --- a/drivers/thermal/qcom/qti_virtual_sensor.c +++ b/drivers/thermal/qcom/qti_virtual_sensor.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -180,6 +180,17 @@ static const struct virtual_sensor_data qti_virtual_sensors[] = { "gpuss-3-usr"}, .logic = VIRT_MAXIMUM, }, + { + .virt_zone_name = "hexa-cpu-max-step", + .num_sensors = 6, + .sensor_names = {"apc1-cpu0-usr", + "apc1-cpu1-usr", + "apc1-cpu2-usr", + "apc1-cpu3-usr", + "cpuss0-usr", + "cpuss1-usr"}, + .logic = VIRT_MAXIMUM, + }, }; int qti_virtual_sensor_register(struct device *dev) diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c index 7d2db23d71a3..ca313c9c3aec 100644 --- a/drivers/thermal/tegra/soctherm.c +++ b/drivers/thermal/tegra/soctherm.c @@ -1352,8 +1352,8 @@ static int tegra_soctherm_probe(struct platform_device *pdev) return PTR_ERR(tegra->clock_soctherm); } - tegra->calib = devm_kzalloc(&pdev->dev, - sizeof(u32) * soc->num_tsensors, + tegra->calib = devm_kcalloc(&pdev->dev, + soc->num_tsensors, sizeof(u32), GFP_KERNEL); if (!tegra->calib) return -ENOMEM; @@ -1372,8 +1372,8 @@ static int tegra_soctherm_probe(struct platform_device *pdev) return err; } - tegra->thermctl_tzs = devm_kzalloc(&pdev->dev, - sizeof(*z) * soc->num_ttgs, + tegra->thermctl_tzs = devm_kcalloc(&pdev->dev, + soc->num_ttgs, sizeof(*z), GFP_KERNEL); if (!tegra->thermctl_tzs) return -ENOMEM; diff --git a/drivers/thermal/thermal-generic-adc.c b/drivers/thermal/thermal-generic-adc.c index ad601e5b4175..173856665430 100644 --- a/drivers/thermal/thermal-generic-adc.c +++ b/drivers/thermal/thermal-generic-adc.c @@ -91,8 +91,9 @@ static int gadc_thermal_read_linear_lookup_table(struct device *dev, return -EINVAL; } - gti->lookup_table = devm_kzalloc(dev, sizeof(*gti->lookup_table) * - ntable, GFP_KERNEL); + gti->lookup_table = devm_kcalloc(dev, + ntable, sizeof(*gti->lookup_table), + GFP_KERNEL); if (!gti->lookup_table) return -ENOMEM; diff --git a/drivers/thermal/tsens2xxx.c b/drivers/thermal/tsens2xxx.c index 8bad35996078..a178978c44da 100644 --- a/drivers/thermal/tsens2xxx.c +++ b/drivers/thermal/tsens2xxx.c @@ -69,7 +69,6 @@ #define TSENS_TM_TRDY_FIRST_ROUND_COMPLETE_SHIFT 3 #define TSENS_INIT_ID 0x5 #define TSENS_RECOVERY_LOOP_COUNT 5 -#define TSENS_RE_INIT_MAX_COUNT 5 static void msm_tsens_convert_temp(int last_temp, int *temp) { @@ -185,6 +184,7 @@ static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp) if (tmdev->tsens_reinit_wa) { struct scm_desc desc = { 0 }; + int scm_cnt = 0, reg_write_cnt = 0; if (atomic_read(&in_tsens_reinit)) { pr_err("%s: tsens re-init is in progress\n", @@ -198,45 +198,87 @@ static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp) tmdev->ops->dbg(tmdev, 0, TSENS_DBG_LOG_BUS_ID_DATA, NULL); - if (tmdev->tsens_reinit_cnt >= - TSENS_RE_INIT_MAX_COUNT) { - pr_err( - "%s: TSENS not recovered after %d re-init\n", - __func__, tmdev->tsens_reinit_cnt); - BUG(); + while (1) { + /* + * Invoke scm call only if SW register write is + * reflecting in controller. If not, wait for + * 2 ms and then retry. + */ + if (reg_write_cnt >= 100) { + msleep(100); + pr_err( + "%s: Tsens write is failed. cnt:%d\n", + __func__, reg_write_cnt); + BUG(); + } + writel_relaxed(BIT(2), + TSENS_TM_INT_EN(tmdev->tsens_tm_addr)); + code = readl_relaxed( + TSENS_TM_INT_EN(tmdev->tsens_tm_addr)); + if (!(code & BIT(2))) { + udelay(2000); + TSENS_DBG(tmdev, "%s cnt:%d\n", + "Re-try TSENS write prior to scm", + reg_write_cnt++); + continue; + } + reg_write_cnt = 0; + + /* Make an scm call to re-init TSENS */ + TSENS_DBG(tmdev, "%s", + "Calling TZ to re-init TSENS\n"); + ret = scm_call2(SCM_SIP_FNID(SCM_SVC_TSENS, + TSENS_INIT_ID), &desc); + TSENS_DBG(tmdev, "%s", + "return from scm call\n"); + if (ret) { + msleep(100); + pr_err("%s: scm call failed %d\n", + __func__, ret); + BUG(); + } + tsens_ret = desc.ret[0]; + if (tsens_ret) { + msleep(100); + pr_err("%s: scm call failed, ret:%d\n", + __func__, tsens_ret); + BUG(); + } + + scm_cnt++; + rc = 0; + list_for_each_entry(tmdev_itr, + &tsens_device_list, list) { + rc = __tsens2xxx_hw_init(tmdev_itr); + if (rc) { + pr_err( + "%s: TSENS hw_init error\n", + __func__); + break; + } + } + + if (!rc) + break; + + if (scm_cnt >= 100) { + msleep(100); + pr_err( + "%s: Tsens is not up after %d scm\n", + __func__, scm_cnt); + BUG(); + } + udelay(2000); + TSENS_DBG(tmdev, "%s cnt:%d\n", + "Re-try TSENS scm call", scm_cnt); } - /* Make an scm call to re-init TSENS */ - TSENS_DBG(tmdev, "%s", - "Calling TZ to re-init TSENS\n"); - ret = scm_call2(SCM_SIP_FNID(SCM_SVC_TSENS, - TSENS_INIT_ID), &desc); - TSENS_DBG(tmdev, "%s", - "return from scm call\n"); - if (ret) { - pr_err("%s: scm call failed %d\n", - __func__, ret); - BUG(); - } - tsens_ret = desc.ret[0]; - if (tsens_ret) { - pr_err("%s: scm call failed to init tsens %d\n", - __func__, tsens_ret); - BUG(); - } tmdev->tsens_reinit_cnt++; atomic_set(&in_tsens_reinit, 0); /* Notify thermal fwk */ list_for_each_entry(tmdev_itr, &tsens_device_list, list) { - rc = __tsens2xxx_hw_init(tmdev_itr); - if (rc) { - pr_err( - "%s: Failed to re-initialize TSENS controller\n", - __func__); - BUG(); - } queue_work(tmdev_itr->tsens_reinit_work, &tmdev_itr->therm_fwk_notify); } @@ -251,7 +293,6 @@ static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp) sensor_read: tmdev->trdy_fail_ctr = 0; - tmdev->tsens_reinit_cnt = 0; code = readl_relaxed(sensor_addr + (sensor->hw_id << TSENS_STATUS_ADDR_OFFSET)); diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c index d93eee2f101b..a4001e08bd32 100644 --- a/drivers/thermal/x86_pkg_temp_thermal.c +++ b/drivers/thermal/x86_pkg_temp_thermal.c @@ -516,7 +516,8 @@ static int __init pkg_temp_thermal_init(void) return -ENODEV; max_packages = topology_max_packages(); - packages = kzalloc(max_packages * sizeof(struct pkg_device *), GFP_KERNEL); + packages = kcalloc(max_packages, sizeof(struct pkg_device *), + GFP_KERNEL); if (!packages) return -ENOMEM; diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 5a348efb91ad..f05b92b3be70 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c @@ -772,7 +772,7 @@ static int __init ehv_bc_init(void) * array, then you can use pointer math (e.g. "bc - bcs") to get its * tty index. */ - bcs = kzalloc(count * sizeof(struct ehv_bc_data), GFP_KERNEL); + bcs = kcalloc(count, sizeof(struct ehv_bc_data), GFP_KERNEL); if (!bcs) return -ENOMEM; diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c index 85a500ddbcaa..65a6831d3c74 100644 --- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c @@ -254,8 +254,9 @@ static int goldfish_tty_create_driver(void) int ret; struct tty_driver *tty; - goldfish_ttys = kzalloc(sizeof(*goldfish_ttys) * - goldfish_tty_line_count, GFP_KERNEL); + goldfish_ttys = kcalloc(goldfish_tty_line_count, + sizeof(*goldfish_ttys), + GFP_KERNEL); if (goldfish_ttys == NULL) { ret = -ENOMEM; goto err_alloc_goldfish_ttys_failed; diff --git a/drivers/tty/hvc/hvc_iucv.c b/drivers/tty/hvc/hvc_iucv.c index a74680729825..2af1e5751bd6 100644 --- a/drivers/tty/hvc/hvc_iucv.c +++ b/drivers/tty/hvc/hvc_iucv.c @@ -1252,7 +1252,7 @@ static int hvc_iucv_setup_filter(const char *val) if (size > MAX_VMID_FILTER) return -ENOSPC; - array = kzalloc(size * 8, GFP_KERNEL); + array = kcalloc(size, 8, GFP_KERNEL); if (!array) return -ENOMEM; diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index 63c29fe9d21f..b55616b26fdc 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -1454,7 +1454,8 @@ static int hvcs_alloc_index_list(int n) { int i; - hvcs_index_list = kmalloc(n * sizeof(hvcs_index_count),GFP_KERNEL); + hvcs_index_list = kmalloc_array(n, sizeof(hvcs_index_count), + GFP_KERNEL); if (!hvcs_index_list) return -ENOMEM; hvcs_index_count = n; diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index 61ecdd6b2fc2..f7d8204ce09b 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c @@ -1485,7 +1485,7 @@ static int load_firmware(struct pci_dev *pdev, goto errrelfw; } - data = kmalloc(word_count * 2, GFP_KERNEL); + data = kmalloc_array(word_count, 2, GFP_KERNEL); if (data == NULL) { dev_err(&pdev->dev, "Card%d, firmware upload " "failed, not enough memory\n", index + 1); diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index a00227d312d3..690ecf9fa990 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -2789,8 +2789,9 @@ static int atmel_serial_probe(struct platform_device *pdev) if (!atmel_use_pdc_rx(&atmel_port->uart)) { ret = -ENOMEM; - data = kmalloc(sizeof(struct atmel_uart_char) - * ATMEL_SERIAL_RINGSIZE, GFP_KERNEL); + data = kmalloc_array(ATMEL_SERIAL_RINGSIZE, + sizeof(struct atmel_uart_char), + GFP_KERNEL); if (!data) goto err_alloc_ring; atmel_port->rx_ring.buf = data; diff --git a/drivers/tty/serial/msm_geni_serial.c b/drivers/tty/serial/msm_geni_serial.c index 9d72d3a27828..b6fc8ff31678 100644 --- a/drivers/tty/serial/msm_geni_serial.c +++ b/drivers/tty/serial/msm_geni_serial.c @@ -2441,14 +2441,6 @@ static int msm_geni_serial_probe(struct platform_device *pdev) line = pdev->id; } - if (strcmp(id->compatible, "qcom,msm-geni-console") == 0) - snprintf(boot_marker, sizeof(boot_marker), - "M - DRIVER GENI_UART_%d Init", line); - else - snprintf(boot_marker, sizeof(boot_marker), - "M - DRIVER GENI_HS_UART_%d Init", line); - place_marker(boot_marker); - #ifdef SERIAL_CONSOLE is_console = (drv->cons ? true : false); dev_port = get_port_from_line(line, is_console); @@ -2638,15 +2630,6 @@ static int msm_geni_serial_probe(struct platform_device *pdev) goto exit_geni_serial_probe; ret = uart_add_one_port(drv, uport); - if (!ret) { - if (strcmp(id->compatible, "qcom,msm-geni-console") == 0) - snprintf(boot_marker, sizeof(boot_marker), - "M - DRIVER GENI_UART_%d Ready", line); - else - snprintf(boot_marker, sizeof(boot_marker), - "M - DRIVER GENI_HS_UART_%d Ready", line); - place_marker(boot_marker); - } exit_geni_serial_probe: return ret; } diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 15ddcbd1f9d2..dbca9b901fb5 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -1005,7 +1005,7 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) priv->tx_dma_use = 1; - priv->sg_tx_p = kzalloc(sizeof(struct scatterlist)*num, GFP_ATOMIC); + priv->sg_tx_p = kcalloc(num, sizeof(struct scatterlist), GFP_ATOMIC); if (!priv->sg_tx_p) { dev_err(priv->port.dev, "%s:kzalloc Failed\n", __func__); return 0; diff --git a/drivers/tty/serial/rp2.c b/drivers/tty/serial/rp2.c index 056f91b3a4ca..6dc3fee6dc61 100644 --- a/drivers/tty/serial/rp2.c +++ b/drivers/tty/serial/rp2.c @@ -777,7 +777,7 @@ static int rp2_probe(struct pci_dev *pdev, rp2_init_card(card); - ports = devm_kzalloc(&pdev->dev, sizeof(*ports) * card->n_ports, + ports = devm_kcalloc(&pdev->dev, card->n_ports, sizeof(*ports), GFP_KERNEL); if (!ports) return -ENOMEM; diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index dbec0f6063f8..c357d49e087e 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2506,7 +2506,7 @@ int uart_register_driver(struct uart_driver *drv) * Maybe we should be using a slab cache for this, especially if * we have a large number of ports to handle. */ - drv->state = kzalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL); + drv->state = kcalloc(drv->nr, sizeof(struct uart_state), GFP_KERNEL); if (!drv->state) goto out; diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index 653a076d89d3..fbb8afe4a71f 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c @@ -1124,8 +1124,9 @@ static int __init sunsab_init(void) } if (num_channels) { - sunsab_ports = kzalloc(sizeof(struct uart_sunsab_port) * - num_channels, GFP_KERNEL); + sunsab_ports = kcalloc(num_channels, + sizeof(struct uart_sunsab_port), + GFP_KERNEL); if (!sunsab_ports) return -ENOMEM; diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index a5f88cf0f61d..749543d8e33e 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c @@ -230,7 +230,7 @@ static void set_inverse_trans_unicode(struct vc_data *conp, q = p->inverse_trans_unicode; if (!q) { q = p->inverse_trans_unicode = - kmalloc(MAX_GLYPH * sizeof(u16), GFP_KERNEL); + kmalloc_array(MAX_GLYPH, sizeof(u16), GFP_KERNEL); if (!q) return; } @@ -478,7 +478,8 @@ con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos) p1 = p->uni_pgdir[n = unicode >> 11]; if (!p1) { - p1 = p->uni_pgdir[n] = kmalloc(32*sizeof(u16 *), GFP_KERNEL); + p1 = p->uni_pgdir[n] = kmalloc_array(32, sizeof(u16 *), + GFP_KERNEL); if (!p1) return -ENOMEM; for (i = 0; i < 32; i++) p1[i] = NULL; @@ -486,7 +487,7 @@ con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos) p2 = p1[n = (unicode >> 6) & 0x1f]; if (!p2) { - p2 = p1[n] = kmalloc(64*sizeof(u16), GFP_KERNEL); + p2 = p1[n] = kmalloc_array(64, sizeof(u16), GFP_KERNEL); if (!p2) return -ENOMEM; memset(p2, 0xff, 64*sizeof(u16)); /* No glyphs for the characters (yet) */ } diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index 610cb8338d53..dce5523d0736 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c @@ -1630,7 +1630,7 @@ int vt_do_diacrit(unsigned int cmd, void __user *udp, int perm) struct kbdiacr *dia; int i; - dia = kmalloc(MAX_DIACR * sizeof(struct kbdiacr), + dia = kmalloc_array(MAX_DIACR, sizeof(struct kbdiacr), GFP_KERNEL); if (!dia) return -ENOMEM; @@ -1663,7 +1663,7 @@ int vt_do_diacrit(unsigned int cmd, void __user *udp, int perm) struct kbdiacrsuc __user *a = udp; void *buf; - buf = kmalloc(MAX_DIACR * sizeof(struct kbdiacruc), + buf = kmalloc_array(MAX_DIACR, sizeof(struct kbdiacruc), GFP_KERNEL); if (buf == NULL) return -ENOMEM; diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index 8687b17f6cf0..0a997c801b4d 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c @@ -301,7 +301,8 @@ static int __set_selection(const struct tiocl_selection __user *sel, struct tty_ /* Allocate a new buffer before freeing the old one ... */ multiplier = use_unicode ? 3 : 1; /* chars can take up to 3 bytes */ - bp = kmalloc(((sel_end-sel_start)/2+1)*multiplier, GFP_KERNEL); + bp = kmalloc_array((sel_end - sel_start) / 2 + 1, multiplier, + GFP_KERNEL); if (!bp) { printk(KERN_WARNING "selection: kmalloc() failed\n"); clear_selection(); diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c index 31d5b1d3b5af..91aea8823af5 100644 --- a/drivers/uio/uio_pruss.c +++ b/drivers/uio/uio_pruss.c @@ -129,7 +129,7 @@ static int pruss_probe(struct platform_device *pdev) if (!gdev) return -ENOMEM; - gdev->info = kzalloc(sizeof(*p) * MAX_PRUSS_EVT, GFP_KERNEL); + gdev->info = kcalloc(MAX_PRUSS_EVT, sizeof(*p), GFP_KERNEL); if (!gdev->info) { kfree(gdev); return -ENOMEM; diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 4fb4cf8c2f14..50f9da4ec99b 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -927,7 +927,7 @@ static int parse_usbdevfs_streams(struct usb_dev_state *ps, if (num_streams_ret && (num_streams < 2 || num_streams > 65536)) return -EINVAL; - eps = kmalloc(num_eps * sizeof(*eps), GFP_KERNEL); + eps = kmalloc_array(num_eps, sizeof(*eps), GFP_KERNEL); if (!eps) return -ENOMEM; @@ -1646,8 +1646,9 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb as->mem_usage = u; if (num_sgs) { - as->urb->sg = kmalloc(num_sgs * sizeof(struct scatterlist), - GFP_KERNEL); + as->urb->sg = kmalloc_array(num_sgs, + sizeof(struct scatterlist), + GFP_KERNEL); if (!as->urb->sg) { ret = -ENOMEM; goto error; diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index b71409a0e6b0..c3df4079f3cb 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1404,7 +1404,7 @@ static int hub_configure(struct usb_hub *hub, dev_info(hub_dev, "%d port%s detected\n", maxchild, (maxchild == 1) ? "" : "s"); - hub->ports = kzalloc(maxchild * sizeof(struct usb_port *), GFP_KERNEL); + hub->ports = kcalloc(maxchild, sizeof(struct usb_port *), GFP_KERNEL); if (!hub->ports) { ret = -ENOMEM; goto fail; diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 298c91f83aee..230acf0d44aa 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -389,7 +389,7 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, } /* initialize all the urbs we'll use */ - io->urbs = kmalloc(io->entries * sizeof(*io->urbs), mem_flags); + io->urbs = kmalloc_array(io->entries, sizeof(*io->urbs), mem_flags); if (!io->urbs) goto nomem; @@ -1782,8 +1782,8 @@ int usb_set_configuration(struct usb_device *dev, int configuration) n = nintf = 0; if (cp) { nintf = cp->desc.bNumInterfaces; - new_interfaces = kmalloc(nintf * sizeof(*new_interfaces), - GFP_NOIO); + new_interfaces = kmalloc_array(nintf, sizeof(*new_interfaces), + GFP_NOIO); if (!new_interfaces) return -ENOMEM; diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index e6f8825835b0..376ab024330d 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -5184,13 +5184,14 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, "hcfg=%08x\n", hcfg); #ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS - hsotg->frame_num_array = kzalloc(sizeof(*hsotg->frame_num_array) * - FRAME_NUM_ARRAY_SIZE, GFP_KERNEL); + hsotg->frame_num_array = kcalloc(FRAME_NUM_ARRAY_SIZE, + sizeof(*hsotg->frame_num_array), + GFP_KERNEL); if (!hsotg->frame_num_array) goto error1; - hsotg->last_frame_num_array = kzalloc( - sizeof(*hsotg->last_frame_num_array) * - FRAME_NUM_ARRAY_SIZE, GFP_KERNEL); + hsotg->last_frame_num_array = kcalloc(FRAME_NUM_ARRAY_SIZE, + sizeof(*hsotg->last_frame_num_array), + GFP_KERNEL); if (!hsotg->last_frame_num_array) goto error1; #endif diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 6c160ea7e17e..dfcb70783856 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -944,6 +944,9 @@ int dwc3_core_init(struct dwc3 *dwc) if (dwc->dis_tx_ipgap_linecheck_quirk) reg |= DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS; + if (dwc->parkmode_disable_ss_quirk) + reg |= DWC3_GUCTL1_PARKMODE_DISABLE_SS; + /* * STAR: 9001415732: Host failure when Park mode is enabled: * Disable parkmode for Gen1 controllers to fix the stall @@ -954,7 +957,6 @@ int dwc3_core_init(struct dwc3 *dwc) reg |= DWC3_GUCTL1_PARKMODE_DISABLE_HS; reg |= DWC3_GUCTL1_PARKMODE_DISABLE_FSLS; } - if (dwc->parkmode_disable_ss_quirk) reg |= DWC3_GUCTL1_PARKMODE_DISABLE_SS; diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index cc8a42fb5284..1ef97d80654d 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -47,6 +47,7 @@ #include #include #include +#include #include "power.h" #include "core.h" @@ -496,8 +497,10 @@ static inline bool dwc3_msm_is_dev_superspeed(struct dwc3_msm *mdwc) speed = dwc3_msm_read_reg(mdwc->base, DWC3_DSTS) & DWC3_DSTS_CONNECTSPD; if ((speed & DWC3_DSTS_SUPERSPEED) || - (speed & DWC3_DSTS_SUPERSPEED_PLUS)) + (speed & DWC3_DSTS_SUPERSPEED_PLUS)) { + mdwc->ss_phy->flags |= DEVICE_IN_SS_MODE; return true; + } return false; } @@ -2085,8 +2088,8 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event, if (!mdwc->num_gsi_event_buffers) break; - mdwc->gsi_ev_buff = devm_kzalloc(dwc->dev, - sizeof(*dwc->ev_buf) * mdwc->num_gsi_event_buffers, + mdwc->gsi_ev_buff = devm_kcalloc(dwc->dev, + mdwc->num_gsi_event_buffers, sizeof(*dwc->ev_buf), GFP_KERNEL); if (!mdwc->gsi_ev_buff) { dev_err(dwc->dev, "can't allocate gsi_ev_buff\n"); @@ -3292,6 +3295,11 @@ static irqreturn_t msm_dwc3_pwr_irq(int irq, void *data) dwc->t_pwr_evt_irq = ktime_get(); dev_dbg(mdwc->dev, "%s received\n", __func__); + + if (mdwc->drd_state == DRD_STATE_PERIPHERAL_SUSPEND) { + dev_info(mdwc->dev, "USB Resume start\n"); + } + /* * When in Low Power Mode, can't read PWR_EVNT_IRQ_STAT_REG to acertain * which interrupts have been triggered, as the clocks are disabled. @@ -5161,6 +5169,11 @@ static int dwc3_msm_pm_resume(struct device *dev) flush_workqueue(mdwc->dwc3_wq); atomic_set(&mdwc->pm_suspended, 0); + if (atomic_read(&dwc->in_lpm) && + mdwc->drd_state == DRD_STATE_PERIPHERAL_SUSPEND) { + dev_info(mdwc->dev, "USB Resume start\n"); + } + if (!dwc->ignore_wakeup_src_in_hostmode || !mdwc->in_host_mode) { /* kick in otg state machine */ queue_work(mdwc->dwc3_wq, &mdwc->resume_work); diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index 3a61ee06e201..fa549c576911 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c @@ -1429,7 +1429,7 @@ static ssize_t show_registers(struct device *dev, return 0; } - dump = kmalloc(sizeof(u32) * DUMP_ENTRIES, GFP_KERNEL); + dump = kmalloc_array(DUMP_ENTRIES, sizeof(u32), GFP_KERNEL); if (!dump) return 0; diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index a81493d764d9..ba97cbb46787 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -612,14 +612,14 @@ static u8 encode_bMaxPower(enum usb_device_speed speed, val = CONFIG_USB_GADGET_VBUS_DRAW; if (!val) return 0; - switch (speed) { - case USB_SPEED_SUPER: - case USB_SPEED_SUPER_PLUS: - return (u8)(val / 8); - default: - /* only SuperSpeed and faster support > 500mA */ - return DIV_ROUND_UP(min(val, 500U), 2); - } + if (speed < USB_SPEED_SUPER) + return min(val, 500U) / 2; + else + /* + * USB 3.x supports up to 900mA, but since 900 isn't divisible + * by 8 the integral division will effectively cap to 896mA. + */ + return min(val, 900U) / 8; } static int config_buf(struct usb_configuration *config, @@ -965,7 +965,6 @@ static int set_config(struct usb_composite_dev *cdev, if (!c) goto done; - place_marker("M - USB Device is enumerated"); usb_gadget_set_state(gadget, USB_STATE_CONFIGURED); cdev->config = c; @@ -2481,8 +2480,7 @@ void composite_resume(struct usb_gadget *gadget) /* REVISIT: should we have config level * suspend/resume callbacks? */ - INFO(cdev, "USB Resume\n"); - place_marker("M - USB device is resumed"); + INFO(cdev, "USB Resume end\n"); if (cdev->driver->resume) cdev->driver->resume(cdev); @@ -2516,10 +2514,16 @@ void composite_resume(struct usb_gadget *gadget) f->resume(f); } - maxpower = cdev->config->MaxPower; - maxpower = maxpower ? maxpower : CONFIG_USB_GADGET_VBUS_DRAW; + maxpower = cdev->config->MaxPower ? + cdev->config->MaxPower : CONFIG_USB_GADGET_VBUS_DRAW; if (gadget->speed < USB_SPEED_SUPER) maxpower = min(maxpower, 500U); + else + maxpower = min(maxpower, 900U); + + if (maxpower > USB_SELF_POWER_VBUS_MAX_DRAW) + usb_gadget_clear_selfpowered(gadget); + usb_gadget_vbus_draw(gadget, maxpower); } diff --git a/drivers/usb/gadget/function/f_cdev.c b/drivers/usb/gadget/function/f_cdev.c index 2451aab593ba..be24a8c83acf 100644 --- a/drivers/usb/gadget/function/f_cdev.c +++ b/drivers/usb/gadget/function/f_cdev.c @@ -1990,7 +1990,7 @@ static ssize_t usb_cser_status_show(struct config_item *item, char *page) int temp = 0; int ret; - buf = kzalloc(sizeof(char) * 512, GFP_KERNEL); + buf = kzalloc(512, GFP_KERNEL); if (!buf) return -ENOMEM; diff --git a/drivers/usb/gadget/function/f_ipc.c b/drivers/usb/gadget/function/f_ipc.c index f77991cd1f80..d0c1613a1d27 100644 --- a/drivers/usb/gadget/function/f_ipc.c +++ b/drivers/usb/gadget/function/f_ipc.c @@ -25,8 +25,8 @@ #define MAX_INST_NAME_LEN 40 -#define IPC_BRIDGE_MAX_READ_SZ (8 * 1024) -#define IPC_BRIDGE_MAX_WRITE_SZ (8 * 1024) +#define IPC_BRIDGE_MAX_READ_SZ (24 * 1024) +#define IPC_BRIDGE_MAX_WRITE_SZ (24 * 1024) #define IPC_WRITE_WAIT_TIMEOUT 10000 @@ -297,7 +297,7 @@ retry_write_done: /* Notify the GPIO driver to wakeup the host and reintialize the * completion structure. */ - } else if (!ipc_dev->online) { + } else if (ipc_dev->connected && !ipc_dev->online) { sb_notifier_call_chain(EVT_WAKE_UP, NULL); reinit_completion(&ipc_dev->write_done); goto retry_write_done; diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index 6b8b80879ec8..7400027bcf7e 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -1353,9 +1353,8 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi) } /* allocate and initialize one new instance */ - midi = kzalloc( - sizeof(*midi) + opts->in_ports * sizeof(*midi->in_ports_array), - GFP_KERNEL); + midi = kzalloc(struct_size(midi, in_ports_array, opts->in_ports), + GFP_KERNEL); if (!midi) { status = -ENOMEM; goto setup_fail; diff --git a/drivers/usb/gadget/function/u_bam_dmux.c b/drivers/usb/gadget/function/u_bam_dmux.c index f40b8e7ecb7f..57aaebfcfd64 100644 --- a/drivers/usb/gadget/function/u_bam_dmux.c +++ b/drivers/usb/gadget/function/u_bam_dmux.c @@ -35,7 +35,6 @@ static struct workqueue_struct *gbam_wq; static unsigned int n_tx_req_queued; static unsigned int bam_ch_ids[BAM_DMUX_NUM_FUNCS] = { - BAM_DMUX_USB_RMNET_0, BAM_DMUX_USB_RMNET_0, BAM_DMUX_USB_DPL }; @@ -1026,11 +1025,12 @@ static void gbam_port_free(enum bam_dmux_func_type func) struct gbam_port *port = bam_ports[func].port; struct platform_driver *pdrv = &bam_ports[func].pdrv; - if (port) + if (port) { platform_driver_unregister(pdrv); - kfree(port); - bam_ports[func].port = NULL; + kfree(port); + bam_ports[func].port = NULL; + } } static int gbam_port_alloc(enum bam_dmux_func_type func) @@ -1217,6 +1217,9 @@ static void gbam_debugfs_init(void) } static void gbam_debugfs_remove(void) { + if (!gbam_dent) + return; + debugfs_remove_recursive(gbam_dent); debugfs_remove(gbam_dent); gbam_dent = NULL; @@ -1451,7 +1454,8 @@ int gbam_mbim_setup(void) { int ret = 0; - ret = gbam_setup(BAM_DMUX_FUNC_MBIM); + if (!bam_ports[BAM_DMUX_FUNC_RMNET].port) + ret = gbam_setup(BAM_DMUX_FUNC_MBIM); return ret; } diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index 7fdcc368fc91..214fad87ce05 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -798,7 +798,7 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, } spin_unlock_irqrestore(&dev->lock, flags); - if (skb && !in) { + if (!in) { dev_kfree_skb_any(skb); return NETDEV_TX_OK; } diff --git a/drivers/usb/gadget/function/u_rmnet.h b/drivers/usb/gadget/function/u_rmnet.h index dbc3002bb99e..2e963f813a7f 100644 --- a/drivers/usb/gadget/function/u_rmnet.h +++ b/drivers/usb/gadget/function/u_rmnet.h @@ -22,7 +22,7 @@ enum bam_dmux_func_type { BAM_DMUX_FUNC_RMNET, - BAM_DMUX_FUNC_MBIM, + BAM_DMUX_FUNC_MBIM = 0, BAM_DMUX_FUNC_DPL, BAM_DMUX_NUM_FUNCS, }; diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 8540e52c28a9..c13edfc71fe6 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -2095,7 +2095,7 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev, udc->num_ep = usba_config_fifo_table(udc); } - eps = devm_kzalloc(&pdev->dev, sizeof(struct usba_ep) * udc->num_ep, + eps = devm_kcalloc(&pdev->dev, udc->num_ep, sizeof(struct usba_ep), GFP_KERNEL); if (!eps) return ERR_PTR(-ENOMEM); @@ -2229,7 +2229,7 @@ static struct usba_ep * usba_udc_pdata(struct platform_device *pdev, if (!pdata) return ERR_PTR(-ENXIO); - eps = devm_kzalloc(&pdev->dev, sizeof(struct usba_ep) * pdata->num_ep, + eps = devm_kcalloc(&pdev->dev, pdata->num_ep, sizeof(struct usba_ep), GFP_KERNEL); if (!eps) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c index be9f40bc9c12..642f7912f6de 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_ep.c +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c @@ -143,9 +143,9 @@ static int ep_bd_list_alloc(struct bdc_ep *ep) __func__, ep, num_tabs); /* Allocate memory for table array */ - ep->bd_list.bd_table_array = kzalloc( - num_tabs * sizeof(struct bd_table *), - GFP_ATOMIC); + ep->bd_list.bd_table_array = kcalloc(num_tabs, + sizeof(struct bd_table *), + GFP_ATOMIC); if (!ep->bd_list.bd_table_array) return -ENOMEM; diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index ee48c7938d61..dfacd20c4ee3 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -2263,7 +2263,7 @@ static int struct_udc_setup(struct fsl_udc *udc, pdata = dev_get_platdata(&pdev->dev); udc->phy_mode = pdata->phy_mode; - udc->eps = kzalloc(sizeof(struct fsl_ep) * udc->max_ep, GFP_KERNEL); + udc->eps = kcalloc(udc->max_ep, sizeof(struct fsl_ep), GFP_KERNEL); if (!udc->eps) return -1; diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 189d4e01010b..d34ddc44bfdd 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -2447,7 +2447,8 @@ static int renesas_usb3_init_ep(struct renesas_usb3 *usb3, struct device *dev, if (usb3->num_usb3_eps > USB3_MAX_NUM_PIPES) usb3->num_usb3_eps = USB3_MAX_NUM_PIPES; - usb3->usb3_ep = devm_kzalloc(dev, sizeof(*usb3_ep) * usb3->num_usb3_eps, + usb3->usb3_ep = devm_kcalloc(dev, + usb3->num_usb3_eps, sizeof(*usb3_ep), GFP_KERNEL); if (!usb3->usb3_ep) return -ENOMEM; diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index fb4f104d5830..e04edb71fa43 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -130,8 +130,9 @@ static struct ehci_tt *find_tt(struct usb_device *udev) if (utt->multi) { tt_index = utt->hcpriv; if (!tt_index) { /* Create the index array */ - tt_index = kzalloc(utt->hub->maxchild * - sizeof(*tt_index), GFP_ATOMIC); + tt_index = kcalloc(utt->hub->maxchild, + sizeof(*tt_index), + GFP_ATOMIC); if (!tt_index) return ERR_PTR(-ENOMEM); utt->hcpriv = tt_index; diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c index f82ad5df1b0d..9d39458dbab2 100644 --- a/drivers/usb/host/fhci-tds.c +++ b/drivers/usb/host/fhci-tds.c @@ -193,7 +193,7 @@ u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem, goto err; } - buff = kmalloc(1028 * sizeof(*buff), GFP_KERNEL); + buff = kmalloc_array(1028, sizeof(*buff), GFP_KERNEL); if (!buff) { kfree(pkt); err_for = "buffer"; diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index 39ae7fb64b6f..f7b08280ab11 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -754,8 +754,8 @@ static int imx21_hc_urb_enqueue_isoc(struct usb_hcd *hcd, if (urb_priv == NULL) return -ENOMEM; - urb_priv->isoc_td = kzalloc( - sizeof(struct td) * urb->number_of_packets, mem_flags); + urb_priv->isoc_td = kcalloc(urb->number_of_packets, sizeof(struct td), + mem_flags); if (urb_priv->isoc_td == NULL) { ret = -ENOMEM; goto alloc_td_failed; diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 56176222b0b6..86239e58aed5 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c @@ -491,7 +491,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) char *next; unsigned i; - seen = kmalloc(DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC); + seen = kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC); if (!seen) return 0; seen_count = 0; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index f567fec65b50..55e3b85c3875 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -646,9 +646,9 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci, stream_info->num_stream_ctxs = num_stream_ctxs; /* Initialize the array of virtual pointers to stream rings. */ - stream_info->stream_rings = kzalloc( - sizeof(struct xhci_ring *)*num_streams, - mem_flags); + stream_info->stream_rings = kcalloc(num_streams, + sizeof(struct xhci_ring *), + mem_flags); if (!stream_info->stream_rings) goto cleanup_info; @@ -1479,14 +1479,15 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, /* Allow 3 retries for everything but isoc, set CErr = 3 */ if (!usb_endpoint_xfer_isoc(&ep->desc)) err_count = 3; - /* Some devices get this wrong */ - if (usb_endpoint_xfer_bulk(&ep->desc) && udev->speed == USB_SPEED_HIGH) - max_packet = 512; - - if (usb_endpoint_xfer_bulk(&ep->desc) && udev->speed == USB_SPEED_FULL - && max_packet < 8) - max_packet = 8; - + /* HS bulk max packet should be 512, FS bulk supports 8, 16, 32 or 64 */ + if (usb_endpoint_xfer_bulk(&ep->desc)) { + if (udev->speed == USB_SPEED_HIGH) + max_packet = 512; + if (udev->speed == USB_SPEED_FULL) { + max_packet = rounddown_pow_of_two(max_packet); + max_packet = clamp_val(max_packet, 8, 64); + } + } /* xHCI 1.0 and 1.1 indicates that ctrl ep avg TRB Length should be 8 */ if (usb_endpoint_xfer_control(&ep->desc) && xhci->hci_version >= 0x100) avg_trb_len = 8; @@ -1669,7 +1670,7 @@ static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags) if (!xhci->scratchpad->sp_array) goto fail_sp2; - xhci->scratchpad->sp_buffers = kzalloc(sizeof(void *) * num_sp, flags); + xhci->scratchpad->sp_buffers = kcalloc(num_sp, sizeof(void *), flags); if (!xhci->scratchpad->sp_buffers) goto fail_sp3; @@ -2312,11 +2313,12 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) u32 cap_start; num_ports = HCS_MAX_PORTS(xhci->hcs_params1); - xhci->port_array = kzalloc(sizeof(*xhci->port_array)*num_ports, flags); + xhci->port_array = kcalloc(num_ports, sizeof(*xhci->port_array), + flags); if (!xhci->port_array) return -ENOMEM; - xhci->rh_bw = kzalloc(sizeof(*xhci->rh_bw)*num_ports, flags); + xhci->rh_bw = kcalloc(num_ports, sizeof(*xhci->rh_bw), flags); if (!xhci->rh_bw) return -ENOMEM; for (i = 0; i < num_ports; i++) { @@ -2343,7 +2345,7 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) XHCI_EXT_CAPS_PROTOCOL); } - xhci->ext_caps = kzalloc(sizeof(*xhci->ext_caps) * cap_count, flags); + xhci->ext_caps = kcalloc(cap_count, sizeof(*xhci->ext_caps), flags); if (!xhci->ext_caps) return -ENOMEM; @@ -2386,8 +2388,9 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) * Not sure how the USB core will handle a hub with no ports... */ if (xhci->num_usb2_ports) { - xhci->usb2_ports = kmalloc(sizeof(*xhci->usb2_ports)* - xhci->num_usb2_ports, flags); + xhci->usb2_ports = kmalloc_array(xhci->num_usb2_ports, + sizeof(*xhci->usb2_ports), + flags); if (!xhci->usb2_ports) return -ENOMEM; @@ -2411,8 +2414,9 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) } } if (xhci->num_usb3_ports) { - xhci->usb3_ports = kmalloc(sizeof(*xhci->usb3_ports)* - xhci->num_usb3_ports, flags); + xhci->usb3_ports = kmalloc_array(xhci->num_usb3_ports, + sizeof(*xhci->usb3_ports), + flags); if (!xhci->usb3_ports) return -ENOMEM; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 2d7706d0f54d..72bdfb9760ca 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1633,7 +1633,7 @@ struct urb_priv { * (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table, * meaning 64 ring segments. * Initial allocated size of the ERST, in number of entries */ -#define ERST_NUM_SEGS 1 +#define ERST_NUM_SEGS 4 /* Initial allocated size of the ERST, in number of entries */ #define ERST_SIZE 64 /* Initial number of event segment rings allocated */ diff --git a/drivers/usb/misc/diag_bridge.c b/drivers/usb/misc/diag_bridge.c index 5a0dc78be31f..2bb5f3403a25 100644 --- a/drivers/usb/misc/diag_bridge.c +++ b/drivers/usb/misc/diag_bridge.c @@ -389,7 +389,7 @@ static ssize_t diag_read_stats(struct file *file, char __user *ubuf, char *buf; int i, ret = 0; - buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL); + buf = kzalloc(DEBUG_BUF_SIZE, GFP_KERNEL); if (!buf) return -ENOMEM; diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index e16af177d467..a1cab05f6b44 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -712,7 +712,9 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id * goto error; dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? usb_endpoint_maxp(dev->interrupt_out_endpoint) : udev->descriptor.bMaxPacketSize0; - dev->interrupt_out_buffer = kmalloc(write_buffer_size*dev->interrupt_out_endpoint_size, GFP_KERNEL); + dev->interrupt_out_buffer = kmalloc_array(write_buffer_size, + dev->interrupt_out_endpoint_size, + GFP_KERNEL); if (!dev->interrupt_out_buffer) goto error; dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); diff --git a/drivers/usb/misc/mdm_data_bridge.c b/drivers/usb/misc/mdm_data_bridge.c index 9bd5a1f00d3f..3cc96fa06628 100644 --- a/drivers/usb/misc/mdm_data_bridge.c +++ b/drivers/usb/misc/mdm_data_bridge.c @@ -863,6 +863,12 @@ bridge_probe(struct usb_interface *iface, const struct usb_device_id *id) return -EINVAL; } + if (devid == USB_BRIDGE_DIAG && + udev->actconfig->desc.bNumInterfaces == 1) { + pr_err("Invalid configuration: Only one interface\n"); + return -EINVAL; + } + num_eps = iface->cur_altsetting->desc.bNumEndpoints; for (i = 0; i < num_eps; i++) { endpoint = iface->cur_altsetting->endpoint + i; diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c index dc45cfc8eb10..e2ac7d84f236 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/drivers/usb/misc/sisusbvga/sisusb_con.c @@ -1242,7 +1242,7 @@ sisusbcon_font_set(struct vc_data *c, struct console_font *font, } if (!sisusb->font_backup) - sisusb->font_backup = vmalloc(charcount * 32); + sisusb->font_backup = vmalloc(array_size(charcount, 32)); if (sisusb->font_backup) { memcpy(sisusb->font_backup, font->data, charcount * 32); diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index 156aebf62e61..9d1ac043fdfe 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c @@ -1024,7 +1024,8 @@ static long mon_bin_ioctl(struct file *file, unsigned int cmd, unsigned long arg return -EINVAL; size = CHUNK_ALIGN(arg); - vec = kzalloc(sizeof(struct mon_pgmap) * (size / CHUNK_SIZE), GFP_KERNEL); + vec = kcalloc(size / CHUNK_SIZE, sizeof(struct mon_pgmap), + GFP_KERNEL); if (vec == NULL) { ret = -ENOMEM; break; diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c index af98245a3e95..a4478cbc2b05 100644 --- a/drivers/usb/pd/policy_engine.c +++ b/drivers/usb/pd/policy_engine.c @@ -1899,10 +1899,12 @@ int usbpd_send_svdm(struct usbpd *pd, u16 svid, u8 cmd, enum usbpd_svdm_cmd_type cmd_type, int obj_pos, const u32 *vdos, int num_vdos) { - u32 svdm_hdr = SVDM_HDR(svid, 0, obj_pos, cmd_type, cmd); + u32 svdm_hdr = SVDM_HDR(svid, pd->spec_rev == USBPD_REV_30 ? 1 : 0, + obj_pos, cmd_type, cmd); - usbpd_dbg(&pd->dev, "VDM tx: svid:%x cmd:%x cmd_type:%x svdm_hdr:%x\n", - svid, cmd, cmd_type, svdm_hdr); + usbpd_dbg(&pd->dev, "VDM tx: svid:%04x ver:%d obj_pos:%d cmd:%x cmd_type:%x svdm_hdr:%x\n", + svid, pd->spec_rev == USBPD_REV_30 ? 1 : 0, obj_pos, + cmd, cmd_type, svdm_hdr); return usbpd_send_vdm(pd, svdm_hdr, vdos, num_vdos); } @@ -1932,7 +1934,7 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) ktime_t recvd_time = ktime_get(); usbpd_dbg(&pd->dev, - "VDM rx: svid:%x cmd:%x cmd_type:%x vdm_hdr:%x has_dp: %s\n", + "VDM rx: svid:%04x cmd:%x cmd_type:%x vdm_hdr:%x has_dp: %s\n", svid, cmd, cmd_type, vdm_hdr, pd->has_dp ? "true" : "false"); @@ -1960,11 +1962,9 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) return; } - if (SVDM_HDR_VER(vdm_hdr) > 1) { - usbpd_dbg(&pd->dev, "Discarding SVDM with incorrect version:%d\n", + if (SVDM_HDR_VER(vdm_hdr) > 1) + usbpd_dbg(&pd->dev, "Received SVDM with incorrect version:%d\n", SVDM_HDR_VER(vdm_hdr)); - return; - } if (cmd_type != SVDM_CMD_TYPE_INITIATOR && pd->current_state != PE_SRC_STARTUP_WAIT_FOR_VDM_RESP) diff --git a/drivers/usb/phy/phy-msm-snps-hs.c b/drivers/usb/phy/phy-msm-snps-hs.c index 913c612c2abd..2bb473d2409b 100644 --- a/drivers/usb/phy/phy-msm-snps-hs.c +++ b/drivers/usb/phy/phy-msm-snps-hs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -515,9 +515,17 @@ static int msm_hsphy_set_suspend(struct usb_phy *uphy, int suspend) } if (suspend) { /* Bus suspend */ - if (phy->cable_connected) { - /* Enable auto-resume functionality by pulsing signal */ - if (phy->phy.flags & PHY_HOST_MODE) { + if (phy->cable_connected || + (phy->phy.flags & PHY_HOST_MODE)) { + /* Enable auto-resume functionality only when + * there is some peripheral connected and real + * bus suspend happened + */ + if ((phy->phy.flags & PHY_HSFS_MODE) || + (phy->phy.flags & PHY_LS_MODE)) { + /* Enable auto-resume functionality by pulsing + * signal + */ msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL2, USB2_AUTO_RESUME, USB2_AUTO_RESUME); diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index e45cfa42e5ad..e2d6dc16c6c3 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -3734,8 +3734,8 @@ struct msm_otg_platform_data *msm_otg_dt_to_pdata(struct platform_device *pdev) len = of_property_count_elems_of_size(node, "qcom,hsusb-otg-phy-init-seq", sizeof(len)); if (len > 0) { - pdata->phy_init_seq = devm_kzalloc(&pdev->dev, - len * sizeof(len), GFP_KERNEL); + pdata->phy_init_seq = devm_kcalloc(&pdev->dev, + len, sizeof(len), GFP_KERNEL); if (!pdata->phy_init_seq) return NULL; of_property_read_u32_array(node, "qcom,hsusb-otg-phy-init-seq", diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index b27f2135b66d..17d574896a05 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -1095,7 +1095,7 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) if (!gpriv) return -ENOMEM; - uep = kzalloc(sizeof(struct usbhsg_uep) * pipe_size, GFP_KERNEL); + uep = kcalloc(pipe_size, sizeof(struct usbhsg_uep), GFP_KERNEL); if (!uep) { ret = -ENOMEM; goto usbhs_mod_gadget_probe_err_gpriv; diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c index 98ed6fcacd36..3c61d3ec2c10 100644 --- a/drivers/usb/renesas_usbhs/pipe.c +++ b/drivers/usb/renesas_usbhs/pipe.c @@ -818,7 +818,8 @@ int usbhs_pipe_probe(struct usbhs_priv *priv) return -EINVAL; } - info->pipe = kzalloc(sizeof(struct usbhs_pipe) * pipe_size, GFP_KERNEL); + info->pipe = kcalloc(pipe_size, sizeof(struct usbhs_pipe), + GFP_KERNEL); if (!info->pipe) return -ENOMEM; diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index a1a11f8bb2a3..f7bdc2578fb7 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -744,7 +744,7 @@ static int iuu_uart_on(struct usb_serial_port *port) int status; u8 *buf; - buf = kmalloc(sizeof(u8) * 4, GFP_KERNEL); + buf = kmalloc(4, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -798,7 +798,7 @@ static int iuu_uart_baud(struct usb_serial_port *port, u32 baud_base, unsigned int T1FrekvensHZ = 0; dev_dbg(&port->dev, "%s - enter baud_base=%d\n", __func__, baud_base); - dataout = kmalloc(sizeof(u8) * 5, GFP_KERNEL); + dataout = kmalloc(5, GFP_KERNEL); if (!dataout) return -ENOMEM; diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c index 878b4b8761f5..049b0c3a44d5 100644 --- a/drivers/usb/storage/alauda.c +++ b/drivers/usb/storage/alauda.c @@ -1038,7 +1038,7 @@ static int alauda_write_data(struct us_data *us, unsigned long address, * We also need a temporary block buffer, where we read in the old data, * overwrite parts with the new data, and manipulate the redundancy data */ - blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO); + blockbuffer = kmalloc_array(pagesize + 64, blocksize, GFP_NOIO); if (!blockbuffer) { kfree(buffer); return USB_STOR_TRANSPORT_ERROR; diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index 28100374f7bd..397ecfdd8871 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c @@ -822,8 +822,12 @@ static int ms_lib_alloc_logicalmap(struct us_data *us) u32 i; struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; - info->MS_Lib.Phy2LogMap = kmalloc(info->MS_Lib.NumberOfPhyBlock * sizeof(u16), GFP_KERNEL); - info->MS_Lib.Log2PhyMap = kmalloc(info->MS_Lib.NumberOfLogBlock * sizeof(u16), GFP_KERNEL); + info->MS_Lib.Phy2LogMap = kmalloc_array(info->MS_Lib.NumberOfPhyBlock, + sizeof(u16), + GFP_KERNEL); + info->MS_Lib.Log2PhyMap = kmalloc_array(info->MS_Lib.NumberOfLogBlock, + sizeof(u16), + GFP_KERNEL); if ((info->MS_Lib.Phy2LogMap == NULL) || (info->MS_Lib.Log2PhyMap == NULL)) { ms_lib_free_logicalmap(us); @@ -1128,8 +1132,12 @@ static int ms_lib_alloc_writebuf(struct us_data *us) info->MS_Lib.wrtblk = (u16)-1; - info->MS_Lib.blkpag = kmalloc(info->MS_Lib.PagesPerBlock * info->MS_Lib.BytesPerSector, GFP_KERNEL); - info->MS_Lib.blkext = kmalloc(info->MS_Lib.PagesPerBlock * sizeof(struct ms_lib_type_extdat), GFP_KERNEL); + info->MS_Lib.blkpag = kmalloc_array(info->MS_Lib.PagesPerBlock, + info->MS_Lib.BytesPerSector, + GFP_KERNEL); + info->MS_Lib.blkext = kmalloc_array(info->MS_Lib.PagesPerBlock, + sizeof(struct ms_lib_type_extdat), + GFP_KERNEL); if ((info->MS_Lib.blkpag == NULL) || (info->MS_Lib.blkext == NULL)) { ms_lib_free_writebuf(us); diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index 44f8ffccd031..271014f03254 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c @@ -1244,8 +1244,8 @@ sddr09_read_map(struct us_data *us) { kfree(info->lba_to_pba); kfree(info->pba_to_lba); - info->lba_to_pba = kmalloc(numblocks*sizeof(int), GFP_NOIO); - info->pba_to_lba = kmalloc(numblocks*sizeof(int), GFP_NOIO); + info->lba_to_pba = kmalloc_array(numblocks, sizeof(int), GFP_NOIO); + info->pba_to_lba = kmalloc_array(numblocks, sizeof(int), GFP_NOIO); if (info->lba_to_pba == NULL || info->pba_to_lba == NULL) { printk(KERN_WARNING "sddr09_read_map: out of memory\n"); diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c index 147c50b3e00f..73186d66b618 100644 --- a/drivers/usb/storage/sddr55.c +++ b/drivers/usb/storage/sddr55.c @@ -663,7 +663,7 @@ static int sddr55_read_map(struct us_data *us) { numblocks = info->capacity >> (info->blockshift + info->pageshift); - buffer = kmalloc( numblocks * 2, GFP_NOIO ); + buffer = kmalloc_array(numblocks, 2, GFP_NOIO ); if (!buffer) return -1; @@ -696,8 +696,8 @@ static int sddr55_read_map(struct us_data *us) { kfree(info->lba_to_pba); kfree(info->pba_to_lba); - info->lba_to_pba = kmalloc(numblocks*sizeof(int), GFP_NOIO); - info->pba_to_lba = kmalloc(numblocks*sizeof(int), GFP_NOIO); + info->lba_to_pba = kmalloc_array(numblocks, sizeof(int), GFP_NOIO); + info->pba_to_lba = kmalloc_array(numblocks, sizeof(int), GFP_NOIO); if (info->lba_to_pba == NULL || info->pba_to_lba == NULL) { kfree(info->lba_to_pba); diff --git a/drivers/usb/wusbcore/wa-rpipe.c b/drivers/usb/wusbcore/wa-rpipe.c index c7ecdbe19a32..ebf0a40d2ea5 100644 --- a/drivers/usb/wusbcore/wa-rpipe.c +++ b/drivers/usb/wusbcore/wa-rpipe.c @@ -484,7 +484,8 @@ error: int wa_rpipes_create(struct wahc *wa) { wa->rpipes = le16_to_cpu(wa->wa_descr->wNumRPipes); - wa->rpipe_bm = kzalloc(BITS_TO_LONGS(wa->rpipes)*sizeof(unsigned long), + wa->rpipe_bm = kcalloc(BITS_TO_LONGS(wa->rpipes), + sizeof(unsigned long), GFP_KERNEL); if (wa->rpipe_bm == NULL) return -ENOMEM; diff --git a/drivers/uwb/est.c b/drivers/uwb/est.c index f3e232584284..ad30ddfe30b3 100644 --- a/drivers/uwb/est.c +++ b/drivers/uwb/est.c @@ -217,7 +217,7 @@ static int uwb_est_grow(void) { size_t actual_size = uwb_est_size * sizeof(uwb_est[0]); - void *new = kmalloc(2 * actual_size, GFP_ATOMIC); + void *new = kmalloc_array(2, actual_size, GFP_ATOMIC); if (new == NULL) return -ENOMEM; memcpy(new, uwb_est, actual_size); diff --git a/drivers/uwb/i1480/dfu/usb.c b/drivers/uwb/i1480/dfu/usb.c index a50cf45e530f..c0430a41e24b 100644 --- a/drivers/uwb/i1480/dfu/usb.c +++ b/drivers/uwb/i1480/dfu/usb.c @@ -376,7 +376,7 @@ int i1480_usb_probe(struct usb_interface *iface, const struct usb_device_id *id) i1480 = &i1480_usb->i1480; i1480->buf_size = 512; - i1480->cmd_buf = kmalloc(2 * i1480->buf_size, GFP_KERNEL); + i1480->cmd_buf = kmalloc_array(2, i1480->buf_size, GFP_KERNEL); if (i1480->cmd_buf == NULL) { dev_err(dev, "Cannot allocate transfer buffers\n"); result = -ENOMEM; diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 8fe07622ae59..3e5245ad6c91 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -259,8 +259,9 @@ static int vhost_net_set_ubuf_info(struct vhost_net *n) zcopy = vhost_net_zcopy_mask & (0x1 << i); if (!zcopy) continue; - n->vqs[i].ubuf_info = kmalloc(sizeof(*n->vqs[i].ubuf_info) * - UIO_MAXIOV, GFP_KERNEL); + n->vqs[i].ubuf_info = kmalloc_array(UIO_MAXIOV, + sizeof(*n->vqs[i].ubuf_info), + GFP_KERNEL); if (!n->vqs[i].ubuf_info) goto err; } @@ -911,7 +912,7 @@ static int vhost_net_open(struct inode *inode, struct file *f) n = kvmalloc(sizeof *n, GFP_KERNEL | __GFP_RETRY_MAYFAIL); if (!n) return -ENOMEM; - vqs = kmalloc(VHOST_NET_VQ_MAX * sizeof(*vqs), GFP_KERNEL); + vqs = kmalloc_array(VHOST_NET_VQ_MAX, sizeof(*vqs), GFP_KERNEL); if (!vqs) { kvfree(n); return -ENOMEM; diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index cb4ab5b955ad..57cea5a891dc 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -1415,7 +1415,7 @@ static int vhost_scsi_open(struct inode *inode, struct file *f) goto err_vs; } - vqs = kmalloc(VHOST_SCSI_MAX_VQ * sizeof(*vqs), GFP_KERNEL); + vqs = kmalloc_array(VHOST_SCSI_MAX_VQ, sizeof(*vqs), GFP_KERNEL); if (!vqs) goto err_vqs; @@ -1722,22 +1722,25 @@ static int vhost_scsi_nexus_cb(struct se_portal_group *se_tpg, for (i = 0; i < VHOST_SCSI_DEFAULT_TAGS; i++) { tv_cmd = &((struct vhost_scsi_cmd *)se_sess->sess_cmd_map)[i]; - tv_cmd->tvc_sgl = kzalloc(sizeof(struct scatterlist) * - VHOST_SCSI_PREALLOC_SGLS, GFP_KERNEL); + tv_cmd->tvc_sgl = kcalloc(VHOST_SCSI_PREALLOC_SGLS, + sizeof(struct scatterlist), + GFP_KERNEL); if (!tv_cmd->tvc_sgl) { pr_err("Unable to allocate tv_cmd->tvc_sgl\n"); goto out; } - tv_cmd->tvc_upages = kzalloc(sizeof(struct page *) * - VHOST_SCSI_PREALLOC_UPAGES, GFP_KERNEL); + tv_cmd->tvc_upages = kcalloc(VHOST_SCSI_PREALLOC_UPAGES, + sizeof(struct page *), + GFP_KERNEL); if (!tv_cmd->tvc_upages) { pr_err("Unable to allocate tv_cmd->tvc_upages\n"); goto out; } - tv_cmd->tvc_prot_sgl = kzalloc(sizeof(struct scatterlist) * - VHOST_SCSI_PREALLOC_PROT_SGLS, GFP_KERNEL); + tv_cmd->tvc_prot_sgl = kcalloc(VHOST_SCSI_PREALLOC_PROT_SGLS, + sizeof(struct scatterlist), + GFP_KERNEL); if (!tv_cmd->tvc_prot_sgl) { pr_err("Unable to allocate tv_cmd->tvc_prot_sgl\n"); goto out; diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c index 682fc58e1f75..bf24ecc46ed6 100644 --- a/drivers/vhost/test.c +++ b/drivers/vhost/test.c @@ -111,7 +111,7 @@ static int vhost_test_open(struct inode *inode, struct file *f) if (!n) return -ENOMEM; - vqs = kmalloc(VHOST_TEST_VQ_MAX * sizeof(*vqs), GFP_KERNEL); + vqs = kmalloc_array(VHOST_TEST_VQ_MAX, sizeof(*vqs), GFP_KERNEL); if (!vqs) { kfree(n); return -ENOMEM; diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 85edacc0be47..8ef554c28aee 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -392,10 +392,13 @@ static long vhost_dev_alloc_iovecs(struct vhost_dev *dev) for (i = 0; i < dev->nvqs; ++i) { vq = dev->vqs[i]; - vq->indirect = kmalloc(sizeof *vq->indirect * UIO_MAXIOV, - GFP_KERNEL); - vq->log = kmalloc(sizeof *vq->log * UIO_MAXIOV, GFP_KERNEL); - vq->heads = kmalloc(sizeof *vq->heads * UIO_MAXIOV, GFP_KERNEL); + vq->indirect = kmalloc_array(UIO_MAXIOV, + sizeof(*vq->indirect), + GFP_KERNEL); + vq->log = kmalloc_array(UIO_MAXIOV, sizeof(*vq->log), + GFP_KERNEL); + vq->heads = kmalloc_array(UIO_MAXIOV, sizeof(*vq->heads), + GFP_KERNEL); if (!vq->indirect || !vq->log || !vq->heads) goto err_nomem; } diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c index bb8971f2a634..a94d700a4503 100644 --- a/drivers/vhost/vringh.c +++ b/drivers/vhost/vringh.c @@ -191,7 +191,7 @@ static int resize_iovec(struct vringh_kiov *iov, gfp_t gfp) if (flag) new = krealloc(iov->iov, new_num * sizeof(struct iovec), gfp); else { - new = kmalloc(new_num * sizeof(struct iovec), gfp); + new = kmalloc_array(new_num, sizeof(struct iovec), gfp); if (new) { memcpy(new, iov->iov, iov->max_num * sizeof(struct iovec)); diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c index e7315bf14d60..16119bde9750 100644 --- a/drivers/video/backlight/adp8860_bl.c +++ b/drivers/video/backlight/adp8860_bl.c @@ -223,7 +223,7 @@ static int adp8860_led_probe(struct i2c_client *client) struct led_info *cur_led; int ret, i; - led = devm_kzalloc(&client->dev, sizeof(*led) * pdata->num_leds, + led = devm_kcalloc(&client->dev, pdata->num_leds, sizeof(*led), GFP_KERNEL); if (led == NULL) return -ENOMEM; diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c index 058d1def2d1f..4fec9aa92d9b 100644 --- a/drivers/video/backlight/adp8870_bl.c +++ b/drivers/video/backlight/adp8870_bl.c @@ -246,7 +246,7 @@ static int adp8870_led_probe(struct i2c_client *client) struct led_info *cur_led; int ret, i; - led = devm_kzalloc(&client->dev, pdata->num_leds * sizeof(*led), + led = devm_kcalloc(&client->dev, pdata->num_leds, sizeof(*led), GFP_KERNEL); if (led == NULL) return -ENOMEM; diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c index 4cdc7a3f6dc5..bd43d8cff389 100644 --- a/drivers/video/backlight/lp855x_bl.c +++ b/drivers/video/backlight/lp855x_bl.c @@ -374,7 +374,7 @@ static int lp855x_parse_dt(struct lp855x *lp) struct device_node *child; int i = 0; - rom = devm_kzalloc(dev, sizeof(*rom) * rom_length, GFP_KERNEL); + rom = devm_kcalloc(dev, rom_length, sizeof(*rom), GFP_KERNEL); if (!rom) return -ENOMEM; diff --git a/drivers/video/backlight/qcom-spmi-wled.c b/drivers/video/backlight/qcom-spmi-wled.c index 33a100d70658..8060d93097db 100644 --- a/drivers/video/backlight/qcom-spmi-wled.c +++ b/drivers/video/backlight/qcom-spmi-wled.c @@ -1,6 +1,6 @@ /* Copyright (c) 2015, Sony Mobile Communications, AB. * - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -91,6 +91,7 @@ #define WLED_SINK_REG_STR_MOD_EN BIT(7) #define WLED_SINK_SYNC_DLY_REG(n) (0x51 + (n * 0x10)) +#define WLED_SINK_SYNC_DLY_MASK GENMASK(2, 0) #define WLED_SINK_FS_CURR_REG(n) (0x52 + (n * 0x10)) #define WLED_SINK_FS_MASK GENMASK(3, 0) @@ -207,6 +208,7 @@ struct wled_config { int string_cfg; int mod_sel; int cabc_sel; + int sync_dly; bool en_cabc; bool ext_pfet_sc_pro_en; bool auto_calib_enabled; @@ -1259,6 +1261,14 @@ static int wled4_setup(struct wled *wled) if (rc < 0) return rc; + addr = wled->sink_addr + + WLED_SINK_SYNC_DLY_REG(i); + rc = regmap_update_bits(wled->regmap, addr, + WLED_SINK_SYNC_DLY_MASK, + wled->cfg.sync_dly); + if (rc < 0) + return rc; + temp = i + WLED_SINK_CURR_SINK_SHFT; sink_en |= 1 << temp; } @@ -1344,6 +1354,7 @@ static const struct wled_config wled4_config_defaults = { .fs_current = 10, .ovp = 1, .switch_freq = 11, + .sync_dly = 2, .string_cfg = 0xf, .mod_sel = -EINVAL, .cabc_sel = -EINVAL, @@ -1409,6 +1420,15 @@ static const struct wled_var_cfg wled4_ovp_cfg = { .size = ARRAY_SIZE(wled4_ovp_values), }; +static const u32 wled4_sync_dly_values[] = { + 0, 200, 400, 600, 800, 1000, 1200, 1400, +}; + +static const struct wled_var_cfg wled4_sync_dly_cfg = { + .values = wled4_sync_dly_values, + .size = ARRAY_SIZE(wled4_sync_dly_values), +}; + static inline u32 wled5_ovp_values_fn(u32 idx) { /* @@ -2131,6 +2151,11 @@ static int wled_configure(struct wled *wled, struct device *dev) .val_ptr = &cfg->string_cfg, .cfg = &wled_string_cfg, }, + { + .name = "qcom,sync-dly", + .val_ptr = &cfg->sync_dly, + .cfg = &wled4_sync_dly_cfg, + }, }; const struct wled_u32_opts wled5_opts[] = { diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index d1d3796773aa..63884a68bd24 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -649,7 +649,7 @@ static void *sti_bmode_font_raw(struct sti_cooked_font *f) unsigned char *n, *p, *q; int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font); - n = kzalloc(4*size, STI_LOWMEM); + n = kcalloc(4, size, STI_LOWMEM); if (!n) return NULL; p = n + 3; diff --git a/drivers/video/fbdev/au1100fb.c b/drivers/video/fbdev/au1100fb.c index 8de42f617d16..de2bfc6c3e2d 100644 --- a/drivers/video/fbdev/au1100fb.c +++ b/drivers/video/fbdev/au1100fb.c @@ -504,7 +504,7 @@ static int au1100fb_drv_probe(struct platform_device *dev) fbdev->info.fix = au1100fb_fix; fbdev->info.pseudo_palette = - devm_kzalloc(&dev->dev, sizeof(u32) * 16, GFP_KERNEL); + devm_kcalloc(&dev->dev, 16, sizeof(u32), GFP_KERNEL); if (!fbdev->info.pseudo_palette) return -ENOMEM; diff --git a/drivers/video/fbdev/bf537-lq035.c b/drivers/video/fbdev/bf537-lq035.c index ef29fb425122..57e3a6814e6b 100644 --- a/drivers/video/fbdev/bf537-lq035.c +++ b/drivers/video/fbdev/bf537-lq035.c @@ -737,8 +737,8 @@ static int bfin_lq035_probe(struct platform_device *pdev) bfin_lq035_fb.flags = FBINFO_DEFAULT; - bfin_lq035_fb.pseudo_palette = devm_kzalloc(&pdev->dev, - sizeof(u32) * 16, + bfin_lq035_fb.pseudo_palette = devm_kcalloc(&pdev->dev, + 16, sizeof(u32), GFP_KERNEL); if (bfin_lq035_fb.pseudo_palette == NULL) { pr_err("failed to allocate pseudo_palette\n"); diff --git a/drivers/video/fbdev/bf54x-lq043fb.c b/drivers/video/fbdev/bf54x-lq043fb.c index 8f1f97c75619..9b5d0b358279 100644 --- a/drivers/video/fbdev/bf54x-lq043fb.c +++ b/drivers/video/fbdev/bf54x-lq043fb.c @@ -602,7 +602,7 @@ static int bfin_bf54x_probe(struct platform_device *pdev) fbinfo->fbops = &bfin_bf54x_fb_ops; - fbinfo->pseudo_palette = devm_kzalloc(&pdev->dev, sizeof(u32) * 16, + fbinfo->pseudo_palette = devm_kcalloc(&pdev->dev, 16, sizeof(u32), GFP_KERNEL); if (!fbinfo->pseudo_palette) { printk(KERN_ERR DRIVER_NAME diff --git a/drivers/video/fbdev/bfin_adv7393fb.c b/drivers/video/fbdev/bfin_adv7393fb.c index 542ffaddc6ab..1dccffcc42f5 100644 --- a/drivers/video/fbdev/bfin_adv7393fb.c +++ b/drivers/video/fbdev/bfin_adv7393fb.c @@ -459,7 +459,7 @@ static int bfin_adv7393_fb_probe(struct i2c_client *client, fbdev->info.par = &bfin_par; fbdev->info.flags = FBINFO_DEFAULT; - fbdev->info.pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL); + fbdev->info.pseudo_palette = kcalloc(16, sizeof(u32), GFP_KERNEL); if (!fbdev->info.pseudo_palette) { dev_err(&client->dev, "failed to allocate pseudo_palette\n"); ret = -ENOMEM; diff --git a/drivers/video/fbdev/broadsheetfb.c b/drivers/video/fbdev/broadsheetfb.c index 9f9a7bef1ff6..d6ba348deb9f 100644 --- a/drivers/video/fbdev/broadsheetfb.c +++ b/drivers/video/fbdev/broadsheetfb.c @@ -617,7 +617,7 @@ static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par, int tail_start_addr; int start_sector_addr; - sector_buffer = kzalloc(sizeof(char)*sector_size, GFP_KERNEL); + sector_buffer = kzalloc(sector_size, GFP_KERNEL); if (!sector_buffer) return -ENOMEM; diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c index 5dce2b10c09a..35ebeeccde4d 100644 --- a/drivers/video/fbdev/core/bitblit.c +++ b/drivers/video/fbdev/core/bitblit.c @@ -269,7 +269,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, if (attribute) { u8 *dst; - dst = kmalloc(w * vc->vc_font.height, GFP_ATOMIC); + dst = kmalloc_array(w, vc->vc_font.height, GFP_ATOMIC); if (!dst) return; kfree(ops->cursor_data); @@ -312,7 +312,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, vc->vc_cursor_type != ops->p->cursor_shape || ops->cursor_state.mask == NULL || ops->cursor_reset) { - char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC); + char *mask = kmalloc_array(w, vc->vc_font.height, GFP_ATOMIC); int cur_height, size, i = 0; u8 msk = 0xff; diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 2f946cdd9945..3d0f7747d9d6 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -592,7 +592,8 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, if (scr_readw(r) != vc->vc_video_erase_char) break; if (r != q && new_rows >= rows + logo_lines) { - save = kmalloc(logo_lines * new_cols * 2, GFP_KERNEL); + save = kmalloc(array3_size(logo_lines, new_cols, 2), + GFP_KERNEL); if (save) { int i = cols < new_cols ? cols : new_cols; scr_memsetw(save, erase, logo_lines * new_cols * 2); diff --git a/drivers/video/fbdev/core/fbcon_ccw.c b/drivers/video/fbdev/core/fbcon_ccw.c index e0b9fbe7ca9e..78f3a5621478 100644 --- a/drivers/video/fbdev/core/fbcon_ccw.c +++ b/drivers/video/fbdev/core/fbcon_ccw.c @@ -258,7 +258,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode, if (attribute) { u8 *dst; - dst = kmalloc(w * vc->vc_font.width, GFP_ATOMIC); + dst = kmalloc_array(w, vc->vc_font.width, GFP_ATOMIC); if (!dst) return; kfree(ops->cursor_data); @@ -304,14 +304,15 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode, vc->vc_cursor_type != ops->p->cursor_shape || ops->cursor_state.mask == NULL || ops->cursor_reset) { - char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC); + char *tmp, *mask = kmalloc_array(w, vc->vc_font.width, + GFP_ATOMIC); int cur_height, size, i = 0; int width = (vc->vc_font.width + 7)/8; if (!mask) return; - tmp = kmalloc(width * vc->vc_font.height, GFP_ATOMIC); + tmp = kmalloc_array(width, vc->vc_font.height, GFP_ATOMIC); if (!tmp) { kfree(mask); diff --git a/drivers/video/fbdev/core/fbcon_cw.c b/drivers/video/fbdev/core/fbcon_cw.c index 158e6ea1c0f6..fd098ff17574 100644 --- a/drivers/video/fbdev/core/fbcon_cw.c +++ b/drivers/video/fbdev/core/fbcon_cw.c @@ -241,7 +241,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode, if (attribute) { u8 *dst; - dst = kmalloc(w * vc->vc_font.width, GFP_ATOMIC); + dst = kmalloc_array(w, vc->vc_font.width, GFP_ATOMIC); if (!dst) return; kfree(ops->cursor_data); @@ -287,14 +287,15 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode, vc->vc_cursor_type != ops->p->cursor_shape || ops->cursor_state.mask == NULL || ops->cursor_reset) { - char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC); + char *tmp, *mask = kmalloc_array(w, vc->vc_font.width, + GFP_ATOMIC); int cur_height, size, i = 0; int width = (vc->vc_font.width + 7)/8; if (!mask) return; - tmp = kmalloc(width * vc->vc_font.height, GFP_ATOMIC); + tmp = kmalloc_array(width, vc->vc_font.height, GFP_ATOMIC); if (!tmp) { kfree(mask); diff --git a/drivers/video/fbdev/core/fbcon_rotate.c b/drivers/video/fbdev/core/fbcon_rotate.c index 8a51e4d95cc5..c0d445294aa7 100644 --- a/drivers/video/fbdev/core/fbcon_rotate.c +++ b/drivers/video/fbdev/core/fbcon_rotate.c @@ -46,7 +46,7 @@ static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc) info->fbops->fb_sync(info); if (ops->fd_size < d_cellsize * len) { - dst = kmalloc(d_cellsize * len, GFP_KERNEL); + dst = kmalloc_array(len, d_cellsize, GFP_KERNEL); if (dst == NULL) { err = -ENOMEM; diff --git a/drivers/video/fbdev/core/fbcon_ud.c b/drivers/video/fbdev/core/fbcon_ud.c index 3df269638166..e165a3fad29a 100644 --- a/drivers/video/fbdev/core/fbcon_ud.c +++ b/drivers/video/fbdev/core/fbcon_ud.c @@ -289,7 +289,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode, if (attribute) { u8 *dst; - dst = kmalloc(w * vc->vc_font.height, GFP_ATOMIC); + dst = kmalloc_array(w, vc->vc_font.height, GFP_ATOMIC); if (!dst) return; kfree(ops->cursor_data); @@ -335,7 +335,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode, vc->vc_cursor_type != ops->p->cursor_shape || ops->cursor_state.mask == NULL || ops->cursor_reset) { - char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC); + char *mask = kmalloc_array(w, vc->vc_font.height, GFP_ATOMIC); int cur_height, size, i = 0; u8 msk = 0xff; diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 4e2c6c8e549a..3ac97c8d7166 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -496,7 +496,8 @@ static int fb_show_logo_line(struct fb_info *info, int rotate, } if (fb_logo.depth <= 4) { - logo_new = kmalloc(logo->width * logo->height, GFP_KERNEL); + logo_new = kmalloc_array(logo->width, logo->height, + GFP_KERNEL); if (logo_new == NULL) { kfree(palette); if (saved_pseudo_palette) @@ -513,8 +514,8 @@ static int fb_show_logo_line(struct fb_info *info, int rotate, image.height = logo->height; if (rotate) { - logo_rotate = kmalloc(logo->width * - logo->height, GFP_KERNEL); + logo_rotate = kmalloc_array(logo->width, logo->height, + GFP_KERNEL); if (logo_rotate) fb_rotate_logo(info, logo_rotate, &image, rotate); } diff --git a/drivers/video/fbdev/core/fbmon.c b/drivers/video/fbdev/core/fbmon.c index ed202f1e13b8..8607439d6932 100644 --- a/drivers/video/fbdev/core/fbmon.c +++ b/drivers/video/fbdev/core/fbmon.c @@ -620,7 +620,7 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize, int num = 0, i, first = 1; int ver, rev; - mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL); + mode = kcalloc(50, sizeof(struct fb_videomode), GFP_KERNEL); if (mode == NULL) return NULL; @@ -671,7 +671,7 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize, } *dbsize = num; - m = kmalloc(num * sizeof(struct fb_videomode), GFP_KERNEL); + m = kmalloc_array(num, sizeof(struct fb_videomode), GFP_KERNEL); if (!m) return mode; memmove(m, mode, num * sizeof(struct fb_videomode)); diff --git a/drivers/video/fbdev/igafb.c b/drivers/video/fbdev/igafb.c index 486f18897414..0d8ee405344b 100644 --- a/drivers/video/fbdev/igafb.c +++ b/drivers/video/fbdev/igafb.c @@ -462,7 +462,7 @@ static int __init igafb_init(void) * one additional region with size == 0. */ - par->mmap_map = kzalloc(4 * sizeof(*par->mmap_map), GFP_ATOMIC); + par->mmap_map = kcalloc(4, sizeof(*par->mmap_map), GFP_ATOMIC); if (!par->mmap_map) { printk("igafb_init: can't alloc mmap_map\n"); iounmap((void *)par->io_base); diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c index ba82f97fb42b..c4eb8661f751 100644 --- a/drivers/video/fbdev/imxfb.c +++ b/drivers/video/fbdev/imxfb.c @@ -662,7 +662,7 @@ static int imxfb_init_fbinfo(struct platform_device *pdev) pr_debug("%s\n",__func__); - info->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL); + info->pseudo_palette = kmalloc_array(16, sizeof(u32), GFP_KERNEL); if (!info->pseudo_palette) return -ENOMEM; diff --git a/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c index fe92eed6da70..8dd296d257dd 100644 --- a/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c +++ b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c @@ -245,7 +245,7 @@ static void mb86290fb_imageblit(struct fb_info *info, return; } - cmd = kmalloc(cmdlen * 4, GFP_DMA); + cmd = kmalloc_array(cmdlen, 4, GFP_DMA); if (!cmd) return cfb_imageblit(info, image); cmdfn(cmd, step, dx, dy, width, height, fgcolor, bgcolor, image, info); diff --git a/drivers/video/fbdev/mmp/fb/mmpfb.c b/drivers/video/fbdev/mmp/fb/mmpfb.c index 92279e02dd94..f27697e07c55 100644 --- a/drivers/video/fbdev/mmp/fb/mmpfb.c +++ b/drivers/video/fbdev/mmp/fb/mmpfb.c @@ -493,8 +493,8 @@ static int modes_setup(struct mmpfb_info *fbi) return 0; } /* put videomode list to info structure */ - videomodes = kzalloc(sizeof(struct fb_videomode) * videomode_num, - GFP_KERNEL); + videomodes = kcalloc(videomode_num, sizeof(struct fb_videomode), + GFP_KERNEL); if (!videomodes) { dev_err(fbi->dev, "can't malloc video modes\n"); return -ENOMEM; diff --git a/drivers/video/fbdev/msm/dsi_v2.c b/drivers/video/fbdev/msm/dsi_v2.c index 60c57e45212d..5ac17eb2c383 100644 --- a/drivers/video/fbdev/msm/dsi_v2.c +++ b/drivers/video/fbdev/msm/dsi_v2.c @@ -286,8 +286,9 @@ static int mdss_dsi_get_dt_vreg_data(struct device *dev, pr_debug("%s: vreg found. count=%d\n", __func__, mp->num_vreg); } - mp->vreg_config = devm_kzalloc(dev, sizeof(struct dss_vreg) * - mp->num_vreg, GFP_KERNEL); + mp->vreg_config = devm_kcalloc(dev, + mp->num_vreg, sizeof(struct dss_vreg), + GFP_KERNEL); if (!mp->vreg_config) { rc = -ENOMEM; goto error; diff --git a/drivers/video/fbdev/msm/mdp3_ctrl.c b/drivers/video/fbdev/msm/mdp3_ctrl.c index 9a2b739e6b5e..29276da66a23 100644 --- a/drivers/video/fbdev/msm/mdp3_ctrl.c +++ b/drivers/video/fbdev/msm/mdp3_ctrl.c @@ -2222,22 +2222,22 @@ static int mdp3_alloc_lut_buffer(struct platform_device *pdev, void **cmap) memset(map, 0, sizeof(struct fb_cmap)); - map->red = devm_kzalloc(&pdev->dev, MDP_LUT_SIZE * sizeof(u16), + map->red = devm_kcalloc(&pdev->dev, MDP_LUT_SIZE, sizeof(u16), GFP_KERNEL); if (map->red == NULL) goto exit_red; memset(map->red, 0, sizeof(u16) * MDP_LUT_SIZE); - map->green = devm_kzalloc(&pdev->dev, MDP_LUT_SIZE * sizeof(u16), - GFP_KERNEL); + map->green = devm_kcalloc(&pdev->dev, MDP_LUT_SIZE, sizeof(u16), + GFP_KERNEL); if (map->green == NULL) goto exit_green; memset(map->green, 0, sizeof(u16) * MDP_LUT_SIZE); - map->blue = devm_kzalloc(&pdev->dev, MDP_LUT_SIZE * sizeof(u16), - GFP_KERNEL); + map->blue = devm_kcalloc(&pdev->dev, MDP_LUT_SIZE, sizeof(u16), + GFP_KERNEL); if (map->blue == NULL) goto exit_blue; diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index f578c73ac394..0461f821027d 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -559,8 +559,9 @@ int mdss_dsi_get_dt_vreg_data(struct device *dev, pr_debug("%s: vreg found. count=%d\n", __func__, mp->num_vreg); } - mp->vreg_config = devm_kzalloc(dev, sizeof(struct dss_vreg) * - mp->num_vreg, GFP_KERNEL); + mp->vreg_config = devm_kcalloc(dev, + mp->num_vreg, sizeof(struct dss_vreg), + GFP_KERNEL); if (!mp->vreg_config) { rc = -ENOMEM; goto error; diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h index f6c19fbdaf30..59ddd2c2a666 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.h +++ b/drivers/video/fbdev/msm/mdss_dsi.h @@ -475,6 +475,7 @@ struct mdss_dsi_ctrl_pdata { bool dsi_irq_line; bool dcs_cmd_insert; atomic_t te_irq_ready; + bool idle; bool cmd_sync_wait_broadcast; bool cmd_sync_wait_trigger; @@ -506,6 +507,8 @@ struct mdss_dsi_ctrl_pdata { struct dsi_panel_cmds lp_on_cmds; struct dsi_panel_cmds lp_off_cmds; struct dsi_panel_cmds status_cmds; + struct dsi_panel_cmds idle_on_cmds; /* for lp mode */ + struct dsi_panel_cmds idle_off_cmds; u32 *status_valid_params; u32 *status_cmds_rlen; u32 *status_value; diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c index 15befe26fc2b..95a997811dfa 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_panel.c +++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c @@ -251,6 +251,55 @@ static void mdss_dsi_panel_bklt_dcs(struct mdss_dsi_ctrl_pdata *ctrl, int level) mdss_dsi_cmdlist_put(ctrl, &cmdreq); } +static void mdss_dsi_panel_set_idle_mode(struct mdss_panel_data *pdata, + bool enable) +{ + struct mdss_dsi_ctrl_pdata *ctrl = NULL; + + if (pdata == NULL) { + pr_err("%s: Invalid input data\n", __func__); + return; + } + + ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, + panel_data); + + pr_debug("%s: Idle (%d->%d)\n", __func__, ctrl->idle, enable); + + if (ctrl->idle == enable) + return; + + if (enable) { + if (ctrl->idle_on_cmds.cmd_cnt) { + mdss_dsi_panel_cmds_send(ctrl, &ctrl->idle_on_cmds, + CMD_REQ_COMMIT); + ctrl->idle = true; + pr_debug("Idle on\n"); + } + } else { + if (ctrl->idle_off_cmds.cmd_cnt) { + mdss_dsi_panel_cmds_send(ctrl, &ctrl->idle_off_cmds, + CMD_REQ_COMMIT); + ctrl->idle = false; + pr_debug("Idle off\n"); + } + } +} + +static bool mdss_dsi_panel_get_idle_mode(struct mdss_panel_data *pdata) + +{ + struct mdss_dsi_ctrl_pdata *ctrl = NULL; + + if (pdata == NULL) { + pr_err("%s: Invalid input data\n", __func__); + return 0; + } + ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, + panel_data); + return ctrl->idle; +} + static int mdss_dsi_request_gpios(struct mdss_dsi_ctrl_pdata *ctrl_pdata) { int rc = 0; @@ -411,6 +460,11 @@ int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable) return rc; } + if (pinfo->skip_panel_reset && !pinfo->cont_splash_enabled) { + pr_debug("%s: skip_panel_reset is set\n", __func__); + return 0; + } + pr_debug("%s: enable = %d\n", __func__, enable); if (enable) { @@ -1009,6 +1063,8 @@ static int mdss_dsi_post_panel_on(struct mdss_panel_data *pdata) } end: + /* clear idle state */ + ctrl->idle = false; pr_debug("%s:-\n", __func__); return 0; } @@ -1066,7 +1122,11 @@ static int mdss_dsi_panel_low_power_config(struct mdss_panel_data *pdata, enable); /* Any panel specific low power commands/config */ - + /* Control idle mode for panel */ + if (enable) + mdss_dsi_panel_set_idle_mode(pdata, true); + else + mdss_dsi_panel_set_idle_mode(pdata, false); pr_debug("%s:-\n", __func__); return 0; } @@ -2969,12 +3029,26 @@ static int mdss_panel_parse_dt(struct device_node *np, mdss_dsi_parse_dcs_cmds(np, &ctrl_pdata->off_cmds, "qcom,mdss-dsi-off-command", "qcom,mdss-dsi-off-command-state"); + mdss_dsi_parse_dcs_cmds(np, &ctrl_pdata->idle_on_cmds, + "qcom,mdss-dsi-idle-on-command", + "qcom,mdss-dsi-idle-on-command-state"); + + mdss_dsi_parse_dcs_cmds(np, &ctrl_pdata->idle_off_cmds, + "qcom,mdss-dsi-idle-off-command", + "qcom,mdss-dsi-idle-off-command-state"); + + rc = of_property_read_u32(np, "qcom,mdss-dsi-idle-fps", &tmp); + pinfo->mipi.frame_rate_idle = (!rc ? tmp : 60); + rc = of_property_read_u32(np, "qcom,adjust-timer-wakeup-ms", &tmp); pinfo->adjust_timer_delay_ms = (!rc ? tmp : 0); pinfo->mipi.force_clk_lane_hs = of_property_read_bool(np, "qcom,mdss-dsi-force-clock-lane-hs"); + pinfo->skip_panel_reset = + of_property_read_bool(np, "qcom,mdss-skip-panel-reset"); + rc = mdss_dsi_parse_panel_features(np, ctrl_pdata); if (rc) { pr_err("%s: failed to parse panel features\n", __func__); @@ -3060,6 +3134,6 @@ int mdss_dsi_panel_init(struct device_node *node, ctrl_pdata->panel_data.apply_display_setting = mdss_dsi_panel_apply_display_setting; ctrl_pdata->switch_mode = mdss_dsi_panel_switch_mode; - + ctrl_pdata->panel_data.get_idle = mdss_dsi_panel_get_idle_mode; return 0; } diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c index 918fe6a12f06..b8594852b5f0 100644 --- a/drivers/video/fbdev/msm/mdss_fb.c +++ b/drivers/video/fbdev/msm/mdss_fb.c @@ -1189,8 +1189,8 @@ static int mdss_fb_init_panel_modes(struct msm_fb_data_type *mfd, list_for_each(pos, &pdata->timings_list) num_timings++; - modedb = devm_kzalloc(fbi->dev, num_timings * sizeof(*modedb), - GFP_KERNEL); + modedb = devm_kcalloc(fbi->dev, num_timings, sizeof(*modedb), + GFP_KERNEL); if (!modedb) return -ENOMEM; diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c index e634fffcf1e4..7cc3c49dbe5d 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c @@ -4191,8 +4191,10 @@ static int hdmi_tx_init_power_data(struct device *dev, } hpd_power_data->num_clk = hpd_clk_count; - hpd_power_data->clk_config = devm_kzalloc(dev, sizeof(struct dss_clk) * - hpd_power_data->num_clk, GFP_KERNEL); + hpd_power_data->clk_config = devm_kcalloc(dev, + hpd_power_data->num_clk, + sizeof(struct dss_clk), + GFP_KERNEL); if (!hpd_power_data->clk_config) { rc = -EINVAL; goto exit; @@ -4206,8 +4208,10 @@ static int hdmi_tx_init_power_data(struct device *dev, } core_power_data->num_clk = core_clk_count; - core_power_data->clk_config = devm_kzalloc(dev, sizeof(struct dss_clk) * - core_power_data->num_clk, GFP_KERNEL); + core_power_data->clk_config = devm_kcalloc(dev, + core_power_data->num_clk, + sizeof(struct dss_clk), + GFP_KERNEL); if (!core_power_data->clk_config) { core_power_data->num_clk = 0; rc = -EINVAL; @@ -4386,8 +4390,10 @@ static int hdmi_tx_get_dt_vreg_data(struct device *dev, if (mod_vreg_total > 0) { mp->num_vreg = mod_vreg_total; - mp->vreg_config = devm_kzalloc(dev, sizeof(struct dss_vreg) * - mod_vreg_total, GFP_KERNEL); + mp->vreg_config = devm_kcalloc(dev, + mod_vreg_total, + sizeof(struct dss_vreg), + GFP_KERNEL); if (!mp->vreg_config) { DEV_ERR("%s: can't alloc '%s' vreg mem\n", __func__, hdmi_tx_pm_name(module_type)); @@ -4398,7 +4404,7 @@ static int hdmi_tx_get_dt_vreg_data(struct device *dev, return 0; } - val_array = devm_kzalloc(dev, sizeof(u32) * dt_vreg_total, GFP_KERNEL); + val_array = devm_kcalloc(dev, dt_vreg_total, sizeof(u32), GFP_KERNEL); if (!val_array) { DEV_ERR("%s: can't allocate vreg scratch mem\n", __func__); rc = -ENOMEM; @@ -4570,8 +4576,9 @@ static int hdmi_tx_get_dt_gpio_data(struct device *dev, DEV_DBG("%s: mp_gpio_cnt = %d\n", __func__, mp_gpio_cnt); mp->num_gpio = mp_gpio_cnt; - mp->gpio_config = devm_kzalloc(dev, sizeof(struct dss_gpio) * - mp_gpio_cnt, GFP_KERNEL); + mp->gpio_config = devm_kcalloc(dev, + mp_gpio_cnt, sizeof(struct dss_gpio), + GFP_KERNEL); if (!mp->gpio_config) { DEV_ERR("%s: can't alloc '%s' gpio mem\n", __func__, hdmi_tx_pm_name(module_type)); diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index afd11b5eb603..e9625d0636f9 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -2432,8 +2432,9 @@ static u32 mdss_mdp_scaler_init(struct mdss_data_type *mdata, mdata->scaler_off->ndest_scalers = len/sizeof(u32); mdata->scaler_off->dest_scaler_off = - devm_kzalloc(dev, sizeof(u32) * + devm_kcalloc(&mdata->pdev->dev, mdata->scaler_off->ndest_scalers, + sizeof(u32), GFP_KERNEL); if (!mdata->scaler_off->dest_scaler_off) return -ENOMEM; @@ -2446,8 +2447,9 @@ static u32 mdss_mdp_scaler_init(struct mdss_data_type *mdata, return ret; mdata->scaler_off->dest_scaler_lut_off = - devm_kzalloc(dev, sizeof(u32) * + devm_kcalloc(&mdata->pdev->dev, mdata->scaler_off->ndest_scalers, + sizeof(u32), GFP_KERNEL); if (!mdata->scaler_off->dest_scaler_lut_off) return -ENOMEM; @@ -3344,8 +3346,10 @@ int mdss_mdp_parse_dt_hw_settings(struct platform_device *pdev) if (!(mdp_len + vbif_len + vbif_nrt_len)) return 0; - hws = devm_kzalloc(&pdev->dev, sizeof(*hws) * (vbif_len + mdp_len + - vbif_nrt_len + 1), GFP_KERNEL); + hws = devm_kcalloc(&pdev->dev, + vbif_len + mdp_len + vbif_nrt_len + 1, + sizeof(*hws), + GFP_KERNEL); if (!hws) return -ENOMEM; @@ -3909,10 +3913,9 @@ static int mdss_mdp_cdm_addr_setup(struct mdss_data_type *mdata, struct mdss_mdp_cdm *head; u32 i = 0; - head = devm_kzalloc(&mdata->pdev->dev, sizeof(struct mdss_mdp_cdm) * - len, GFP_KERNEL); - if (!head) { - pr_err("%s: no memory for CDM info\n", __func__); + head = devm_kcalloc(&mdata->pdev->dev, + len, sizeof(struct mdss_mdp_cdm), GFP_KERNEL); + if (!head) return -ENOMEM; } @@ -3978,8 +3981,8 @@ static int mdss_mdp_dsc_addr_setup(struct mdss_data_type *mdata, struct mdss_mdp_dsc *head; u32 i = 0; - head = devm_kzalloc(&mdata->pdev->dev, sizeof(struct mdss_mdp_dsc) * - len, GFP_KERNEL); + head = devm_kcalloc(&mdata->pdev->dev, + len, sizeof(struct mdss_mdp_dsc), GFP_KERNEL); if (!head) return -ENOMEM; @@ -4408,10 +4411,11 @@ static void mdss_mdp_parse_max_bandwidth(struct platform_device *pdev) max_bw_settings_cnt /= 2 * sizeof(u32); - max_bw_settings = devm_kzalloc(&pdev->dev, sizeof(*max_bw_settings) - * max_bw_settings_cnt, GFP_KERNEL); - if (!max_bw_settings) { - pr_err("Memory allocation failed for max_bw_settings\n"); + max_bw_settings = devm_kcalloc(&pdev->dev, + max_bw_settings_cnt, + sizeof(*max_bw_settings), + GFP_KERNEL); + if (!max_bw_settings) return; } @@ -4450,8 +4454,8 @@ static void mdss_mdp_parse_per_pipe_bandwidth(struct platform_device *pdev) max_bw_settings_cnt /= 2 * sizeof(u32); - max_bw_per_pipe_settings = devm_kzalloc(&pdev->dev, - sizeof(struct mdss_max_bw_settings) * max_bw_settings_cnt, + max_bw_per_pipe_settings = devm_kcalloc(&pdev->dev, + max_bw_settings_cnt, sizeof(struct mdss_max_bw_settings), GFP_KERNEL); if (!max_bw_per_pipe_settings) { pr_err("Memory allocation failed for max_bw_settings\n"); @@ -4710,8 +4714,8 @@ static int mdss_mdp_parse_dt_ppb_off(struct platform_device *pdev) arr = of_get_property(pdev->dev.of_node, "qcom,mdss-ppb-ctl-off", &len); if (arr) { mdata->nppb_ctl = len / sizeof(u32); - mdata->ppb_ctl = devm_kzalloc(&mdata->pdev->dev, - sizeof(u32) * mdata->nppb_ctl, GFP_KERNEL); + mdata->ppb_ctl = devm_kcalloc(&mdata->pdev->dev, + mdata->nppb_ctl, sizeof(u32), GFP_KERNEL); if (mdata->ppb_ctl == NULL) return -ENOMEM; @@ -4723,8 +4727,8 @@ static int mdss_mdp_parse_dt_ppb_off(struct platform_device *pdev) arr = of_get_property(pdev->dev.of_node, "qcom,mdss-ppb-cfg-off", &len); if (arr) { mdata->nppb_cfg = len / sizeof(u32); - mdata->ppb_cfg = devm_kzalloc(&mdata->pdev->dev, - sizeof(u32) * mdata->nppb_cfg, GFP_KERNEL); + mdata->ppb_cfg = devm_kcalloc(&mdata->pdev->dev, + mdata->nppb_cfg, sizeof(u32), GFP_KERNEL); if (mdata->ppb_cfg == NULL) return -ENOMEM; diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index 758f97197f84..b4962b0eb2e5 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -5248,8 +5248,8 @@ int mdss_mdp_mixer_addr_setup(struct mdss_data_type *mdata, (mdata->wfd_mode == MDSS_MDP_WFD_SHARED)) size++; - head = devm_kzalloc(&mdata->pdev->dev, sizeof(struct mdss_mdp_mixer) * - size, GFP_KERNEL); + head = devm_kcalloc(&mdata->pdev->dev, + size, sizeof(struct mdss_mdp_mixer), GFP_KERNEL); if (!head) { pr_err("unable to setup mixer type=%d :kzalloc fail\n", @@ -5319,8 +5319,8 @@ int mdss_mdp_ctl_addr_setup(struct mdss_data_type *mdata, mutex_init(shared_lock); } - head = devm_kzalloc(&mdata->pdev->dev, sizeof(struct mdss_mdp_ctl) * - size, GFP_KERNEL); + head = devm_kcalloc(&mdata->pdev->dev, + size, sizeof(struct mdss_mdp_ctl), GFP_KERNEL); if (!head) { pr_err("unable to setup ctl and wb: kzalloc fail\n"); @@ -5355,10 +5355,10 @@ int mdss_mdp_wb_addr_setup(struct mdss_data_type *mdata, u32 total, i; total = num_block_wb + num_intf_wb; - wb = devm_kzalloc(&mdata->pdev->dev, sizeof(struct mdss_mdp_writeback) * - total, GFP_KERNEL); - if (!wb) { - pr_err("unable to setup wb: kzalloc fail\n"); + wb = devm_kcalloc(&mdata->pdev->dev, + total, sizeof(struct mdss_mdp_writeback), + GFP_KERNEL); + if (!wb) return -ENOMEM; } diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c index 1ae6ebbf001e..e17a6ee2076e 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c @@ -317,8 +317,8 @@ int mdss_mdp_video_addr_setup(struct mdss_data_type *mdata, struct mdss_mdp_video_ctx *head; u32 i; - head = devm_kzalloc(&mdata->pdev->dev, - sizeof(struct mdss_mdp_video_ctx) * count, GFP_KERNEL); + head = devm_kcalloc(&mdata->pdev->dev, + count, sizeof(struct mdss_mdp_video_ctx), GFP_KERNEL); if (!head) return -ENOMEM; diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c index 2007ed66e725..6f0d8fa4738d 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pp.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c @@ -3186,9 +3186,9 @@ int mdss_mdp_pp_init(struct device *dev) goto pp_exit; } pp_ops = pp_driver_ops.pp_ops; - hist = devm_kzalloc(dev, - sizeof(struct pp_hist_col_info) * + hist = devm_kcalloc(dev, mdata->ndspp, + sizeof(struct pp_hist_col_info), GFP_KERNEL); if (hist == NULL) { pr_err("dspp histogram allocation failed!\n"); @@ -5620,8 +5620,9 @@ int mdss_mdp_hist_collect(struct mdp_histogram_data *hist) goto hist_collect_exit; } if (pipe_cnt > 1) { - hist_concat = kzalloc(HIST_V_SIZE * pipe_cnt * - sizeof(u32), GFP_KERNEL); + hist_concat = kcalloc(HIST_V_SIZE * pipe_cnt, + sizeof(u32), + GFP_KERNEL); if (!hist_concat) { ret = -ENOMEM; goto hist_collect_exit; @@ -6804,8 +6805,8 @@ int mdss_mdp_ad_addr_setup(struct mdss_data_type *mdata, u32 *ad_offsets) u32 i; int rc = 0; - mdata->ad_off = devm_kzalloc(&mdata->pdev->dev, - sizeof(struct mdss_mdp_ad) * mdata->nad_cfgs, + mdata->ad_off = devm_kcalloc(&mdata->pdev->dev, + mdata->nad_cfgs, sizeof(struct mdss_mdp_ad), GFP_KERNEL); if (!mdata->ad_off) { @@ -6813,8 +6814,8 @@ int mdss_mdp_ad_addr_setup(struct mdss_data_type *mdata, u32 *ad_offsets) return -ENOMEM; } - mdata->ad_cfgs = devm_kzalloc(&mdata->pdev->dev, - sizeof(struct mdss_ad_info) * mdata->nad_cfgs, + mdata->ad_cfgs = devm_kcalloc(&mdata->pdev->dev, + mdata->nad_cfgs, sizeof(struct mdss_ad_info), GFP_KERNEL); if (!mdata->ad_cfgs) { diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c b/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c index f13670e40ae6..f2d76d351834 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c @@ -491,8 +491,7 @@ static int pp_gamut_cache_params_v1_7(struct mdp_gamut_cfg_data *config, } /* Allocate for fine mode other modes will fit */ if (!tbl_gamut) - tbl_gamut = vmalloc(GAMUT_TOTAL_TABLE_SIZE_V1_7 * - sizeof(u32)); + tbl_gamut = vmalloc(array_size(GAMUT_TOTAL_TABLE_SIZE_V1_7, sizeof(u32))); if (!tbl_gamut) { pr_err("failed to allocate buffer for gamut size %zd", (GAMUT_TOTAL_TABLE_SIZE_V1_7 * sizeof(u32))); diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp_v1_7.c b/drivers/video/fbdev/msm/mdss_mdp_pp_v1_7.c index 5ffa4ad6b692..2ba16c97fcf8 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pp_v1_7.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pp_v1_7.c @@ -1834,7 +1834,7 @@ static int pp_igc_get_config(char __iomem *base_addr, void *cfg_data, goto exit; } /* Allocate for c0c1 and c2 tables */ - c0c1_data = kzalloc(sz * 2, GFP_KERNEL); + c0c1_data = kcalloc(sz, 2, GFP_KERNEL); if (!c0c1_data) { pr_err("allocation failed for c0c1 size %d\n", sz * 2); ret = -ENOMEM; @@ -1994,9 +1994,8 @@ static int pp_pgc_get_config(char __iomem *base_addr, void *cfg_data, PGC_LUT_ENTRIES); return -EFAULT; } - c0_data = kzalloc(sz * 3, GFP_KERNEL); - if (!c0_data) { - pr_err("memory allocation failure sz %d", sz * 3); + c0_data = kcalloc(sz, 3, GFP_KERNEL); + if (!c0_data) return -ENOMEM; } c1_data = c0_data + PGC_LUT_ENTRIES; diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h index c0e84c86c938..9e80044a0a6d 100644 --- a/drivers/video/fbdev/msm/mdss_panel.h +++ b/drivers/video/fbdev/msm/mdss_panel.h @@ -517,6 +517,7 @@ struct mipi_panel_info { char traffic_mode; char frame_rate; /* command mode */ + char frame_rate_idle; char interleave_max; char insert_dcs_cmd; char wr_mem_continue; @@ -940,6 +941,12 @@ struct mdss_panel_info { /* stores initial adaptive variable refresh vtotal value */ u32 saved_avr_vtotal; + /* + * Skip panel reset during panel on/off. + * Set for some in-cell panels + */ + bool skip_panel_reset; + /* HDR properties of display panel*/ struct mdss_panel_hdr_properties hdr_properties; @@ -1001,6 +1008,7 @@ struct mdss_panel_data { */ int (*event_handler) (struct mdss_panel_data *pdata, int e, void *arg); struct device_node *(*get_fb_node)(struct platform_device *pdev); + bool (*get_idle)(struct mdss_panel_data *pdata); struct list_head timings_list; struct mdss_panel_timing *current_timing; @@ -1036,6 +1044,10 @@ static inline u32 mdss_panel_get_framerate(struct mdss_panel_info *panel_info) { u32 frame_rate, pixel_total; u64 rate; + struct mdss_panel_data *panel_data = + container_of(panel_info, typeof(*panel_data), + panel_info); + bool idle = false; if (panel_info == NULL) return DEFAULT_FRAME_RATE; @@ -1044,6 +1056,12 @@ static inline u32 mdss_panel_get_framerate(struct mdss_panel_info *panel_info) case MIPI_VIDEO_PANEL: case MIPI_CMD_PANEL: frame_rate = panel_info->mipi.frame_rate; + if (panel_data->get_idle) + idle = panel_data->get_idle(panel_data); + if (idle) + frame_rate = panel_info->mipi.frame_rate_idle; + else + frame_rate = panel_info->mipi.frame_rate; break; case EDP_PANEL: frame_rate = panel_info->edp.frame_rate; diff --git a/drivers/video/fbdev/msm/mdss_rotator.c b/drivers/video/fbdev/msm/mdss_rotator.c index f285d793d520..0997384531af 100644 --- a/drivers/video/fbdev/msm/mdss_rotator.c +++ b/drivers/video/fbdev/msm/mdss_rotator.c @@ -1942,8 +1942,8 @@ static int mdss_rotator_open_session(struct mdss_rot_mgr *mgr, return -ENOMEM; ATRACE_BEGIN(__func__); /* Open session votes for bw */ - perf->work_distribution = devm_kzalloc(&mgr->pdev->dev, - sizeof(u32) * mgr->queue_count, GFP_KERNEL); + perf->work_distribution = devm_kcalloc(&mgr->pdev->dev, + mgr->queue_count, sizeof(u32), GFP_KERNEL); if (!perf->work_distribution) { ret = -ENOMEM; goto alloc_err; @@ -2696,8 +2696,9 @@ static int mdss_rotator_get_dt_vreg_data(struct device *dev, return 0; } mp->num_vreg = dt_vreg_total; - mp->vreg_config = devm_kzalloc(dev, sizeof(struct dss_vreg) * - dt_vreg_total, GFP_KERNEL); + mp->vreg_config = devm_kcalloc(dev, + dt_vreg_total, sizeof(struct dss_vreg), + GFP_KERNEL); if (!mp->vreg_config) { DEV_ERR("%s: can't alloc vreg mem\n", __func__); return -ENOMEM; diff --git a/drivers/video/fbdev/msm/mdss_smmu.c b/drivers/video/fbdev/msm/mdss_smmu.c index 79554f9a10b0..1fd7e5f7ff1c 100644 --- a/drivers/video/fbdev/msm/mdss_smmu.c +++ b/drivers/video/fbdev/msm/mdss_smmu.c @@ -196,8 +196,8 @@ static int mdss_smmu_util_parse_dt_clock(struct platform_device *pdev, } mp->num_clk = num_clk; - mp->clk_config = devm_kzalloc(&pdev->dev, - sizeof(struct dss_clk) * mp->num_clk, GFP_KERNEL); + mp->clk_config = devm_kcalloc(&pdev->dev, + mp->num_clk, sizeof(struct dss_clk), GFP_KERNEL); if (!mp->clk_config) { pr_err("clock configuration allocation failed\n"); rc = -ENOMEM; diff --git a/drivers/video/fbdev/msm/mdss_spi_panel.c b/drivers/video/fbdev/msm/mdss_spi_panel.c index 5f4f4eab0547..b973e97c109a 100644 --- a/drivers/video/fbdev/msm/mdss_spi_panel.c +++ b/drivers/video/fbdev/msm/mdss_spi_panel.c @@ -732,10 +732,12 @@ static void mdss_spi_parse_esd_params(struct device_node *np, ctrl->status_cmds_rlen = (!rc ? tmp : 1); - ctrl->exp_status_value = devm_kzalloc(&mdss_pdev->dev, sizeof(u8) * - (ctrl->status_cmds_rlen + 1), GFP_KERNEL); - ctrl->act_status_value = devm_kzalloc(&mdss_pdev->dev, sizeof(u8) * - (ctrl->status_cmds_rlen + 1), GFP_KERNEL); + ctrl->exp_status_value = devm_kzalloc(&mdss_pdev->dev, + ctrl->status_cmds_rlen + 1, + GFP_KERNEL); + ctrl->act_status_value = devm_kzalloc(&mdss_pdev->dev, + ctrl->status_cmds_rlen + 1, + GFP_KERNEL); if (!ctrl->exp_status_value || !ctrl->act_status_value) { pinfo->esd_check_enabled = false; diff --git a/drivers/video/fbdev/msm/msm_dba/adv7533.c b/drivers/video/fbdev/msm/msm_dba/adv7533.c index 49303625c3d9..50648aa5fc69 100644 --- a/drivers/video/fbdev/msm/msm_dba/adv7533.c +++ b/drivers/video/fbdev/msm/msm_dba/adv7533.c @@ -449,12 +449,13 @@ static void adv7533_parse_vreg_dt(struct device *dev, goto end; } mp->num_vreg = dt_vreg_total; - mp->vreg_config = devm_kzalloc(dev, sizeof(struct dss_vreg) * - dt_vreg_total, GFP_KERNEL); + mp->vreg_config = devm_kcalloc(dev, + dt_vreg_total, sizeof(struct dss_vreg), + GFP_KERNEL); if (!mp->vreg_config) goto end; - val_array = devm_kzalloc(dev, sizeof(u32) * dt_vreg_total, GFP_KERNEL); + val_array = devm_kcalloc(dev, dt_vreg_total, sizeof(u32), GFP_KERNEL); if (!val_array) goto end; diff --git a/drivers/video/fbdev/mxsfb.c b/drivers/video/fbdev/mxsfb.c index 7846f0e8bbbb..f3657d093ce5 100644 --- a/drivers/video/fbdev/mxsfb.c +++ b/drivers/video/fbdev/mxsfb.c @@ -925,7 +925,7 @@ static int mxsfb_probe(struct platform_device *pdev) if (IS_ERR(host->reg_lcd)) host->reg_lcd = NULL; - fb_info->pseudo_palette = devm_kzalloc(&pdev->dev, sizeof(u32) * 16, + fb_info->pseudo_palette = devm_kcalloc(&pdev->dev, 16, sizeof(u32), GFP_KERNEL); if (!fb_info->pseudo_palette) { ret = -ENOMEM; diff --git a/drivers/video/fbdev/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c index 418a2d0d06a9..2e50120bcfae 100644 --- a/drivers/video/fbdev/nvidia/nvidia.c +++ b/drivers/video/fbdev/nvidia/nvidia.c @@ -566,7 +566,7 @@ static int nvidiafb_cursor(struct fb_info *info, struct fb_cursor *cursor) u8 *msk = (u8 *) cursor->mask; u8 *src; - src = kmalloc(s_pitch * cursor->image.height, GFP_ATOMIC); + src = kmalloc_array(s_pitch, cursor->image.height, GFP_ATOMIC); if (src) { switch (cursor->rop) { diff --git a/drivers/video/fbdev/omap2/omapfb/dss/manager.c b/drivers/video/fbdev/omap2/omapfb/dss/manager.c index 69f86d2cc274..d21c641e1f3c 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/manager.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/manager.c @@ -42,8 +42,8 @@ int dss_init_overlay_managers(void) num_managers = dss_feat_get_num_mgrs(); - managers = kzalloc(sizeof(struct omap_overlay_manager) * num_managers, - GFP_KERNEL); + managers = kcalloc(num_managers, sizeof(struct omap_overlay_manager), + GFP_KERNEL); BUG_ON(managers == NULL); diff --git a/drivers/video/fbdev/omap2/omapfb/dss/overlay.c b/drivers/video/fbdev/omap2/omapfb/dss/overlay.c index d6c5d75d2ef8..be17a4785a5e 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/overlay.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/overlay.c @@ -59,8 +59,8 @@ void dss_init_overlays(struct platform_device *pdev) num_overlays = dss_feat_get_num_ovls(); - overlays = kzalloc(sizeof(struct omap_overlay) * num_overlays, - GFP_KERNEL); + overlays = kcalloc(num_overlays, sizeof(struct omap_overlay), + GFP_KERNEL); BUG_ON(overlays == NULL); diff --git a/drivers/video/fbdev/omap2/omapfb/vrfb.c b/drivers/video/fbdev/omap2/omapfb/vrfb.c index f346b02eee1d..f355ecfac3b1 100644 --- a/drivers/video/fbdev/omap2/omapfb/vrfb.c +++ b/drivers/video/fbdev/omap2/omapfb/vrfb.c @@ -359,8 +359,8 @@ static int __init vrfb_probe(struct platform_device *pdev) num_ctxs = pdev->num_resources - 1; - ctxs = devm_kzalloc(&pdev->dev, - sizeof(struct vrfb_ctx) * num_ctxs, + ctxs = devm_kcalloc(&pdev->dev, + num_ctxs, sizeof(struct vrfb_ctx), GFP_KERNEL); if (!ctxs) diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c index 867c5218968f..22e3850d970c 100644 --- a/drivers/video/fbdev/pvr2fb.c +++ b/drivers/video/fbdev/pvr2fb.c @@ -682,7 +682,7 @@ static ssize_t pvr2fb_write(struct fb_info *info, const char *buf, nr_pages = (count + PAGE_SIZE - 1) >> PAGE_SHIFT; - pages = kmalloc(nr_pages * sizeof(struct page *), GFP_KERNEL); + pages = kmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL); if (!pages) return -ENOMEM; diff --git a/drivers/video/fbdev/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c index 1ea78bb911fb..3ab9ff169cff 100644 --- a/drivers/video/fbdev/riva/fbdev.c +++ b/drivers/video/fbdev/riva/fbdev.c @@ -1615,7 +1615,7 @@ static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor) u8 *msk = (u8 *) cursor->mask; u8 *src; - src = kmalloc(s_pitch * cursor->image.height, GFP_ATOMIC); + src = kmalloc_array(s_pitch, cursor->image.height, GFP_ATOMIC); if (src) { switch (cursor->rop) { diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c index c592ca513115..440a6636d8f0 100644 --- a/drivers/video/fbdev/uvesafb.c +++ b/drivers/video/fbdev/uvesafb.c @@ -486,8 +486,9 @@ static int uvesafb_vbe_getmodes(struct uvesafb_ktask *task, mode++; } - par->vbe_modes = kzalloc(sizeof(struct vbe_mode_ib) * - par->vbe_modes_cnt, GFP_KERNEL); + par->vbe_modes = kcalloc(par->vbe_modes_cnt, + sizeof(struct vbe_mode_ib), + GFP_KERNEL); if (!par->vbe_modes) return -ENOMEM; @@ -858,7 +859,7 @@ static int uvesafb_vbe_init_mode(struct fb_info *info) * Convert the modelist into a modedb so that we can use it with * fb_find_mode(). */ - mode = kzalloc(i * sizeof(*mode), GFP_KERNEL); + mode = kcalloc(i, sizeof(*mode), GFP_KERNEL); if (mode) { i = 0; list_for_each(pos, &info->modelist) { diff --git a/drivers/video/fbdev/via/viafbdev.c b/drivers/video/fbdev/via/viafbdev.c index 71b5dca95bdb..a5857f917cb3 100644 --- a/drivers/video/fbdev/via/viafbdev.c +++ b/drivers/video/fbdev/via/viafbdev.c @@ -597,7 +597,8 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) break; case VIAFB_GET_GAMMA_LUT: - viafb_gamma_table = kmalloc(256 * sizeof(u32), GFP_KERNEL); + viafb_gamma_table = kmalloc_array(256, sizeof(u32), + GFP_KERNEL); if (!viafb_gamma_table) return -ENOMEM; viafb_get_gamma_table(viafb_gamma_table); diff --git a/drivers/video/fbdev/w100fb.c b/drivers/video/fbdev/w100fb.c index ffda1d68fb05..9e8496331ad3 100644 --- a/drivers/video/fbdev/w100fb.c +++ b/drivers/video/fbdev/w100fb.c @@ -695,7 +695,8 @@ int w100fb_probe(struct platform_device *pdev) goto out; } - info->pseudo_palette = kmalloc(sizeof (u32) * MAX_PALETTES, GFP_KERNEL); + info->pseudo_palette = kmalloc_array(MAX_PALETTES, sizeof(u32), + GFP_KERNEL); if (!info->pseudo_palette) { err = -ENOMEM; goto out; diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c index 46f63960fa9e..6a4bbc9e1fb0 100644 --- a/drivers/video/fbdev/xen-fbfront.c +++ b/drivers/video/fbdev/xen-fbfront.c @@ -412,7 +412,7 @@ static int xenfb_probe(struct xenbus_device *dev, info->nr_pages = (fb_size + PAGE_SIZE - 1) >> PAGE_SHIFT; - info->gfns = vmalloc(sizeof(unsigned long) * info->nr_pages); + info->gfns = vmalloc(array_size(sizeof(unsigned long), info->nr_pages)); if (!info->gfns) goto error_nomem; diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c index 8ce0a99bf17c..684e9ec5985c 100644 --- a/drivers/video/of_display_timing.c +++ b/drivers/video/of_display_timing.c @@ -181,8 +181,9 @@ struct display_timings *of_get_display_timings(const struct device_node *np) goto entryfail; } - disp->timings = kzalloc(sizeof(struct display_timing *) * - disp->num_timings, GFP_KERNEL); + disp->timings = kcalloc(disp->num_timings, + sizeof(struct display_timing *), + GFP_KERNEL); if (!disp->timings) { pr_err("%pOF: could not allocate timings array\n", np); goto entryfail; diff --git a/drivers/virt/fsl_hypervisor.c b/drivers/virt/fsl_hypervisor.c index 2e1678d22f6f..14748bb8b33f 100644 --- a/drivers/virt/fsl_hypervisor.c +++ b/drivers/virt/fsl_hypervisor.c @@ -226,7 +226,7 @@ static long ioctl_memcpy(struct fsl_hv_ioctl_memcpy __user *p) * 'pages' is an array of struct page pointers that's initialized by * get_user_pages(). */ - pages = kzalloc(num_pages * sizeof(struct page *), GFP_KERNEL); + pages = kcalloc(num_pages, sizeof(struct page *), GFP_KERNEL); if (!pages) { pr_debug("fsl-hv: could not allocate page list\n"); return -ENOMEM; diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c index 80a3704939cd..51527648ff0b 100644 --- a/drivers/virtio/virtio_pci_common.c +++ b/drivers/virtio/virtio_pci_common.c @@ -113,12 +113,13 @@ static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors, vp_dev->msix_vectors = nvectors; - vp_dev->msix_names = kmalloc(nvectors * sizeof *vp_dev->msix_names, - GFP_KERNEL); + vp_dev->msix_names = kmalloc_array(nvectors, + sizeof(*vp_dev->msix_names), + GFP_KERNEL); if (!vp_dev->msix_names) goto error; vp_dev->msix_affinity_masks - = kzalloc(nvectors * sizeof *vp_dev->msix_affinity_masks, + = kcalloc(nvectors, sizeof(*vp_dev->msix_affinity_masks), GFP_KERNEL); if (!vp_dev->msix_affinity_masks) goto error; diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index b82bb0b08161..03f85b80df88 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -248,7 +248,7 @@ static struct vring_desc *alloc_indirect(struct virtqueue *_vq, */ gfp &= ~__GFP_HIGHMEM; - desc = kmalloc(total_sg * sizeof(struct vring_desc), gfp); + desc = kmalloc_array(total_sg, sizeof(struct vring_desc), gfp); if (!desc) return NULL; diff --git a/drivers/vservices/devio.c b/drivers/vservices/devio.c index 8155c8c88dae..f95685e970a0 100644 --- a/drivers/vservices/devio.c +++ b/drivers/vservices/devio.c @@ -415,7 +415,7 @@ vs_devio_check_iov(struct vs_ioctl_iovec *io, bool is_send, ssize_t *total) if (io->iovcnt > UIO_MAXIOV) return ERR_PTR(-EINVAL); - iov = kmalloc(sizeof(*iov) * io->iovcnt, GFP_KERNEL); + iov = kmalloc_array(io->iovcnt, sizeof(*iov), GFP_KERNEL); if (!iov) return ERR_PTR(-ENOMEM); @@ -816,11 +816,11 @@ vs_devio_check_compat_iov(struct vs_compat_ioctl_iovec *c_io, if (c_io->iovcnt > UIO_MAXIOV) return ERR_PTR(-EINVAL); - c_iov = kzalloc(sizeof(*c_iov) * c_io->iovcnt, GFP_KERNEL); + c_iov = kcalloc(c_io->iovcnt, sizeof(*c_iov), GFP_KERNEL); if (!c_iov) return ERR_PTR(-ENOMEM); - iov = kzalloc(sizeof(*iov) * c_io->iovcnt, GFP_KERNEL); + iov = kcalloc(c_io->iovcnt, sizeof(*iov), GFP_KERNEL); if (!iov) { kfree(c_iov); return ERR_PTR(-ENOMEM); diff --git a/drivers/vservices/transport/axon.c b/drivers/vservices/transport/axon.c index 4604b2831922..a66d3f013f26 100644 --- a/drivers/vservices/transport/axon.c +++ b/drivers/vservices/transport/axon.c @@ -3056,8 +3056,8 @@ static int transport_axon_setup_descs(struct vs_transport_axon *transport) } /* Array of pointers to the source TX pool for each outgoing buffer. */ - transport->tx_pools = devm_kzalloc(transport->axon_dev, - sizeof(*transport->tx_pools) * transport->queue_size, + transport->tx_pools = devm_kcalloc(transport->axon_dev, + transport->queue_size, sizeof(*transport->tx_pools), GFP_KERNEL); if (!transport->tx_pools) { err = -ENOMEM; diff --git a/drivers/xen/arm-device.c b/drivers/xen/arm-device.c index 85dd20e05726..3e789c77f568 100644 --- a/drivers/xen/arm-device.c +++ b/drivers/xen/arm-device.c @@ -70,9 +70,9 @@ static int xen_map_device_mmio(const struct resource *resources, if ((resource_type(r) != IORESOURCE_MEM) || (nr == 0)) continue; - gpfns = kzalloc(sizeof(xen_pfn_t) * nr, GFP_KERNEL); - idxs = kzalloc(sizeof(xen_ulong_t) * nr, GFP_KERNEL); - errs = kzalloc(sizeof(int) * nr, GFP_KERNEL); + gpfns = kcalloc(nr, sizeof(xen_pfn_t), GFP_KERNEL); + idxs = kcalloc(nr, sizeof(xen_ulong_t), GFP_KERNEL); + errs = kcalloc(nr, sizeof(int), GFP_KERNEL); if (!gpfns || !idxs || !errs) { kfree(gpfns); kfree(idxs); diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index 055123f48039..0f4ce6c09763 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c @@ -322,7 +322,7 @@ static int evtchn_resize_ring(struct per_user_data *u) else new_size = 2 * u->ring_size; - new_ring = kvmalloc(new_size * sizeof(*new_ring), GFP_KERNEL); + new_ring = kvmalloc_array(new_size, sizeof(*new_ring), GFP_KERNEL); if (!new_ring) return -ENOMEM; diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 1fb374466e84..9047187dd9b7 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -990,7 +990,7 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx) /* No need for kzalloc as it is initialized in following hypercall * GNTTABOP_setup_table. */ - frames = kmalloc(nr_gframes * sizeof(unsigned long), GFP_ATOMIC); + frames = kmalloc_array(nr_gframes, sizeof(unsigned long), GFP_ATOMIC); if (!frames) return -ENOMEM; @@ -1108,8 +1108,9 @@ int gnttab_init(void) max_nr_glist_frames = (max_nr_grant_frames * grefs_per_grant_frame / RPP); - gnttab_list = kmalloc(max_nr_glist_frames * sizeof(grant_ref_t *), - GFP_KERNEL); + gnttab_list = kmalloc_array(max_nr_glist_frames, + sizeof(grant_ref_t *), + GFP_KERNEL); if (gnttab_list == NULL) return -ENOMEM; diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c index 7af047008ea2..787966f44589 100644 --- a/drivers/xen/xen-pciback/pciback_ops.c +++ b/drivers/xen/xen-pciback/pciback_ops.c @@ -232,7 +232,7 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev, if (dev->msi_enabled || !(cmd & PCI_COMMAND_MEMORY)) return -ENXIO; - entries = kmalloc(op->value * sizeof(*entries), GFP_KERNEL); + entries = kmalloc_array(op->value, sizeof(*entries), GFP_KERNEL); if (entries == NULL) return -ENOMEM; diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c index 47728477297e..875e569bf123 100644 --- a/drivers/zorro/zorro.c +++ b/drivers/zorro/zorro.c @@ -136,8 +136,7 @@ static int __init amiga_zorro_probe(struct platform_device *pdev) int error; /* Initialize the Zorro bus */ - bus = kzalloc(sizeof(*bus) + - zorro_num_autocon * sizeof(bus->devices[0]), + bus = kzalloc(struct_size(bus, devices, zorro_num_autocon), GFP_KERNEL); if (!bus) return -ENOMEM; diff --git a/fs/9p/fid.c b/fs/9p/fid.c index ed4f8519b627..a9ef46f02354 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -100,7 +100,7 @@ static int build_path_from_dentry(struct v9fs_session_info *v9ses, for (ds = dentry; !IS_ROOT(ds); ds = ds->d_parent) n++; - wnames = kmalloc(sizeof(char *) * n, GFP_KERNEL); + wnames = kmalloc_array(n, sizeof(char *), GFP_KERNEL); if (!wnames) goto err_out; diff --git a/fs/Kconfig b/fs/Kconfig index 45bdb320743f..a1f9a02733b5 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -316,4 +316,6 @@ config FILE_TABLE_DEBUG help This option enables debug of the open files using a global filetable +source "fs/exfat/Kconfig" + endmenu diff --git a/fs/Makefile b/fs/Makefile index b27c7bb26d51..67a46cf408b4 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -136,3 +136,4 @@ obj-y += exofs/ # Multiple modules obj-$(CONFIG_CEPH_FS) += ceph/ obj-$(CONFIG_PSTORE) += pstore/ obj-$(CONFIG_EFIVAR_FS) += efivarfs/ +obj-$(CONFIG_EXFAT_FS) += exfat/ diff --git a/fs/adfs/super.c b/fs/adfs/super.c index e42c30001509..6d04905e9774 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c @@ -313,7 +313,7 @@ static struct adfs_discmap *adfs_read_map(struct super_block *sb, struct adfs_di asb->s_ids_per_zone = zone_size / (asb->s_idlen + 1); - dm = kmalloc(nzones * sizeof(*dm), GFP_KERNEL); + dm = kmalloc_array(nzones, sizeof(*dm), GFP_KERNEL); if (dm == NULL) { adfs_error(sb, "not enough memory"); return ERR_PTR(-ENOMEM); diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c index c7475867a52b..63100f8b00f9 100644 --- a/fs/afs/cmservice.c +++ b/fs/afs/cmservice.c @@ -212,7 +212,8 @@ static int afs_deliver_cb_callback(struct afs_call *call) if (call->count > AFSCBMAX) return -EBADMSG; - call->buffer = kmalloc(call->count * 3 * 4, GFP_KERNEL); + call->buffer = kmalloc(array3_size(call->count, 3, 4), + GFP_KERNEL); if (!call->buffer) return -ENOMEM; call->offset = 0; @@ -367,7 +368,7 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) switch (call->unmarshall) { case 0: call->offset = 0; - call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL); + call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL); if (!call->buffer) return -ENOMEM; call->unmarshall++; @@ -489,7 +490,7 @@ static int afs_deliver_cb_probe_uuid(struct afs_call *call) switch (call->unmarshall) { case 0: call->offset = 0; - call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL); + call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL); if (!call->buffer) return -ENOMEM; call->unmarshall++; diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index fe31f911a648..0d010cd5fb38 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1999,7 +1999,7 @@ static int elf_note_info_init(struct elf_note_info *info) INIT_LIST_HEAD(&info->thread_list); /* Allocate space for ELF notes */ - info->notes = kmalloc(8 * sizeof(struct memelfnote), GFP_KERNEL); + info->notes = kmalloc_array(8, sizeof(struct memelfnote), GFP_KERNEL); if (!info->notes) return 0; info->psinfo = kmalloc(sizeof(*info->psinfo), GFP_KERNEL); @@ -2283,7 +2283,7 @@ static int elf_core_dump(struct coredump_params *cprm) if (segs - 1 > ULONG_MAX / sizeof(*vma_filesz)) goto end_coredump; - vma_filesz = vmalloc((segs - 1) * sizeof(*vma_filesz)); + vma_filesz = vmalloc(array_size(sizeof(*vma_filesz), (segs - 1))); if (!vma_filesz) goto end_coredump; diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index e70c039ac190..9fa4bfafcc51 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -1588,7 +1588,8 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) psinfo = kmalloc(sizeof(*psinfo), GFP_KERNEL); if (!psinfo) goto cleanup; - notes = kmalloc(NUM_NOTES * sizeof(struct memelfnote), GFP_KERNEL); + notes = kmalloc_array(NUM_NOTES, sizeof(struct memelfnote), + GFP_KERNEL); if (!notes) goto cleanup; fpu = kmalloc(sizeof(*fpu), GFP_KERNEL); diff --git a/fs/block_dev.c b/fs/block_dev.c index 9584df0e29b1..b8605000216e 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -231,7 +231,8 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter, if (nr_pages <= DIO_INLINE_BIO_VECS) vecs = inline_vecs; else { - vecs = kmalloc(nr_pages * sizeof(struct bio_vec), GFP_KERNEL); + vecs = kmalloc_array(nr_pages, sizeof(struct bio_vec), + GFP_KERNEL); if (!vecs) return -ENOMEM; } diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index 4be07cf31d74..42e898b2cf35 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c @@ -1615,8 +1615,7 @@ static int btrfsic_read_block(struct btrfsic_state *state, num_pages = (block_ctx->len + (u64)PAGE_SIZE - 1) >> PAGE_SHIFT; - block_ctx->mem_to_free = kzalloc((sizeof(*block_ctx->datav) + - sizeof(*block_ctx->pagev)) * + block_ctx->mem_to_free = kcalloc(sizeof(*block_ctx->datav) + sizeof(*block_ctx->pagev), num_pages, GFP_NOFS); if (!block_ctx->mem_to_free) return -ENOMEM; diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c index c073a0f680fd..a3e279894c6d 100644 --- a/fs/cachefiles/rdwr.c +++ b/fs/cachefiles/rdwr.c @@ -263,8 +263,7 @@ static int cachefiles_read_backing_file_one(struct cachefiles_object *object, goto backing_page_already_present; if (!newpage) { - newpage = __page_cache_alloc(cachefiles_gfp | - __GFP_COLD); + newpage = __page_cache_alloc(cachefiles_gfp); if (!newpage) goto nomem_monitor; } @@ -500,8 +499,7 @@ static int cachefiles_read_backing_file(struct cachefiles_object *object, goto backing_page_already_present; if (!newpage) { - newpage = __page_cache_alloc(cachefiles_gfp | - __GFP_COLD); + newpage = __page_cache_alloc(cachefiles_gfp); if (!newpage) goto nomem; } diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 26c682db94ee..7052639a7ebd 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -368,7 +368,7 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max) /* build page vector */ nr_pages = calc_pages_for(0, len); - pages = kmalloc(sizeof(*pages) * nr_pages, GFP_KERNEL); + pages = kmalloc_array(nr_pages, sizeof(*pages), GFP_KERNEL); if (!pages) { ret = -ENOMEM; goto out_put; @@ -958,8 +958,9 @@ get_more_pages: BUG_ON(pages); max_pages = calc_pages_for(0, (u64)len); - pages = kmalloc(max_pages * sizeof (*pages), - GFP_NOFS); + pages = kmalloc_array(max_pages, + sizeof(*pages), + GFP_NOFS); if (!pages) { pool = fsc->wb_pagevec_pool; pages = mempool_alloc(pool, GFP_NOFS); @@ -1105,8 +1106,8 @@ new_request: /* allocate new pages array for next request */ data_pages = pages; - pages = kmalloc(locked_pages * sizeof (*pages), - GFP_NOFS); + pages = kmalloc_array(locked_pages, sizeof(*pages), + GFP_NOFS); if (!pages) { pool = fsc->wb_pagevec_pool; pages = mempool_alloc(pool, GFP_NOFS); diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 6d653235e323..d20598614ace 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -107,7 +107,7 @@ dio_get_pages_alloc(const struct iov_iter *it, size_t nbytes, align = (unsigned long)(it->iov->iov_base + it->iov_offset) & (PAGE_SIZE - 1); npages = calc_pages_for(align, nbytes); - pages = kvmalloc(sizeof(*pages) * npages, GFP_KERNEL); + pages = kvmalloc_array(npages, sizeof(*pages), GFP_KERNEL); if (!pages) return ERR_PTR(-ENOMEM); diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index f36ddfea4997..5178874baf55 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -2981,8 +2981,9 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, encode_again: ceph_count_locks(inode, &num_fcntl_locks, &num_flock_locks); - flocks = kmalloc((num_fcntl_locks+num_flock_locks) * - sizeof(struct ceph_filelock), GFP_NOFS); + flocks = kmalloc_array(num_fcntl_locks + num_flock_locks, + sizeof(struct ceph_filelock), + GFP_NOFS); if (!flocks) { err = -ENOMEM; goto out_free; diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c index a3b56544c21b..3d19595eb352 100644 --- a/fs/cifs/asn1.c +++ b/fs/cifs/asn1.c @@ -428,7 +428,7 @@ asn1_oid_decode(struct asn1_ctx *ctx, if (size < 2 || size > UINT_MAX/sizeof(unsigned long)) return 0; - *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); + *oid = kmalloc_array(size, sizeof(unsigned long), GFP_ATOMIC); if (*oid == NULL) return 0; diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 73d428af97a9..207be1fae2f8 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c @@ -747,8 +747,8 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *)) return; - ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), - GFP_KERNEL); + ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *), + GFP_KERNEL); if (!ppace) return; diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index b76e73395299..15a586e78e33 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1821,7 +1821,7 @@ cifs_rename2(struct inode *source_dir, struct dentry *source_dentry, * with unix extensions enabled. */ info_buf_source = - kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), + kmalloc_array(2, sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); if (info_buf_source == NULL) { rc = -ENOMEM; diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 76f1649ab444..6ff2c88e45e5 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -815,7 +815,7 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw) GFP_KERNEL); if (!bv) { - bv = vmalloc(max_pages * sizeof(struct bio_vec)); + bv = vmalloc(array_size(max_pages, sizeof(struct bio_vec))); if (!bv) return -ENOMEM; } @@ -825,7 +825,7 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw) GFP_KERNEL); if (!pages) { - pages = vmalloc(max_pages * sizeof(struct page *)); + pages = vmalloc(array_size(max_pages, sizeof(struct page *))); if (!pages) { kvfree(bv); return -ENOMEM; diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 1c87a429ce72..58dc8496a145 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -3150,7 +3150,7 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon, if (!num) return -EINVAL; - iov = kmalloc(sizeof(struct kvec) * num, GFP_KERNEL); + iov = kmalloc_array(num, sizeof(struct kvec), GFP_KERNEL); if (!iov) return -ENOMEM; @@ -3213,7 +3213,7 @@ SMB2_rename(const unsigned int xid, struct cifs_tcon *tcon, int rc; int len = (2 * UniStrnlen((wchar_t *)target_file, PATH_MAX)); - data = kmalloc(sizeof(void *) * 2, GFP_KERNEL); + data = kmalloc_array(2, sizeof(void *), GFP_KERNEL); if (!data) return -ENOMEM; @@ -3261,7 +3261,7 @@ SMB2_set_hardlink(const unsigned int xid, struct cifs_tcon *tcon, int rc; int len = (2 * UniStrnlen((wchar_t *)target_file, PATH_MAX)); - data = kmalloc(sizeof(void *) * 2, GFP_KERNEL); + data = kmalloc_array(2, sizeof(void *), GFP_KERNEL); if (!data) return -ENOMEM; diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index ffc8757e5a3c..f1d2ac7ce1fa 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -822,7 +822,7 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses, struct kvec *new_iov; int rc; - new_iov = kmalloc(sizeof(struct kvec) * (n_vec + 1), GFP_KERNEL); + new_iov = kmalloc_array(n_vec + 1, sizeof(struct kvec), GFP_KERNEL); if (!new_iov) return -ENOMEM; diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index 9c8c9a09b4a6..f1261fa0af8a 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -517,7 +517,7 @@ static int new_lockspace(const char *name, const char *cluster, size = dlm_config.ci_rsbtbl_size; ls->ls_rsbtbl_size = size; - ls->ls_rsbtbl = vmalloc(sizeof(struct dlm_rsbtable) * size); + ls->ls_rsbtbl = vmalloc(array_size(size, sizeof(struct dlm_rsbtable))); if (!ls->ls_rsbtbl) goto out_lsfree; for (i = 0; i < size; i++) { diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 6b801186baa5..25aeaa7328ba 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -660,7 +660,7 @@ static struct ecryptfs_cache_info { struct kmem_cache **cache; const char *name; size_t size; - unsigned long flags; + slab_flags_t flags; void (*ctor)(void *obj); } ecryptfs_cache_infos[] = { { diff --git a/fs/exec.c b/fs/exec.c index 8dd583d0ef22..3fb5e4bd523e 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -77,15 +77,14 @@ int suid_dumpable = 0; static LIST_HEAD(formats); static DEFINE_RWLOCK(binfmt_lock); -#define ZYGOTE32_BIN "/system/bin/app_process32" -#define ZYGOTE64_BIN "/system/bin/app_process64" -static atomic_t zygote32_pid; -static atomic_t zygote64_pid; +#define ZYGOTE32_BIN "/system/bin/app_process32" +#define ZYGOTE64_BIN "/system/bin/app_process64" +static struct signal_struct *zygote32_sig; +static struct signal_struct *zygote64_sig; -bool is_zygote_pid(pid_t pid) +bool task_is_zygote(struct task_struct *p) { - return atomic_read(&zygote32_pid) == pid || - atomic_read(&zygote64_pid) == pid; + return p->signal == zygote32_sig || p->signal == zygote64_sig; } void __register_binfmt(struct linux_binfmt * fmt, int insert) @@ -1810,11 +1809,11 @@ static int do_execveat_common(int fd, struct filename *filename, if (retval < 0) goto out; - if (capable(CAP_SYS_ADMIN)) { + if (is_global_init(current->parent)) { if (unlikely(!strcmp(filename->name, ZYGOTE32_BIN))) - atomic_set(&zygote32_pid, current->pid); + zygote32_sig = current->signal; else if (unlikely(!strcmp(filename->name, ZYGOTE64_BIN))) - atomic_set(&zygote64_pid, current->pid); + zygote64_sig = current->signal; } /* execve succeeded */ diff --git a/fs/exfat/.gitignore b/fs/exfat/.gitignore new file mode 100644 index 000000000000..810b0062282a --- /dev/null +++ b/fs/exfat/.gitignore @@ -0,0 +1,142 @@ +# +# NOTE! Don't add files that are generated in specific +# subdirectories here. Add them in the ".gitignore" file +# in that subdirectory instead. +# +# NOTE! Please use 'git ls-files -i --exclude-standard' +# command after changing this file, to see if there are +# any tracked files which get ignored after the change. +# +# Normal rules (sorted alphabetically) +# +.* +*.a +*.asn1.[ch] +*.bin +*.bz2 +*.c.[012]*.* +*.dt.yaml +*.dtb +*.dtb.S +*.dwo +*.elf +*.gcno +*.gz +*.i +*.ko +*.lex.c +*.ll +*.lst +*.lz4 +*.lzma +*.lzo +*.mod +*.mod.c +*.o +*.o.* +*.order +*.patch +*.s +*.so +*.so.dbg +*.su +*.symtypes +*.tab.[ch] +*.tar +*.xz +Module.symvers +modules.builtin + +# +# Top-level generic files +# +/tags +/TAGS +/linux +/vmlinux +/vmlinux.32 +/vmlinux-gdb.py +/vmlinuz +/System.map +/Module.markers +/modules.builtin.modinfo + +# +# RPM spec file (make rpm-pkg) +# +/*.spec + +# +# Snap directory (make snap-pkg) +# +/snap/ + +# +# tar directory (make tar*-pkg) +# +/tar-install/ + +# +# We don't want to ignore the following even if they are dot-files +# +!.clang-format +!.cocciconfig +!.get_maintainer.ignore +!.gitattributes +!.gitignore +!.mailmap + +# +# Generated include files +# +/include/config/ +/include/generated/ +/include/ksym/ +/arch/*/include/generated/ + +# stgit generated dirs +patches-* + +# quilt's files +patches +series + +# cscope files +cscope.* +ncscope.* + +# gnu global files +GPATH +GRTAGS +GSYMS +GTAGS + +# id-utils files +ID + +*.orig +*~ +\#*# + +# +# Leavings from module signing +# +extra_certificates +signing_key.pem +signing_key.priv +signing_key.x509 +x509.genkey + +# Kconfig presets +/all.config +/alldef.config +/allmod.config +/allno.config +/allrandom.config +/allyes.config + +# Kdevelop4 +*.kdev4 + +# Clang's compilation database file +/compile_commands.json diff --git a/fs/exfat/Kconfig b/fs/exfat/Kconfig new file mode 100644 index 000000000000..e9841704f743 --- /dev/null +++ b/fs/exfat/Kconfig @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +config EXFAT_FS + tristate "exFAT filesystem support" + select NLS + help + This allows you to mount devices formatted with the exFAT file system. + exFAT is typically used on SD-Cards or USB sticks. + + To compile this as a module, choose M here: the module will be called + exfat. + +if EXFAT_FS + +config EXFAT_DEFAULT_IOCHARSET + string "Default iocharset for exFAT" + default "utf8" + help + Set this to the default input/output character set to use for + converting between the encoding that is used for user visible + filenames and the UTF-16 character encoding that the exFAT + filesystem uses. This can be overridden with the "iocharset" mount + option for the exFAT filesystems. + +config EXFAT_VIRTUAL_XATTR + bool "Virtual xattr support for exFAT" + default y + help + To support virtual xattr. + +config EXFAT_VIRTUAL_XATTR_SELINUX_LABEL + string "Default string for SELinux label" + default "u:object_r:exfat:s0" + depends on EXFAT_VIRTUAL_XATTR + help + Set this to the default string for SELinux label. + Support for "u:object_r:exfat:s0" was added in Android Pie, + if you're running Oreo or lower, use "u:object_r:vfat:s0" instead. + +endif # if EXFAT_FS diff --git a/fs/exfat/LICENSE b/fs/exfat/LICENSE new file mode 100644 index 000000000000..ff0812fd89cc --- /dev/null +++ b/fs/exfat/LICENSE @@ -0,0 +1,359 @@ +Valid-License-Identifier: GPL-2.0 +Valid-License-Identifier: GPL-2.0-only +Valid-License-Identifier: GPL-2.0+ +Valid-License-Identifier: GPL-2.0-or-later +SPDX-URL: https://spdx.org/licenses/GPL-2.0.html +Usage-Guide: + To use this license in source code, put one of the following SPDX + tag/value pairs into a comment according to the placement + guidelines in the licensing rules documentation. + For 'GNU General Public License (GPL) version 2 only' use: + SPDX-License-Identifier: GPL-2.0 + or + SPDX-License-Identifier: GPL-2.0-only + For 'GNU General Public License (GPL) version 2 or any later version' use: + SPDX-License-Identifier: GPL-2.0+ + or + SPDX-License-Identifier: GPL-2.0-or-later +License-Text: + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/fs/exfat/Makefile b/fs/exfat/Makefile new file mode 100644 index 000000000000..a9b6a5ff98bc --- /dev/null +++ b/fs/exfat/Makefile @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Makefile for the linux exFAT filesystem support. +# + +ifneq ($(KERNELRELEASE),) +# Called from inline kernel build +# DKMS_DEFINE +obj-$(CONFIG_EXFAT_FS) += exfat.o + +exfat-objs := inode.o namei.o dir.o super.o fatent.o cache.o nls.o misc.o \ + file.o balloc.o xattr.o +else +# Called from external kernel module build + +KERNELRELEASE ?= $(shell uname -r) +KDIR ?= /lib/modules/${KERNELRELEASE}/build +MDIR ?= /lib/modules/${KERNELRELEASE} +PWD := $(shell pwd) + +export CONFIG_EXFAT_FS := m + +all: + $(MAKE) -C $(KDIR) M=$(PWD) modules + +clean: + $(MAKE) -C $(KDIR) M=$(PWD) clean + +help: + $(MAKE) -C $(KDIR) M=$(PWD) help + +install: exfat.ko + rm -f ${MDIR}/kernel/fs/exfat/exfat.ko + install -m644 -b -D exfat.ko ${MDIR}/kernel/fs/exfat/exfat.ko + depmod -aq + +uninstall: + rm -rf ${MDIR}/kernel/fs/exfat + depmod -aq + +endif + +.PHONY : all clean install uninstall diff --git a/fs/exfat/README.md b/fs/exfat/README.md new file mode 100644 index 000000000000..d1f44c532306 --- /dev/null +++ b/fs/exfat/README.md @@ -0,0 +1,184 @@ +# exfat-linux + +This __exFAT filesystem module for Linux kernel__ is a backport of the latest Linux mainline's exFAT drivers by Samsung. + +This project can be used for everyday Linux users by simply doing `make && make install`. Ubuntu users can simply add a PPA and start using it, without even downloading the code. This can also be directly dropped-in to an existing Linux kernel source for building the filesystem drivers inline, which should be useful for Android kernel developers. + +**exfat-linux** has been tested with all major LTS kernels ranging from v4.9 to v5.4 and the ones Canonical uses for Ubuntu: `v4.9`, `v4.14`, `v4.19`, `v5.4` and `v4.15`, `v5.3`, and `v5.6`. + +It's also been tested with `x86(i386)`, `x86_64(amd64)`, `arm32(AArch32)` and `arm64(AArch64)`. + +Linux kernels since `v5.4` includes an exFAT driver, but it is an extremely outdated version from 2016. This was later revised by Samsung directly with `v5.7`. + +People on `v5.7` kernel or higher can just use the bundled exFAT drivers. + +People on `v5.4+` are highly recommended to use this drivers. + +Support for kernel versions lower than `v4.9` were dropped for easier maintenance. For people interested in exFAT support for said kernels, please use the [old branch](https://github.com/arter97/exfat-linux/tree/old). It still works nicely and it's actively being shipped to production smartphones. + +exfat-linux is planned to be maintained until Android devices with `v5.7+` LTS kernel become more common. + +## Disclaimer + +#### ● Original authorship and copyright: Samsung + +#### ● Maintainer of exfat-linux: Park Ju Hyung([arter97](https://twitter.com/arter97)) + +## Using exfat-linux + +### ● Ubuntu PPA + +If you're an Ubuntu user, you can simply add a [PPA repository](https://launchpad.net/~arter97/+archive/ubuntu/exfat-linux) and start using the exFAT module. + +Ubuntu will handle upgrades automatically as well. + +1. Add the exfat-linux repository + + ``` + sudo add-apt-repository ppa:arter97/exfat-linux + sudo apt update + ``` + +2. Install the module + + `sudo apt install exfat-dkms` + +This will use DKMS(Dynamic Kernel Module Support) and automatically build exFAT module for your current Ubuntu installation. + +### ● Manually installing the module + +1. Download the code + + ``` + git clone https://github.com/arter97/exfat-linux + cd exfat-linux + ``` + +2. Build + + `make` + +3. Install + + `sudo make install` + +This will install the module to your __currently running kernel__. + +__If you're running a `v5.4+` kernel, it is highly recommended to reboot at this point to prevent the existing staging exFAT drivers to load.__ + +4. And finally load + + `sudo modprobe exfat` + +If you upgrade the kernel, you'll have to repeat this process. + +If you want to update **exfat-linux** to the latest version, you'll have to repeat this process. + +### ● Merging the drivers to existing Linux kernel source + +If you're using `git`, using `git subtree` or `git submodule` is highly recommended. + +1. Add this repository to `fs/exfat` + +2. Modify `fs/Kconfig` + +``` + menu "DOS/FAT/NT Filesystems" + + source "fs/fat/Kconfig" ++source "fs/exfat/Kconfig" + source "fs/ntfs/Kconfig" + endmenu +``` + +3. Modify `fs/Makefile` + +``` + obj-$(CONFIG_FAT_FS) += fat/ ++obj-$(CONFIG_EXFAT_FS) += exfat/ + obj-$(CONFIG_BFS_FS) += bfs/ +``` + +And you're good to go! + +## Benchmarks + +For reference, existing exFAT implementations were tested and compared on a server running Ubuntu 16.04 with Linux kernel 4.14 under a contained virtual machine. + +Linux 4.14 was used as higher LTS kernels don't work with [exfat-nofuse] at the time of testing. + +__The new base backported from mainline is not benchmarked yet.__ + +### ● Ramdisk + +#### fio sequential I/O + +| Implementation | Base | Read | Write | +| --------------- | ------ | ------------ | ------------ | +| **exfat-linux** | 2.2.0 | 7042 MB/s | 2173 MB/s | +| [exfat-nofuse] | 1.2.9 | 6849 MB/s | 1961 MB/s | +| [exfat-fuse] | N/A | 3097 MB/s | 1710 MB/s | +| ext4 | N/A | 7352 MB/s | 3333 MB/s | + +#### fio random I/O + +| Implementation | Base | Read | Write | +| --------------- | ------ | ------------ | ------------ | +| **exfat-linux** | 2.2.0 | 760 MB/s | 2222 MB/s | +| [exfat-nofuse] | 1.2.9 | 760 MB/s | 2160 MB/s | +| [exfat-fuse] | N/A | 1.7 MB/s | 1.6 MB/s | +| ext4 | N/A | 747 MB/s | 2816 MB/s | + +### ● NVMe device + +#### fio sequential I/O + +| Implementation | Base | Read | Write | +| --------------- | ------ | ------------ | ------------ | +| **exfat-linux** | 2.2.0 | 1283 MB/s | 1832 MB/s | +| [exfat-nofuse] | 1.2.9 | 1285 MB/s | 1678 MB/s | +| [exfat-fuse] | N/A | 751 MB/s | 1464 MB/s | +| ext4 | N/A | 1283 MB/s | 3356 MB/s | + +#### fio random I/O + +| Implementation | Base | Read | Write | +| --------------- | ------ | ------------ | ------------ | +| **exfat-linux** | 2.2.0 | 26 MB/s | 1885 MB/s | +| [exfat-nofuse] | 1.2.9 | 24 MB/s | 1827 MB/s | +| [exfat-fuse] | N/A | 1.6 MB/s | 1.6 MB/s | +| ext4 | N/A | 29 MB/s | 2821 MB/s | + +[exfat-fuse]: https://github.com/relan/exfat + +## Mount options + +* uid +* gid +* umask +* dmask +* fmask +* allow_utime +* iocharset +* quiet +* time_offset + + * Please refer to the [vfat](https://github.com/torvalds/linux/blob/master/Documentation/filesystems/vfat.txt)'s documentation. + +* errors=continue + + * Keep going on a filesystem error. + +* errors=panic + + * Panic and halt the machine if an error occurs. + +* errors=remount-ro + + * Remount the filesystem read-only on an error. + +* discard + + * Enable the use of discard/TRIM commands to ensure flash storage doesn't run out of free blocks. This option may introduce latency penalty on file removal operations. + +## Enjoy! diff --git a/fs/exfat/balloc.c b/fs/exfat/balloc.c new file mode 100644 index 000000000000..d8c398b005b5 --- /dev/null +++ b/fs/exfat/balloc.c @@ -0,0 +1,274 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#include +#include +#include + +#include "exfat_fs.h" + +static const unsigned char free_bit[] = { + 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2,/* 0 ~ 19*/ + 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3,/* 20 ~ 39*/ + 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2,/* 40 ~ 59*/ + 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,/* 60 ~ 79*/ + 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2,/* 80 ~ 99*/ + 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3,/*100 ~ 119*/ + 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2,/*120 ~ 139*/ + 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5,/*140 ~ 159*/ + 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2,/*160 ~ 179*/ + 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3,/*180 ~ 199*/ + 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2,/*200 ~ 219*/ + 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,/*220 ~ 239*/ + 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 /*240 ~ 254*/ +}; + +static const unsigned char used_bit[] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3,/* 0 ~ 19*/ + 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4,/* 20 ~ 39*/ + 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5,/* 40 ~ 59*/ + 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,/* 60 ~ 79*/ + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4,/* 80 ~ 99*/ + 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,/*100 ~ 119*/ + 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4,/*120 ~ 139*/ + 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,/*140 ~ 159*/ + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5,/*160 ~ 179*/ + 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5,/*180 ~ 199*/ + 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6,/*200 ~ 219*/ + 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,/*220 ~ 239*/ + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 /*240 ~ 255*/ +}; + +/* + * Allocation Bitmap Management Functions + */ +static int exfat_allocate_bitmap(struct super_block *sb, + struct exfat_dentry *ep) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + long long map_size; + unsigned int i, need_map_size; + sector_t sector; + + sbi->map_clu = le32_to_cpu(ep->dentry.bitmap.start_clu); + map_size = le64_to_cpu(ep->dentry.bitmap.size); + need_map_size = ((EXFAT_DATA_CLUSTER_COUNT(sbi) - 1) / BITS_PER_BYTE) + + 1; + if (need_map_size != map_size) { + exfat_err(sb, "bogus allocation bitmap size(need : %u, cur : %lld)", + need_map_size, map_size); + /* + * Only allowed when bogus allocation + * bitmap size is large + */ + if (need_map_size > map_size) + return -EIO; + } + sbi->map_sectors = ((need_map_size - 1) >> + (sb->s_blocksize_bits)) + 1; + sbi->vol_amap = kmalloc_array(sbi->map_sectors, + sizeof(struct buffer_head *), GFP_KERNEL); + if (!sbi->vol_amap) + return -ENOMEM; + + sector = exfat_cluster_to_sector(sbi, sbi->map_clu); + for (i = 0; i < sbi->map_sectors; i++) { + sbi->vol_amap[i] = sb_bread(sb, sector + i); + if (!sbi->vol_amap[i]) { + /* release all buffers and free vol_amap */ + int j = 0; + + while (j < i) + brelse(sbi->vol_amap[j++]); + + kfree(sbi->vol_amap); + sbi->vol_amap = NULL; + return -EIO; + } + } + + return 0; +} + +int exfat_load_bitmap(struct super_block *sb) +{ + unsigned int i, type; + struct exfat_chain clu; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + exfat_chain_set(&clu, sbi->root_dir, 0, ALLOC_FAT_CHAIN); + while (clu.dir != EXFAT_EOF_CLUSTER) { + for (i = 0; i < sbi->dentries_per_clu; i++) { + struct exfat_dentry *ep; + struct buffer_head *bh; + + ep = exfat_get_dentry(sb, &clu, i, &bh, NULL); + if (!ep) + return -EIO; + + type = exfat_get_entry_type(ep); + if (type == TYPE_UNUSED) + break; + if (type != TYPE_BITMAP) + continue; + if (ep->dentry.bitmap.flags == 0x0) { + int err; + + err = exfat_allocate_bitmap(sb, ep); + brelse(bh); + return err; + } + brelse(bh); + } + + if (exfat_get_next_cluster(sb, &clu.dir)) + return -EIO; + } + + return -EINVAL; +} + +void exfat_free_bitmap(struct exfat_sb_info *sbi) +{ + int i; + + for (i = 0; i < sbi->map_sectors; i++) + __brelse(sbi->vol_amap[i]); + + kfree(sbi->vol_amap); +} + +/* + * If the value of "clu" is 0, it means cluster 2 which is the first cluster of + * the cluster heap. + */ +int exfat_set_bitmap(struct inode *inode, unsigned int clu) +{ + int i, b; + unsigned int ent_idx; + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + WARN_ON(clu < EXFAT_FIRST_CLUSTER); + ent_idx = CLUSTER_TO_BITMAP_ENT(clu); + i = BITMAP_OFFSET_SECTOR_INDEX(sb, ent_idx); + b = BITMAP_OFFSET_BIT_IN_SECTOR(sb, ent_idx); + + set_bit_le(b, sbi->vol_amap[i]->b_data); + exfat_update_bh(sb, sbi->vol_amap[i], IS_DIRSYNC(inode)); + return 0; +} + +/* + * If the value of "clu" is 0, it means cluster 2 which is the first cluster of + * the cluster heap. + */ +void exfat_clear_bitmap(struct inode *inode, unsigned int clu) +{ + int i, b; + unsigned int ent_idx; + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_mount_options *opts = &sbi->options; + + WARN_ON(clu < EXFAT_FIRST_CLUSTER); + ent_idx = CLUSTER_TO_BITMAP_ENT(clu); + i = BITMAP_OFFSET_SECTOR_INDEX(sb, ent_idx); + b = BITMAP_OFFSET_BIT_IN_SECTOR(sb, ent_idx); + + clear_bit_le(b, sbi->vol_amap[i]->b_data); + exfat_update_bh(sb, sbi->vol_amap[i], IS_DIRSYNC(inode)); + + if (opts->discard) { + int ret_discard; + + ret_discard = sb_issue_discard(sb, + exfat_cluster_to_sector(sbi, clu + + EXFAT_RESERVED_CLUSTERS), + (1 << sbi->sect_per_clus_bits), GFP_NOFS, 0); + + if (ret_discard == -EOPNOTSUPP) { + exfat_err(sb, "discard not supported by device, disabling"); + opts->discard = 0; + } + } +} + +/* + * If the value of "clu" is 0, it means cluster 2 which is the first cluster of + * the cluster heap. + */ +unsigned int exfat_find_free_bitmap(struct super_block *sb, unsigned int clu) +{ + unsigned int i, map_i, map_b, ent_idx; + unsigned int clu_base, clu_free; + unsigned char k, clu_mask; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + WARN_ON(clu < EXFAT_FIRST_CLUSTER); + ent_idx = CLUSTER_TO_BITMAP_ENT(clu); + clu_base = BITMAP_ENT_TO_CLUSTER(ent_idx & ~(BITS_PER_BYTE_MASK)); + clu_mask = IGNORED_BITS_REMAINED(clu, clu_base); + + map_i = BITMAP_OFFSET_SECTOR_INDEX(sb, ent_idx); + map_b = BITMAP_OFFSET_BYTE_IN_SECTOR(sb, ent_idx); + + for (i = EXFAT_FIRST_CLUSTER; i < sbi->num_clusters; + i += BITS_PER_BYTE) { + k = *(sbi->vol_amap[map_i]->b_data + map_b); + if (clu_mask > 0) { + k |= clu_mask; + clu_mask = 0; + } + if (k < 0xFF) { + clu_free = clu_base + free_bit[k]; + if (clu_free < sbi->num_clusters) + return clu_free; + } + clu_base += BITS_PER_BYTE; + + if (++map_b >= sb->s_blocksize || + clu_base >= sbi->num_clusters) { + if (++map_i >= sbi->map_sectors) { + clu_base = EXFAT_FIRST_CLUSTER; + map_i = 0; + } + map_b = 0; + } + } + + return EXFAT_EOF_CLUSTER; +} + +int exfat_count_used_clusters(struct super_block *sb, unsigned int *ret_count) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + unsigned int count = 0; + unsigned int i, map_i = 0, map_b = 0; + unsigned int total_clus = EXFAT_DATA_CLUSTER_COUNT(sbi); + unsigned int last_mask = total_clus & BITS_PER_BYTE_MASK; + unsigned char clu_bits; + const unsigned char last_bit_mask[] = {0, 0b00000001, 0b00000011, + 0b00000111, 0b00001111, 0b00011111, 0b00111111, 0b01111111}; + + total_clus &= ~last_mask; + for (i = 0; i < total_clus; i += BITS_PER_BYTE) { + clu_bits = *(sbi->vol_amap[map_i]->b_data + map_b); + count += used_bit[clu_bits]; + if (++map_b >= (unsigned int)sb->s_blocksize) { + map_i++; + map_b = 0; + } + } + + if (last_mask) { + clu_bits = *(sbi->vol_amap[map_i]->b_data + map_b); + clu_bits &= last_bit_mask[last_mask]; + count += used_bit[clu_bits]; + } + + *ret_count = count; + return 0; +} diff --git a/fs/exfat/cache.c b/fs/exfat/cache.c new file mode 100644 index 000000000000..47882395a884 --- /dev/null +++ b/fs/exfat/cache.c @@ -0,0 +1,324 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * linux/fs/fat/cache.c + * + * Written 1992,1993 by Werner Almesberger + * + * Mar 1999. AV. Changed cache, so that it uses the starting cluster instead + * of inode number. + * May 1999. AV. Fixed the bogosity with FAT32 (read "FAT28"). Fscking lusers. + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#include +#include +#include + +#include "exfat_fs.h" + +#define EXFAT_CACHE_VALID 0 +#define EXFAT_MAX_CACHE 16 + +struct exfat_cache { + struct list_head cache_list; + unsigned int nr_contig; /* number of contiguous clusters */ + unsigned int fcluster; /* cluster number in the file. */ + unsigned int dcluster; /* cluster number on disk. */ +}; + +struct exfat_cache_id { + unsigned int id; + unsigned int nr_contig; + unsigned int fcluster; + unsigned int dcluster; +}; + +static struct kmem_cache *exfat_cachep; + +static void exfat_cache_init_once(void *c) +{ + struct exfat_cache *cache = (struct exfat_cache *)c; + + INIT_LIST_HEAD(&cache->cache_list); +} + +int exfat_cache_init(void) +{ + exfat_cachep = kmem_cache_create("exfat_cache", + sizeof(struct exfat_cache), + 0, SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, + exfat_cache_init_once); + if (!exfat_cachep) + return -ENOMEM; + return 0; +} + +void exfat_cache_shutdown(void) +{ + if (!exfat_cachep) + return; + kmem_cache_destroy(exfat_cachep); +} + +void exfat_cache_init_inode(struct inode *inode) +{ + struct exfat_inode_info *ei = EXFAT_I(inode); + + spin_lock_init(&ei->cache_lru_lock); + ei->nr_caches = 0; + ei->cache_valid_id = EXFAT_CACHE_VALID + 1; + INIT_LIST_HEAD(&ei->cache_lru); +} + +static inline struct exfat_cache *exfat_cache_alloc(void) +{ + return kmem_cache_alloc(exfat_cachep, GFP_NOFS); +} + +static inline void exfat_cache_free(struct exfat_cache *cache) +{ + WARN_ON(!list_empty(&cache->cache_list)); + kmem_cache_free(exfat_cachep, cache); +} + +static inline void exfat_cache_update_lru(struct inode *inode, + struct exfat_cache *cache) +{ + struct exfat_inode_info *ei = EXFAT_I(inode); + + if (ei->cache_lru.next != &cache->cache_list) + list_move(&cache->cache_list, &ei->cache_lru); +} + +static unsigned int exfat_cache_lookup(struct inode *inode, + unsigned int fclus, struct exfat_cache_id *cid, + unsigned int *cached_fclus, unsigned int *cached_dclus) +{ + struct exfat_inode_info *ei = EXFAT_I(inode); + static struct exfat_cache nohit = { .fcluster = 0, }; + struct exfat_cache *hit = &nohit, *p; + unsigned int offset = EXFAT_EOF_CLUSTER; + + spin_lock(&ei->cache_lru_lock); + list_for_each_entry(p, &ei->cache_lru, cache_list) { + /* Find the cache of "fclus" or nearest cache. */ + if (p->fcluster <= fclus && hit->fcluster < p->fcluster) { + hit = p; + if (hit->fcluster + hit->nr_contig < fclus) { + offset = hit->nr_contig; + } else { + offset = fclus - hit->fcluster; + break; + } + } + } + if (hit != &nohit) { + exfat_cache_update_lru(inode, hit); + + cid->id = ei->cache_valid_id; + cid->nr_contig = hit->nr_contig; + cid->fcluster = hit->fcluster; + cid->dcluster = hit->dcluster; + *cached_fclus = cid->fcluster + offset; + *cached_dclus = cid->dcluster + offset; + } + spin_unlock(&ei->cache_lru_lock); + + return offset; +} + +static struct exfat_cache *exfat_cache_merge(struct inode *inode, + struct exfat_cache_id *new) +{ + struct exfat_inode_info *ei = EXFAT_I(inode); + struct exfat_cache *p; + + list_for_each_entry(p, &ei->cache_lru, cache_list) { + /* Find the same part as "new" in cluster-chain. */ + if (p->fcluster == new->fcluster) { + if (new->nr_contig > p->nr_contig) + p->nr_contig = new->nr_contig; + return p; + } + } + return NULL; +} + +static void exfat_cache_add(struct inode *inode, + struct exfat_cache_id *new) +{ + struct exfat_inode_info *ei = EXFAT_I(inode); + struct exfat_cache *cache, *tmp; + + if (new->fcluster == EXFAT_EOF_CLUSTER) /* dummy cache */ + return; + + spin_lock(&ei->cache_lru_lock); + if (new->id != EXFAT_CACHE_VALID && + new->id != ei->cache_valid_id) + goto unlock; /* this cache was invalidated */ + + cache = exfat_cache_merge(inode, new); + if (cache == NULL) { + if (ei->nr_caches < EXFAT_MAX_CACHE) { + ei->nr_caches++; + spin_unlock(&ei->cache_lru_lock); + + tmp = exfat_cache_alloc(); + if (!tmp) { + spin_lock(&ei->cache_lru_lock); + ei->nr_caches--; + spin_unlock(&ei->cache_lru_lock); + return; + } + + spin_lock(&ei->cache_lru_lock); + cache = exfat_cache_merge(inode, new); + if (cache != NULL) { + ei->nr_caches--; + exfat_cache_free(tmp); + goto out_update_lru; + } + cache = tmp; + } else { + struct list_head *p = ei->cache_lru.prev; + + cache = list_entry(p, + struct exfat_cache, cache_list); + } + cache->fcluster = new->fcluster; + cache->dcluster = new->dcluster; + cache->nr_contig = new->nr_contig; + } +out_update_lru: + exfat_cache_update_lru(inode, cache); +unlock: + spin_unlock(&ei->cache_lru_lock); +} + +/* + * Cache invalidation occurs rarely, thus the LRU chain is not updated. It + * fixes itself after a while. + */ +static void __exfat_cache_inval_inode(struct inode *inode) +{ + struct exfat_inode_info *ei = EXFAT_I(inode); + struct exfat_cache *cache; + + while (!list_empty(&ei->cache_lru)) { + cache = list_entry(ei->cache_lru.next, + struct exfat_cache, cache_list); + list_del_init(&cache->cache_list); + ei->nr_caches--; + exfat_cache_free(cache); + } + /* Update. The copy of caches before this id is discarded. */ + ei->cache_valid_id++; + if (ei->cache_valid_id == EXFAT_CACHE_VALID) + ei->cache_valid_id++; +} + +void exfat_cache_inval_inode(struct inode *inode) +{ + struct exfat_inode_info *ei = EXFAT_I(inode); + + spin_lock(&ei->cache_lru_lock); + __exfat_cache_inval_inode(inode); + spin_unlock(&ei->cache_lru_lock); +} + +static inline int cache_contiguous(struct exfat_cache_id *cid, + unsigned int dclus) +{ + cid->nr_contig++; + return cid->dcluster + cid->nr_contig == dclus; +} + +static inline void cache_init(struct exfat_cache_id *cid, + unsigned int fclus, unsigned int dclus) +{ + cid->id = EXFAT_CACHE_VALID; + cid->fcluster = fclus; + cid->dcluster = dclus; + cid->nr_contig = 0; +} + +int exfat_get_cluster(struct inode *inode, unsigned int cluster, + unsigned int *fclus, unsigned int *dclus, + unsigned int *last_dclus, int allow_eof) +{ + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + unsigned int limit = sbi->num_clusters; + struct exfat_inode_info *ei = EXFAT_I(inode); + struct exfat_cache_id cid; + unsigned int content; + + if (ei->start_clu == EXFAT_FREE_CLUSTER) { + exfat_fs_error(sb, + "invalid access to exfat cache (entry 0x%08x)", + ei->start_clu); + return -EIO; + } + + *fclus = 0; + *dclus = ei->start_clu; + *last_dclus = *dclus; + + /* + * Don`t use exfat_cache if zero offset or non-cluster allocation + */ + if (cluster == 0 || *dclus == EXFAT_EOF_CLUSTER) + return 0; + + cache_init(&cid, EXFAT_EOF_CLUSTER, EXFAT_EOF_CLUSTER); + + if (exfat_cache_lookup(inode, cluster, &cid, fclus, dclus) == + EXFAT_EOF_CLUSTER) { + /* + * dummy, always not contiguous + * This is reinitialized by cache_init(), later. + */ + WARN_ON(cid.id != EXFAT_CACHE_VALID || + cid.fcluster != EXFAT_EOF_CLUSTER || + cid.dcluster != EXFAT_EOF_CLUSTER || + cid.nr_contig != 0); + } + + if (*fclus == cluster) + return 0; + + while (*fclus < cluster) { + /* prevent the infinite loop of cluster chain */ + if (*fclus > limit) { + exfat_fs_error(sb, + "detected the cluster chain loop (i_pos %u)", + (*fclus)); + return -EIO; + } + + if (exfat_ent_get(sb, *dclus, &content)) + return -EIO; + + *last_dclus = *dclus; + *dclus = content; + (*fclus)++; + + if (content == EXFAT_EOF_CLUSTER) { + if (!allow_eof) { + exfat_fs_error(sb, + "invalid cluster chain (i_pos %u, last_clus 0x%08x is EOF)", + *fclus, (*last_dclus)); + return -EIO; + } + + break; + } + + if (!cache_contiguous(&cid, *dclus)) + cache_init(&cid, *fclus, *dclus); + } + + exfat_cache_add(inode, &cid); + return 0; +} diff --git a/fs/exfat/compat.h b/fs/exfat/compat.h new file mode 100644 index 000000000000..29e022917d2b --- /dev/null +++ b/fs/exfat/compat.h @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#ifndef _EXFAT_COMPAT_H +#define _EXFAT_COMPAT_H + +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) +#error "This driver doesn't support v5.8+, " \ + "please use the included driver from your kernel" +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0) +#error "This driver doesn't support kernel versions lower than v4.9, " \ + "please use the driver from https://github.com/arter97/exfat-linux/tree/old" +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) +#include +#else +#define inode_inc_iversion(inode) (inode->i_version++) +#define inode_query_iversion(inode) (inode->i_version) +#define inode_eq_iversion(inode, version) (inode->i_version == version) +#define inode_peek_iversion_raw(inode) (inode->i_version) +#define inode_set_iversion(inode, val) (inode->i_version = val) +#endif + +/* MS flags were renamed to SB on v4.15 */ +#ifndef SB_NODIRATIME +#define SB_NODIRATIME MS_NODIRATIME +#endif + +#ifndef SB_RDONLY +#define SB_RDONLY MS_RDONLY +#endif + +#ifndef SB_SYNCHRONOUS +#define SB_SYNCHRONOUS MS_SYNCHRONOUS +#endif + +#ifndef sb_rdonly +#define sb_rdonly(sb) ((sb)->s_flags & SB_RDONLY) +#endif + +#endif /* _EXFAT_COMPAT_H */ diff --git a/fs/exfat/config.h b/fs/exfat/config.h new file mode 100644 index 000000000000..59bf2bea3386 --- /dev/null +++ b/fs/exfat/config.h @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#ifndef _EXFAT_CONFIG_H +#define _EXFAT_CONFIG_H + +#ifndef CONFIG_EXFAT_DEFAULT_IOCHARSET /* if Kconfig lacked iocharset */ +#define CONFIG_EXFAT_DEFAULT_IOCHARSET "utf8" +#endif + +#endif /* _EXFAT_CONFIG_H */ diff --git a/fs/exfat/debian/changelog b/fs/exfat/debian/changelog new file mode 100644 index 000000000000..dbb799fc01f2 --- /dev/null +++ b/fs/exfat/debian/changelog @@ -0,0 +1,34 @@ +exfat-dkms (5.8~2arter97) UNRELEASED; urgency=medium + + * Applied fixes from Linux v5.8-rc4 + * Fixed sanity-checks on allow_utime and discard mount options + * Added build-time error messages for unsupported kernel versions + + -- Park Ju Hyung Wed, 01 Jul 2020 02:47:26 +0900 + +exfat-dkms (5.8~1arter97) UNRELEASED; urgency=medium + + * Rebased to Linux mainline's drivers + * Supports for kernels lower than v4.9 dropped + + -- Park Ju Hyung Sat, 27 Jun 2020 08:32:23 +0900 + +exfat-dkms (2.2.0-3arter97) UNRELEASED; urgency=medium + + * Added "quiet" mount option. + + -- Park Ju Hyung Tue, 29 Oct 2019 17:34:32 +0900 + +exfat-dkms (2.2.0-2arter97) UNRELEASED; urgency=medium + + * Fix xattr support. + * Merged upstream exFAT changes. + * More code clean-ups. + + -- Park Ju Hyung Wed, 9 Oct 2019 23:16:22 +0900 + +exfat-dkms (2.2.0-1arter97) UNRELEASED; urgency=medium + + * Initial release. + + -- Park Ju Hyung Tue, 13 Aug 2019 08:53:31 +0900 diff --git a/fs/exfat/debian/compat b/fs/exfat/debian/compat new file mode 100644 index 000000000000..f599e28b8ab0 --- /dev/null +++ b/fs/exfat/debian/compat @@ -0,0 +1 @@ +10 diff --git a/fs/exfat/debian/control b/fs/exfat/debian/control new file mode 100644 index 000000000000..d6ccaabb25b1 --- /dev/null +++ b/fs/exfat/debian/control @@ -0,0 +1,11 @@ +Source: exfat-dkms +Section: misc +Priority: optional +Maintainer: Park Ju Hyung +Build-Depends: debhelper (>= 9), dkms + +Package: exfat-dkms +Architecture: all +Depends: ${misc:Depends}, dkms +Conflicts: exfat-fuse +Description: exFAT filesystem driver for Linux kernel diff --git a/fs/exfat/debian/copyright b/fs/exfat/debian/copyright new file mode 100644 index 000000000000..ac85309b07f4 --- /dev/null +++ b/fs/exfat/debian/copyright @@ -0,0 +1,6 @@ +Author: Park Ju Hyung + +License: + +GNU General Public License version 2, see /usr/share/common-licenses/GPL-2 +for more information. diff --git a/fs/exfat/debian/exfat-dkms.dkms b/fs/exfat/debian/exfat-dkms.dkms new file mode 100644 index 000000000000..bdb443c8d685 --- /dev/null +++ b/fs/exfat/debian/exfat-dkms.dkms @@ -0,0 +1,5 @@ +PACKAGE_NAME="exfat" +PACKAGE_VERSION="#MODULE_VERSION#" +BUILT_MODULE_NAME[0]="$PACKAGE_NAME" +DEST_MODULE_LOCATION[0]="/extra/dkms" +AUTOINSTALL="YES" diff --git a/fs/exfat/debian/exfat-dkms.install b/fs/exfat/debian/exfat-dkms.install new file mode 100644 index 000000000000..b601f22c481a --- /dev/null +++ b/fs/exfat/debian/exfat-dkms.install @@ -0,0 +1 @@ +usr/src diff --git a/fs/exfat/debian/local/print_rule.mk b/fs/exfat/debian/local/print_rule.mk new file mode 100644 index 000000000000..43f1c668629a --- /dev/null +++ b/fs/exfat/debian/local/print_rule.mk @@ -0,0 +1,2 @@ +writeKbuild: + @printf 'obj-m += exfat.o\nexfat-objs := %s\n' "$(strip $(exfat-objs))" > $(KBUILD_PATH) diff --git a/fs/exfat/debian/rules b/fs/exfat/debian/rules new file mode 100755 index 000000000000..1ea3e72c982b --- /dev/null +++ b/fs/exfat/debian/rules @@ -0,0 +1,23 @@ +#!/usr/bin/make -f + +include /usr/share/dpkg/pkg-info.mk + +version := $(shell echo $(DEB_VERSION_UPSTREAM) | sed -e 's/~[^~]*$$//') +targetdir := debian/tmp/usr/src/exfat-$(version) + +%: + dh $@ --with dkms + +override_dh_auto_install: + mkdir -p $(targetdir) + install -m644 *.c *.h Kconfig LICENSE Makefile $(targetdir) + # create a Kbuild file instead of patching the Makefile + $(MAKE) KERNELRELEASE=1 KBUILD_PATH=$(targetdir)/Kbuild -s -f Makefile -f debian/local/print_rule.mk writeKbuild + +override_dh_dkms: + dh_dkms -V $(version) + +override_dh_auto_configure: +override_dh_auto_build: +override_dh_auto_test: +override_dh_auto_clean: diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c new file mode 100644 index 000000000000..a54ac925955e --- /dev/null +++ b/fs/exfat/dir.c @@ -0,0 +1,1191 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#include +#include +#include + +#include "exfat_fs.h" + +static int exfat_extract_uni_name(struct exfat_dentry *ep, + unsigned short *uniname) +{ + int i, len = 0; + + for (i = 0; i < EXFAT_FILE_NAME_LEN; i++) { + *uniname = le16_to_cpu(ep->dentry.name.unicode_0_14[i]); + if (*uniname == 0x0) + return len; + uniname++; + len++; + } + + *uniname = 0x0; + return len; + +} + +static void exfat_get_uniname_from_ext_entry(struct super_block *sb, + struct exfat_chain *p_dir, int entry, unsigned short *uniname) +{ + int i; + struct exfat_entry_set_cache *es; + + es = exfat_get_dentry_set(sb, p_dir, entry, ES_ALL_ENTRIES); + if (!es) + return; + + /* + * First entry : file entry + * Second entry : stream-extension entry + * Third entry : first file-name entry + * So, the index of first file-name dentry should start from 2. + */ + for (i = 2; i < es->num_entries; i++) { + struct exfat_dentry *ep = exfat_get_dentry_cached(es, i); + + /* end of name entry */ + if (exfat_get_entry_type(ep) != TYPE_EXTEND) + break; + + exfat_extract_uni_name(ep, uniname); + uniname += EXFAT_FILE_NAME_LEN; + } + + exfat_free_dentry_set(es, false); +} + +/* read a directory entry from the opened directory */ +static int exfat_readdir(struct inode *inode, struct exfat_dir_entry *dir_entry) +{ + int i, dentries_per_clu, dentries_per_clu_bits = 0; + unsigned int type, clu_offset; + sector_t sector; + struct exfat_chain dir, clu; + struct exfat_uni_name uni_name; + struct exfat_dentry *ep; + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_inode_info *ei = EXFAT_I(inode); + unsigned int dentry = ei->rwoffset & 0xFFFFFFFF; + struct buffer_head *bh; + + /* check if the given file ID is opened */ + if (ei->type != TYPE_DIR) + return -EPERM; + + if (ei->entry == -1) + exfat_chain_set(&dir, sbi->root_dir, 0, ALLOC_FAT_CHAIN); + else + exfat_chain_set(&dir, ei->start_clu, + EXFAT_B_TO_CLU(i_size_read(inode), sbi), ei->flags); + + dentries_per_clu = sbi->dentries_per_clu; + dentries_per_clu_bits = ilog2(dentries_per_clu); + + clu_offset = dentry >> dentries_per_clu_bits; + exfat_chain_dup(&clu, &dir); + + if (clu.flags == ALLOC_NO_FAT_CHAIN) { + clu.dir += clu_offset; + clu.size -= clu_offset; + } else { + /* hint_information */ + if (clu_offset > 0 && ei->hint_bmap.off != EXFAT_EOF_CLUSTER && + ei->hint_bmap.off > 0 && clu_offset >= ei->hint_bmap.off) { + clu_offset -= ei->hint_bmap.off; + clu.dir = ei->hint_bmap.clu; + } + + while (clu_offset > 0) { + if (exfat_get_next_cluster(sb, &(clu.dir))) + return -EIO; + + clu_offset--; + } + } + + while (clu.dir != EXFAT_EOF_CLUSTER) { + i = dentry & (dentries_per_clu - 1); + + for ( ; i < dentries_per_clu; i++, dentry++) { + ep = exfat_get_dentry(sb, &clu, i, &bh, §or); + if (!ep) + return -EIO; + + type = exfat_get_entry_type(ep); + if (type == TYPE_UNUSED) { + brelse(bh); + break; + } + + if (type != TYPE_FILE && type != TYPE_DIR) { + brelse(bh); + continue; + } + + dir_entry->attr = le16_to_cpu(ep->dentry.file.attr); + exfat_get_entry_time(sbi, &dir_entry->crtime, + ep->dentry.file.create_tz, + ep->dentry.file.create_time, + ep->dentry.file.create_date, + ep->dentry.file.create_time_cs); + exfat_get_entry_time(sbi, &dir_entry->mtime, + ep->dentry.file.modify_tz, + ep->dentry.file.modify_time, + ep->dentry.file.modify_date, + ep->dentry.file.modify_time_cs); + exfat_get_entry_time(sbi, &dir_entry->atime, + ep->dentry.file.access_tz, + ep->dentry.file.access_time, + ep->dentry.file.access_date, + 0); + + *uni_name.name = 0x0; + exfat_get_uniname_from_ext_entry(sb, &dir, dentry, + uni_name.name); + exfat_utf16_to_nls(sb, &uni_name, + dir_entry->namebuf.lfn, + dir_entry->namebuf.lfnbuf_len); + brelse(bh); + + ep = exfat_get_dentry(sb, &clu, i + 1, &bh, NULL); + if (!ep) + return -EIO; + dir_entry->size = + le64_to_cpu(ep->dentry.stream.valid_size); + brelse(bh); + + ei->hint_bmap.off = dentry >> dentries_per_clu_bits; + ei->hint_bmap.clu = clu.dir; + + ei->rwoffset = ++dentry; + return 0; + } + + if (clu.flags == ALLOC_NO_FAT_CHAIN) { + if (--clu.size > 0) + clu.dir++; + else + clu.dir = EXFAT_EOF_CLUSTER; + } else { + if (exfat_get_next_cluster(sb, &(clu.dir))) + return -EIO; + } + } + + dir_entry->namebuf.lfn[0] = '\0'; + ei->rwoffset = dentry; + return 0; +} + +static void exfat_init_namebuf(struct exfat_dentry_namebuf *nb) +{ + nb->lfn = NULL; + nb->lfnbuf_len = 0; +} + +static int exfat_alloc_namebuf(struct exfat_dentry_namebuf *nb) +{ + nb->lfn = __getname(); + if (!nb->lfn) + return -ENOMEM; + nb->lfnbuf_len = MAX_VFSNAME_BUF_SIZE; + return 0; +} + +static void exfat_free_namebuf(struct exfat_dentry_namebuf *nb) +{ + if (!nb->lfn) + return; + + __putname(nb->lfn); + exfat_init_namebuf(nb); +} + +/* skip iterating emit_dots when dir is empty */ +#define ITER_POS_FILLED_DOTS (2) +static int exfat_iterate(struct file *filp, struct dir_context *ctx) +{ + struct inode *inode = filp->f_path.dentry->d_inode; + struct super_block *sb = inode->i_sb; + struct inode *tmp; + struct exfat_dir_entry de; + struct exfat_dentry_namebuf *nb = &(de.namebuf); + struct exfat_inode_info *ei = EXFAT_I(inode); + unsigned long inum; + loff_t cpos, i_pos; + int err = 0, fake_offset = 0; + + exfat_init_namebuf(nb); + mutex_lock(&EXFAT_SB(sb)->s_lock); + + cpos = ctx->pos; + if (!dir_emit_dots(filp, ctx)) + goto unlock; + + if (ctx->pos == ITER_POS_FILLED_DOTS) { + cpos = 0; + fake_offset = 1; + } + + if (cpos & (DENTRY_SIZE - 1)) { + err = -ENOENT; + goto unlock; + } + + /* name buffer should be allocated before use */ + err = exfat_alloc_namebuf(nb); + if (err) + goto unlock; +get_new: + ei->rwoffset = EXFAT_B_TO_DEN(cpos); + + if (cpos >= i_size_read(inode)) + goto end_of_dir; + + err = exfat_readdir(inode, &de); + if (err) { + /* + * At least we tried to read a sector. Move cpos to next sector + * position (should be aligned). + */ + if (err == -EIO) { + cpos += 1 << (sb->s_blocksize_bits); + cpos &= ~(sb->s_blocksize - 1); + } + + err = -EIO; + goto end_of_dir; + } + + cpos = EXFAT_DEN_TO_B(ei->rwoffset); + + if (!nb->lfn[0]) + goto end_of_dir; + + i_pos = ((loff_t)ei->start_clu << 32) | + ((ei->rwoffset - 1) & 0xffffffff); + tmp = exfat_iget(sb, i_pos); + if (tmp) { + inum = tmp->i_ino; + iput(tmp); + } else { + inum = iunique(sb, EXFAT_ROOT_INO); + } + + /* + * Before calling dir_emit(), sb_lock should be released. + * Because page fault can occur in dir_emit() when the size + * of buffer given from user is larger than one page size. + */ + mutex_unlock(&EXFAT_SB(sb)->s_lock); + if (!dir_emit(ctx, nb->lfn, strlen(nb->lfn), inum, + (de.attr & ATTR_SUBDIR) ? DT_DIR : DT_REG)) + goto out_unlocked; + mutex_lock(&EXFAT_SB(sb)->s_lock); + ctx->pos = cpos; + goto get_new; + +end_of_dir: + if (!cpos && fake_offset) + cpos = ITER_POS_FILLED_DOTS; + ctx->pos = cpos; +unlock: + mutex_unlock(&EXFAT_SB(sb)->s_lock); +out_unlocked: + /* + * To improve performance, free namebuf after unlock sb_lock. + * If namebuf is not allocated, this function do nothing + */ + exfat_free_namebuf(nb); + return err; +} + +const struct file_operations exfat_dir_operations = { + .llseek = generic_file_llseek, + .read = generic_read_dir, + .iterate = exfat_iterate, + .fsync = exfat_file_fsync, +}; + +int exfat_alloc_new_dir(struct inode *inode, struct exfat_chain *clu) +{ + int ret; + + exfat_chain_set(clu, EXFAT_EOF_CLUSTER, 0, ALLOC_NO_FAT_CHAIN); + + ret = exfat_alloc_cluster(inode, 1, clu); + if (ret) + return ret; + + return exfat_zeroed_cluster(inode, clu->dir); +} + +int exfat_calc_num_entries(struct exfat_uni_name *p_uniname) +{ + int len; + + len = p_uniname->name_len; + if (len == 0) + return -EINVAL; + + /* 1 file entry + 1 stream entry + name entries */ + return ((len - 1) / EXFAT_FILE_NAME_LEN + 3); +} + +unsigned int exfat_get_entry_type(struct exfat_dentry *ep) +{ + if (ep->type == EXFAT_UNUSED) + return TYPE_UNUSED; + if (IS_EXFAT_DELETED(ep->type)) + return TYPE_DELETED; + if (ep->type == EXFAT_INVAL) + return TYPE_INVALID; + if (IS_EXFAT_CRITICAL_PRI(ep->type)) { + if (ep->type == EXFAT_BITMAP) + return TYPE_BITMAP; + if (ep->type == EXFAT_UPCASE) + return TYPE_UPCASE; + if (ep->type == EXFAT_VOLUME) + return TYPE_VOLUME; + if (ep->type == EXFAT_FILE) { + if (le16_to_cpu(ep->dentry.file.attr) & ATTR_SUBDIR) + return TYPE_DIR; + return TYPE_FILE; + } + return TYPE_CRITICAL_PRI; + } + if (IS_EXFAT_BENIGN_PRI(ep->type)) { + if (ep->type == EXFAT_GUID) + return TYPE_GUID; + if (ep->type == EXFAT_PADDING) + return TYPE_PADDING; + if (ep->type == EXFAT_ACLTAB) + return TYPE_ACLTAB; + return TYPE_BENIGN_PRI; + } + if (IS_EXFAT_CRITICAL_SEC(ep->type)) { + if (ep->type == EXFAT_STREAM) + return TYPE_STREAM; + if (ep->type == EXFAT_NAME) + return TYPE_EXTEND; + if (ep->type == EXFAT_ACL) + return TYPE_ACL; + return TYPE_CRITICAL_SEC; + } + return TYPE_BENIGN_SEC; +} + +static void exfat_set_entry_type(struct exfat_dentry *ep, unsigned int type) +{ + if (type == TYPE_UNUSED) { + ep->type = EXFAT_UNUSED; + } else if (type == TYPE_DELETED) { + ep->type &= EXFAT_DELETE; + } else if (type == TYPE_STREAM) { + ep->type = EXFAT_STREAM; + } else if (type == TYPE_EXTEND) { + ep->type = EXFAT_NAME; + } else if (type == TYPE_BITMAP) { + ep->type = EXFAT_BITMAP; + } else if (type == TYPE_UPCASE) { + ep->type = EXFAT_UPCASE; + } else if (type == TYPE_VOLUME) { + ep->type = EXFAT_VOLUME; + } else if (type == TYPE_DIR) { + ep->type = EXFAT_FILE; + ep->dentry.file.attr = cpu_to_le16(ATTR_SUBDIR); + } else if (type == TYPE_FILE) { + ep->type = EXFAT_FILE; + ep->dentry.file.attr = cpu_to_le16(ATTR_ARCHIVE); + } +} + +static void exfat_init_stream_entry(struct exfat_dentry *ep, + unsigned char flags, unsigned int start_clu, + unsigned long long size) +{ + exfat_set_entry_type(ep, TYPE_STREAM); + ep->dentry.stream.flags = flags; + ep->dentry.stream.start_clu = cpu_to_le32(start_clu); + ep->dentry.stream.valid_size = cpu_to_le64(size); + ep->dentry.stream.size = cpu_to_le64(size); +} + +static void exfat_init_name_entry(struct exfat_dentry *ep, + unsigned short *uniname) +{ + int i; + + exfat_set_entry_type(ep, TYPE_EXTEND); + ep->dentry.name.flags = 0x0; + + for (i = 0; i < EXFAT_FILE_NAME_LEN; i++) { + if (*uniname != 0x0) { + ep->dentry.name.unicode_0_14[i] = cpu_to_le16(*uniname); + uniname++; + } else { + ep->dentry.name.unicode_0_14[i] = 0x0; + } + } +} + +int exfat_init_dir_entry(struct inode *inode, struct exfat_chain *p_dir, + int entry, unsigned int type, unsigned int start_clu, + unsigned long long size) +{ + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct timespec64 ts = current_time(inode); + sector_t sector; + struct exfat_dentry *ep; + struct buffer_head *bh; + + /* + * We cannot use exfat_get_dentry_set here because file ep is not + * initialized yet. + */ + ep = exfat_get_dentry(sb, p_dir, entry, &bh, §or); + if (!ep) + return -EIO; + + exfat_set_entry_type(ep, type); + exfat_set_entry_time(sbi, &ts, + &ep->dentry.file.create_tz, + &ep->dentry.file.create_time, + &ep->dentry.file.create_date, + &ep->dentry.file.create_time_cs); + exfat_set_entry_time(sbi, &ts, + &ep->dentry.file.modify_tz, + &ep->dentry.file.modify_time, + &ep->dentry.file.modify_date, + &ep->dentry.file.modify_time_cs); + exfat_set_entry_time(sbi, &ts, + &ep->dentry.file.access_tz, + &ep->dentry.file.access_time, + &ep->dentry.file.access_date, + NULL); + + exfat_update_bh(sb, bh, IS_DIRSYNC(inode)); + brelse(bh); + + ep = exfat_get_dentry(sb, p_dir, entry + 1, &bh, §or); + if (!ep) + return -EIO; + + exfat_init_stream_entry(ep, + (type == TYPE_FILE) ? ALLOC_FAT_CHAIN : ALLOC_NO_FAT_CHAIN, + start_clu, size); + exfat_update_bh(sb, bh, IS_DIRSYNC(inode)); + brelse(bh); + + return 0; +} + +int exfat_update_dir_chksum(struct inode *inode, struct exfat_chain *p_dir, + int entry) +{ + struct super_block *sb = inode->i_sb; + int ret = 0; + int i, num_entries; + sector_t sector; + u16 chksum; + struct exfat_dentry *ep, *fep; + struct buffer_head *fbh, *bh; + + fep = exfat_get_dentry(sb, p_dir, entry, &fbh, §or); + if (!fep) + return -EIO; + + num_entries = fep->dentry.file.num_ext + 1; + chksum = exfat_calc_chksum16(fep, DENTRY_SIZE, 0, CS_DIR_ENTRY); + + for (i = 1; i < num_entries; i++) { + ep = exfat_get_dentry(sb, p_dir, entry + i, &bh, NULL); + if (!ep) { + ret = -EIO; + goto release_fbh; + } + chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, chksum, + CS_DEFAULT); + brelse(bh); + } + + fep->dentry.file.checksum = cpu_to_le16(chksum); + exfat_update_bh(sb, fbh, IS_DIRSYNC(inode)); +release_fbh: + brelse(fbh); + return ret; +} + +int exfat_init_ext_entry(struct inode *inode, struct exfat_chain *p_dir, + int entry, int num_entries, struct exfat_uni_name *p_uniname) +{ + struct super_block *sb = inode->i_sb; + int i; + sector_t sector; + unsigned short *uniname = p_uniname->name; + struct exfat_dentry *ep; + struct buffer_head *bh; + int sync = IS_DIRSYNC(inode); + + ep = exfat_get_dentry(sb, p_dir, entry, &bh, §or); + if (!ep) + return -EIO; + + ep->dentry.file.num_ext = (unsigned char)(num_entries - 1); + exfat_update_bh(sb, bh, sync); + brelse(bh); + + ep = exfat_get_dentry(sb, p_dir, entry + 1, &bh, §or); + if (!ep) + return -EIO; + + ep->dentry.stream.name_len = p_uniname->name_len; + ep->dentry.stream.name_hash = cpu_to_le16(p_uniname->name_hash); + exfat_update_bh(sb, bh, sync); + brelse(bh); + + for (i = EXFAT_FIRST_CLUSTER; i < num_entries; i++) { + ep = exfat_get_dentry(sb, p_dir, entry + i, &bh, §or); + if (!ep) + return -EIO; + + exfat_init_name_entry(ep, uniname); + exfat_update_bh(sb, bh, sync); + brelse(bh); + uniname += EXFAT_FILE_NAME_LEN; + } + + exfat_update_dir_chksum(inode, p_dir, entry); + return 0; +} + +int exfat_remove_entries(struct inode *inode, struct exfat_chain *p_dir, + int entry, int order, int num_entries) +{ + struct super_block *sb = inode->i_sb; + int i; + sector_t sector; + struct exfat_dentry *ep; + struct buffer_head *bh; + + for (i = order; i < num_entries; i++) { + ep = exfat_get_dentry(sb, p_dir, entry + i, &bh, §or); + if (!ep) + return -EIO; + + exfat_set_entry_type(ep, TYPE_DELETED); + exfat_update_bh(sb, bh, IS_DIRSYNC(inode)); + brelse(bh); + } + + return 0; +} + +void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es) +{ + int chksum_type = CS_DIR_ENTRY, i; + unsigned short chksum = 0; + struct exfat_dentry *ep; + + for (i = 0; i < es->num_entries; i++) { + ep = exfat_get_dentry_cached(es, i); + chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, chksum, + chksum_type); + chksum_type = CS_DEFAULT; + } + ep = exfat_get_dentry_cached(es, 0); + ep->dentry.file.checksum = cpu_to_le16(chksum); + es->modified = true; +} + +void exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync) +{ + int i; + + for (i = 0; i < es->num_bh; i++) { + if (es->modified) + exfat_update_bh(es->sb, es->bh[i], sync); + brelse(es->bh[i]); + } + kfree(es); +} + +static int exfat_walk_fat_chain(struct super_block *sb, + struct exfat_chain *p_dir, unsigned int byte_offset, + unsigned int *clu) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + unsigned int clu_offset; + unsigned int cur_clu; + + clu_offset = EXFAT_B_TO_CLU(byte_offset, sbi); + cur_clu = p_dir->dir; + + if (p_dir->flags == ALLOC_NO_FAT_CHAIN) { + cur_clu += clu_offset; + } else { + while (clu_offset > 0) { + if (exfat_get_next_cluster(sb, &cur_clu)) + return -EIO; + if (cur_clu == EXFAT_EOF_CLUSTER) { + exfat_fs_error(sb, + "invalid dentry access beyond EOF (clu : %u, eidx : %d)", + p_dir->dir, + EXFAT_B_TO_DEN(byte_offset)); + return -EIO; + } + clu_offset--; + } + } + + *clu = cur_clu; + return 0; +} + +int exfat_find_location(struct super_block *sb, struct exfat_chain *p_dir, + int entry, sector_t *sector, int *offset) +{ + int ret; + unsigned int off, clu = 0; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + off = EXFAT_DEN_TO_B(entry); + + ret = exfat_walk_fat_chain(sb, p_dir, off, &clu); + if (ret) + return ret; + + /* byte offset in cluster */ + off = EXFAT_CLU_OFFSET(off, sbi); + + /* byte offset in sector */ + *offset = EXFAT_BLK_OFFSET(off, sb); + + /* sector offset in cluster */ + *sector = EXFAT_B_TO_BLK(off, sb); + *sector += exfat_cluster_to_sector(sbi, clu); + return 0; +} + +#define EXFAT_MAX_RA_SIZE (128*1024) +static int exfat_dir_readahead(struct super_block *sb, sector_t sec) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct buffer_head *bh; + unsigned int max_ra_count = EXFAT_MAX_RA_SIZE >> sb->s_blocksize_bits; + unsigned int page_ra_count = PAGE_SIZE >> sb->s_blocksize_bits; + unsigned int adj_ra_count = max(sbi->sect_per_clus, page_ra_count); + unsigned int ra_count = min(adj_ra_count, max_ra_count); + + /* Read-ahead is not required */ + if (sbi->sect_per_clus == 1) + return 0; + + if (sec < sbi->data_start_sector) { + exfat_err(sb, "requested sector is invalid(sect:%llu, root:%llu)", + (unsigned long long)sec, sbi->data_start_sector); + return -EIO; + } + + /* Not sector aligned with ra_count, resize ra_count to page size */ + if ((sec - sbi->data_start_sector) & (ra_count - 1)) + ra_count = page_ra_count; + + bh = sb_find_get_block(sb, sec); + if (!bh || !buffer_uptodate(bh)) { + unsigned int i; + + for (i = 0; i < ra_count; i++) + sb_breadahead(sb, (sector_t)(sec + i)); + } + brelse(bh); + return 0; +} + +struct exfat_dentry *exfat_get_dentry(struct super_block *sb, + struct exfat_chain *p_dir, int entry, struct buffer_head **bh, + sector_t *sector) +{ + unsigned int dentries_per_page = EXFAT_B_TO_DEN(PAGE_SIZE); + int off; + sector_t sec; + + if (p_dir->dir == DIR_DELETED) { + exfat_err(sb, "abnormal access to deleted dentry"); + return NULL; + } + + if (exfat_find_location(sb, p_dir, entry, &sec, &off)) + return NULL; + + if (p_dir->dir != EXFAT_FREE_CLUSTER && + !(entry & (dentries_per_page - 1))) + exfat_dir_readahead(sb, sec); + + *bh = sb_bread(sb, sec); + if (!*bh) + return NULL; + + if (sector) + *sector = sec; + return (struct exfat_dentry *)((*bh)->b_data + off); +} + +enum exfat_validate_dentry_mode { + ES_MODE_STARTED, + ES_MODE_GET_FILE_ENTRY, + ES_MODE_GET_STRM_ENTRY, + ES_MODE_GET_NAME_ENTRY, + ES_MODE_GET_CRITICAL_SEC_ENTRY, +}; + +static bool exfat_validate_entry(unsigned int type, + enum exfat_validate_dentry_mode *mode) +{ + if (type == TYPE_UNUSED || type == TYPE_DELETED) + return false; + + switch (*mode) { + case ES_MODE_STARTED: + if (type != TYPE_FILE && type != TYPE_DIR) + return false; + *mode = ES_MODE_GET_FILE_ENTRY; + return true; + case ES_MODE_GET_FILE_ENTRY: + if (type != TYPE_STREAM) + return false; + *mode = ES_MODE_GET_STRM_ENTRY; + return true; + case ES_MODE_GET_STRM_ENTRY: + if (type != TYPE_EXTEND) + return false; + *mode = ES_MODE_GET_NAME_ENTRY; + return true; + case ES_MODE_GET_NAME_ENTRY: + if (type == TYPE_STREAM) + return false; + if (type != TYPE_EXTEND) { + if (!(type & TYPE_CRITICAL_SEC)) + return false; + *mode = ES_MODE_GET_CRITICAL_SEC_ENTRY; + } + return true; + case ES_MODE_GET_CRITICAL_SEC_ENTRY: + if (type == TYPE_EXTEND || type == TYPE_STREAM) + return false; + if ((type & TYPE_CRITICAL_SEC) != TYPE_CRITICAL_SEC) + return false; + return true; + default: + WARN_ON_ONCE(1); + return false; + } +} + +struct exfat_dentry *exfat_get_dentry_cached( + struct exfat_entry_set_cache *es, int num) +{ + int off = es->start_off + num * DENTRY_SIZE; + struct buffer_head *bh = es->bh[EXFAT_B_TO_BLK(off, es->sb)]; + char *p = bh->b_data + EXFAT_BLK_OFFSET(off, es->sb); + + return (struct exfat_dentry *)p; +} + +/* + * Returns a set of dentries for a file or dir. + * + * Note It provides a direct pointer to bh->data via exfat_get_dentry_cached(). + * User should call exfat_get_dentry_set() after setting 'modified' to apply + * changes made in this entry set to the real device. + * + * in: + * sb+p_dir+entry: indicates a file/dir + * type: specifies how many dentries should be included. + * return: + * pointer of entry set on success, + * NULL on failure. + */ +struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, + struct exfat_chain *p_dir, int entry, unsigned int type) +{ + int ret, i, num_bh; + unsigned int off, byte_offset, clu = 0; + sector_t sec; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_entry_set_cache *es; + struct exfat_dentry *ep; + int num_entries; + enum exfat_validate_dentry_mode mode = ES_MODE_STARTED; + struct buffer_head *bh; + + if (p_dir->dir == DIR_DELETED) { + exfat_err(sb, "access to deleted dentry"); + return NULL; + } + + byte_offset = EXFAT_DEN_TO_B(entry); + ret = exfat_walk_fat_chain(sb, p_dir, byte_offset, &clu); + if (ret) + return NULL; + + es = kzalloc(sizeof(*es), GFP_KERNEL); + if (!es) + return NULL; + es->sb = sb; + es->modified = false; + + /* byte offset in cluster */ + byte_offset = EXFAT_CLU_OFFSET(byte_offset, sbi); + + /* byte offset in sector */ + off = EXFAT_BLK_OFFSET(byte_offset, sb); + es->start_off = off; + + /* sector offset in cluster */ + sec = EXFAT_B_TO_BLK(byte_offset, sb); + sec += exfat_cluster_to_sector(sbi, clu); + + bh = sb_bread(sb, sec); + if (!bh) + goto free_es; + es->bh[es->num_bh++] = bh; + + ep = exfat_get_dentry_cached(es, 0); + if (!exfat_validate_entry(exfat_get_entry_type(ep), &mode)) + goto free_es; + + num_entries = type == ES_ALL_ENTRIES ? + ep->dentry.file.num_ext + 1 : type; + es->num_entries = num_entries; + + num_bh = EXFAT_B_TO_BLK_ROUND_UP(off + num_entries * DENTRY_SIZE, sb); + for (i = 1; i < num_bh; i++) { + /* get the next sector */ + if (exfat_is_last_sector_in_cluster(sbi, sec)) { + if (p_dir->flags == ALLOC_NO_FAT_CHAIN) + clu++; + else if (exfat_get_next_cluster(sb, &clu)) + goto free_es; + sec = exfat_cluster_to_sector(sbi, clu); + } else { + sec++; + } + + bh = sb_bread(sb, sec); + if (!bh) + goto free_es; + es->bh[es->num_bh++] = bh; + } + + /* validiate cached dentries */ + for (i = 1; i < num_entries; i++) { + ep = exfat_get_dentry_cached(es, i); + if (!exfat_validate_entry(exfat_get_entry_type(ep), &mode)) + goto free_es; + } + return es; + +free_es: + exfat_free_dentry_set(es, false); + return NULL; +} + +enum { + DIRENT_STEP_FILE, + DIRENT_STEP_STRM, + DIRENT_STEP_NAME, + DIRENT_STEP_SECD, +}; + +/* + * return values: + * >= 0 : return dir entiry position with the name in dir + * -EEXIST : (root dir, ".") it is the root dir itself + * -ENOENT : entry with the name does not exist + * -EIO : I/O error + */ +int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei, + struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname, + int num_entries, unsigned int type) +{ + int i, rewind = 0, dentry = 0, end_eidx = 0, num_ext = 0, len; + int order, step, name_len = 0; + int dentries_per_clu, num_empty = 0; + unsigned int entry_type; + unsigned short *uniname = NULL; + struct exfat_chain clu; + struct exfat_hint *hint_stat = &ei->hint_stat; + struct exfat_hint_femp candi_empty; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + dentries_per_clu = sbi->dentries_per_clu; + + exfat_chain_dup(&clu, p_dir); + + if (hint_stat->eidx) { + clu.dir = hint_stat->clu; + dentry = hint_stat->eidx; + end_eidx = dentry; + } + + candi_empty.eidx = EXFAT_HINT_NONE; +rewind: + order = 0; + step = DIRENT_STEP_FILE; + while (clu.dir != EXFAT_EOF_CLUSTER) { + i = dentry & (dentries_per_clu - 1); + for (; i < dentries_per_clu; i++, dentry++) { + struct exfat_dentry *ep; + struct buffer_head *bh; + + if (rewind && dentry == end_eidx) + goto not_found; + + ep = exfat_get_dentry(sb, &clu, i, &bh, NULL); + if (!ep) + return -EIO; + + entry_type = exfat_get_entry_type(ep); + + if (entry_type == TYPE_UNUSED || + entry_type == TYPE_DELETED) { + step = DIRENT_STEP_FILE; + + num_empty++; + if (candi_empty.eidx == EXFAT_HINT_NONE && + num_empty == 1) { + exfat_chain_set(&candi_empty.cur, + clu.dir, clu.size, clu.flags); + } + + if (candi_empty.eidx == EXFAT_HINT_NONE && + num_empty >= num_entries) { + candi_empty.eidx = + dentry - (num_empty - 1); + WARN_ON(candi_empty.eidx < 0); + candi_empty.count = num_empty; + + if (ei->hint_femp.eidx == + EXFAT_HINT_NONE || + candi_empty.eidx <= + ei->hint_femp.eidx) { + memcpy(&ei->hint_femp, + &candi_empty, + sizeof(candi_empty)); + } + } + + brelse(bh); + if (entry_type == TYPE_UNUSED) + goto not_found; + continue; + } + + num_empty = 0; + candi_empty.eidx = EXFAT_HINT_NONE; + + if (entry_type == TYPE_FILE || entry_type == TYPE_DIR) { + step = DIRENT_STEP_FILE; + if (type == TYPE_ALL || type == entry_type) { + num_ext = ep->dentry.file.num_ext; + step = DIRENT_STEP_STRM; + } + brelse(bh); + continue; + } + + if (entry_type == TYPE_STREAM) { + u16 name_hash; + + if (step != DIRENT_STEP_STRM) { + step = DIRENT_STEP_FILE; + brelse(bh); + continue; + } + step = DIRENT_STEP_FILE; + name_hash = le16_to_cpu( + ep->dentry.stream.name_hash); + if (p_uniname->name_hash == name_hash && + p_uniname->name_len == + ep->dentry.stream.name_len) { + step = DIRENT_STEP_NAME; + order = 1; + name_len = 0; + } + brelse(bh); + continue; + } + + brelse(bh); + if (entry_type == TYPE_EXTEND) { + unsigned short entry_uniname[16], unichar; + + if (step != DIRENT_STEP_NAME) { + step = DIRENT_STEP_FILE; + continue; + } + + if (++order == 2) + uniname = p_uniname->name; + else + uniname += EXFAT_FILE_NAME_LEN; + + len = exfat_extract_uni_name(ep, entry_uniname); + name_len += len; + + unichar = *(uniname+len); + *(uniname+len) = 0x0; + + if (exfat_uniname_ncmp(sb, uniname, + entry_uniname, len)) { + step = DIRENT_STEP_FILE; + } else if (p_uniname->name_len == name_len) { + if (order == num_ext) + goto found; + step = DIRENT_STEP_SECD; + } + + *(uniname+len) = unichar; + continue; + } + + if (entry_type & + (TYPE_CRITICAL_SEC | TYPE_BENIGN_SEC)) { + if (step == DIRENT_STEP_SECD) { + if (++order == num_ext) + goto found; + continue; + } + } + step = DIRENT_STEP_FILE; + } + + if (clu.flags == ALLOC_NO_FAT_CHAIN) { + if (--clu.size > 0) + clu.dir++; + else + clu.dir = EXFAT_EOF_CLUSTER; + } else { + if (exfat_get_next_cluster(sb, &clu.dir)) + return -EIO; + } + } + +not_found: + /* + * We started at not 0 index,so we should try to find target + * from 0 index to the index we started at. + */ + if (!rewind && end_eidx) { + rewind = 1; + dentry = 0; + clu.dir = p_dir->dir; + /* reset empty hint */ + num_empty = 0; + candi_empty.eidx = EXFAT_HINT_NONE; + goto rewind; + } + + /* initialized hint_stat */ + hint_stat->clu = p_dir->dir; + hint_stat->eidx = 0; + return -ENOENT; + +found: + /* next dentry we'll find is out of this cluster */ + if (!((dentry + 1) & (dentries_per_clu - 1))) { + int ret = 0; + + if (clu.flags == ALLOC_NO_FAT_CHAIN) { + if (--clu.size > 0) + clu.dir++; + else + clu.dir = EXFAT_EOF_CLUSTER; + } else { + ret = exfat_get_next_cluster(sb, &clu.dir); + } + + if (ret || clu.dir != EXFAT_EOF_CLUSTER) { + /* just initialized hint_stat */ + hint_stat->clu = p_dir->dir; + hint_stat->eidx = 0; + return (dentry - num_ext); + } + } + + hint_stat->clu = clu.dir; + hint_stat->eidx = dentry + 1; + return dentry - num_ext; +} + +int exfat_count_ext_entries(struct super_block *sb, struct exfat_chain *p_dir, + int entry, struct exfat_dentry *ep) +{ + int i, count = 0; + unsigned int type; + struct exfat_dentry *ext_ep; + struct buffer_head *bh; + + for (i = 0, entry++; i < ep->dentry.file.num_ext; i++, entry++) { + ext_ep = exfat_get_dentry(sb, p_dir, entry, &bh, NULL); + if (!ext_ep) + return -EIO; + + type = exfat_get_entry_type(ext_ep); + brelse(bh); + if (type == TYPE_EXTEND || type == TYPE_STREAM) + count++; + else + break; + } + return count; +} + +int exfat_count_dir_entries(struct super_block *sb, struct exfat_chain *p_dir) +{ + int i, count = 0; + int dentries_per_clu; + unsigned int entry_type; + struct exfat_chain clu; + struct exfat_dentry *ep; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct buffer_head *bh; + + dentries_per_clu = sbi->dentries_per_clu; + + exfat_chain_dup(&clu, p_dir); + + while (clu.dir != EXFAT_EOF_CLUSTER) { + for (i = 0; i < dentries_per_clu; i++) { + ep = exfat_get_dentry(sb, &clu, i, &bh, NULL); + if (!ep) + return -EIO; + entry_type = exfat_get_entry_type(ep); + brelse(bh); + + if (entry_type == TYPE_UNUSED) + return count; + if (entry_type != TYPE_DIR) + continue; + count++; + } + + if (clu.flags == ALLOC_NO_FAT_CHAIN) { + if (--clu.size > 0) + clu.dir++; + else + clu.dir = EXFAT_EOF_CLUSTER; + } else { + if (exfat_get_next_cluster(sb, &(clu.dir))) + return -EIO; + } + } + + return count; +} diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h new file mode 100644 index 000000000000..99796391ff26 --- /dev/null +++ b/fs/exfat/exfat_fs.h @@ -0,0 +1,545 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#ifndef _EXFAT_FS_H +#define _EXFAT_FS_H + +#include +#include +#include + +#include "config.h" +#include "compat.h" +#include "version.h" +#include "exfat_raw.h" + +#define EXFAT_SUPER_MAGIC 0x2011BAB0UL +#define EXFAT_ROOT_INO 1 + +#define EXFAT_SB_DIRTY 0 + +#define EXFAT_CLUSTERS_UNTRACKED (~0u) + +/* + * exfat error flags + */ +enum exfat_error_mode { + EXFAT_ERRORS_CONT, /* ignore error and continue */ + EXFAT_ERRORS_PANIC, /* panic on error */ + EXFAT_ERRORS_RO, /* remount r/o on error */ +}; + +/* + * exfat nls lossy flag + */ +enum { + NLS_NAME_NO_LOSSY, /* no lossy */ + NLS_NAME_LOSSY, /* just detected incorrect filename(s) */ + NLS_NAME_OVERLEN, /* the length is over than its limit */ +}; + +#define EXFAT_HASH_BITS 8 +#define EXFAT_HASH_SIZE (1UL << EXFAT_HASH_BITS) + +/* + * Type Definitions + */ +#define ES_2_ENTRIES 2 +#define ES_ALL_ENTRIES 0 + +#define DIR_DELETED 0xFFFF0321 + +/* type values */ +#define TYPE_UNUSED 0x0000 +#define TYPE_DELETED 0x0001 +#define TYPE_INVALID 0x0002 +#define TYPE_CRITICAL_PRI 0x0100 +#define TYPE_BITMAP 0x0101 +#define TYPE_UPCASE 0x0102 +#define TYPE_VOLUME 0x0103 +#define TYPE_DIR 0x0104 +#define TYPE_FILE 0x011F +#define TYPE_CRITICAL_SEC 0x0200 +#define TYPE_STREAM 0x0201 +#define TYPE_EXTEND 0x0202 +#define TYPE_ACL 0x0203 +#define TYPE_BENIGN_PRI 0x0400 +#define TYPE_GUID 0x0401 +#define TYPE_PADDING 0x0402 +#define TYPE_ACLTAB 0x0403 +#define TYPE_BENIGN_SEC 0x0800 +#define TYPE_ALL 0x0FFF + +#define MAX_CHARSET_SIZE 6 /* max size of multi-byte character */ +#define MAX_NAME_LENGTH 255 /* max len of file name excluding NULL */ +#define MAX_VFSNAME_BUF_SIZE ((MAX_NAME_LENGTH + 1) * MAX_CHARSET_SIZE) + +/* Enough size to hold 256 dentry (even 512 Byte sector) */ +#define DIR_CACHE_SIZE (256*sizeof(struct exfat_dentry)/512+1) + +#define EXFAT_HINT_NONE -1 +#define EXFAT_MIN_SUBDIR 2 + +/* + * helpers for cluster size to byte conversion. + */ +#define EXFAT_CLU_TO_B(b, sbi) ((b) << (sbi)->cluster_size_bits) +#define EXFAT_B_TO_CLU(b, sbi) ((b) >> (sbi)->cluster_size_bits) +#define EXFAT_B_TO_CLU_ROUND_UP(b, sbi) \ + (((b - 1) >> (sbi)->cluster_size_bits) + 1) +#define EXFAT_CLU_OFFSET(off, sbi) ((off) & ((sbi)->cluster_size - 1)) + +/* + * helpers for block size to byte conversion. + */ +#define EXFAT_BLK_TO_B(b, sb) ((b) << (sb)->s_blocksize_bits) +#define EXFAT_B_TO_BLK(b, sb) ((b) >> (sb)->s_blocksize_bits) +#define EXFAT_B_TO_BLK_ROUND_UP(b, sb) \ + (((b - 1) >> (sb)->s_blocksize_bits) + 1) +#define EXFAT_BLK_OFFSET(off, sb) ((off) & ((sb)->s_blocksize - 1)) + +/* + * helpers for block size to dentry size conversion. + */ +#define EXFAT_B_TO_DEN_IDX(b, sbi) \ + ((b) << ((sbi)->cluster_size_bits - DENTRY_SIZE_BITS)) +#define EXFAT_B_TO_DEN(b) ((b) >> DENTRY_SIZE_BITS) +#define EXFAT_DEN_TO_B(b) ((b) << DENTRY_SIZE_BITS) + +/* + * helpers for fat entry. + */ +#define FAT_ENT_SIZE (4) +#define FAT_ENT_SIZE_BITS (2) +#define FAT_ENT_OFFSET_SECTOR(sb, loc) (EXFAT_SB(sb)->FAT1_start_sector + \ + (((u64)loc << FAT_ENT_SIZE_BITS) >> sb->s_blocksize_bits)) +#define FAT_ENT_OFFSET_BYTE_IN_SECTOR(sb, loc) \ + ((loc << FAT_ENT_SIZE_BITS) & (sb->s_blocksize - 1)) + +/* + * helpers for bitmap. + */ +#define CLUSTER_TO_BITMAP_ENT(clu) ((clu) - EXFAT_RESERVED_CLUSTERS) +#define BITMAP_ENT_TO_CLUSTER(ent) ((ent) + EXFAT_RESERVED_CLUSTERS) +#define BITS_PER_SECTOR(sb) ((sb)->s_blocksize * BITS_PER_BYTE) +#define BITS_PER_SECTOR_MASK(sb) (BITS_PER_SECTOR(sb) - 1) +#define BITMAP_OFFSET_SECTOR_INDEX(sb, ent) \ + ((ent / BITS_PER_BYTE) >> (sb)->s_blocksize_bits) +#define BITMAP_OFFSET_BIT_IN_SECTOR(sb, ent) (ent & BITS_PER_SECTOR_MASK(sb)) +#define BITMAP_OFFSET_BYTE_IN_SECTOR(sb, ent) \ + ((ent / BITS_PER_BYTE) & ((sb)->s_blocksize - 1)) +#define BITS_PER_BYTE_MASK 0x7 +#define IGNORED_BITS_REMAINED(clu, clu_base) ((1 << ((clu) - (clu_base))) - 1) + +struct exfat_dentry_namebuf { + char *lfn; + int lfnbuf_len; /* usally MAX_UNINAME_BUF_SIZE */ +}; + +/* unicode name structure */ +struct exfat_uni_name { + /* +3 for null and for converting */ + unsigned short name[MAX_NAME_LENGTH + 3]; + u16 name_hash; + unsigned char name_len; +}; + +/* directory structure */ +struct exfat_chain { + unsigned int dir; + unsigned int size; + unsigned char flags; +}; + +/* first empty entry hint information */ +struct exfat_hint_femp { + /* entry index of a directory */ + int eidx; + /* count of continuous empty entry */ + int count; + /* the cluster that first empty slot exists in */ + struct exfat_chain cur; +}; + +/* hint structure */ +struct exfat_hint { + unsigned int clu; + union { + unsigned int off; /* cluster offset */ + int eidx; /* entry index */ + }; +}; + +struct exfat_entry_set_cache { + struct super_block *sb; + bool modified; + unsigned int start_off; + int num_bh; + struct buffer_head *bh[DIR_CACHE_SIZE]; + unsigned int num_entries; +}; + +struct exfat_dir_entry { + struct exfat_chain dir; + int entry; + unsigned int type; + unsigned int start_clu; + unsigned char flags; + unsigned short attr; + loff_t size; + unsigned int num_subdirs; + struct timespec64 atime; + struct timespec64 mtime; + struct timespec64 crtime; + struct exfat_dentry_namebuf namebuf; +}; + +/* + * exfat mount in-memory data + */ +struct exfat_mount_options { + kuid_t fs_uid; + kgid_t fs_gid; + unsigned short fs_fmask; + unsigned short fs_dmask; + /* permission for setting the [am]time */ + unsigned short allow_utime; + /* charset for filename input/display */ + char *iocharset; + /* fake return success on setattr(e.g. chmods/chowns) */ + unsigned char quiet; + /* on error: continue, panic, remount-ro */ + enum exfat_error_mode errors; + unsigned utf8:1, /* Use of UTF-8 character set */ + discard:1; /* Issue discard requests on deletions */ + int time_offset; /* Offset of timestamps from UTC (in minutes) */ +}; + +/* + * EXFAT file system superblock in-memory data + */ +struct exfat_sb_info { + unsigned long long num_sectors; /* num of sectors in volume */ + unsigned int num_clusters; /* num of clusters in volume */ + unsigned int cluster_size; /* cluster size in bytes */ + unsigned int cluster_size_bits; + unsigned int sect_per_clus; /* cluster size in sectors */ + unsigned int sect_per_clus_bits; + unsigned long long FAT1_start_sector; /* FAT1 start sector */ + unsigned long long FAT2_start_sector; /* FAT2 start sector */ + unsigned long long data_start_sector; /* data area start sector */ + unsigned int num_FAT_sectors; /* num of FAT sectors */ + unsigned int root_dir; /* root dir cluster */ + unsigned int dentries_per_clu; /* num of dentries per cluster */ + unsigned int vol_flag; /* volume dirty flag */ + struct buffer_head *boot_bh; /* buffer_head of BOOT sector */ + + unsigned int map_clu; /* allocation bitmap start cluster */ + unsigned int map_sectors; /* num of allocation bitmap sectors */ + struct buffer_head **vol_amap; /* allocation bitmap */ + + unsigned short *vol_utbl; /* upcase table */ + + unsigned int clu_srch_ptr; /* cluster search pointer */ + unsigned int used_clusters; /* number of used clusters */ + + unsigned long s_state; + struct mutex s_lock; /* superblock lock */ + struct exfat_mount_options options; + struct nls_table *nls_io; /* Charset used for input and display */ + struct ratelimit_state ratelimit; + + spinlock_t inode_hash_lock; + struct hlist_head inode_hashtable[EXFAT_HASH_SIZE]; + + struct rcu_head rcu; +}; + +/* + * EXFAT file system inode in-memory data + */ +struct exfat_inode_info { + struct exfat_chain dir; + int entry; + unsigned int type; + unsigned short attr; + unsigned int start_clu; + unsigned char flags; + /* + * the copy of low 32bit of i_version to check + * the validation of hint_stat. + */ + unsigned int version; + /* file offset or dentry index for readdir */ + loff_t rwoffset; + + /* hint for cluster last accessed */ + struct exfat_hint hint_bmap; + /* hint for entry index we try to lookup next time */ + struct exfat_hint hint_stat; + /* hint for first empty entry */ + struct exfat_hint_femp hint_femp; + + spinlock_t cache_lru_lock; + struct list_head cache_lru; + int nr_caches; + /* for avoiding the race between alloc and free */ + unsigned int cache_valid_id; + + /* + * NOTE: i_size_ondisk is 64bits, so must hold ->inode_lock to access. + * physically allocated size. + */ + loff_t i_size_ondisk; + /* block-aligned i_size (used in cont_write_begin) */ + loff_t i_size_aligned; + /* on-disk position of directory entry or 0 */ + loff_t i_pos; + /* hash by i_location */ + struct hlist_node i_hash_fat; + /* protect bmap against truncate */ + struct rw_semaphore truncate_lock; + struct inode vfs_inode; + /* File creation time */ + struct timespec64 i_crtime; +}; + +static inline struct exfat_sb_info *EXFAT_SB(struct super_block *sb) +{ + return sb->s_fs_info; +} + +static inline struct exfat_inode_info *EXFAT_I(struct inode *inode) +{ + return container_of(inode, struct exfat_inode_info, vfs_inode); +} + +/* + * If ->i_mode can't hold 0222 (i.e. ATTR_RO), we use ->i_attrs to + * save ATTR_RO instead of ->i_mode. + * + * If it's directory and !sbi->options.rodir, ATTR_RO isn't read-only + * bit, it's just used as flag for app. + */ +static inline int exfat_mode_can_hold_ro(struct inode *inode) +{ + struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb); + + if (S_ISDIR(inode->i_mode)) + return 0; + + if ((~sbi->options.fs_fmask) & 0222) + return 1; + return 0; +} + +/* Convert attribute bits and a mask to the UNIX mode. */ +static inline mode_t exfat_make_mode(struct exfat_sb_info *sbi, + unsigned short attr, mode_t mode) +{ + if ((attr & ATTR_READONLY) && !(attr & ATTR_SUBDIR)) + mode &= ~0222; + + if (attr & ATTR_SUBDIR) + return (mode & ~sbi->options.fs_dmask) | S_IFDIR; + + return (mode & ~sbi->options.fs_fmask) | S_IFREG; +} + +/* Return the FAT attribute byte for this inode */ +static inline unsigned short exfat_make_attr(struct inode *inode) +{ + unsigned short attr = EXFAT_I(inode)->attr; + + if (S_ISDIR(inode->i_mode)) + attr |= ATTR_SUBDIR; + if (exfat_mode_can_hold_ro(inode) && !(inode->i_mode & 0222)) + attr |= ATTR_READONLY; + return attr; +} + +static inline void exfat_save_attr(struct inode *inode, unsigned short attr) +{ + if (exfat_mode_can_hold_ro(inode)) + EXFAT_I(inode)->attr = attr & (ATTR_RWMASK | ATTR_READONLY); + else + EXFAT_I(inode)->attr = attr & ATTR_RWMASK; +} + +static inline bool exfat_is_last_sector_in_cluster(struct exfat_sb_info *sbi, + sector_t sec) +{ + return ((sec - sbi->data_start_sector + 1) & + ((1 << sbi->sect_per_clus_bits) - 1)) == 0; +} + +static inline sector_t exfat_cluster_to_sector(struct exfat_sb_info *sbi, + unsigned int clus) +{ + return ((clus - EXFAT_RESERVED_CLUSTERS) << sbi->sect_per_clus_bits) + + sbi->data_start_sector; +} + +static inline int exfat_sector_to_cluster(struct exfat_sb_info *sbi, + sector_t sec) +{ + return ((sec - sbi->data_start_sector) >> sbi->sect_per_clus_bits) + + EXFAT_RESERVED_CLUSTERS; +} + +/* super.c */ +int exfat_set_vol_flags(struct super_block *sb, unsigned short new_flag); + +/* fatent.c */ +#define exfat_get_next_cluster(sb, pclu) exfat_ent_get(sb, *(pclu), pclu) + +int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc, + struct exfat_chain *p_chain); +int exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain); +int exfat_ent_get(struct super_block *sb, unsigned int loc, + unsigned int *content); +int exfat_ent_set(struct super_block *sb, unsigned int loc, + unsigned int content); +int exfat_count_ext_entries(struct super_block *sb, struct exfat_chain *p_dir, + int entry, struct exfat_dentry *p_entry); +int exfat_chain_cont_cluster(struct super_block *sb, unsigned int chain, + unsigned int len); +int exfat_zeroed_cluster(struct inode *dir, unsigned int clu); +int exfat_find_last_cluster(struct super_block *sb, struct exfat_chain *p_chain, + unsigned int *ret_clu); +int exfat_count_num_clusters(struct super_block *sb, + struct exfat_chain *p_chain, unsigned int *ret_count); + +/* balloc.c */ +int exfat_load_bitmap(struct super_block *sb); +void exfat_free_bitmap(struct exfat_sb_info *sbi); +int exfat_set_bitmap(struct inode *inode, unsigned int clu); +void exfat_clear_bitmap(struct inode *inode, unsigned int clu); +unsigned int exfat_find_free_bitmap(struct super_block *sb, unsigned int clu); +int exfat_count_used_clusters(struct super_block *sb, unsigned int *ret_count); + +/* file.c */ +extern const struct file_operations exfat_file_operations; +int __exfat_truncate(struct inode *inode, loff_t new_size); +void exfat_truncate(struct inode *inode, loff_t size); +int exfat_setattr(struct dentry *dentry, struct iattr *attr); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) +int exfat_getattr(const struct path *path, struct kstat *stat, + unsigned int request_mask, unsigned int query_flags); +#else +int exfat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); +#endif +int exfat_file_fsync(struct file *file, loff_t start, loff_t end, int datasync); + +/* namei.c */ +extern const struct dentry_operations exfat_dentry_ops; +extern const struct dentry_operations exfat_utf8_dentry_ops; + +/* cache.c */ +int exfat_cache_init(void); +void exfat_cache_shutdown(void); +void exfat_cache_init_inode(struct inode *inode); +void exfat_cache_inval_inode(struct inode *inode); +int exfat_get_cluster(struct inode *inode, unsigned int cluster, + unsigned int *fclus, unsigned int *dclus, + unsigned int *last_dclus, int allow_eof); + +/* dir.c */ +extern const struct inode_operations exfat_dir_inode_operations; +extern const struct file_operations exfat_dir_operations; +unsigned int exfat_get_entry_type(struct exfat_dentry *p_entry); +int exfat_init_dir_entry(struct inode *inode, struct exfat_chain *p_dir, + int entry, unsigned int type, unsigned int start_clu, + unsigned long long size); +int exfat_init_ext_entry(struct inode *inode, struct exfat_chain *p_dir, + int entry, int num_entries, struct exfat_uni_name *p_uniname); +int exfat_remove_entries(struct inode *inode, struct exfat_chain *p_dir, + int entry, int order, int num_entries); +int exfat_update_dir_chksum(struct inode *inode, struct exfat_chain *p_dir, + int entry); +void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es); +int exfat_calc_num_entries(struct exfat_uni_name *p_uniname); +int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei, + struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname, + int num_entries, unsigned int type); +int exfat_alloc_new_dir(struct inode *inode, struct exfat_chain *clu); +int exfat_find_location(struct super_block *sb, struct exfat_chain *p_dir, + int entry, sector_t *sector, int *offset); +struct exfat_dentry *exfat_get_dentry(struct super_block *sb, + struct exfat_chain *p_dir, int entry, struct buffer_head **bh, + sector_t *sector); +struct exfat_dentry *exfat_get_dentry_cached(struct exfat_entry_set_cache *es, + int num); +struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, + struct exfat_chain *p_dir, int entry, unsigned int type); +void exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync); +int exfat_count_dir_entries(struct super_block *sb, struct exfat_chain *p_dir); + +/* inode.c */ +extern const struct inode_operations exfat_file_inode_operations; +void exfat_sync_inode(struct inode *inode); +struct inode *exfat_build_inode(struct super_block *sb, + struct exfat_dir_entry *info, loff_t i_pos); +void exfat_hash_inode(struct inode *inode, loff_t i_pos); +void exfat_unhash_inode(struct inode *inode); +struct inode *exfat_iget(struct super_block *sb, loff_t i_pos); +int exfat_write_inode(struct inode *inode, struct writeback_control *wbc); +void exfat_evict_inode(struct inode *inode); +int exfat_block_truncate_page(struct inode *inode, loff_t from); + +/* xattr.c */ +#ifdef CONFIG_EXFAT_VIRTUAL_XATTR +extern int exfat_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); +extern ssize_t exfat_getxattr(struct dentry *dentry, const char *name, void *value, size_t size); +extern ssize_t exfat_listxattr(struct dentry *dentry, char *list, size_t size); +extern int exfat_removexattr(struct dentry *dentry, const char *name); +extern const struct xattr_handler *exfat_xattr_handlers[]; +#else +#define exfat_xattr_handlers NULL +#endif + +/* exfat/nls.c */ +unsigned short exfat_toupper(struct super_block *sb, unsigned short a); +int exfat_uniname_ncmp(struct super_block *sb, unsigned short *a, + unsigned short *b, unsigned int len); +int exfat_utf16_to_nls(struct super_block *sb, + struct exfat_uni_name *uniname, unsigned char *p_cstring, + int len); +int exfat_nls_to_utf16(struct super_block *sb, + const unsigned char *p_cstring, const int len, + struct exfat_uni_name *uniname, int *p_lossy); +int exfat_create_upcase_table(struct super_block *sb); +void exfat_free_upcase_table(struct exfat_sb_info *sbi); + +/* exfat/misc.c */ +void __exfat_fs_error(struct super_block *sb, int report, const char *fmt, ...) + __printf(3, 4) __cold; +#define exfat_fs_error(sb, fmt, args...) \ + __exfat_fs_error(sb, 1, fmt, ## args) +#define exfat_fs_error_ratelimit(sb, fmt, args...) \ + __exfat_fs_error(sb, __ratelimit(&EXFAT_SB(sb)->ratelimit), \ + fmt, ## args) +void exfat_msg(struct super_block *sb, const char *lv, const char *fmt, ...) + __printf(3, 4) __cold; +#define exfat_err(sb, fmt, ...) \ + exfat_msg(sb, KERN_ERR, fmt, ##__VA_ARGS__) +#define exfat_warn(sb, fmt, ...) \ + exfat_msg(sb, KERN_WARNING, fmt, ##__VA_ARGS__) +#define exfat_info(sb, fmt, ...) \ + exfat_msg(sb, KERN_INFO, fmt, ##__VA_ARGS__) + +void exfat_get_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts, + u8 tz, __le16 time, __le16 date, u8 time_cs); +void exfat_truncate_atime(struct timespec64 *ts); +void exfat_set_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts, + u8 *tz, __le16 *time, __le16 *date, u8 *time_cs); +u16 exfat_calc_chksum16(void *data, int len, u16 chksum, int type); +u32 exfat_calc_chksum32(void *data, int len, u32 chksum, int type); +void exfat_update_bh(struct super_block *sb, struct buffer_head *bh, int sync); +void exfat_chain_set(struct exfat_chain *ec, unsigned int dir, + unsigned int size, unsigned char flags); +void exfat_chain_dup(struct exfat_chain *dup, struct exfat_chain *ec); + +#endif /* !_EXFAT_FS_H */ diff --git a/fs/exfat/exfat_raw.h b/fs/exfat/exfat_raw.h new file mode 100644 index 000000000000..350ce59cc324 --- /dev/null +++ b/fs/exfat/exfat_raw.h @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#ifndef _EXFAT_RAW_H +#define _EXFAT_RAW_H + +#include + +#define BOOT_SIGNATURE 0xAA55 +#define EXBOOT_SIGNATURE 0xAA550000 +#define STR_EXFAT "EXFAT " /* size should be 8 */ + +#define EXFAT_MAX_FILE_LEN 255 + +#define VOL_CLEAN 0x0000 +#define VOL_DIRTY 0x0002 +#define ERR_MEDIUM 0x0004 + +#define EXFAT_EOF_CLUSTER 0xFFFFFFFFu +#define EXFAT_BAD_CLUSTER 0xFFFFFFF7u +#define EXFAT_FREE_CLUSTER 0 +/* Cluster 0, 1 are reserved, the first cluster is 2 in the cluster heap. */ +#define EXFAT_RESERVED_CLUSTERS 2 +#define EXFAT_FIRST_CLUSTER 2 +#define EXFAT_DATA_CLUSTER_COUNT(sbi) \ + ((sbi)->num_clusters - EXFAT_RESERVED_CLUSTERS) + +/* AllocationPossible and NoFatChain field in GeneralSecondaryFlags Field */ +#define ALLOC_FAT_CHAIN 0x01 +#define ALLOC_NO_FAT_CHAIN 0x03 + +#define DENTRY_SIZE 32 /* directory entry size */ +#define DENTRY_SIZE_BITS 5 +/* exFAT allows 8388608(256MB) directory entries */ +#define MAX_EXFAT_DENTRIES 8388608 + +/* dentry types */ +#define EXFAT_UNUSED 0x00 /* end of directory */ +#define EXFAT_DELETE (~0x80) +#define IS_EXFAT_DELETED(x) ((x) < 0x80) /* deleted file (0x01~0x7F) */ +#define EXFAT_INVAL 0x80 /* invalid value */ +#define EXFAT_BITMAP 0x81 /* allocation bitmap */ +#define EXFAT_UPCASE 0x82 /* upcase table */ +#define EXFAT_VOLUME 0x83 /* volume label */ +#define EXFAT_FILE 0x85 /* file or dir */ +#define EXFAT_GUID 0xA0 +#define EXFAT_PADDING 0xA1 +#define EXFAT_ACLTAB 0xA2 +#define EXFAT_STREAM 0xC0 /* stream entry */ +#define EXFAT_NAME 0xC1 /* file name entry */ +#define EXFAT_ACL 0xC2 /* stream entry */ + +#define IS_EXFAT_CRITICAL_PRI(x) (x < 0xA0) +#define IS_EXFAT_BENIGN_PRI(x) (x < 0xC0) +#define IS_EXFAT_CRITICAL_SEC(x) (x < 0xE0) + +/* checksum types */ +#define CS_DIR_ENTRY 0 +#define CS_BOOT_SECTOR 1 +#define CS_DEFAULT 2 + +/* file attributes */ +#define ATTR_READONLY 0x0001 +#define ATTR_HIDDEN 0x0002 +#define ATTR_SYSTEM 0x0004 +#define ATTR_VOLUME 0x0008 +#define ATTR_SUBDIR 0x0010 +#define ATTR_ARCHIVE 0x0020 + +#define ATTR_RWMASK (ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME | \ + ATTR_SUBDIR | ATTR_ARCHIVE) + +#define BOOTSEC_JUMP_BOOT_LEN 3 +#define BOOTSEC_FS_NAME_LEN 8 +#define BOOTSEC_OLDBPB_LEN 53 + +#define EXFAT_FILE_NAME_LEN 15 + +/* EXFAT: Main and Backup Boot Sector (512 bytes) */ +struct boot_sector { + __u8 jmp_boot[BOOTSEC_JUMP_BOOT_LEN]; + __u8 fs_name[BOOTSEC_FS_NAME_LEN]; + __u8 must_be_zero[BOOTSEC_OLDBPB_LEN]; + __le64 partition_offset; + __le64 vol_length; + __le32 fat_offset; + __le32 fat_length; + __le32 clu_offset; + __le32 clu_count; + __le32 root_cluster; + __le32 vol_serial; + __u8 fs_revision[2]; + __le16 vol_flags; + __u8 sect_size_bits; + __u8 sect_per_clus_bits; + __u8 num_fats; + __u8 drv_sel; + __u8 percent_in_use; + __u8 reserved[7]; + __u8 boot_code[390]; + __le16 signature; +} __packed; + +struct exfat_dentry { + __u8 type; + union { + struct { + __u8 num_ext; + __le16 checksum; + __le16 attr; + __le16 reserved1; + __le16 create_time; + __le16 create_date; + __le16 modify_time; + __le16 modify_date; + __le16 access_time; + __le16 access_date; + __u8 create_time_cs; + __u8 modify_time_cs; + __u8 create_tz; + __u8 modify_tz; + __u8 access_tz; + __u8 reserved2[7]; + } __packed file; /* file directory entry */ + struct { + __u8 flags; + __u8 reserved1; + __u8 name_len; + __le16 name_hash; + __le16 reserved2; + __le64 valid_size; + __le32 reserved3; + __le32 start_clu; + __le64 size; + } __packed stream; /* stream extension directory entry */ + struct { + __u8 flags; + __le16 unicode_0_14[EXFAT_FILE_NAME_LEN]; + } __packed name; /* file name directory entry */ + struct { + __u8 flags; + __u8 reserved[18]; + __le32 start_clu; + __le64 size; + } __packed bitmap; /* allocation bitmap directory entry */ + struct { + __u8 reserved1[3]; + __le32 checksum; + __u8 reserved2[12]; + __le32 start_clu; + __le64 size; + } __packed upcase; /* up-case table directory entry */ + } __packed dentry; +} __packed; + +#define EXFAT_TZ_VALID (1 << 7) + +/* Jan 1 GMT 00:00:00 1980 */ +#define EXFAT_MIN_TIMESTAMP_SECS 315532800LL +/* Dec 31 GMT 23:59:59 2107 */ +#define EXFAT_MAX_TIMESTAMP_SECS 4354819199LL + +#endif /* !_EXFAT_RAW_H */ diff --git a/fs/exfat/fatent.c b/fs/exfat/fatent.c new file mode 100644 index 000000000000..317c966e380b --- /dev/null +++ b/fs/exfat/fatent.c @@ -0,0 +1,459 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#include +#include +#include + +#include "exfat_fs.h" + +static int exfat_mirror_bh(struct super_block *sb, sector_t sec, + struct buffer_head *bh) +{ + struct buffer_head *c_bh; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + sector_t sec2; + int err = 0; + + if (sbi->FAT2_start_sector != sbi->FAT1_start_sector) { + sec2 = sec - sbi->FAT1_start_sector + sbi->FAT2_start_sector; + c_bh = sb_getblk(sb, sec2); + if (!c_bh) + return -ENOMEM; + memcpy(c_bh->b_data, bh->b_data, sb->s_blocksize); + set_buffer_uptodate(c_bh); + mark_buffer_dirty(c_bh); + if (sb->s_flags & SB_SYNCHRONOUS) + err = sync_dirty_buffer(c_bh); + brelse(c_bh); + } + + return err; +} + +static int __exfat_ent_get(struct super_block *sb, unsigned int loc, + unsigned int *content) +{ + unsigned int off; + sector_t sec; + struct buffer_head *bh; + + sec = FAT_ENT_OFFSET_SECTOR(sb, loc); + off = FAT_ENT_OFFSET_BYTE_IN_SECTOR(sb, loc); + + bh = sb_bread(sb, sec); + if (!bh) + return -EIO; + + *content = le32_to_cpu(*(__le32 *)(&bh->b_data[off])); + + /* remap reserved clusters to simplify code */ + if (*content > EXFAT_BAD_CLUSTER) + *content = EXFAT_EOF_CLUSTER; + + brelse(bh); + return 0; +} + +int exfat_ent_set(struct super_block *sb, unsigned int loc, + unsigned int content) +{ + unsigned int off; + sector_t sec; + __le32 *fat_entry; + struct buffer_head *bh; + + sec = FAT_ENT_OFFSET_SECTOR(sb, loc); + off = FAT_ENT_OFFSET_BYTE_IN_SECTOR(sb, loc); + + bh = sb_bread(sb, sec); + if (!bh) + return -EIO; + + fat_entry = (__le32 *)&(bh->b_data[off]); + *fat_entry = cpu_to_le32(content); + exfat_update_bh(sb, bh, sb->s_flags & SB_SYNCHRONOUS); + exfat_mirror_bh(sb, sec, bh); + brelse(bh); + return 0; +} + +static inline bool is_valid_cluster(struct exfat_sb_info *sbi, + unsigned int clus) +{ + if (clus < EXFAT_FIRST_CLUSTER || sbi->num_clusters <= clus) + return false; + return true; +} + +int exfat_ent_get(struct super_block *sb, unsigned int loc, + unsigned int *content) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + int err; + + if (!is_valid_cluster(sbi, loc)) { + exfat_fs_error(sb, "invalid access to FAT (entry 0x%08x)", + loc); + return -EIO; + } + + err = __exfat_ent_get(sb, loc, content); + if (err) { + exfat_fs_error(sb, + "failed to access to FAT (entry 0x%08x, err:%d)", + loc, err); + return err; + } + + if (*content == EXFAT_FREE_CLUSTER) { + exfat_fs_error(sb, + "invalid access to FAT free cluster (entry 0x%08x)", + loc); + return -EIO; + } + + if (*content == EXFAT_BAD_CLUSTER) { + exfat_fs_error(sb, + "invalid access to FAT bad cluster (entry 0x%08x)", + loc); + return -EIO; + } + + if (*content != EXFAT_EOF_CLUSTER && !is_valid_cluster(sbi, *content)) { + exfat_fs_error(sb, + "invalid access to FAT (entry 0x%08x) bogus content (0x%08x)", + loc, *content); + return -EIO; + } + + return 0; +} + +int exfat_chain_cont_cluster(struct super_block *sb, unsigned int chain, + unsigned int len) +{ + if (!len) + return 0; + + while (len > 1) { + if (exfat_ent_set(sb, chain, chain + 1)) + return -EIO; + chain++; + len--; + } + + if (exfat_ent_set(sb, chain, EXFAT_EOF_CLUSTER)) + return -EIO; + return 0; +} + +int exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain) +{ + unsigned int num_clusters = 0; + unsigned int clu; + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + /* invalid cluster number */ + if (p_chain->dir == EXFAT_FREE_CLUSTER || + p_chain->dir == EXFAT_EOF_CLUSTER || + p_chain->dir < EXFAT_FIRST_CLUSTER) + return 0; + + /* no cluster to truncate */ + if (p_chain->size == 0) + return 0; + + /* check cluster validation */ + if (!is_valid_cluster(sbi, p_chain->dir)) { + exfat_err(sb, "invalid start cluster (%u)", p_chain->dir); + return -EIO; + } + + set_bit(EXFAT_SB_DIRTY, &sbi->s_state); + clu = p_chain->dir; + + if (p_chain->flags == ALLOC_NO_FAT_CHAIN) { + do { + exfat_clear_bitmap(inode, clu); + clu++; + + num_clusters++; + } while (num_clusters < p_chain->size); + } else { + do { + exfat_clear_bitmap(inode, clu); + + if (exfat_get_next_cluster(sb, &clu)) + goto dec_used_clus; + + num_clusters++; + } while (clu != EXFAT_EOF_CLUSTER); + } + +dec_used_clus: + sbi->used_clusters -= num_clusters; + return 0; +} + +int exfat_find_last_cluster(struct super_block *sb, struct exfat_chain *p_chain, + unsigned int *ret_clu) +{ + unsigned int clu, next; + unsigned int count = 0; + + next = p_chain->dir; + if (p_chain->flags == ALLOC_NO_FAT_CHAIN) { + *ret_clu = next + p_chain->size - 1; + return 0; + } + + do { + count++; + clu = next; + if (exfat_ent_get(sb, clu, &next)) + return -EIO; + } while (next != EXFAT_EOF_CLUSTER); + + if (p_chain->size != count) { + exfat_fs_error(sb, + "bogus directory size (clus : ondisk(%d) != counted(%d))", + p_chain->size, count); + return -EIO; + } + + *ret_clu = clu; + return 0; +} + +static inline int exfat_sync_bhs(struct buffer_head **bhs, int nr_bhs) +{ + int i, err = 0; + + for (i = 0; i < nr_bhs; i++) + write_dirty_buffer(bhs[i], 0); + + for (i = 0; i < nr_bhs; i++) { + wait_on_buffer(bhs[i]); + if (!err && !buffer_uptodate(bhs[i])) + err = -EIO; + } + return err; +} + +int exfat_zeroed_cluster(struct inode *dir, unsigned int clu) +{ + struct super_block *sb = dir->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct buffer_head *bhs[MAX_BUF_PER_PAGE]; + int nr_bhs = MAX_BUF_PER_PAGE; + sector_t blknr, last_blknr; + int err, i, n; + + blknr = exfat_cluster_to_sector(sbi, clu); + last_blknr = blknr + sbi->sect_per_clus; + + if (last_blknr > sbi->num_sectors && sbi->num_sectors > 0) { + exfat_fs_error_ratelimit(sb, + "%s: out of range(sect:%llu len:%u)", + __func__, (unsigned long long)blknr, + sbi->sect_per_clus); + return -EIO; + } + + /* Zeroing the unused blocks on this cluster */ + n = 0; + while (blknr < last_blknr) { + bhs[n] = sb_getblk(sb, blknr); + if (!bhs[n]) { + err = -ENOMEM; + goto release_bhs; + } + memset(bhs[n]->b_data, 0, sb->s_blocksize); + exfat_update_bh(sb, bhs[n], 0); + + n++; + blknr++; + + if (n == nr_bhs) { + if (IS_DIRSYNC(dir)) { + err = exfat_sync_bhs(bhs, n); + if (err) + goto release_bhs; + } + + for (i = 0; i < n; i++) + brelse(bhs[i]); + n = 0; + } + } + + if (IS_DIRSYNC(dir)) { + err = exfat_sync_bhs(bhs, n); + if (err) + goto release_bhs; + } + + for (i = 0; i < n; i++) + brelse(bhs[i]); + + return 0; + +release_bhs: + exfat_err(sb, "failed zeroed sect %llu\n", (unsigned long long)blknr); + for (i = 0; i < n; i++) + bforget(bhs[i]); + return err; +} + +int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc, + struct exfat_chain *p_chain) +{ + int ret = -ENOSPC; + unsigned int num_clusters = 0, total_cnt; + unsigned int hint_clu, new_clu, last_clu = EXFAT_EOF_CLUSTER; + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + total_cnt = EXFAT_DATA_CLUSTER_COUNT(sbi); + + if (unlikely(total_cnt < sbi->used_clusters)) { + exfat_fs_error_ratelimit(sb, + "%s: invalid used clusters(t:%u,u:%u)\n", + __func__, total_cnt, sbi->used_clusters); + return -EIO; + } + + if (num_alloc > total_cnt - sbi->used_clusters) + return -ENOSPC; + + hint_clu = p_chain->dir; + /* find new cluster */ + if (hint_clu == EXFAT_EOF_CLUSTER) { + if (sbi->clu_srch_ptr < EXFAT_FIRST_CLUSTER) { + exfat_err(sb, "sbi->clu_srch_ptr is invalid (%u)\n", + sbi->clu_srch_ptr); + sbi->clu_srch_ptr = EXFAT_FIRST_CLUSTER; + } + + hint_clu = exfat_find_free_bitmap(sb, sbi->clu_srch_ptr); + if (hint_clu == EXFAT_EOF_CLUSTER) + return -ENOSPC; + } + + /* check cluster validation */ + if (!is_valid_cluster(sbi, hint_clu)) { + exfat_err(sb, "hint_cluster is invalid (%u)", + hint_clu); + hint_clu = EXFAT_FIRST_CLUSTER; + if (p_chain->flags == ALLOC_NO_FAT_CHAIN) { + if (exfat_chain_cont_cluster(sb, p_chain->dir, + num_clusters)) + return -EIO; + p_chain->flags = ALLOC_FAT_CHAIN; + } + } + + set_bit(EXFAT_SB_DIRTY, &sbi->s_state); + + p_chain->dir = EXFAT_EOF_CLUSTER; + + while ((new_clu = exfat_find_free_bitmap(sb, hint_clu)) != + EXFAT_EOF_CLUSTER) { + if (new_clu != hint_clu && + p_chain->flags == ALLOC_NO_FAT_CHAIN) { + if (exfat_chain_cont_cluster(sb, p_chain->dir, + num_clusters)) { + ret = -EIO; + goto free_cluster; + } + p_chain->flags = ALLOC_FAT_CHAIN; + } + + /* update allocation bitmap */ + if (exfat_set_bitmap(inode, new_clu)) { + ret = -EIO; + goto free_cluster; + } + + num_clusters++; + + /* update FAT table */ + if (p_chain->flags == ALLOC_FAT_CHAIN) { + if (exfat_ent_set(sb, new_clu, EXFAT_EOF_CLUSTER)) { + ret = -EIO; + goto free_cluster; + } + } + + if (p_chain->dir == EXFAT_EOF_CLUSTER) { + p_chain->dir = new_clu; + } else if (p_chain->flags == ALLOC_FAT_CHAIN) { + if (exfat_ent_set(sb, last_clu, new_clu)) { + ret = -EIO; + goto free_cluster; + } + } + last_clu = new_clu; + + if (--num_alloc == 0) { + sbi->clu_srch_ptr = hint_clu; + sbi->used_clusters += num_clusters; + + p_chain->size += num_clusters; + return 0; + } + + hint_clu = new_clu + 1; + if (hint_clu >= sbi->num_clusters) { + hint_clu = EXFAT_FIRST_CLUSTER; + + if (p_chain->flags == ALLOC_NO_FAT_CHAIN) { + if (exfat_chain_cont_cluster(sb, p_chain->dir, + num_clusters)) { + ret = -EIO; + goto free_cluster; + } + p_chain->flags = ALLOC_FAT_CHAIN; + } + } + } +free_cluster: + if (num_clusters) + exfat_free_cluster(inode, p_chain); + return ret; +} + +int exfat_count_num_clusters(struct super_block *sb, + struct exfat_chain *p_chain, unsigned int *ret_count) +{ + unsigned int i, count; + unsigned int clu; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + if (!p_chain->dir || p_chain->dir == EXFAT_EOF_CLUSTER) { + *ret_count = 0; + return 0; + } + + if (p_chain->flags == ALLOC_NO_FAT_CHAIN) { + *ret_count = p_chain->size; + return 0; + } + + clu = p_chain->dir; + count = 0; + for (i = EXFAT_FIRST_CLUSTER; i < sbi->num_clusters; i++) { + count++; + if (exfat_ent_get(sb, clu, &clu)) + return -EIO; + if (clu == EXFAT_EOF_CLUSTER) + break; + } + + *ret_count = count; + return 0; +} diff --git a/fs/exfat/file.c b/fs/exfat/file.c new file mode 100644 index 000000000000..50565d3a4433 --- /dev/null +++ b/fs/exfat/file.c @@ -0,0 +1,403 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#include +#include +#include +#include + +#include "exfat_fs.h" + +static int exfat_cont_expand(struct inode *inode, loff_t size) +{ + struct address_space *mapping = inode->i_mapping; + loff_t start = i_size_read(inode), count = size - i_size_read(inode); + int err, err2; + + err = generic_cont_expand_simple(inode, size); + if (err) + return err; + + inode->i_ctime = inode->i_mtime = current_time(inode); + mark_inode_dirty(inode); + + if (!IS_SYNC(inode)) + return 0; + + err = filemap_fdatawrite_range(mapping, start, start + count - 1); + err2 = sync_mapping_buffers(mapping); + if (!err) + err = err2; + err2 = write_inode_now(inode, 1); + if (!err) + err = err2; + if (err) + return err; + + return filemap_fdatawait_range(mapping, start, start + count - 1); +} + +static bool exfat_allow_set_time(struct exfat_sb_info *sbi, struct inode *inode) +{ + mode_t allow_utime = sbi->options.allow_utime; + + if (!uid_eq(current_fsuid(), inode->i_uid)) { + if (in_group_p(inode->i_gid)) + allow_utime >>= 3; + if (allow_utime & MAY_WRITE) + return true; + } + + /* use a default check */ + return false; +} + +static int exfat_sanitize_mode(const struct exfat_sb_info *sbi, + struct inode *inode, umode_t *mode_ptr) +{ + mode_t i_mode, mask, perm; + + i_mode = inode->i_mode; + + mask = (S_ISREG(i_mode) || S_ISLNK(i_mode)) ? + sbi->options.fs_fmask : sbi->options.fs_dmask; + perm = *mode_ptr & ~(S_IFMT | mask); + + /* Of the r and x bits, all (subject to umask) must be present.*/ + if ((perm & 0555) != (i_mode & 0555)) + return -EPERM; + + if (exfat_mode_can_hold_ro(inode)) { + /* + * Of the w bits, either all (subject to umask) or none must + * be present. + */ + if ((perm & 0222) && ((perm & 0222) != (0222 & ~mask))) + return -EPERM; + } else { + /* + * If exfat_mode_can_hold_ro(inode) is false, can't change + * w bits. + */ + if ((perm & 0222) != (0222 & ~mask)) + return -EPERM; + } + + *mode_ptr &= S_IFMT | perm; + + return 0; +} + +/* resize the file length */ +int __exfat_truncate(struct inode *inode, loff_t new_size) +{ + unsigned int num_clusters_new, num_clusters_phys; + unsigned int last_clu = EXFAT_FREE_CLUSTER; + struct exfat_chain clu; + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_inode_info *ei = EXFAT_I(inode); + int evict = (ei->dir.dir == DIR_DELETED) ? 1 : 0; + + /* check if the given file ID is opened */ + if (ei->type != TYPE_FILE && ei->type != TYPE_DIR) + return -EPERM; + + exfat_set_vol_flags(sb, VOL_DIRTY); + + num_clusters_new = EXFAT_B_TO_CLU_ROUND_UP(i_size_read(inode), sbi); + num_clusters_phys = + EXFAT_B_TO_CLU_ROUND_UP(EXFAT_I(inode)->i_size_ondisk, sbi); + + exfat_chain_set(&clu, ei->start_clu, num_clusters_phys, ei->flags); + + if (new_size > 0) { + /* + * Truncate FAT chain num_clusters after the first cluster + * num_clusters = min(new, phys); + */ + unsigned int num_clusters = + min(num_clusters_new, num_clusters_phys); + + /* + * Follow FAT chain + * (defensive coding - works fine even with corrupted FAT table + */ + if (clu.flags == ALLOC_NO_FAT_CHAIN) { + clu.dir += num_clusters; + clu.size -= num_clusters; + } else { + while (num_clusters > 0) { + last_clu = clu.dir; + if (exfat_get_next_cluster(sb, &(clu.dir))) + return -EIO; + + num_clusters--; + clu.size--; + } + } + } else { + ei->flags = ALLOC_NO_FAT_CHAIN; + ei->start_clu = EXFAT_EOF_CLUSTER; + } + + i_size_write(inode, new_size); + + if (ei->type == TYPE_FILE) + ei->attr |= ATTR_ARCHIVE; + + /* update the directory entry */ + if (!evict) { + struct timespec64 ts; + struct exfat_dentry *ep, *ep2; + struct exfat_entry_set_cache *es; + + es = exfat_get_dentry_set(sb, &(ei->dir), ei->entry, + ES_ALL_ENTRIES); + if (!es) + return -EIO; + ep = exfat_get_dentry_cached(es, 0); + ep2 = exfat_get_dentry_cached(es, 1); + + ts = current_time(inode); + exfat_set_entry_time(sbi, &ts, + &ep->dentry.file.modify_tz, + &ep->dentry.file.modify_time, + &ep->dentry.file.modify_date, + &ep->dentry.file.modify_time_cs); + ep->dentry.file.attr = cpu_to_le16(ei->attr); + + /* File size should be zero if there is no cluster allocated */ + if (ei->start_clu == EXFAT_EOF_CLUSTER) { + ep2->dentry.stream.valid_size = 0; + ep2->dentry.stream.size = 0; + } else { + ep2->dentry.stream.valid_size = cpu_to_le64(new_size); + ep2->dentry.stream.size = ep->dentry.stream.valid_size; + } + + if (new_size == 0) { + /* Any directory can not be truncated to zero */ + WARN_ON(ei->type != TYPE_FILE); + + ep2->dentry.stream.flags = ALLOC_FAT_CHAIN; + ep2->dentry.stream.start_clu = EXFAT_FREE_CLUSTER; + } + + exfat_update_dir_chksum_with_entry_set(es); + exfat_free_dentry_set(es, inode_needs_sync(inode)); + } + + /* cut off from the FAT chain */ + if (ei->flags == ALLOC_FAT_CHAIN && last_clu != EXFAT_FREE_CLUSTER && + last_clu != EXFAT_EOF_CLUSTER) { + if (exfat_ent_set(sb, last_clu, EXFAT_EOF_CLUSTER)) + return -EIO; + } + + /* invalidate cache and free the clusters */ + /* clear exfat cache */ + exfat_cache_inval_inode(inode); + + /* hint information */ + ei->hint_bmap.off = EXFAT_EOF_CLUSTER; + ei->hint_bmap.clu = EXFAT_EOF_CLUSTER; + if (ei->rwoffset > new_size) + ei->rwoffset = new_size; + + /* hint_stat will be used if this is directory. */ + ei->hint_stat.eidx = 0; + ei->hint_stat.clu = ei->start_clu; + ei->hint_femp.eidx = EXFAT_HINT_NONE; + + /* free the clusters */ + if (exfat_free_cluster(inode, &clu)) + return -EIO; + + exfat_set_vol_flags(sb, VOL_CLEAN); + + return 0; +} + +void exfat_truncate(struct inode *inode, loff_t size) +{ + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + unsigned int blocksize = 1 << inode->i_blkbits; + loff_t aligned_size; + int err; + + mutex_lock(&sbi->s_lock); + if (EXFAT_I(inode)->start_clu == 0) { + /* + * Empty start_clu != ~0 (not allocated) + */ + exfat_fs_error(sb, "tried to truncate zeroed cluster."); + goto write_size; + } + + err = __exfat_truncate(inode, i_size_read(inode)); + if (err) + goto write_size; + + inode->i_ctime = inode->i_mtime = current_time(inode); + if (IS_DIRSYNC(inode)) + exfat_sync_inode(inode); + else + mark_inode_dirty(inode); + + inode->i_blocks = ((i_size_read(inode) + (sbi->cluster_size - 1)) & + ~(sbi->cluster_size - 1)) >> inode->i_blkbits; +write_size: + aligned_size = i_size_read(inode); + if (aligned_size & (blocksize - 1)) { + aligned_size |= (blocksize - 1); + aligned_size++; + } + + if (EXFAT_I(inode)->i_size_ondisk > i_size_read(inode)) + EXFAT_I(inode)->i_size_ondisk = aligned_size; + + if (EXFAT_I(inode)->i_size_aligned > i_size_read(inode)) + EXFAT_I(inode)->i_size_aligned = aligned_size; + mutex_unlock(&sbi->s_lock); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) +int exfat_getattr(const struct path *path, struct kstat *stat, + unsigned int request_mask, unsigned int query_flags) +{ + struct inode *inode = d_backing_inode(path->dentry); + struct exfat_inode_info *ei = EXFAT_I(inode); + + generic_fillattr(inode, stat); + exfat_truncate_atime(&stat->atime); + stat->result_mask |= STATX_BTIME; + stat->btime.tv_sec = ei->i_crtime.tv_sec; + stat->btime.tv_nsec = ei->i_crtime.tv_nsec; + stat->blksize = EXFAT_SB(inode->i_sb)->cluster_size; + return 0; +} +#else +int exfat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) +{ + struct inode *inode = dentry->d_inode; + + generic_fillattr(inode, stat); + exfat_truncate_atime(&stat->atime); + stat->blksize = EXFAT_SB(inode->i_sb)->cluster_size; + + return 0; +} +#endif + +int exfat_setattr(struct dentry *dentry, struct iattr *attr) +{ + struct exfat_sb_info *sbi = EXFAT_SB(dentry->d_sb); + struct inode *inode = dentry->d_inode; + unsigned int ia_valid; + int error; + + if ((attr->ia_valid & ATTR_SIZE) && + attr->ia_size > i_size_read(inode)) { + error = exfat_cont_expand(inode, attr->ia_size); + if (error || attr->ia_valid == ATTR_SIZE) + goto out; + attr->ia_valid &= ~ATTR_SIZE; + } + + /* Check for setting the inode time. */ + ia_valid = attr->ia_valid; + if ((ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) && + exfat_allow_set_time(sbi, inode)) { + attr->ia_valid &= ~(ATTR_MTIME_SET | ATTR_ATIME_SET | + ATTR_TIMES_SET); + } + + error = setattr_prepare(dentry, attr); + attr->ia_valid = ia_valid; + if (error) { + if (sbi->options.quiet) + error = 0; + goto out; + } + + if (((attr->ia_valid & ATTR_UID) && + !uid_eq(attr->ia_uid, sbi->options.fs_uid)) || + ((attr->ia_valid & ATTR_GID) && + !gid_eq(attr->ia_gid, sbi->options.fs_gid)) || + ((attr->ia_valid & ATTR_MODE) && + (attr->ia_mode & ~(S_IFREG | S_IFLNK | S_IFDIR | 0777)))) { + error = -EPERM; + goto out; + } + + if (error) { + if (sbi->options.quiet) + error = 0; + goto out; + } + + /* + * We don't return -EPERM here. Yes, strange, but this is too + * old behavior. + */ + if (attr->ia_valid & ATTR_MODE) { + if (exfat_sanitize_mode(sbi, inode, &attr->ia_mode) < 0) + attr->ia_valid &= ~ATTR_MODE; + } + + if (attr->ia_valid & ATTR_SIZE) { + error = exfat_block_truncate_page(inode, attr->ia_size); + if (error) + goto out; + + down_write(&EXFAT_I(inode)->truncate_lock); + truncate_setsize(inode, attr->ia_size); + exfat_truncate(inode, attr->ia_size); + up_write(&EXFAT_I(inode)->truncate_lock); + } + + setattr_copy(inode, attr); + exfat_truncate_atime(&inode->i_atime); + mark_inode_dirty(inode); + +out: + return error; +} + +int exfat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync) +{ + struct inode *inode = filp->f_mapping->host; + int err; + + err = __generic_file_fsync(filp, start, end, datasync); + if (err) + return err; + + err = sync_blockdev(inode->i_sb->s_bdev); + if (err) + return err; + + return blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); +} + +const struct file_operations exfat_file_operations = { + .llseek = generic_file_llseek, + .read_iter = generic_file_read_iter, + .write_iter = generic_file_write_iter, + .mmap = generic_file_mmap, + .fsync = exfat_file_fsync, + .splice_read = generic_file_splice_read, + .splice_write = iter_file_splice_write, +}; + +const struct inode_operations exfat_file_inode_operations = { + .setattr = exfat_setattr, + .getattr = exfat_getattr, +#ifdef CONFIG_EXFAT_VIRTUAL_XATTR + .listxattr = exfat_listxattr, +#endif +}; diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c new file mode 100644 index 000000000000..20dddebfd706 --- /dev/null +++ b/fs/exfat/inode.c @@ -0,0 +1,660 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "exfat_fs.h" + +static int __exfat_write_inode(struct inode *inode, int sync) +{ + unsigned long long on_disk_size; + struct exfat_dentry *ep, *ep2; + struct exfat_entry_set_cache *es = NULL; + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_inode_info *ei = EXFAT_I(inode); + bool is_dir = (ei->type == TYPE_DIR) ? true : false; + + if (inode->i_ino == EXFAT_ROOT_INO) + return 0; + + /* + * If the indode is already unlinked, there is no need for updating it. + */ + if (ei->dir.dir == DIR_DELETED) + return 0; + + if (is_dir && ei->dir.dir == sbi->root_dir && ei->entry == -1) + return 0; + + exfat_set_vol_flags(sb, VOL_DIRTY); + + /* get the directory entry of given file or directory */ + es = exfat_get_dentry_set(sb, &(ei->dir), ei->entry, ES_ALL_ENTRIES); + if (!es) + return -EIO; + ep = exfat_get_dentry_cached(es, 0); + ep2 = exfat_get_dentry_cached(es, 1); + + ep->dentry.file.attr = cpu_to_le16(exfat_make_attr(inode)); + + /* set FILE_INFO structure using the acquired struct exfat_dentry */ + exfat_set_entry_time(sbi, &ei->i_crtime, + &ep->dentry.file.create_tz, + &ep->dentry.file.create_time, + &ep->dentry.file.create_date, + &ep->dentry.file.create_time_cs); + exfat_set_entry_time(sbi, &inode->i_mtime, + &ep->dentry.file.modify_tz, + &ep->dentry.file.modify_time, + &ep->dentry.file.modify_date, + &ep->dentry.file.modify_time_cs); + exfat_set_entry_time(sbi, &inode->i_atime, + &ep->dentry.file.access_tz, + &ep->dentry.file.access_time, + &ep->dentry.file.access_date, + NULL); + + /* File size should be zero if there is no cluster allocated */ + on_disk_size = i_size_read(inode); + + if (ei->start_clu == EXFAT_EOF_CLUSTER) + on_disk_size = 0; + + ep2->dentry.stream.valid_size = cpu_to_le64(on_disk_size); + ep2->dentry.stream.size = ep2->dentry.stream.valid_size; + + exfat_update_dir_chksum_with_entry_set(es); + exfat_free_dentry_set(es, sync); + return 0; +} + +int exfat_write_inode(struct inode *inode, struct writeback_control *wbc) +{ + int ret; + + mutex_lock(&EXFAT_SB(inode->i_sb)->s_lock); + ret = __exfat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); + mutex_unlock(&EXFAT_SB(inode->i_sb)->s_lock); + + return ret; +} + +void exfat_sync_inode(struct inode *inode) +{ + lockdep_assert_held(&EXFAT_SB(inode->i_sb)->s_lock); + __exfat_write_inode(inode, 1); +} + +/* + * Input: inode, (logical) clu_offset, target allocation area + * Output: errcode, cluster number + * *clu = (~0), if it's unable to allocate a new cluster + */ +static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset, + unsigned int *clu, int create) +{ + int ret, modified = false; + unsigned int last_clu; + struct exfat_chain new_clu; + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_inode_info *ei = EXFAT_I(inode); + unsigned int local_clu_offset = clu_offset; + unsigned int num_to_be_allocated = 0, num_clusters = 0; + + ei->rwoffset = EXFAT_CLU_TO_B(clu_offset, sbi); + + if (EXFAT_I(inode)->i_size_ondisk > 0) + num_clusters = + EXFAT_B_TO_CLU_ROUND_UP(EXFAT_I(inode)->i_size_ondisk, + sbi); + + if (clu_offset >= num_clusters) + num_to_be_allocated = clu_offset - num_clusters + 1; + + if (!create && (num_to_be_allocated > 0)) { + *clu = EXFAT_EOF_CLUSTER; + return 0; + } + + *clu = last_clu = ei->start_clu; + + if (ei->flags == ALLOC_NO_FAT_CHAIN) { + if (clu_offset > 0 && *clu != EXFAT_EOF_CLUSTER) { + last_clu += clu_offset - 1; + + if (clu_offset == num_clusters) + *clu = EXFAT_EOF_CLUSTER; + else + *clu += clu_offset; + } + } else if (ei->type == TYPE_FILE) { + unsigned int fclus = 0; + int err = exfat_get_cluster(inode, clu_offset, + &fclus, clu, &last_clu, 1); + if (err) + return -EIO; + + clu_offset -= fclus; + } else { + /* hint information */ + if (clu_offset > 0 && ei->hint_bmap.off != EXFAT_EOF_CLUSTER && + ei->hint_bmap.off > 0 && clu_offset >= ei->hint_bmap.off) { + clu_offset -= ei->hint_bmap.off; + /* hint_bmap.clu should be valid */ + WARN_ON(ei->hint_bmap.clu < 2); + *clu = ei->hint_bmap.clu; + } + + while (clu_offset > 0 && *clu != EXFAT_EOF_CLUSTER) { + last_clu = *clu; + if (exfat_get_next_cluster(sb, clu)) + return -EIO; + clu_offset--; + } + } + + if (*clu == EXFAT_EOF_CLUSTER) { + exfat_set_vol_flags(sb, VOL_DIRTY); + + new_clu.dir = (last_clu == EXFAT_EOF_CLUSTER) ? + EXFAT_EOF_CLUSTER : last_clu + 1; + new_clu.size = 0; + new_clu.flags = ei->flags; + + /* allocate a cluster */ + if (num_to_be_allocated < 1) { + /* Broken FAT (i_sze > allocated FAT) */ + exfat_fs_error(sb, "broken FAT chain."); + return -EIO; + } + + ret = exfat_alloc_cluster(inode, num_to_be_allocated, &new_clu); + if (ret) + return ret; + + if (new_clu.dir == EXFAT_EOF_CLUSTER || + new_clu.dir == EXFAT_FREE_CLUSTER) { + exfat_fs_error(sb, + "bogus cluster new allocated (last_clu : %u, new_clu : %u)", + last_clu, new_clu.dir); + return -EIO; + } + + /* append to the FAT chain */ + if (last_clu == EXFAT_EOF_CLUSTER) { + if (new_clu.flags == ALLOC_FAT_CHAIN) + ei->flags = ALLOC_FAT_CHAIN; + ei->start_clu = new_clu.dir; + modified = true; + } else { + if (new_clu.flags != ei->flags) { + /* no-fat-chain bit is disabled, + * so fat-chain should be synced with + * alloc-bitmap + */ + exfat_chain_cont_cluster(sb, ei->start_clu, + num_clusters); + ei->flags = ALLOC_FAT_CHAIN; + modified = true; + } + if (new_clu.flags == ALLOC_FAT_CHAIN) + if (exfat_ent_set(sb, last_clu, new_clu.dir)) + return -EIO; + } + + num_clusters += num_to_be_allocated; + *clu = new_clu.dir; + + if (ei->dir.dir != DIR_DELETED && modified) { + struct exfat_dentry *ep; + struct exfat_entry_set_cache *es; + + es = exfat_get_dentry_set(sb, &(ei->dir), ei->entry, + ES_ALL_ENTRIES); + if (!es) + return -EIO; + /* get stream entry */ + ep = exfat_get_dentry_cached(es, 1); + + /* update directory entry */ + ep->dentry.stream.flags = ei->flags; + ep->dentry.stream.start_clu = + cpu_to_le32(ei->start_clu); + ep->dentry.stream.valid_size = + cpu_to_le64(i_size_read(inode)); + ep->dentry.stream.size = + ep->dentry.stream.valid_size; + + exfat_update_dir_chksum_with_entry_set(es); + exfat_free_dentry_set(es, inode_needs_sync(inode)); + + } /* end of if != DIR_DELETED */ + + inode->i_blocks += + num_to_be_allocated << sbi->sect_per_clus_bits; + + /* + * Move *clu pointer along FAT chains (hole care) because the + * caller of this function expect *clu to be the last cluster. + * This only works when num_to_be_allocated >= 2, + * *clu = (the first cluster of the allocated chain) => + * (the last cluster of ...) + */ + if (ei->flags == ALLOC_NO_FAT_CHAIN) { + *clu += num_to_be_allocated - 1; + } else { + while (num_to_be_allocated > 1) { + if (exfat_get_next_cluster(sb, clu)) + return -EIO; + num_to_be_allocated--; + } + } + + } + + /* hint information */ + ei->hint_bmap.off = local_clu_offset; + ei->hint_bmap.clu = *clu; + + return 0; +} + +static int exfat_map_new_buffer(struct exfat_inode_info *ei, + struct buffer_head *bh, loff_t pos) +{ + if (buffer_delay(bh) && pos > ei->i_size_aligned) + return -EIO; + set_buffer_new(bh); + + /* + * Adjust i_size_aligned if i_size_ondisk is bigger than it. + */ + if (ei->i_size_ondisk > ei->i_size_aligned) + ei->i_size_aligned = ei->i_size_ondisk; + return 0; +} + +static int exfat_get_block(struct inode *inode, sector_t iblock, + struct buffer_head *bh_result, int create) +{ + struct exfat_inode_info *ei = EXFAT_I(inode); + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits; + int err = 0; + unsigned long mapped_blocks = 0; + unsigned int cluster, sec_offset; + sector_t last_block; + sector_t phys = 0; + loff_t pos; + + mutex_lock(&sbi->s_lock); + last_block = EXFAT_B_TO_BLK_ROUND_UP(i_size_read(inode), sb); + if (iblock >= last_block && !create) + goto done; + + /* Is this block already allocated? */ + err = exfat_map_cluster(inode, iblock >> sbi->sect_per_clus_bits, + &cluster, create); + if (err) { + if (err != -ENOSPC) + exfat_fs_error_ratelimit(sb, + "failed to bmap (inode : %p iblock : %llu, err : %d)", + inode, (unsigned long long)iblock, err); + goto unlock_ret; + } + + if (cluster == EXFAT_EOF_CLUSTER) + goto done; + + /* sector offset in cluster */ + sec_offset = iblock & (sbi->sect_per_clus - 1); + + phys = exfat_cluster_to_sector(sbi, cluster) + sec_offset; + mapped_blocks = sbi->sect_per_clus - sec_offset; + max_blocks = min(mapped_blocks, max_blocks); + + /* Treat newly added block / cluster */ + if (iblock < last_block) + create = 0; + + if (create || buffer_delay(bh_result)) { + pos = EXFAT_BLK_TO_B((iblock + 1), sb); + if (ei->i_size_ondisk < pos) + ei->i_size_ondisk = pos; + } + + if (create) { + err = exfat_map_new_buffer(ei, bh_result, pos); + if (err) { + exfat_fs_error(sb, + "requested for bmap out of range(pos : (%llu) > i_size_aligned(%llu)\n", + pos, ei->i_size_aligned); + goto unlock_ret; + } + } + + if (buffer_delay(bh_result)) + clear_buffer_delay(bh_result); + map_bh(bh_result, sb, phys); +done: + bh_result->b_size = EXFAT_BLK_TO_B(max_blocks, sb); +unlock_ret: + mutex_unlock(&sbi->s_lock); + return err; +} + +static int exfat_readpage(struct file *file, struct page *page) +{ + return mpage_readpage(page, exfat_get_block); +} + +static int exfat_readpages(struct file *file, struct address_space *mapping, + struct list_head *pages, unsigned int nr_pages) +{ + return mpage_readpages(mapping, pages, nr_pages, exfat_get_block); +} + +static int exfat_writepage(struct page *page, struct writeback_control *wbc) +{ + return block_write_full_page(page, exfat_get_block, wbc); +} + +static int exfat_writepages(struct address_space *mapping, + struct writeback_control *wbc) +{ + return mpage_writepages(mapping, wbc, exfat_get_block); +} + +static void exfat_write_failed(struct address_space *mapping, loff_t to) +{ + struct inode *inode = mapping->host; + + if (to > i_size_read(inode)) { + truncate_pagecache(inode, i_size_read(inode)); + exfat_truncate(inode, EXFAT_I(inode)->i_size_aligned); + } +} + +static int exfat_write_begin(struct file *file, struct address_space *mapping, + loff_t pos, unsigned int len, unsigned int flags, + struct page **pagep, void **fsdata) +{ + int ret; + + *pagep = NULL; + ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata, + exfat_get_block, + &EXFAT_I(mapping->host)->i_size_ondisk); + + if (ret < 0) + exfat_write_failed(mapping, pos+len); + + return ret; +} + +static int exfat_write_end(struct file *file, struct address_space *mapping, + loff_t pos, unsigned int len, unsigned int copied, + struct page *pagep, void *fsdata) +{ + struct inode *inode = mapping->host; + struct exfat_inode_info *ei = EXFAT_I(inode); + int err; + + err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata); + + if (EXFAT_I(inode)->i_size_aligned < i_size_read(inode)) { + exfat_fs_error(inode->i_sb, + "invalid size(size(%llu) > aligned(%llu)\n", + i_size_read(inode), EXFAT_I(inode)->i_size_aligned); + return -EIO; + } + + if (err < len) + exfat_write_failed(mapping, pos+len); + + if (!(err < 0) && !(ei->attr & ATTR_ARCHIVE)) { + inode->i_mtime = inode->i_ctime = current_time(inode); + ei->attr |= ATTR_ARCHIVE; + mark_inode_dirty(inode); + } + + return err; +} + +static ssize_t exfat_direct_IO(struct kiocb *iocb, struct iov_iter *iter) +{ + struct address_space *mapping = iocb->ki_filp->f_mapping; + struct inode *inode = mapping->host; + loff_t size = iocb->ki_pos + iov_iter_count(iter); + int rw = iov_iter_rw(iter); + ssize_t ret; + + if (rw == WRITE) { + /* + * FIXME: blockdev_direct_IO() doesn't use ->write_begin(), + * so we need to update the ->i_size_aligned to block boundary. + * + * But we must fill the remaining area or hole by nul for + * updating ->i_size_aligned + * + * Return 0, and fallback to normal buffered write. + */ + if (EXFAT_I(inode)->i_size_aligned < size) + return 0; + } + + /* + * Need to use the DIO_LOCKING for avoiding the race + * condition of exfat_get_block() and ->truncate(). + */ + ret = blockdev_direct_IO(iocb, inode, iter, exfat_get_block); + if (ret < 0 && (rw & WRITE)) + exfat_write_failed(mapping, size); + return ret; +} + +static sector_t exfat_aop_bmap(struct address_space *mapping, sector_t block) +{ + sector_t blocknr; + + /* exfat_get_cluster() assumes the requested blocknr isn't truncated. */ + down_read(&EXFAT_I(mapping->host)->truncate_lock); + blocknr = generic_block_bmap(mapping, block, exfat_get_block); + up_read(&EXFAT_I(mapping->host)->truncate_lock); + return blocknr; +} + +/* + * exfat_block_truncate_page() zeroes out a mapping from file offset `from' + * up to the end of the block which corresponds to `from'. + * This is required during truncate to physically zeroout the tail end + * of that block so it doesn't yield old data if the file is later grown. + * Also, avoid causing failure from fsx for cases of "data past EOF" + */ +int exfat_block_truncate_page(struct inode *inode, loff_t from) +{ + return block_truncate_page(inode->i_mapping, from, exfat_get_block); +} + +static const struct address_space_operations exfat_aops = { + .readpage = exfat_readpage, + .readpages = exfat_readpages, + .writepage = exfat_writepage, + .writepages = exfat_writepages, + .write_begin = exfat_write_begin, + .write_end = exfat_write_end, + .direct_IO = exfat_direct_IO, + .bmap = exfat_aop_bmap +}; + +static inline unsigned long exfat_hash(loff_t i_pos) +{ + return hash_32(i_pos, EXFAT_HASH_BITS); +} + +void exfat_hash_inode(struct inode *inode, loff_t i_pos) +{ + struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb); + struct hlist_head *head = sbi->inode_hashtable + exfat_hash(i_pos); + + spin_lock(&sbi->inode_hash_lock); + EXFAT_I(inode)->i_pos = i_pos; + hlist_add_head(&EXFAT_I(inode)->i_hash_fat, head); + spin_unlock(&sbi->inode_hash_lock); +} + +void exfat_unhash_inode(struct inode *inode) +{ + struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb); + + spin_lock(&sbi->inode_hash_lock); + hlist_del_init(&EXFAT_I(inode)->i_hash_fat); + EXFAT_I(inode)->i_pos = 0; + spin_unlock(&sbi->inode_hash_lock); +} + +struct inode *exfat_iget(struct super_block *sb, loff_t i_pos) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_inode_info *info; + struct hlist_head *head = sbi->inode_hashtable + exfat_hash(i_pos); + struct inode *inode = NULL; + + spin_lock(&sbi->inode_hash_lock); + hlist_for_each_entry(info, head, i_hash_fat) { + WARN_ON(info->vfs_inode.i_sb != sb); + + if (i_pos != info->i_pos) + continue; + inode = igrab(&info->vfs_inode); + if (inode) + break; + } + spin_unlock(&sbi->inode_hash_lock); + return inode; +} + +/* doesn't deal with root inode */ +static int exfat_fill_inode(struct inode *inode, struct exfat_dir_entry *info) +{ + struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb); + struct exfat_inode_info *ei = EXFAT_I(inode); + loff_t size = info->size; + + memcpy(&ei->dir, &info->dir, sizeof(struct exfat_chain)); + ei->entry = info->entry; + ei->attr = info->attr; + ei->start_clu = info->start_clu; + ei->flags = info->flags; + ei->type = info->type; + + ei->version = 0; + ei->hint_stat.eidx = 0; + ei->hint_stat.clu = info->start_clu; + ei->hint_femp.eidx = EXFAT_HINT_NONE; + ei->rwoffset = 0; + ei->hint_bmap.off = EXFAT_EOF_CLUSTER; + ei->i_pos = 0; + + inode->i_uid = sbi->options.fs_uid; + inode->i_gid = sbi->options.fs_gid; + inode_inc_iversion(inode); + inode->i_generation = prandom_u32(); + + if (info->attr & ATTR_SUBDIR) { /* directory */ + inode->i_generation &= ~1; + inode->i_mode = exfat_make_mode(sbi, info->attr, 0777); + inode->i_op = &exfat_dir_inode_operations; + inode->i_fop = &exfat_dir_operations; + set_nlink(inode, info->num_subdirs); + } else { /* regular file */ + inode->i_generation |= 1; + inode->i_mode = exfat_make_mode(sbi, info->attr, 0777); + inode->i_op = &exfat_file_inode_operations; + inode->i_fop = &exfat_file_operations; + inode->i_mapping->a_ops = &exfat_aops; + inode->i_mapping->nrpages = 0; + } + + i_size_write(inode, size); + + /* ondisk and aligned size should be aligned with block size */ + if (size & (inode->i_sb->s_blocksize - 1)) { + size |= (inode->i_sb->s_blocksize - 1); + size++; + } + + ei->i_size_aligned = size; + ei->i_size_ondisk = size; + + exfat_save_attr(inode, info->attr); + + inode->i_blocks = ((i_size_read(inode) + (sbi->cluster_size - 1)) & + ~(sbi->cluster_size - 1)) >> inode->i_blkbits; + inode->i_mtime = info->mtime; + inode->i_ctime = info->mtime; + ei->i_crtime = info->crtime; + inode->i_atime = info->atime; + + exfat_cache_init_inode(inode); + + return 0; +} + +struct inode *exfat_build_inode(struct super_block *sb, + struct exfat_dir_entry *info, loff_t i_pos) +{ + struct inode *inode; + int err; + + inode = exfat_iget(sb, i_pos); + if (inode) + goto out; + inode = new_inode(sb); + if (!inode) { + inode = ERR_PTR(-ENOMEM); + goto out; + } + inode->i_ino = iunique(sb, EXFAT_ROOT_INO); + inode_set_iversion(inode, 1); + err = exfat_fill_inode(inode, info); + if (err) { + iput(inode); + inode = ERR_PTR(err); + goto out; + } + exfat_hash_inode(inode, i_pos); + insert_inode_hash(inode); +out: + return inode; +} + +void exfat_evict_inode(struct inode *inode) +{ + truncate_inode_pages(&inode->i_data, 0); + + if (!inode->i_nlink) { + i_size_write(inode, 0); + mutex_lock(&EXFAT_SB(inode->i_sb)->s_lock); + __exfat_truncate(inode, 0); + mutex_unlock(&EXFAT_SB(inode->i_sb)->s_lock); + } + + invalidate_inode_buffers(inode); + clear_inode(inode); + exfat_cache_inval_inode(inode); + exfat_unhash_inode(inode); +} diff --git a/fs/exfat/misc.c b/fs/exfat/misc.c new file mode 100644 index 000000000000..93e05ace37bc --- /dev/null +++ b/fs/exfat/misc.c @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Written 1992,1993 by Werner Almesberger + * 22/11/2000 - Fixed fat_date_unix2dos for dates earlier than 01/01/1980 + * and date_dos2unix for date==0 by Igor Zhbanov(bsg@uniyar.ac.ru) + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#include +#include +#include +#include + +#include "exfat_fs.h" + +/* + * exfat_fs_error reports a file system problem that might indicate fa data + * corruption/inconsistency. Depending on 'errors' mount option the + * panic() is called, or error message is printed FAT and nothing is done, + * or filesystem is remounted read-only (default behavior). + * In case the file system is remounted read-only, it can be made writable + * again by remounting it. + */ +void __exfat_fs_error(struct super_block *sb, int report, const char *fmt, ...) +{ + struct exfat_mount_options *opts = &EXFAT_SB(sb)->options; + va_list args; + struct va_format vaf; + + if (report) { + va_start(args, fmt); + vaf.fmt = fmt; + vaf.va = &args; + exfat_err(sb, "error, %pV", &vaf); + va_end(args); + } + + if (opts->errors == EXFAT_ERRORS_PANIC) { + panic("exFAT-fs (%s): fs panic from previous error\n", + sb->s_id); + } else if (opts->errors == EXFAT_ERRORS_RO && !sb_rdonly(sb)) { + sb->s_flags |= SB_RDONLY; + exfat_err(sb, "Filesystem has been set read-only"); + } +} + +/* + * exfat_msg() - print preformated EXFAT specific messages. + * All logs except what uses exfat_fs_error() should be written by exfat_msg() + */ +void exfat_msg(struct super_block *sb, const char *level, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + va_start(args, fmt); + vaf.fmt = fmt; + vaf.va = &args; + /* level means KERN_ pacility level */ + printk("%sexFAT-fs (%s): %pV\n", level, sb->s_id, &vaf); + va_end(args); +} + +#define SECS_PER_MIN (60) +#define TIMEZONE_SEC(x) ((x) * 15 * SECS_PER_MIN) + +static void exfat_adjust_tz(struct timespec64 *ts, u8 tz_off) +{ + if (tz_off <= 0x3F) + ts->tv_sec -= TIMEZONE_SEC(tz_off); + else /* 0x40 <= (tz_off & 0x7F) <=0x7F */ + ts->tv_sec += TIMEZONE_SEC(0x80 - tz_off); +} + +/* Convert a EXFAT time/date pair to a UNIX date (seconds since 1 1 70). */ +void exfat_get_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts, + u8 tz, __le16 time, __le16 date, u8 time_cs) +{ + u16 t = le16_to_cpu(time); + u16 d = le16_to_cpu(date); + + ts->tv_sec = mktime64(1980 + (d >> 9), d >> 5 & 0x000F, d & 0x001F, + t >> 11, (t >> 5) & 0x003F, (t & 0x001F) << 1); + + + /* time_cs field represent 0 ~ 199cs(1990 ms) */ + if (time_cs) { + ts->tv_sec += time_cs / 100; + ts->tv_nsec = (time_cs % 100) * 10 * NSEC_PER_MSEC; + } else + ts->tv_nsec = 0; + + if (tz & EXFAT_TZ_VALID) + /* Adjust timezone to UTC0. */ + exfat_adjust_tz(ts, tz & ~EXFAT_TZ_VALID); + else + /* Convert from local time to UTC using time_offset. */ + ts->tv_sec -= sbi->options.time_offset * SECS_PER_MIN; +} + +/* Convert linear UNIX date to a EXFAT time/date pair. */ +void exfat_set_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts, + u8 *tz, __le16 *time, __le16 *date, u8 *time_cs) +{ + struct tm tm; + u16 t, d; + + time64_to_tm(ts->tv_sec, 0, &tm); + t = (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1); + d = ((tm.tm_year - 80) << 9) | ((tm.tm_mon + 1) << 5) | tm.tm_mday; + + *time = cpu_to_le16(t); + *date = cpu_to_le16(d); + + /* time_cs field represent 0 ~ 199cs(1990 ms) */ + if (time_cs) + *time_cs = (tm.tm_sec & 1) * 100 + + ts->tv_nsec / (10 * NSEC_PER_MSEC); + + /* + * Record 00h value for OffsetFromUtc field and 1 value for OffsetValid + * to indicate that local time and UTC are the same. + */ + *tz = EXFAT_TZ_VALID; +} + +/* + * The timestamp for access_time has double seconds granularity. + * (There is no 10msIncrement field for access_time unlike create/modify_time) + * atime also has only a 2-second resolution. + */ +void exfat_truncate_atime(struct timespec64 *ts) +{ + ts->tv_sec = round_down(ts->tv_sec, 2); + ts->tv_nsec = 0; +} + +u16 exfat_calc_chksum16(void *data, int len, u16 chksum, int type) +{ + int i; + u8 *c = (u8 *)data; + + for (i = 0; i < len; i++, c++) { + if (unlikely(type == CS_DIR_ENTRY && (i == 2 || i == 3))) + continue; + chksum = ((chksum << 15) | (chksum >> 1)) + *c; + } + return chksum; +} + +u32 exfat_calc_chksum32(void *data, int len, u32 chksum, int type) +{ + int i; + u8 *c = (u8 *)data; + + for (i = 0; i < len; i++, c++) { + if (unlikely(type == CS_BOOT_SECTOR && + (i == 106 || i == 107 || i == 112))) + continue; + chksum = ((chksum << 31) | (chksum >> 1)) + *c; + } + return chksum; +} + +void exfat_update_bh(struct super_block *sb, struct buffer_head *bh, int sync) +{ + set_bit(EXFAT_SB_DIRTY, &EXFAT_SB(sb)->s_state); + set_buffer_uptodate(bh); + mark_buffer_dirty(bh); + + if (sync) + sync_dirty_buffer(bh); +} + +void exfat_chain_set(struct exfat_chain *ec, unsigned int dir, + unsigned int size, unsigned char flags) +{ + ec->dir = dir; + ec->size = size; + ec->flags = flags; +} + +void exfat_chain_dup(struct exfat_chain *dup, struct exfat_chain *ec) +{ + return exfat_chain_set(dup, ec->dir, ec->size, ec->flags); +} diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c new file mode 100644 index 000000000000..f0a625e9c9a9 --- /dev/null +++ b/fs/exfat/namei.c @@ -0,0 +1,1450 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#include +#include +#include +#include + +#include "exfat_fs.h" + +static inline unsigned long exfat_d_version(struct dentry *dentry) +{ + return (unsigned long) dentry->d_fsdata; +} + +static inline void exfat_d_version_set(struct dentry *dentry, + unsigned long version) +{ + dentry->d_fsdata = (void *) version; +} + +/* + * If new entry was created in the parent, it could create the 8.3 alias (the + * shortname of logname). So, the parent may have the negative-dentry which + * matches the created 8.3 alias. + * + * If it happened, the negative dentry isn't actually negative anymore. So, + * drop it. + */ +static int exfat_d_revalidate(struct dentry *dentry, unsigned int flags) +{ + int ret; + + if (flags & LOOKUP_RCU) + return -ECHILD; + + /* + * This is not negative dentry. Always valid. + * + * Note, rename() to existing directory entry will have ->d_inode, and + * will use existing name which isn't specified name by user. + * + * We may be able to drop this positive dentry here. But dropping + * positive dentry isn't good idea. So it's unsupported like + * rename("filename", "FILENAME") for now. + */ + if (d_really_is_positive(dentry)) + return 1; + + /* + * Drop the negative dentry, in order to make sure to use the case + * sensitive name which is specified by user if this is for creation. + */ + if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) + return 0; + + spin_lock(&dentry->d_lock); + ret = inode_eq_iversion(d_inode(dentry->d_parent), + exfat_d_version(dentry)); + spin_unlock(&dentry->d_lock); + return ret; +} + +/* returns the length of a struct qstr, ignoring trailing dots */ +static unsigned int exfat_striptail_len(unsigned int len, const char *name) +{ + while (len && name[len - 1] == '.') + len--; + return len; +} + +/* + * Compute the hash for the exfat name corresponding to the dentry. If the name + * is invalid, we leave the hash code unchanged so that the existing dentry can + * be used. The exfat fs routines will return ENOENT or EINVAL as appropriate. + */ +static int exfat_d_hash(const struct dentry *dentry, struct qstr *qstr) +{ + struct super_block *sb = dentry->d_sb; + struct nls_table *t = EXFAT_SB(sb)->nls_io; + const unsigned char *name = qstr->name; + unsigned int len = exfat_striptail_len(qstr->len, qstr->name); + unsigned long hash = init_name_hash(dentry); + int i, charlen; + wchar_t c; + + for (i = 0; i < len; i += charlen) { + charlen = t->char2uni(&name[i], len - i, &c); + if (charlen < 0) + return charlen; + hash = partial_name_hash(exfat_toupper(sb, c), hash); + } + + qstr->hash = end_name_hash(hash); + return 0; +} + +static int exfat_d_cmp(const struct dentry *dentry, unsigned int len, + const char *str, const struct qstr *name) +{ + struct super_block *sb = dentry->d_sb; + struct nls_table *t = EXFAT_SB(sb)->nls_io; + unsigned int alen = exfat_striptail_len(name->len, name->name); + unsigned int blen = exfat_striptail_len(len, str); + wchar_t c1, c2; + int charlen, i; + + if (alen != blen) + return 1; + + for (i = 0; i < len; i += charlen) { + charlen = t->char2uni(&name->name[i], alen - i, &c1); + if (charlen < 0) + return 1; + if (charlen != t->char2uni(&str[i], blen - i, &c2)) + return 1; + + if (exfat_toupper(sb, c1) != exfat_toupper(sb, c2)) + return 1; + } + + return 0; +} + +const struct dentry_operations exfat_dentry_ops = { + .d_revalidate = exfat_d_revalidate, + .d_hash = exfat_d_hash, + .d_compare = exfat_d_cmp, +}; + +static int exfat_utf8_d_hash(const struct dentry *dentry, struct qstr *qstr) +{ + struct super_block *sb = dentry->d_sb; + const unsigned char *name = qstr->name; + unsigned int len = exfat_striptail_len(qstr->len, qstr->name); + unsigned long hash = init_name_hash(dentry); + int i, charlen; + unicode_t u; + + for (i = 0; i < len; i += charlen) { + charlen = utf8_to_utf32(&name[i], len - i, &u); + if (charlen < 0) + return charlen; + + /* + * exfat_toupper() works only for code points up to the U+FFFF. + */ + hash = partial_name_hash(u <= 0xFFFF ? exfat_toupper(sb, u) : u, + hash); + } + + qstr->hash = end_name_hash(hash); + return 0; +} + +static int exfat_utf8_d_cmp(const struct dentry *dentry, unsigned int len, + const char *str, const struct qstr *name) +{ + struct super_block *sb = dentry->d_sb; + unsigned int alen = exfat_striptail_len(name->len, name->name); + unsigned int blen = exfat_striptail_len(len, str); + unicode_t u_a, u_b; + int charlen, i; + + if (alen != blen) + return 1; + + for (i = 0; i < alen; i += charlen) { + charlen = utf8_to_utf32(&name->name[i], alen - i, &u_a); + if (charlen < 0) + return 1; + if (charlen != utf8_to_utf32(&str[i], blen - i, &u_b)) + return 1; + + if (u_a <= 0xFFFF && u_b <= 0xFFFF) { + if (exfat_toupper(sb, u_a) != exfat_toupper(sb, u_b)) + return 1; + } else { + if (u_a != u_b) + return 1; + } + } + + return 0; +} + +const struct dentry_operations exfat_utf8_dentry_ops = { + .d_revalidate = exfat_d_revalidate, + .d_hash = exfat_utf8_d_hash, + .d_compare = exfat_utf8_d_cmp, +}; + +/* used only in search empty_slot() */ +#define CNT_UNUSED_NOHIT (-1) +#define CNT_UNUSED_HIT (-2) +/* search EMPTY CONTINUOUS "num_entries" entries */ +static int exfat_search_empty_slot(struct super_block *sb, + struct exfat_hint_femp *hint_femp, struct exfat_chain *p_dir, + int num_entries) +{ + int i, dentry, num_empty = 0; + int dentries_per_clu; + unsigned int type; + struct exfat_chain clu; + struct exfat_dentry *ep; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct buffer_head *bh; + + dentries_per_clu = sbi->dentries_per_clu; + + if (hint_femp->eidx != EXFAT_HINT_NONE) { + dentry = hint_femp->eidx; + if (num_entries <= hint_femp->count) { + hint_femp->eidx = EXFAT_HINT_NONE; + return dentry; + } + + exfat_chain_dup(&clu, &hint_femp->cur); + } else { + exfat_chain_dup(&clu, p_dir); + dentry = 0; + } + + while (clu.dir != EXFAT_EOF_CLUSTER) { + i = dentry & (dentries_per_clu - 1); + + for (; i < dentries_per_clu; i++, dentry++) { + ep = exfat_get_dentry(sb, &clu, i, &bh, NULL); + if (!ep) + return -EIO; + type = exfat_get_entry_type(ep); + brelse(bh); + + if (type == TYPE_UNUSED || type == TYPE_DELETED) { + num_empty++; + if (hint_femp->eidx == EXFAT_HINT_NONE) { + hint_femp->eidx = dentry; + hint_femp->count = CNT_UNUSED_NOHIT; + exfat_chain_set(&hint_femp->cur, + clu.dir, clu.size, clu.flags); + } + + if (type == TYPE_UNUSED && + hint_femp->count != CNT_UNUSED_HIT) + hint_femp->count = CNT_UNUSED_HIT; + } else { + if (hint_femp->eidx != EXFAT_HINT_NONE && + hint_femp->count == CNT_UNUSED_HIT) { + /* unused empty group means + * an empty group which includes + * unused dentry + */ + exfat_fs_error(sb, + "found bogus dentry(%d) beyond unused empty group(%d) (start_clu : %u, cur_clu : %u)", + dentry, hint_femp->eidx, + p_dir->dir, clu.dir); + return -EIO; + } + + num_empty = 0; + hint_femp->eidx = EXFAT_HINT_NONE; + } + + if (num_empty >= num_entries) { + /* found and invalidate hint_femp */ + hint_femp->eidx = EXFAT_HINT_NONE; + return (dentry - (num_entries - 1)); + } + } + + if (clu.flags == ALLOC_NO_FAT_CHAIN) { + if (--clu.size > 0) + clu.dir++; + else + clu.dir = EXFAT_EOF_CLUSTER; + } else { + if (exfat_get_next_cluster(sb, &clu.dir)) + return -EIO; + } + } + + return -ENOSPC; +} + +static int exfat_check_max_dentries(struct inode *inode) +{ + if (EXFAT_B_TO_DEN(i_size_read(inode)) >= MAX_EXFAT_DENTRIES) { + /* + * exFAT spec allows a dir to grow upto 8388608(256MB) + * dentries + */ + return -ENOSPC; + } + return 0; +} + +/* find empty directory entry. + * if there isn't any empty slot, expand cluster chain. + */ +static int exfat_find_empty_entry(struct inode *inode, + struct exfat_chain *p_dir, int num_entries) +{ + int dentry; + unsigned int ret, last_clu; + sector_t sector; + loff_t size = 0; + struct exfat_chain clu; + struct exfat_dentry *ep = NULL; + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_inode_info *ei = EXFAT_I(inode); + struct exfat_hint_femp hint_femp; + + hint_femp.eidx = EXFAT_HINT_NONE; + + if (ei->hint_femp.eidx != EXFAT_HINT_NONE) { + memcpy(&hint_femp, &ei->hint_femp, + sizeof(struct exfat_hint_femp)); + ei->hint_femp.eidx = EXFAT_HINT_NONE; + } + + while ((dentry = exfat_search_empty_slot(sb, &hint_femp, p_dir, + num_entries)) < 0) { + if (dentry == -EIO) + break; + + if (exfat_check_max_dentries(inode)) + return -ENOSPC; + + /* we trust p_dir->size regardless of FAT type */ + if (exfat_find_last_cluster(sb, p_dir, &last_clu)) + return -EIO; + + /* + * Allocate new cluster to this directory + */ + exfat_chain_set(&clu, last_clu + 1, 0, p_dir->flags); + + /* allocate a cluster */ + ret = exfat_alloc_cluster(inode, 1, &clu); + if (ret) + return ret; + + if (exfat_zeroed_cluster(inode, clu.dir)) + return -EIO; + + /* append to the FAT chain */ + if (clu.flags != p_dir->flags) { + /* no-fat-chain bit is disabled, + * so fat-chain should be synced with alloc-bitmap + */ + exfat_chain_cont_cluster(sb, p_dir->dir, p_dir->size); + p_dir->flags = ALLOC_FAT_CHAIN; + hint_femp.cur.flags = ALLOC_FAT_CHAIN; + } + + if (clu.flags == ALLOC_FAT_CHAIN) + if (exfat_ent_set(sb, last_clu, clu.dir)) + return -EIO; + + if (hint_femp.eidx == EXFAT_HINT_NONE) { + /* the special case that new dentry + * should be allocated from the start of new cluster + */ + hint_femp.eidx = EXFAT_B_TO_DEN_IDX(p_dir->size, sbi); + hint_femp.count = sbi->dentries_per_clu; + + exfat_chain_set(&hint_femp.cur, clu.dir, 0, clu.flags); + } + hint_femp.cur.size++; + p_dir->size++; + size = EXFAT_CLU_TO_B(p_dir->size, sbi); + + /* update the directory entry */ + if (p_dir->dir != sbi->root_dir) { + struct buffer_head *bh; + + ep = exfat_get_dentry(sb, + &(ei->dir), ei->entry + 1, &bh, §or); + if (!ep) + return -EIO; + + ep->dentry.stream.valid_size = cpu_to_le64(size); + ep->dentry.stream.size = ep->dentry.stream.valid_size; + ep->dentry.stream.flags = p_dir->flags; + exfat_update_bh(sb, bh, IS_DIRSYNC(inode)); + brelse(bh); + if (exfat_update_dir_chksum(inode, &(ei->dir), + ei->entry)) + return -EIO; + } + + /* directory inode should be updated in here */ + i_size_write(inode, size); + EXFAT_I(inode)->i_size_ondisk += sbi->cluster_size; + EXFAT_I(inode)->i_size_aligned += sbi->cluster_size; + EXFAT_I(inode)->flags = p_dir->flags; + inode->i_blocks += 1 << sbi->sect_per_clus_bits; + } + + return dentry; +} + +/* + * Name Resolution Functions : + * Zero if it was successful; otherwise nonzero. + */ +static int __exfat_resolve_path(struct inode *inode, const unsigned char *path, + struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname, + int lookup) +{ + int namelen; + int lossy = NLS_NAME_NO_LOSSY; + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_inode_info *ei = EXFAT_I(inode); + + /* strip all trailing periods */ + namelen = exfat_striptail_len(strlen(path), path); + if (!namelen) + return -ENOENT; + + if (strlen(path) > (MAX_NAME_LENGTH * MAX_CHARSET_SIZE)) + return -ENAMETOOLONG; + + /* + * strip all leading spaces : + * "MS windows 7" supports leading spaces. + * So we should skip this preprocessing for compatibility. + */ + + /* file name conversion : + * If lookup case, we allow bad-name for compatibility. + */ + namelen = exfat_nls_to_utf16(sb, path, namelen, p_uniname, + &lossy); + if (namelen < 0) + return namelen; /* return error value */ + + if ((lossy && !lookup) || !namelen) + return -EINVAL; + + exfat_chain_set(p_dir, ei->start_clu, + EXFAT_B_TO_CLU(i_size_read(inode), sbi), ei->flags); + + return 0; +} + +static inline int exfat_resolve_path(struct inode *inode, + const unsigned char *path, struct exfat_chain *dir, + struct exfat_uni_name *uni) +{ + return __exfat_resolve_path(inode, path, dir, uni, 0); +} + +static inline int exfat_resolve_path_for_lookup(struct inode *inode, + const unsigned char *path, struct exfat_chain *dir, + struct exfat_uni_name *uni) +{ + return __exfat_resolve_path(inode, path, dir, uni, 1); +} + +static inline loff_t exfat_make_i_pos(struct exfat_dir_entry *info) +{ + return ((loff_t) info->dir.dir << 32) | (info->entry & 0xffffffff); +} + +static int exfat_add_entry(struct inode *inode, const char *path, + struct exfat_chain *p_dir, unsigned int type, + struct exfat_dir_entry *info) +{ + int ret, dentry, num_entries; + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_uni_name uniname; + struct exfat_chain clu; + int clu_size = 0; + unsigned int start_clu = EXFAT_FREE_CLUSTER; + + ret = exfat_resolve_path(inode, path, p_dir, &uniname); + if (ret) + goto out; + + num_entries = exfat_calc_num_entries(&uniname); + if (num_entries < 0) { + ret = num_entries; + goto out; + } + + /* exfat_find_empty_entry must be called before alloc_cluster() */ + dentry = exfat_find_empty_entry(inode, p_dir, num_entries); + if (dentry < 0) { + ret = dentry; /* -EIO or -ENOSPC */ + goto out; + } + + if (type == TYPE_DIR) { + ret = exfat_alloc_new_dir(inode, &clu); + if (ret) + goto out; + start_clu = clu.dir; + clu_size = sbi->cluster_size; + } + + /* update the directory entry */ + /* fill the dos name directory entry information of the created file. + * the first cluster is not determined yet. (0) + */ + ret = exfat_init_dir_entry(inode, p_dir, dentry, type, + start_clu, clu_size); + if (ret) + goto out; + + ret = exfat_init_ext_entry(inode, p_dir, dentry, num_entries, &uniname); + if (ret) + goto out; + + memcpy(&info->dir, p_dir, sizeof(struct exfat_chain)); + info->entry = dentry; + info->flags = ALLOC_NO_FAT_CHAIN; + info->type = type; + + if (type == TYPE_FILE) { + info->attr = ATTR_ARCHIVE; + info->start_clu = EXFAT_EOF_CLUSTER; + info->size = 0; + info->num_subdirs = 0; + } else { + int count; + struct exfat_chain cdir; + + info->attr = ATTR_SUBDIR; + info->start_clu = start_clu; + info->size = clu_size; + + exfat_chain_set(&cdir, info->start_clu, + EXFAT_B_TO_CLU(info->size, sbi), info->flags); + count = exfat_count_dir_entries(sb, &cdir); + if (count < 0) + return -EIO; + info->num_subdirs = count + EXFAT_MIN_SUBDIR; + } + memset(&info->crtime, 0, sizeof(info->crtime)); + memset(&info->mtime, 0, sizeof(info->mtime)); + memset(&info->atime, 0, sizeof(info->atime)); +out: + return ret; +} + +static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode, + bool excl) +{ + struct super_block *sb = dir->i_sb; + struct inode *inode; + struct exfat_chain cdir; + struct exfat_dir_entry info; + loff_t i_pos; + int err; + + mutex_lock(&EXFAT_SB(sb)->s_lock); + exfat_set_vol_flags(sb, VOL_DIRTY); + err = exfat_add_entry(dir, dentry->d_name.name, &cdir, TYPE_FILE, + &info); + exfat_set_vol_flags(sb, VOL_CLEAN); + if (err) + goto unlock; + + inode_inc_iversion(dir); + dir->i_ctime = dir->i_mtime = current_time(dir); + if (IS_DIRSYNC(dir)) + exfat_sync_inode(dir); + else + mark_inode_dirty(dir); + + i_pos = exfat_make_i_pos(&info); + inode = exfat_build_inode(sb, &info, i_pos); + if (IS_ERR(inode)) + goto unlock; + + inode_inc_iversion(inode); + inode->i_mtime = inode->i_atime = inode->i_ctime = + EXFAT_I(inode)->i_crtime = current_time(inode); + exfat_truncate_atime(&inode->i_atime); + /* timestamp is already written, so mark_inode_dirty() is unneeded. */ + + d_instantiate(dentry, inode); +unlock: + mutex_unlock(&EXFAT_SB(sb)->s_lock); + return err; +} + +/* lookup a file */ +static int exfat_find(struct inode *dir, struct qstr *qname, + struct exfat_dir_entry *info) +{ + int ret, dentry, num_entries, count; + struct exfat_chain cdir; + struct exfat_uni_name uni_name; + struct super_block *sb = dir->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_inode_info *ei = EXFAT_I(dir); + + if (qname->len == 0) + return -ENOENT; + + /* check the validity of directory name in the given pathname */ + ret = exfat_resolve_path_for_lookup(dir, qname->name, &cdir, &uni_name); + if (ret) + return ret; + + num_entries = exfat_calc_num_entries(&uni_name); + if (num_entries < 0) + return num_entries; + + /* check the validation of hint_stat and initialize it if required */ + if (ei->version != (inode_peek_iversion_raw(dir) & 0xffffffff)) { + ei->hint_stat.clu = cdir.dir; + ei->hint_stat.eidx = 0; + ei->version = (inode_peek_iversion_raw(dir) & 0xffffffff); + ei->hint_femp.eidx = EXFAT_HINT_NONE; + } + + /* search the file name for directories */ + dentry = exfat_find_dir_entry(sb, ei, &cdir, &uni_name, + num_entries, TYPE_ALL); + + if ((dentry < 0) && (dentry != -EEXIST)) + return dentry; /* -error value */ + + memcpy(&info->dir, &cdir.dir, sizeof(struct exfat_chain)); + info->entry = dentry; + info->num_subdirs = 0; + + /* root directory itself */ + if (unlikely(dentry == -EEXIST)) { + int num_clu = 0; + + info->type = TYPE_DIR; + info->attr = ATTR_SUBDIR; + info->flags = ALLOC_FAT_CHAIN; + info->start_clu = sbi->root_dir; + memset(&info->crtime, 0, sizeof(info->crtime)); + memset(&info->mtime, 0, sizeof(info->mtime)); + memset(&info->atime, 0, sizeof(info->atime)); + + exfat_chain_set(&cdir, sbi->root_dir, 0, ALLOC_FAT_CHAIN); + if (exfat_count_num_clusters(sb, &cdir, &num_clu)) + return -EIO; + info->size = num_clu << sbi->cluster_size_bits; + + count = exfat_count_dir_entries(sb, &cdir); + if (count < 0) + return -EIO; + + info->num_subdirs = count; + } else { + struct exfat_dentry *ep, *ep2; + struct exfat_entry_set_cache *es; + + es = exfat_get_dentry_set(sb, &cdir, dentry, ES_2_ENTRIES); + if (!es) + return -EIO; + ep = exfat_get_dentry_cached(es, 0); + ep2 = exfat_get_dentry_cached(es, 1); + + info->type = exfat_get_entry_type(ep); + info->attr = le16_to_cpu(ep->dentry.file.attr); + info->size = le64_to_cpu(ep2->dentry.stream.valid_size); + if ((info->type == TYPE_FILE) && (info->size == 0)) { + info->flags = ALLOC_NO_FAT_CHAIN; + info->start_clu = EXFAT_EOF_CLUSTER; + } else { + info->flags = ep2->dentry.stream.flags; + info->start_clu = + le32_to_cpu(ep2->dentry.stream.start_clu); + } + + if (ei->start_clu == EXFAT_FREE_CLUSTER) { + exfat_fs_error(sb, + "non-zero size file starts with zero cluster (size : %llu, p_dir : %u, entry : 0x%08x)", + i_size_read(dir), ei->dir.dir, ei->entry); + exfat_free_dentry_set(es, false); + return -EIO; + } + + exfat_get_entry_time(sbi, &info->crtime, + ep->dentry.file.create_tz, + ep->dentry.file.create_time, + ep->dentry.file.create_date, + ep->dentry.file.create_time_cs); + exfat_get_entry_time(sbi, &info->mtime, + ep->dentry.file.modify_tz, + ep->dentry.file.modify_time, + ep->dentry.file.modify_date, + ep->dentry.file.modify_time_cs); + exfat_get_entry_time(sbi, &info->atime, + ep->dentry.file.access_tz, + ep->dentry.file.access_time, + ep->dentry.file.access_date, + 0); + exfat_free_dentry_set(es, false); + + if (info->type == TYPE_DIR) { + exfat_chain_set(&cdir, info->start_clu, + EXFAT_B_TO_CLU(info->size, sbi), info->flags); + count = exfat_count_dir_entries(sb, &cdir); + if (count < 0) + return -EIO; + + info->num_subdirs = count + EXFAT_MIN_SUBDIR; + } + } + return 0; +} + +static int exfat_d_anon_disconn(struct dentry *dentry) +{ + return IS_ROOT(dentry) && (dentry->d_flags & DCACHE_DISCONNECTED); +} + +static struct dentry *exfat_lookup(struct inode *dir, struct dentry *dentry, + unsigned int flags) +{ + struct super_block *sb = dir->i_sb; + struct inode *inode; + struct dentry *alias; + struct exfat_dir_entry info; + int err; + loff_t i_pos; + mode_t i_mode; + + mutex_lock(&EXFAT_SB(sb)->s_lock); + err = exfat_find(dir, &dentry->d_name, &info); + if (err) { + if (err == -ENOENT) { + inode = NULL; + goto out; + } + goto unlock; + } + + i_pos = exfat_make_i_pos(&info); + inode = exfat_build_inode(sb, &info, i_pos); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto unlock; + } + + i_mode = inode->i_mode; + alias = d_find_alias(inode); + + /* + * Checking "alias->d_parent == dentry->d_parent" to make sure + * FS is not corrupted (especially double linked dir). + */ + if (alias && alias->d_parent == dentry->d_parent && + !exfat_d_anon_disconn(alias)) { + + /* + * Unhashed alias is able to exist because of revalidate() + * called by lookup_fast. You can easily make this status + * by calling create and lookup concurrently + * In such case, we reuse an alias instead of new dentry + */ + if (d_unhashed(alias)) { + WARN_ON(alias->d_name.hash_len != + dentry->d_name.hash_len); + exfat_info(sb, "rehashed a dentry(%p) in read lookup", + alias); + d_drop(dentry); + d_rehash(alias); + } else if (!S_ISDIR(i_mode)) { + /* + * This inode has non anonymous-DCACHE_DISCONNECTED + * dentry. This means, the user did ->lookup() by an + * another name (longname vs 8.3 alias of it) in past. + * + * Switch to new one for reason of locality if possible. + */ + d_move(alias, dentry); + } + iput(inode); + mutex_unlock(&EXFAT_SB(sb)->s_lock); + return alias; + } + dput(alias); +out: + mutex_unlock(&EXFAT_SB(sb)->s_lock); + if (!inode) + exfat_d_version_set(dentry, inode_query_iversion(dir)); + + return d_splice_alias(inode, dentry); +unlock: + mutex_unlock(&EXFAT_SB(sb)->s_lock); + return ERR_PTR(err); +} + +/* remove an entry, BUT don't truncate */ +static int exfat_unlink(struct inode *dir, struct dentry *dentry) +{ + struct exfat_chain cdir; + struct exfat_dentry *ep; + struct super_block *sb = dir->i_sb; + struct inode *inode = dentry->d_inode; + struct exfat_inode_info *ei = EXFAT_I(inode); + struct buffer_head *bh; + sector_t sector; + int num_entries, entry, err = 0; + + mutex_lock(&EXFAT_SB(sb)->s_lock); + exfat_chain_dup(&cdir, &ei->dir); + entry = ei->entry; + if (ei->dir.dir == DIR_DELETED) { + exfat_err(sb, "abnormal access to deleted dentry"); + err = -ENOENT; + goto unlock; + } + + ep = exfat_get_dentry(sb, &cdir, entry, &bh, §or); + if (!ep) { + err = -EIO; + goto unlock; + } + num_entries = exfat_count_ext_entries(sb, &cdir, entry, ep); + if (num_entries < 0) { + err = -EIO; + brelse(bh); + goto unlock; + } + num_entries++; + brelse(bh); + + exfat_set_vol_flags(sb, VOL_DIRTY); + /* update the directory entry */ + if (exfat_remove_entries(dir, &cdir, entry, 0, num_entries)) { + err = -EIO; + goto unlock; + } + + /* This doesn't modify ei */ + ei->dir.dir = DIR_DELETED; + exfat_set_vol_flags(sb, VOL_CLEAN); + + inode_inc_iversion(dir); + dir->i_mtime = dir->i_atime = current_time(dir); + exfat_truncate_atime(&dir->i_atime); + if (IS_DIRSYNC(dir)) + exfat_sync_inode(dir); + else + mark_inode_dirty(dir); + + clear_nlink(inode); + inode->i_mtime = inode->i_atime = current_time(inode); + exfat_truncate_atime(&inode->i_atime); + exfat_unhash_inode(inode); + exfat_d_version_set(dentry, inode_query_iversion(dir)); +unlock: + mutex_unlock(&EXFAT_SB(sb)->s_lock); + return err; +} + +static int exfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +{ + struct super_block *sb = dir->i_sb; + struct inode *inode; + struct exfat_dir_entry info; + struct exfat_chain cdir; + loff_t i_pos; + int err; + + mutex_lock(&EXFAT_SB(sb)->s_lock); + exfat_set_vol_flags(sb, VOL_DIRTY); + err = exfat_add_entry(dir, dentry->d_name.name, &cdir, TYPE_DIR, + &info); + exfat_set_vol_flags(sb, VOL_CLEAN); + if (err) + goto unlock; + + inode_inc_iversion(dir); + dir->i_ctime = dir->i_mtime = current_time(dir); + if (IS_DIRSYNC(dir)) + exfat_sync_inode(dir); + else + mark_inode_dirty(dir); + inc_nlink(dir); + + i_pos = exfat_make_i_pos(&info); + inode = exfat_build_inode(sb, &info, i_pos); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto unlock; + } + + inode_inc_iversion(inode); + inode->i_mtime = inode->i_atime = inode->i_ctime = + EXFAT_I(inode)->i_crtime = current_time(inode); + exfat_truncate_atime(&inode->i_atime); + /* timestamp is already written, so mark_inode_dirty() is unneeded. */ + + d_instantiate(dentry, inode); + +unlock: + mutex_unlock(&EXFAT_SB(sb)->s_lock); + return err; +} + +static int exfat_check_dir_empty(struct super_block *sb, + struct exfat_chain *p_dir) +{ + int i, dentries_per_clu; + unsigned int type; + struct exfat_chain clu; + struct exfat_dentry *ep; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct buffer_head *bh; + + dentries_per_clu = sbi->dentries_per_clu; + + exfat_chain_dup(&clu, p_dir); + + while (clu.dir != EXFAT_EOF_CLUSTER) { + for (i = 0; i < dentries_per_clu; i++) { + ep = exfat_get_dentry(sb, &clu, i, &bh, NULL); + if (!ep) + return -EIO; + type = exfat_get_entry_type(ep); + brelse(bh); + if (type == TYPE_UNUSED) + return 0; + + if (type != TYPE_FILE && type != TYPE_DIR) + continue; + + return -ENOTEMPTY; + } + + if (clu.flags == ALLOC_NO_FAT_CHAIN) { + if (--clu.size > 0) + clu.dir++; + else + clu.dir = EXFAT_EOF_CLUSTER; + } else { + if (exfat_get_next_cluster(sb, &(clu.dir))) + return -EIO; + } + } + + return 0; +} + +static int exfat_rmdir(struct inode *dir, struct dentry *dentry) +{ + struct inode *inode = dentry->d_inode; + struct exfat_dentry *ep; + struct exfat_chain cdir, clu_to_free; + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_inode_info *ei = EXFAT_I(inode); + struct buffer_head *bh; + sector_t sector; + int num_entries, entry, err; + + mutex_lock(&EXFAT_SB(inode->i_sb)->s_lock); + + exfat_chain_dup(&cdir, &ei->dir); + entry = ei->entry; + + if (ei->dir.dir == DIR_DELETED) { + exfat_err(sb, "abnormal access to deleted dentry"); + err = -ENOENT; + goto unlock; + } + + exfat_chain_set(&clu_to_free, ei->start_clu, + EXFAT_B_TO_CLU_ROUND_UP(i_size_read(inode), sbi), ei->flags); + + err = exfat_check_dir_empty(sb, &clu_to_free); + if (err) { + if (err == -EIO) + exfat_err(sb, "failed to exfat_check_dir_empty : err(%d)", + err); + goto unlock; + } + + ep = exfat_get_dentry(sb, &cdir, entry, &bh, §or); + if (!ep) { + err = -EIO; + goto unlock; + } + + num_entries = exfat_count_ext_entries(sb, &cdir, entry, ep); + if (num_entries < 0) { + err = -EIO; + brelse(bh); + goto unlock; + } + num_entries++; + brelse(bh); + + exfat_set_vol_flags(sb, VOL_DIRTY); + err = exfat_remove_entries(dir, &cdir, entry, 0, num_entries); + if (err) { + exfat_err(sb, "failed to exfat_remove_entries : err(%d)", err); + goto unlock; + } + ei->dir.dir = DIR_DELETED; + exfat_set_vol_flags(sb, VOL_CLEAN); + + inode_inc_iversion(dir); + dir->i_mtime = dir->i_atime = current_time(dir); + exfat_truncate_atime(&dir->i_atime); + if (IS_DIRSYNC(dir)) + exfat_sync_inode(dir); + else + mark_inode_dirty(dir); + drop_nlink(dir); + + clear_nlink(inode); + inode->i_mtime = inode->i_atime = current_time(inode); + exfat_truncate_atime(&inode->i_atime); + exfat_unhash_inode(inode); + exfat_d_version_set(dentry, inode_query_iversion(dir)); +unlock: + mutex_unlock(&EXFAT_SB(inode->i_sb)->s_lock); + return err; +} + +static int exfat_rename_file(struct inode *inode, struct exfat_chain *p_dir, + int oldentry, struct exfat_uni_name *p_uniname, + struct exfat_inode_info *ei) +{ + int ret, num_old_entries, num_new_entries; + sector_t sector_old, sector_new; + struct exfat_dentry *epold, *epnew; + struct super_block *sb = inode->i_sb; + struct buffer_head *new_bh, *old_bh; + int sync = IS_DIRSYNC(inode); + + epold = exfat_get_dentry(sb, p_dir, oldentry, &old_bh, §or_old); + if (!epold) + return -EIO; + + num_old_entries = exfat_count_ext_entries(sb, p_dir, oldentry, epold); + if (num_old_entries < 0) + return -EIO; + num_old_entries++; + + num_new_entries = exfat_calc_num_entries(p_uniname); + if (num_new_entries < 0) + return num_new_entries; + + if (num_old_entries < num_new_entries) { + int newentry; + + newentry = + exfat_find_empty_entry(inode, p_dir, num_new_entries); + if (newentry < 0) + return newentry; /* -EIO or -ENOSPC */ + + epnew = exfat_get_dentry(sb, p_dir, newentry, &new_bh, + §or_new); + if (!epnew) + return -EIO; + + memcpy(epnew, epold, DENTRY_SIZE); + if (exfat_get_entry_type(epnew) == TYPE_FILE) { + epnew->dentry.file.attr |= cpu_to_le16(ATTR_ARCHIVE); + ei->attr |= ATTR_ARCHIVE; + } + exfat_update_bh(sb, new_bh, sync); + brelse(old_bh); + brelse(new_bh); + + epold = exfat_get_dentry(sb, p_dir, oldentry + 1, &old_bh, + §or_old); + if (!epold) + return -EIO; + epnew = exfat_get_dentry(sb, p_dir, newentry + 1, &new_bh, + §or_new); + if (!epnew) { + brelse(old_bh); + return -EIO; + } + + memcpy(epnew, epold, DENTRY_SIZE); + exfat_update_bh(sb, new_bh, sync); + brelse(old_bh); + brelse(new_bh); + + ret = exfat_init_ext_entry(inode, p_dir, newentry, + num_new_entries, p_uniname); + if (ret) + return ret; + + exfat_remove_entries(inode, p_dir, oldentry, 0, + num_old_entries); + ei->entry = newentry; + } else { + if (exfat_get_entry_type(epold) == TYPE_FILE) { + epold->dentry.file.attr |= cpu_to_le16(ATTR_ARCHIVE); + ei->attr |= ATTR_ARCHIVE; + } + exfat_update_bh(sb, old_bh, sync); + brelse(old_bh); + ret = exfat_init_ext_entry(inode, p_dir, oldentry, + num_new_entries, p_uniname); + if (ret) + return ret; + + exfat_remove_entries(inode, p_dir, oldentry, num_new_entries, + num_old_entries); + } + return 0; +} + +static int exfat_move_file(struct inode *inode, struct exfat_chain *p_olddir, + int oldentry, struct exfat_chain *p_newdir, + struct exfat_uni_name *p_uniname, struct exfat_inode_info *ei) +{ + int ret, newentry, num_new_entries, num_old_entries; + sector_t sector_mov, sector_new; + struct exfat_dentry *epmov, *epnew; + struct super_block *sb = inode->i_sb; + struct buffer_head *mov_bh, *new_bh; + + epmov = exfat_get_dentry(sb, p_olddir, oldentry, &mov_bh, §or_mov); + if (!epmov) + return -EIO; + + /* check if the source and target directory is the same */ + if (exfat_get_entry_type(epmov) == TYPE_DIR && + le32_to_cpu(epmov->dentry.stream.start_clu) == p_newdir->dir) + return -EINVAL; + + num_old_entries = exfat_count_ext_entries(sb, p_olddir, oldentry, + epmov); + if (num_old_entries < 0) + return -EIO; + num_old_entries++; + + num_new_entries = exfat_calc_num_entries(p_uniname); + if (num_new_entries < 0) + return num_new_entries; + + newentry = exfat_find_empty_entry(inode, p_newdir, num_new_entries); + if (newentry < 0) + return newentry; /* -EIO or -ENOSPC */ + + epnew = exfat_get_dentry(sb, p_newdir, newentry, &new_bh, §or_new); + if (!epnew) + return -EIO; + + memcpy(epnew, epmov, DENTRY_SIZE); + if (exfat_get_entry_type(epnew) == TYPE_FILE) { + epnew->dentry.file.attr |= cpu_to_le16(ATTR_ARCHIVE); + ei->attr |= ATTR_ARCHIVE; + } + exfat_update_bh(sb, new_bh, IS_DIRSYNC(inode)); + brelse(mov_bh); + brelse(new_bh); + + epmov = exfat_get_dentry(sb, p_olddir, oldentry + 1, &mov_bh, + §or_mov); + if (!epmov) + return -EIO; + epnew = exfat_get_dentry(sb, p_newdir, newentry + 1, &new_bh, + §or_new); + if (!epnew) { + brelse(mov_bh); + return -EIO; + } + + memcpy(epnew, epmov, DENTRY_SIZE); + exfat_update_bh(sb, new_bh, IS_DIRSYNC(inode)); + brelse(mov_bh); + brelse(new_bh); + + ret = exfat_init_ext_entry(inode, p_newdir, newentry, num_new_entries, + p_uniname); + if (ret) + return ret; + + exfat_remove_entries(inode, p_olddir, oldentry, 0, num_old_entries); + + exfat_chain_set(&ei->dir, p_newdir->dir, p_newdir->size, + p_newdir->flags); + + ei->entry = newentry; + return 0; +} + +static void exfat_update_parent_info(struct exfat_inode_info *ei, + struct inode *parent_inode) +{ + struct exfat_sb_info *sbi = EXFAT_SB(parent_inode->i_sb); + struct exfat_inode_info *parent_ei = EXFAT_I(parent_inode); + loff_t parent_isize = i_size_read(parent_inode); + + /* + * the problem that struct exfat_inode_info caches wrong parent info. + * + * because of flag-mismatch of ei->dir, + * there is abnormal traversing cluster chain. + */ + if (unlikely(parent_ei->flags != ei->dir.flags || + parent_isize != EXFAT_CLU_TO_B(ei->dir.size, sbi) || + parent_ei->start_clu != ei->dir.dir)) { + exfat_chain_set(&ei->dir, parent_ei->start_clu, + EXFAT_B_TO_CLU_ROUND_UP(parent_isize, sbi), + parent_ei->flags); + } +} + +/* rename or move a old file into a new file */ +static int __exfat_rename(struct inode *old_parent_inode, + struct exfat_inode_info *ei, struct inode *new_parent_inode, + struct dentry *new_dentry) +{ + int ret; + int dentry; + struct exfat_chain olddir, newdir; + struct exfat_chain *p_dir = NULL; + struct exfat_uni_name uni_name; + struct exfat_dentry *ep; + struct super_block *sb = old_parent_inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + const unsigned char *new_path = new_dentry->d_name.name; + struct inode *new_inode = new_dentry->d_inode; + int num_entries; + struct exfat_inode_info *new_ei = NULL; + unsigned int new_entry_type = TYPE_UNUSED; + int new_entry = 0; + struct buffer_head *old_bh, *new_bh = NULL; + + /* check the validity of pointer parameters */ + if (new_path == NULL || strlen(new_path) == 0) + return -EINVAL; + + if (ei->dir.dir == DIR_DELETED) { + exfat_err(sb, "abnormal access to deleted source dentry"); + return -ENOENT; + } + + exfat_update_parent_info(ei, old_parent_inode); + + exfat_chain_dup(&olddir, &ei->dir); + dentry = ei->entry; + + ep = exfat_get_dentry(sb, &olddir, dentry, &old_bh, NULL); + if (!ep) { + ret = -EIO; + goto out; + } + brelse(old_bh); + + /* check whether new dir is existing directory and empty */ + if (new_inode) { + ret = -EIO; + new_ei = EXFAT_I(new_inode); + + if (new_ei->dir.dir == DIR_DELETED) { + exfat_err(sb, "abnormal access to deleted target dentry"); + goto out; + } + + exfat_update_parent_info(new_ei, new_parent_inode); + + p_dir = &(new_ei->dir); + new_entry = new_ei->entry; + ep = exfat_get_dentry(sb, p_dir, new_entry, &new_bh, NULL); + if (!ep) + goto out; + + new_entry_type = exfat_get_entry_type(ep); + brelse(new_bh); + + /* if new_inode exists, update ei */ + if (new_entry_type == TYPE_DIR) { + struct exfat_chain new_clu; + + new_clu.dir = new_ei->start_clu; + new_clu.size = + EXFAT_B_TO_CLU_ROUND_UP(i_size_read(new_inode), + sbi); + new_clu.flags = new_ei->flags; + + ret = exfat_check_dir_empty(sb, &new_clu); + if (ret) + goto out; + } + } + + /* check the validity of directory name in the given new pathname */ + ret = exfat_resolve_path(new_parent_inode, new_path, &newdir, + &uni_name); + if (ret) + goto out; + + exfat_set_vol_flags(sb, VOL_DIRTY); + + if (olddir.dir == newdir.dir) + ret = exfat_rename_file(new_parent_inode, &olddir, dentry, + &uni_name, ei); + else + ret = exfat_move_file(new_parent_inode, &olddir, dentry, + &newdir, &uni_name, ei); + + if (!ret && new_inode) { + /* delete entries of new_dir */ + ep = exfat_get_dentry(sb, p_dir, new_entry, &new_bh, NULL); + if (!ep) { + ret = -EIO; + goto del_out; + } + + num_entries = exfat_count_ext_entries(sb, p_dir, new_entry, ep); + if (num_entries < 0) { + ret = -EIO; + goto del_out; + } + brelse(new_bh); + + if (exfat_remove_entries(new_inode, p_dir, new_entry, 0, + num_entries + 1)) { + ret = -EIO; + goto del_out; + } + + /* Free the clusters if new_inode is a dir(as if exfat_rmdir) */ + if (new_entry_type == TYPE_DIR) { + /* new_ei, new_clu_to_free */ + struct exfat_chain new_clu_to_free; + + exfat_chain_set(&new_clu_to_free, new_ei->start_clu, + EXFAT_B_TO_CLU_ROUND_UP(i_size_read(new_inode), + sbi), new_ei->flags); + + if (exfat_free_cluster(new_inode, &new_clu_to_free)) { + /* just set I/O error only */ + ret = -EIO; + } + + i_size_write(new_inode, 0); + new_ei->start_clu = EXFAT_EOF_CLUSTER; + new_ei->flags = ALLOC_NO_FAT_CHAIN; + } +del_out: + /* Update new_inode ei + * Prevent syncing removed new_inode + * (new_ei is already initialized above code ("if (new_inode)") + */ + new_ei->dir.dir = DIR_DELETED; + } + exfat_set_vol_flags(sb, VOL_CLEAN); +out: + return ret; +} + +static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + unsigned int flags) +{ + struct inode *old_inode, *new_inode; + struct super_block *sb = old_dir->i_sb; + loff_t i_pos; + int err; + + /* + * The VFS already checks for existence, so for local filesystems + * the RENAME_NOREPLACE implementation is equivalent to plain rename. + * Don't support any other flags + */ + if (flags & ~RENAME_NOREPLACE) + return -EINVAL; + + mutex_lock(&EXFAT_SB(sb)->s_lock); + old_inode = old_dentry->d_inode; + new_inode = new_dentry->d_inode; + + err = __exfat_rename(old_dir, EXFAT_I(old_inode), new_dir, new_dentry); + if (err) + goto unlock; + + inode_inc_iversion(new_dir); + new_dir->i_ctime = new_dir->i_mtime = new_dir->i_atime = + EXFAT_I(new_dir)->i_crtime = current_time(new_dir); + exfat_truncate_atime(&new_dir->i_atime); + if (IS_DIRSYNC(new_dir)) + exfat_sync_inode(new_dir); + else + mark_inode_dirty(new_dir); + + i_pos = ((loff_t)EXFAT_I(old_inode)->dir.dir << 32) | + (EXFAT_I(old_inode)->entry & 0xffffffff); + exfat_unhash_inode(old_inode); + exfat_hash_inode(old_inode, i_pos); + if (IS_DIRSYNC(new_dir)) + exfat_sync_inode(old_inode); + else + mark_inode_dirty(old_inode); + + if (S_ISDIR(old_inode->i_mode) && old_dir != new_dir) { + drop_nlink(old_dir); + if (!new_inode) + inc_nlink(new_dir); + } + + inode_inc_iversion(old_dir); + old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir); + if (IS_DIRSYNC(old_dir)) + exfat_sync_inode(old_dir); + else + mark_inode_dirty(old_dir); + + if (new_inode) { + exfat_unhash_inode(new_inode); + + /* skip drop_nlink if new_inode already has been dropped */ + if (new_inode->i_nlink) { + drop_nlink(new_inode); + if (S_ISDIR(new_inode->i_mode)) + drop_nlink(new_inode); + } else { + exfat_warn(sb, "abnormal access to an inode dropped"); + WARN_ON(new_inode->i_nlink == 0); + } + new_inode->i_ctime = EXFAT_I(new_inode)->i_crtime = + current_time(new_inode); + } + +unlock: + mutex_unlock(&EXFAT_SB(sb)->s_lock); + return err; +} + +const struct inode_operations exfat_dir_inode_operations = { + .create = exfat_create, + .lookup = exfat_lookup, + .unlink = exfat_unlink, + .mkdir = exfat_mkdir, + .rmdir = exfat_rmdir, + .rename = exfat_rename, + .setattr = exfat_setattr, + .getattr = exfat_getattr, +#ifdef CONFIG_EXFAT_VIRTUAL_XATTR + .listxattr = exfat_listxattr, +#endif +}; diff --git a/fs/exfat/nls.c b/fs/exfat/nls.c new file mode 100644 index 000000000000..d48060a29702 --- /dev/null +++ b/fs/exfat/nls.c @@ -0,0 +1,806 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#include +#include +#include +#include + +#include "exfat_fs.h" + +/* Upcase tabel macro */ +#define EXFAT_NUM_UPCASE (2918) +#define UTBL_COUNT (0x10000) + +/* + * Upcase table in compressed format (7.2.5.1 Recommended Up-case Table + * in exfat specification, See: + * https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification). + */ +static const unsigned short uni_def_upcase[EXFAT_NUM_UPCASE] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00f7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x0178, + 0x0100, 0x0100, 0x0102, 0x0102, 0x0104, 0x0104, 0x0106, 0x0106, + 0x0108, 0x0108, 0x010a, 0x010a, 0x010c, 0x010c, 0x010e, 0x010e, + 0x0110, 0x0110, 0x0112, 0x0112, 0x0114, 0x0114, 0x0116, 0x0116, + 0x0118, 0x0118, 0x011a, 0x011a, 0x011c, 0x011c, 0x011e, 0x011e, + 0x0120, 0x0120, 0x0122, 0x0122, 0x0124, 0x0124, 0x0126, 0x0126, + 0x0128, 0x0128, 0x012a, 0x012a, 0x012c, 0x012c, 0x012e, 0x012e, + 0x0130, 0x0131, 0x0132, 0x0132, 0x0134, 0x0134, 0x0136, 0x0136, + 0x0138, 0x0139, 0x0139, 0x013b, 0x013b, 0x013d, 0x013d, 0x013f, + 0x013f, 0x0141, 0x0141, 0x0143, 0x0143, 0x0145, 0x0145, 0x0147, + 0x0147, 0x0149, 0x014a, 0x014a, 0x014c, 0x014c, 0x014e, 0x014e, + 0x0150, 0x0150, 0x0152, 0x0152, 0x0154, 0x0154, 0x0156, 0x0156, + 0x0158, 0x0158, 0x015a, 0x015a, 0x015c, 0x015c, 0x015e, 0x015e, + 0x0160, 0x0160, 0x0162, 0x0162, 0x0164, 0x0164, 0x0166, 0x0166, + 0x0168, 0x0168, 0x016a, 0x016a, 0x016c, 0x016c, 0x016e, 0x016e, + 0x0170, 0x0170, 0x0172, 0x0172, 0x0174, 0x0174, 0x0176, 0x0176, + 0x0178, 0x0179, 0x0179, 0x017b, 0x017b, 0x017d, 0x017d, 0x017f, + 0x0243, 0x0181, 0x0182, 0x0182, 0x0184, 0x0184, 0x0186, 0x0187, + 0x0187, 0x0189, 0x018a, 0x018b, 0x018b, 0x018d, 0x018e, 0x018f, + 0x0190, 0x0191, 0x0191, 0x0193, 0x0194, 0x01f6, 0x0196, 0x0197, + 0x0198, 0x0198, 0x023d, 0x019b, 0x019c, 0x019d, 0x0220, 0x019f, + 0x01a0, 0x01a0, 0x01a2, 0x01a2, 0x01a4, 0x01a4, 0x01a6, 0x01a7, + 0x01a7, 0x01a9, 0x01aa, 0x01ab, 0x01ac, 0x01ac, 0x01ae, 0x01af, + 0x01af, 0x01b1, 0x01b2, 0x01b3, 0x01b3, 0x01b5, 0x01b5, 0x01b7, + 0x01b8, 0x01b8, 0x01ba, 0x01bb, 0x01bc, 0x01bc, 0x01be, 0x01f7, + 0x01c0, 0x01c1, 0x01c2, 0x01c3, 0x01c4, 0x01c5, 0x01c4, 0x01c7, + 0x01c8, 0x01c7, 0x01ca, 0x01cb, 0x01ca, 0x01cd, 0x01cd, 0x01cf, + 0x01cf, 0x01d1, 0x01d1, 0x01d3, 0x01d3, 0x01d5, 0x01d5, 0x01d7, + 0x01d7, 0x01d9, 0x01d9, 0x01db, 0x01db, 0x018e, 0x01de, 0x01de, + 0x01e0, 0x01e0, 0x01e2, 0x01e2, 0x01e4, 0x01e4, 0x01e6, 0x01e6, + 0x01e8, 0x01e8, 0x01ea, 0x01ea, 0x01ec, 0x01ec, 0x01ee, 0x01ee, + 0x01f0, 0x01f1, 0x01f2, 0x01f1, 0x01f4, 0x01f4, 0x01f6, 0x01f7, + 0x01f8, 0x01f8, 0x01fa, 0x01fa, 0x01fc, 0x01fc, 0x01fe, 0x01fe, + 0x0200, 0x0200, 0x0202, 0x0202, 0x0204, 0x0204, 0x0206, 0x0206, + 0x0208, 0x0208, 0x020a, 0x020a, 0x020c, 0x020c, 0x020e, 0x020e, + 0x0210, 0x0210, 0x0212, 0x0212, 0x0214, 0x0214, 0x0216, 0x0216, + 0x0218, 0x0218, 0x021a, 0x021a, 0x021c, 0x021c, 0x021e, 0x021e, + 0x0220, 0x0221, 0x0222, 0x0222, 0x0224, 0x0224, 0x0226, 0x0226, + 0x0228, 0x0228, 0x022a, 0x022a, 0x022c, 0x022c, 0x022e, 0x022e, + 0x0230, 0x0230, 0x0232, 0x0232, 0x0234, 0x0235, 0x0236, 0x0237, + 0x0238, 0x0239, 0x2c65, 0x023b, 0x023b, 0x023d, 0x2c66, 0x023f, + 0x0240, 0x0241, 0x0241, 0x0243, 0x0244, 0x0245, 0x0246, 0x0246, + 0x0248, 0x0248, 0x024a, 0x024a, 0x024c, 0x024c, 0x024e, 0x024e, + 0x0250, 0x0251, 0x0252, 0x0181, 0x0186, 0x0255, 0x0189, 0x018a, + 0x0258, 0x018f, 0x025a, 0x0190, 0x025c, 0x025d, 0x025e, 0x025f, + 0x0193, 0x0261, 0x0262, 0x0194, 0x0264, 0x0265, 0x0266, 0x0267, + 0x0197, 0x0196, 0x026a, 0x2c62, 0x026c, 0x026d, 0x026e, 0x019c, + 0x0270, 0x0271, 0x019d, 0x0273, 0x0274, 0x019f, 0x0276, 0x0277, + 0x0278, 0x0279, 0x027a, 0x027b, 0x027c, 0x2c64, 0x027e, 0x027f, + 0x01a6, 0x0281, 0x0282, 0x01a9, 0x0284, 0x0285, 0x0286, 0x0287, + 0x01ae, 0x0244, 0x01b1, 0x01b2, 0x0245, 0x028d, 0x028e, 0x028f, + 0x0290, 0x0291, 0x01b7, 0x0293, 0x0294, 0x0295, 0x0296, 0x0297, + 0x0298, 0x0299, 0x029a, 0x029b, 0x029c, 0x029d, 0x029e, 0x029f, + 0x02a0, 0x02a1, 0x02a2, 0x02a3, 0x02a4, 0x02a5, 0x02a6, 0x02a7, + 0x02a8, 0x02a9, 0x02aa, 0x02ab, 0x02ac, 0x02ad, 0x02ae, 0x02af, + 0x02b0, 0x02b1, 0x02b2, 0x02b3, 0x02b4, 0x02b5, 0x02b6, 0x02b7, + 0x02b8, 0x02b9, 0x02ba, 0x02bb, 0x02bc, 0x02bd, 0x02be, 0x02bf, + 0x02c0, 0x02c1, 0x02c2, 0x02c3, 0x02c4, 0x02c5, 0x02c6, 0x02c7, + 0x02c8, 0x02c9, 0x02ca, 0x02cb, 0x02cc, 0x02cd, 0x02ce, 0x02cf, + 0x02d0, 0x02d1, 0x02d2, 0x02d3, 0x02d4, 0x02d5, 0x02d6, 0x02d7, + 0x02d8, 0x02d9, 0x02da, 0x02db, 0x02dc, 0x02dd, 0x02de, 0x02df, + 0x02e0, 0x02e1, 0x02e2, 0x02e3, 0x02e4, 0x02e5, 0x02e6, 0x02e7, + 0x02e8, 0x02e9, 0x02ea, 0x02eb, 0x02ec, 0x02ed, 0x02ee, 0x02ef, + 0x02f0, 0x02f1, 0x02f2, 0x02f3, 0x02f4, 0x02f5, 0x02f6, 0x02f7, + 0x02f8, 0x02f9, 0x02fa, 0x02fb, 0x02fc, 0x02fd, 0x02fe, 0x02ff, + 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, + 0x0308, 0x0309, 0x030a, 0x030b, 0x030c, 0x030d, 0x030e, 0x030f, + 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317, + 0x0318, 0x0319, 0x031a, 0x031b, 0x031c, 0x031d, 0x031e, 0x031f, + 0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326, 0x0327, + 0x0328, 0x0329, 0x032a, 0x032b, 0x032c, 0x032d, 0x032e, 0x032f, + 0x0330, 0x0331, 0x0332, 0x0333, 0x0334, 0x0335, 0x0336, 0x0337, + 0x0338, 0x0339, 0x033a, 0x033b, 0x033c, 0x033d, 0x033e, 0x033f, + 0x0340, 0x0341, 0x0342, 0x0343, 0x0344, 0x0345, 0x0346, 0x0347, + 0x0348, 0x0349, 0x034a, 0x034b, 0x034c, 0x034d, 0x034e, 0x034f, + 0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356, 0x0357, + 0x0358, 0x0359, 0x035a, 0x035b, 0x035c, 0x035d, 0x035e, 0x035f, + 0x0360, 0x0361, 0x0362, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367, + 0x0368, 0x0369, 0x036a, 0x036b, 0x036c, 0x036d, 0x036e, 0x036f, + 0x0370, 0x0371, 0x0372, 0x0373, 0x0374, 0x0375, 0x0376, 0x0377, + 0x0378, 0x0379, 0x037a, 0x03fd, 0x03fe, 0x03ff, 0x037e, 0x037f, + 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0386, 0x0387, + 0x0388, 0x0389, 0x038a, 0x038b, 0x038c, 0x038d, 0x038e, 0x038f, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, + 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, + 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x0386, 0x0388, 0x0389, 0x038a, + 0x03b0, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, + 0x03a0, 0x03a1, 0x03a3, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, + 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x038c, 0x038e, 0x038f, 0x03cf, + 0x03d0, 0x03d1, 0x03d2, 0x03d3, 0x03d4, 0x03d5, 0x03d6, 0x03d7, + 0x03d8, 0x03d8, 0x03da, 0x03da, 0x03dc, 0x03dc, 0x03de, 0x03de, + 0x03e0, 0x03e0, 0x03e2, 0x03e2, 0x03e4, 0x03e4, 0x03e6, 0x03e6, + 0x03e8, 0x03e8, 0x03ea, 0x03ea, 0x03ec, 0x03ec, 0x03ee, 0x03ee, + 0x03f0, 0x03f1, 0x03f9, 0x03f3, 0x03f4, 0x03f5, 0x03f6, 0x03f7, + 0x03f7, 0x03f9, 0x03fa, 0x03fa, 0x03fc, 0x03fd, 0x03fe, 0x03ff, + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, + 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x040d, 0x040e, 0x040f, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, + 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x040d, 0x040e, 0x040f, + 0x0460, 0x0460, 0x0462, 0x0462, 0x0464, 0x0464, 0x0466, 0x0466, + 0x0468, 0x0468, 0x046a, 0x046a, 0x046c, 0x046c, 0x046e, 0x046e, + 0x0470, 0x0470, 0x0472, 0x0472, 0x0474, 0x0474, 0x0476, 0x0476, + 0x0478, 0x0478, 0x047a, 0x047a, 0x047c, 0x047c, 0x047e, 0x047e, + 0x0480, 0x0480, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, + 0x0488, 0x0489, 0x048a, 0x048a, 0x048c, 0x048c, 0x048e, 0x048e, + 0x0490, 0x0490, 0x0492, 0x0492, 0x0494, 0x0494, 0x0496, 0x0496, + 0x0498, 0x0498, 0x049a, 0x049a, 0x049c, 0x049c, 0x049e, 0x049e, + 0x04a0, 0x04a0, 0x04a2, 0x04a2, 0x04a4, 0x04a4, 0x04a6, 0x04a6, + 0x04a8, 0x04a8, 0x04aa, 0x04aa, 0x04ac, 0x04ac, 0x04ae, 0x04ae, + 0x04b0, 0x04b0, 0x04b2, 0x04b2, 0x04b4, 0x04b4, 0x04b6, 0x04b6, + 0x04b8, 0x04b8, 0x04ba, 0x04ba, 0x04bc, 0x04bc, 0x04be, 0x04be, + 0x04c0, 0x04c1, 0x04c1, 0x04c3, 0x04c3, 0x04c5, 0x04c5, 0x04c7, + 0x04c7, 0x04c9, 0x04c9, 0x04cb, 0x04cb, 0x04cd, 0x04cd, 0x04c0, + 0x04d0, 0x04d0, 0x04d2, 0x04d2, 0x04d4, 0x04d4, 0x04d6, 0x04d6, + 0x04d8, 0x04d8, 0x04da, 0x04da, 0x04dc, 0x04dc, 0x04de, 0x04de, + 0x04e0, 0x04e0, 0x04e2, 0x04e2, 0x04e4, 0x04e4, 0x04e6, 0x04e6, + 0x04e8, 0x04e8, 0x04ea, 0x04ea, 0x04ec, 0x04ec, 0x04ee, 0x04ee, + 0x04f0, 0x04f0, 0x04f2, 0x04f2, 0x04f4, 0x04f4, 0x04f6, 0x04f6, + 0x04f8, 0x04f8, 0x04fa, 0x04fa, 0x04fc, 0x04fc, 0x04fe, 0x04fe, + 0x0500, 0x0500, 0x0502, 0x0502, 0x0504, 0x0504, 0x0506, 0x0506, + 0x0508, 0x0508, 0x050a, 0x050a, 0x050c, 0x050c, 0x050e, 0x050e, + 0x0510, 0x0510, 0x0512, 0x0512, 0x0514, 0x0515, 0x0516, 0x0517, + 0x0518, 0x0519, 0x051a, 0x051b, 0x051c, 0x051d, 0x051e, 0x051f, + 0x0520, 0x0521, 0x0522, 0x0523, 0x0524, 0x0525, 0x0526, 0x0527, + 0x0528, 0x0529, 0x052a, 0x052b, 0x052c, 0x052d, 0x052e, 0x052f, + 0x0530, 0x0531, 0x0532, 0x0533, 0x0534, 0x0535, 0x0536, 0x0537, + 0x0538, 0x0539, 0x053a, 0x053b, 0x053c, 0x053d, 0x053e, 0x053f, + 0x0540, 0x0541, 0x0542, 0x0543, 0x0544, 0x0545, 0x0546, 0x0547, + 0x0548, 0x0549, 0x054a, 0x054b, 0x054c, 0x054d, 0x054e, 0x054f, + 0x0550, 0x0551, 0x0552, 0x0553, 0x0554, 0x0555, 0x0556, 0x0557, + 0x0558, 0x0559, 0x055a, 0x055b, 0x055c, 0x055d, 0x055e, 0x055f, + 0x0560, 0x0531, 0x0532, 0x0533, 0x0534, 0x0535, 0x0536, 0x0537, + 0x0538, 0x0539, 0x053a, 0x053b, 0x053c, 0x053d, 0x053e, 0x053f, + 0x0540, 0x0541, 0x0542, 0x0543, 0x0544, 0x0545, 0x0546, 0x0547, + 0x0548, 0x0549, 0x054a, 0x054b, 0x054c, 0x054d, 0x054e, 0x054f, + 0x0550, 0x0551, 0x0552, 0x0553, 0x0554, 0x0555, 0x0556, 0xffff, + 0x17f6, 0x2c63, 0x1d7e, 0x1d7f, 0x1d80, 0x1d81, 0x1d82, 0x1d83, + 0x1d84, 0x1d85, 0x1d86, 0x1d87, 0x1d88, 0x1d89, 0x1d8a, 0x1d8b, + 0x1d8c, 0x1d8d, 0x1d8e, 0x1d8f, 0x1d90, 0x1d91, 0x1d92, 0x1d93, + 0x1d94, 0x1d95, 0x1d96, 0x1d97, 0x1d98, 0x1d99, 0x1d9a, 0x1d9b, + 0x1d9c, 0x1d9d, 0x1d9e, 0x1d9f, 0x1da0, 0x1da1, 0x1da2, 0x1da3, + 0x1da4, 0x1da5, 0x1da6, 0x1da7, 0x1da8, 0x1da9, 0x1daa, 0x1dab, + 0x1dac, 0x1dad, 0x1dae, 0x1daf, 0x1db0, 0x1db1, 0x1db2, 0x1db3, + 0x1db4, 0x1db5, 0x1db6, 0x1db7, 0x1db8, 0x1db9, 0x1dba, 0x1dbb, + 0x1dbc, 0x1dbd, 0x1dbe, 0x1dbf, 0x1dc0, 0x1dc1, 0x1dc2, 0x1dc3, + 0x1dc4, 0x1dc5, 0x1dc6, 0x1dc7, 0x1dc8, 0x1dc9, 0x1dca, 0x1dcb, + 0x1dcc, 0x1dcd, 0x1dce, 0x1dcf, 0x1dd0, 0x1dd1, 0x1dd2, 0x1dd3, + 0x1dd4, 0x1dd5, 0x1dd6, 0x1dd7, 0x1dd8, 0x1dd9, 0x1dda, 0x1ddb, + 0x1ddc, 0x1ddd, 0x1dde, 0x1ddf, 0x1de0, 0x1de1, 0x1de2, 0x1de3, + 0x1de4, 0x1de5, 0x1de6, 0x1de7, 0x1de8, 0x1de9, 0x1dea, 0x1deb, + 0x1dec, 0x1ded, 0x1dee, 0x1def, 0x1df0, 0x1df1, 0x1df2, 0x1df3, + 0x1df4, 0x1df5, 0x1df6, 0x1df7, 0x1df8, 0x1df9, 0x1dfa, 0x1dfb, + 0x1dfc, 0x1dfd, 0x1dfe, 0x1dff, 0x1e00, 0x1e00, 0x1e02, 0x1e02, + 0x1e04, 0x1e04, 0x1e06, 0x1e06, 0x1e08, 0x1e08, 0x1e0a, 0x1e0a, + 0x1e0c, 0x1e0c, 0x1e0e, 0x1e0e, 0x1e10, 0x1e10, 0x1e12, 0x1e12, + 0x1e14, 0x1e14, 0x1e16, 0x1e16, 0x1e18, 0x1e18, 0x1e1a, 0x1e1a, + 0x1e1c, 0x1e1c, 0x1e1e, 0x1e1e, 0x1e20, 0x1e20, 0x1e22, 0x1e22, + 0x1e24, 0x1e24, 0x1e26, 0x1e26, 0x1e28, 0x1e28, 0x1e2a, 0x1e2a, + 0x1e2c, 0x1e2c, 0x1e2e, 0x1e2e, 0x1e30, 0x1e30, 0x1e32, 0x1e32, + 0x1e34, 0x1e34, 0x1e36, 0x1e36, 0x1e38, 0x1e38, 0x1e3a, 0x1e3a, + 0x1e3c, 0x1e3c, 0x1e3e, 0x1e3e, 0x1e40, 0x1e40, 0x1e42, 0x1e42, + 0x1e44, 0x1e44, 0x1e46, 0x1e46, 0x1e48, 0x1e48, 0x1e4a, 0x1e4a, + 0x1e4c, 0x1e4c, 0x1e4e, 0x1e4e, 0x1e50, 0x1e50, 0x1e52, 0x1e52, + 0x1e54, 0x1e54, 0x1e56, 0x1e56, 0x1e58, 0x1e58, 0x1e5a, 0x1e5a, + 0x1e5c, 0x1e5c, 0x1e5e, 0x1e5e, 0x1e60, 0x1e60, 0x1e62, 0x1e62, + 0x1e64, 0x1e64, 0x1e66, 0x1e66, 0x1e68, 0x1e68, 0x1e6a, 0x1e6a, + 0x1e6c, 0x1e6c, 0x1e6e, 0x1e6e, 0x1e70, 0x1e70, 0x1e72, 0x1e72, + 0x1e74, 0x1e74, 0x1e76, 0x1e76, 0x1e78, 0x1e78, 0x1e7a, 0x1e7a, + 0x1e7c, 0x1e7c, 0x1e7e, 0x1e7e, 0x1e80, 0x1e80, 0x1e82, 0x1e82, + 0x1e84, 0x1e84, 0x1e86, 0x1e86, 0x1e88, 0x1e88, 0x1e8a, 0x1e8a, + 0x1e8c, 0x1e8c, 0x1e8e, 0x1e8e, 0x1e90, 0x1e90, 0x1e92, 0x1e92, + 0x1e94, 0x1e94, 0x1e96, 0x1e97, 0x1e98, 0x1e99, 0x1e9a, 0x1e9b, + 0x1e9c, 0x1e9d, 0x1e9e, 0x1e9f, 0x1ea0, 0x1ea0, 0x1ea2, 0x1ea2, + 0x1ea4, 0x1ea4, 0x1ea6, 0x1ea6, 0x1ea8, 0x1ea8, 0x1eaa, 0x1eaa, + 0x1eac, 0x1eac, 0x1eae, 0x1eae, 0x1eb0, 0x1eb0, 0x1eb2, 0x1eb2, + 0x1eb4, 0x1eb4, 0x1eb6, 0x1eb6, 0x1eb8, 0x1eb8, 0x1eba, 0x1eba, + 0x1ebc, 0x1ebc, 0x1ebe, 0x1ebe, 0x1ec0, 0x1ec0, 0x1ec2, 0x1ec2, + 0x1ec4, 0x1ec4, 0x1ec6, 0x1ec6, 0x1ec8, 0x1ec8, 0x1eca, 0x1eca, + 0x1ecc, 0x1ecc, 0x1ece, 0x1ece, 0x1ed0, 0x1ed0, 0x1ed2, 0x1ed2, + 0x1ed4, 0x1ed4, 0x1ed6, 0x1ed6, 0x1ed8, 0x1ed8, 0x1eda, 0x1eda, + 0x1edc, 0x1edc, 0x1ede, 0x1ede, 0x1ee0, 0x1ee0, 0x1ee2, 0x1ee2, + 0x1ee4, 0x1ee4, 0x1ee6, 0x1ee6, 0x1ee8, 0x1ee8, 0x1eea, 0x1eea, + 0x1eec, 0x1eec, 0x1eee, 0x1eee, 0x1ef0, 0x1ef0, 0x1ef2, 0x1ef2, + 0x1ef4, 0x1ef4, 0x1ef6, 0x1ef6, 0x1ef8, 0x1ef8, 0x1efa, 0x1efb, + 0x1efc, 0x1efd, 0x1efe, 0x1eff, 0x1f08, 0x1f09, 0x1f0a, 0x1f0b, + 0x1f0c, 0x1f0d, 0x1f0e, 0x1f0f, 0x1f08, 0x1f09, 0x1f0a, 0x1f0b, + 0x1f0c, 0x1f0d, 0x1f0e, 0x1f0f, 0x1f18, 0x1f19, 0x1f1a, 0x1f1b, + 0x1f1c, 0x1f1d, 0x1f16, 0x1f17, 0x1f18, 0x1f19, 0x1f1a, 0x1f1b, + 0x1f1c, 0x1f1d, 0x1f1e, 0x1f1f, 0x1f28, 0x1f29, 0x1f2a, 0x1f2b, + 0x1f2c, 0x1f2d, 0x1f2e, 0x1f2f, 0x1f28, 0x1f29, 0x1f2a, 0x1f2b, + 0x1f2c, 0x1f2d, 0x1f2e, 0x1f2f, 0x1f38, 0x1f39, 0x1f3a, 0x1f3b, + 0x1f3c, 0x1f3d, 0x1f3e, 0x1f3f, 0x1f38, 0x1f39, 0x1f3a, 0x1f3b, + 0x1f3c, 0x1f3d, 0x1f3e, 0x1f3f, 0x1f48, 0x1f49, 0x1f4a, 0x1f4b, + 0x1f4c, 0x1f4d, 0x1f46, 0x1f47, 0x1f48, 0x1f49, 0x1f4a, 0x1f4b, + 0x1f4c, 0x1f4d, 0x1f4e, 0x1f4f, 0x1f50, 0x1f59, 0x1f52, 0x1f5b, + 0x1f54, 0x1f5d, 0x1f56, 0x1f5f, 0x1f58, 0x1f59, 0x1f5a, 0x1f5b, + 0x1f5c, 0x1f5d, 0x1f5e, 0x1f5f, 0x1f68, 0x1f69, 0x1f6a, 0x1f6b, + 0x1f6c, 0x1f6d, 0x1f6e, 0x1f6f, 0x1f68, 0x1f69, 0x1f6a, 0x1f6b, + 0x1f6c, 0x1f6d, 0x1f6e, 0x1f6f, 0x1fba, 0x1fbb, 0x1fc8, 0x1fc9, + 0x1fca, 0x1fcb, 0x1fda, 0x1fdb, 0x1ff8, 0x1ff9, 0x1fea, 0x1feb, + 0x1ffa, 0x1ffb, 0x1f7e, 0x1f7f, 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, + 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f, 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, + 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f, 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, + 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, + 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, 0x1fa8, 0x1fa9, 0x1faa, 0x1fab, + 0x1fac, 0x1fad, 0x1fae, 0x1faf, 0x1fa8, 0x1fa9, 0x1faa, 0x1fab, + 0x1fac, 0x1fad, 0x1fae, 0x1faf, 0x1fb8, 0x1fb9, 0x1fb2, 0x1fbc, + 0x1fb4, 0x1fb5, 0x1fb6, 0x1fb7, 0x1fb8, 0x1fb9, 0x1fba, 0x1fbb, + 0x1fbc, 0x1fbd, 0x1fbe, 0x1fbf, 0x1fc0, 0x1fc1, 0x1fc2, 0x1fc3, + 0x1fc4, 0x1fc5, 0x1fc6, 0x1fc7, 0x1fc8, 0x1fc9, 0x1fca, 0x1fcb, + 0x1fc3, 0x1fcd, 0x1fce, 0x1fcf, 0x1fd8, 0x1fd9, 0x1fd2, 0x1fd3, + 0x1fd4, 0x1fd5, 0x1fd6, 0x1fd7, 0x1fd8, 0x1fd9, 0x1fda, 0x1fdb, + 0x1fdc, 0x1fdd, 0x1fde, 0x1fdf, 0x1fe8, 0x1fe9, 0x1fe2, 0x1fe3, + 0x1fe4, 0x1fec, 0x1fe6, 0x1fe7, 0x1fe8, 0x1fe9, 0x1fea, 0x1feb, + 0x1fec, 0x1fed, 0x1fee, 0x1fef, 0x1ff0, 0x1ff1, 0x1ff2, 0x1ff3, + 0x1ff4, 0x1ff5, 0x1ff6, 0x1ff7, 0x1ff8, 0x1ff9, 0x1ffa, 0x1ffb, + 0x1ff3, 0x1ffd, 0x1ffe, 0x1fff, 0x2000, 0x2001, 0x2002, 0x2003, + 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200a, 0x200b, + 0x200c, 0x200d, 0x200e, 0x200f, 0x2010, 0x2011, 0x2012, 0x2013, + 0x2014, 0x2015, 0x2016, 0x2017, 0x2018, 0x2019, 0x201a, 0x201b, + 0x201c, 0x201d, 0x201e, 0x201f, 0x2020, 0x2021, 0x2022, 0x2023, + 0x2024, 0x2025, 0x2026, 0x2027, 0x2028, 0x2029, 0x202a, 0x202b, + 0x202c, 0x202d, 0x202e, 0x202f, 0x2030, 0x2031, 0x2032, 0x2033, + 0x2034, 0x2035, 0x2036, 0x2037, 0x2038, 0x2039, 0x203a, 0x203b, + 0x203c, 0x203d, 0x203e, 0x203f, 0x2040, 0x2041, 0x2042, 0x2043, + 0x2044, 0x2045, 0x2046, 0x2047, 0x2048, 0x2049, 0x204a, 0x204b, + 0x204c, 0x204d, 0x204e, 0x204f, 0x2050, 0x2051, 0x2052, 0x2053, + 0x2054, 0x2055, 0x2056, 0x2057, 0x2058, 0x2059, 0x205a, 0x205b, + 0x205c, 0x205d, 0x205e, 0x205f, 0x2060, 0x2061, 0x2062, 0x2063, + 0x2064, 0x2065, 0x2066, 0x2067, 0x2068, 0x2069, 0x206a, 0x206b, + 0x206c, 0x206d, 0x206e, 0x206f, 0x2070, 0x2071, 0x2072, 0x2073, + 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, 0x2079, 0x207a, 0x207b, + 0x207c, 0x207d, 0x207e, 0x207f, 0x2080, 0x2081, 0x2082, 0x2083, + 0x2084, 0x2085, 0x2086, 0x2087, 0x2088, 0x2089, 0x208a, 0x208b, + 0x208c, 0x208d, 0x208e, 0x208f, 0x2090, 0x2091, 0x2092, 0x2093, + 0x2094, 0x2095, 0x2096, 0x2097, 0x2098, 0x2099, 0x209a, 0x209b, + 0x209c, 0x209d, 0x209e, 0x209f, 0x20a0, 0x20a1, 0x20a2, 0x20a3, + 0x20a4, 0x20a5, 0x20a6, 0x20a7, 0x20a8, 0x20a9, 0x20aa, 0x20ab, + 0x20ac, 0x20ad, 0x20ae, 0x20af, 0x20b0, 0x20b1, 0x20b2, 0x20b3, + 0x20b4, 0x20b5, 0x20b6, 0x20b7, 0x20b8, 0x20b9, 0x20ba, 0x20bb, + 0x20bc, 0x20bd, 0x20be, 0x20bf, 0x20c0, 0x20c1, 0x20c2, 0x20c3, + 0x20c4, 0x20c5, 0x20c6, 0x20c7, 0x20c8, 0x20c9, 0x20ca, 0x20cb, + 0x20cc, 0x20cd, 0x20ce, 0x20cf, 0x20d0, 0x20d1, 0x20d2, 0x20d3, + 0x20d4, 0x20d5, 0x20d6, 0x20d7, 0x20d8, 0x20d9, 0x20da, 0x20db, + 0x20dc, 0x20dd, 0x20de, 0x20df, 0x20e0, 0x20e1, 0x20e2, 0x20e3, + 0x20e4, 0x20e5, 0x20e6, 0x20e7, 0x20e8, 0x20e9, 0x20ea, 0x20eb, + 0x20ec, 0x20ed, 0x20ee, 0x20ef, 0x20f0, 0x20f1, 0x20f2, 0x20f3, + 0x20f4, 0x20f5, 0x20f6, 0x20f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, + 0x20fc, 0x20fd, 0x20fe, 0x20ff, 0x2100, 0x2101, 0x2102, 0x2103, + 0x2104, 0x2105, 0x2106, 0x2107, 0x2108, 0x2109, 0x210a, 0x210b, + 0x210c, 0x210d, 0x210e, 0x210f, 0x2110, 0x2111, 0x2112, 0x2113, + 0x2114, 0x2115, 0x2116, 0x2117, 0x2118, 0x2119, 0x211a, 0x211b, + 0x211c, 0x211d, 0x211e, 0x211f, 0x2120, 0x2121, 0x2122, 0x2123, + 0x2124, 0x2125, 0x2126, 0x2127, 0x2128, 0x2129, 0x212a, 0x212b, + 0x212c, 0x212d, 0x212e, 0x212f, 0x2130, 0x2131, 0x2132, 0x2133, + 0x2134, 0x2135, 0x2136, 0x2137, 0x2138, 0x2139, 0x213a, 0x213b, + 0x213c, 0x213d, 0x213e, 0x213f, 0x2140, 0x2141, 0x2142, 0x2143, + 0x2144, 0x2145, 0x2146, 0x2147, 0x2148, 0x2149, 0x214a, 0x214b, + 0x214c, 0x214d, 0x2132, 0x214f, 0x2150, 0x2151, 0x2152, 0x2153, + 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a, 0x215b, + 0x215c, 0x215d, 0x215e, 0x215f, 0x2160, 0x2161, 0x2162, 0x2163, + 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216a, 0x216b, + 0x216c, 0x216d, 0x216e, 0x216f, 0x2160, 0x2161, 0x2162, 0x2163, + 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216a, 0x216b, + 0x216c, 0x216d, 0x216e, 0x216f, 0x2180, 0x2181, 0x2182, 0x2183, + 0x2183, 0xffff, 0x034b, 0x24b6, 0x24b7, 0x24b8, 0x24b9, 0x24ba, + 0x24bb, 0x24bc, 0x24bd, 0x24be, 0x24bf, 0x24c0, 0x24c1, 0x24c2, + 0x24c3, 0x24c4, 0x24c5, 0x24c6, 0x24c7, 0x24c8, 0x24c9, 0x24ca, + 0x24cb, 0x24cc, 0x24cd, 0x24ce, 0x24cf, 0xffff, 0x0746, 0x2c00, + 0x2c01, 0x2c02, 0x2c03, 0x2c04, 0x2c05, 0x2c06, 0x2c07, 0x2c08, + 0x2c09, 0x2c0a, 0x2c0b, 0x2c0c, 0x2c0d, 0x2c0e, 0x2c0f, 0x2c10, + 0x2c11, 0x2c12, 0x2c13, 0x2c14, 0x2c15, 0x2c16, 0x2c17, 0x2c18, + 0x2c19, 0x2c1a, 0x2c1b, 0x2c1c, 0x2c1d, 0x2c1e, 0x2c1f, 0x2c20, + 0x2c21, 0x2c22, 0x2c23, 0x2c24, 0x2c25, 0x2c26, 0x2c27, 0x2c28, + 0x2c29, 0x2c2a, 0x2c2b, 0x2c2c, 0x2c2d, 0x2c2e, 0x2c5f, 0x2c60, + 0x2c60, 0x2c62, 0x2c63, 0x2c64, 0x2c65, 0x2c66, 0x2c67, 0x2c67, + 0x2c69, 0x2c69, 0x2c6b, 0x2c6b, 0x2c6d, 0x2c6e, 0x2c6f, 0x2c70, + 0x2c71, 0x2c72, 0x2c73, 0x2c74, 0x2c75, 0x2c75, 0x2c77, 0x2c78, + 0x2c79, 0x2c7a, 0x2c7b, 0x2c7c, 0x2c7d, 0x2c7e, 0x2c7f, 0x2c80, + 0x2c80, 0x2c82, 0x2c82, 0x2c84, 0x2c84, 0x2c86, 0x2c86, 0x2c88, + 0x2c88, 0x2c8a, 0x2c8a, 0x2c8c, 0x2c8c, 0x2c8e, 0x2c8e, 0x2c90, + 0x2c90, 0x2c92, 0x2c92, 0x2c94, 0x2c94, 0x2c96, 0x2c96, 0x2c98, + 0x2c98, 0x2c9a, 0x2c9a, 0x2c9c, 0x2c9c, 0x2c9e, 0x2c9e, 0x2ca0, + 0x2ca0, 0x2ca2, 0x2ca2, 0x2ca4, 0x2ca4, 0x2ca6, 0x2ca6, 0x2ca8, + 0x2ca8, 0x2caa, 0x2caa, 0x2cac, 0x2cac, 0x2cae, 0x2cae, 0x2cb0, + 0x2cb0, 0x2cb2, 0x2cb2, 0x2cb4, 0x2cb4, 0x2cb6, 0x2cb6, 0x2cb8, + 0x2cb8, 0x2cba, 0x2cba, 0x2cbc, 0x2cbc, 0x2cbe, 0x2cbe, 0x2cc0, + 0x2cc0, 0x2cc2, 0x2cc2, 0x2cc4, 0x2cc4, 0x2cc6, 0x2cc6, 0x2cc8, + 0x2cc8, 0x2cca, 0x2cca, 0x2ccc, 0x2ccc, 0x2cce, 0x2cce, 0x2cd0, + 0x2cd0, 0x2cd2, 0x2cd2, 0x2cd4, 0x2cd4, 0x2cd6, 0x2cd6, 0x2cd8, + 0x2cd8, 0x2cda, 0x2cda, 0x2cdc, 0x2cdc, 0x2cde, 0x2cde, 0x2ce0, + 0x2ce0, 0x2ce2, 0x2ce2, 0x2ce4, 0x2ce5, 0x2ce6, 0x2ce7, 0x2ce8, + 0x2ce9, 0x2cea, 0x2ceb, 0x2cec, 0x2ced, 0x2cee, 0x2cef, 0x2cf0, + 0x2cf1, 0x2cf2, 0x2cf3, 0x2cf4, 0x2cf5, 0x2cf6, 0x2cf7, 0x2cf8, + 0x2cf9, 0x2cfa, 0x2cfb, 0x2cfc, 0x2cfd, 0x2cfe, 0x2cff, 0x10a0, + 0x10a1, 0x10a2, 0x10a3, 0x10a4, 0x10a5, 0x10a6, 0x10a7, 0x10a8, + 0x10a9, 0x10aa, 0x10ab, 0x10ac, 0x10ad, 0x10ae, 0x10af, 0x10b0, + 0x10b1, 0x10b2, 0x10b3, 0x10b4, 0x10b5, 0x10b6, 0x10b7, 0x10b8, + 0x10b9, 0x10ba, 0x10bb, 0x10bc, 0x10bd, 0x10be, 0x10bf, 0x10c0, + 0x10c1, 0x10c2, 0x10c3, 0x10c4, 0x10c5, 0xffff, 0xd21b, 0xff21, + 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, 0xff28, 0xff29, + 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, 0xff31, + 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, 0xff39, + 0xff3a, 0xff5b, 0xff5c, 0xff5d, 0xff5e, 0xff5f, 0xff60, 0xff61, + 0xff62, 0xff63, 0xff64, 0xff65, 0xff66, 0xff67, 0xff68, 0xff69, + 0xff6a, 0xff6b, 0xff6c, 0xff6d, 0xff6e, 0xff6f, 0xff70, 0xff71, + 0xff72, 0xff73, 0xff74, 0xff75, 0xff76, 0xff77, 0xff78, 0xff79, + 0xff7a, 0xff7b, 0xff7c, 0xff7d, 0xff7e, 0xff7f, 0xff80, 0xff81, + 0xff82, 0xff83, 0xff84, 0xff85, 0xff86, 0xff87, 0xff88, 0xff89, + 0xff8a, 0xff8b, 0xff8c, 0xff8d, 0xff8e, 0xff8f, 0xff90, 0xff91, + 0xff92, 0xff93, 0xff94, 0xff95, 0xff96, 0xff97, 0xff98, 0xff99, + 0xff9a, 0xff9b, 0xff9c, 0xff9d, 0xff9e, 0xff9f, 0xffa0, 0xffa1, + 0xffa2, 0xffa3, 0xffa4, 0xffa5, 0xffa6, 0xffa7, 0xffa8, 0xffa9, + 0xffaa, 0xffab, 0xffac, 0xffad, 0xffae, 0xffaf, 0xffb0, 0xffb1, + 0xffb2, 0xffb3, 0xffb4, 0xffb5, 0xffb6, 0xffb7, 0xffb8, 0xffb9, + 0xffba, 0xffbb, 0xffbc, 0xffbd, 0xffbe, 0xffbf, 0xffc0, 0xffc1, + 0xffc2, 0xffc3, 0xffc4, 0xffc5, 0xffc6, 0xffc7, 0xffc8, 0xffc9, + 0xffca, 0xffcb, 0xffcc, 0xffcd, 0xffce, 0xffcf, 0xffd0, 0xffd1, + 0xffd2, 0xffd3, 0xffd4, 0xffd5, 0xffd6, 0xffd7, 0xffd8, 0xffd9, + 0xffda, 0xffdb, 0xffdc, 0xffdd, 0xffde, 0xffdf, 0xffe0, 0xffe1, + 0xffe2, 0xffe3, 0xffe4, 0xffe5, 0xffe6, 0xffe7, 0xffe8, 0xffe9, + 0xffea, 0xffeb, 0xffec, 0xffed, 0xffee, 0xffef, 0xfff0, 0xfff1, + 0xfff2, 0xfff3, 0xfff4, 0xfff5, 0xfff6, 0xfff7, 0xfff8, 0xfff9, + 0xfffa, 0xfffb, 0xfffc, 0xfffd, 0xfffe, 0xffff, +}; + +/* + * Allow full-width illegal characters : + * "MS windows 7" supports full-width-invalid-name-characters. + * So we should check half-width-invalid-name-characters(ASCII) only + * for compatibility. + * + * " * / : < > ? \ | + */ +static unsigned short bad_uni_chars[] = { + 0x0022, 0x002A, 0x002F, 0x003A, + 0x003C, 0x003E, 0x003F, 0x005C, 0x007C, + 0 +}; + +static int exfat_convert_char_to_ucs2(struct nls_table *nls, + const unsigned char *ch, int ch_len, unsigned short *ucs2, + int *lossy) +{ + int len; + + *ucs2 = 0x0; + + if (ch[0] < 0x80) { + *ucs2 = ch[0]; + return 1; + } + + len = nls->char2uni(ch, ch_len, ucs2); + if (len < 0) { + /* conversion failed */ + if (lossy != NULL) + *lossy |= NLS_NAME_LOSSY; + *ucs2 = '_'; + return 1; + } + return len; +} + +static int exfat_convert_ucs2_to_char(struct nls_table *nls, + unsigned short ucs2, unsigned char *ch, int *lossy) +{ + int len; + + ch[0] = 0x0; + + if (ucs2 < 0x0080) { + ch[0] = ucs2; + return 1; + } + + len = nls->uni2char(ucs2, ch, MAX_CHARSET_SIZE); + if (len < 0) { + /* conversion failed */ + if (lossy != NULL) + *lossy |= NLS_NAME_LOSSY; + ch[0] = '_'; + return 1; + } + return len; +} + +unsigned short exfat_toupper(struct super_block *sb, unsigned short a) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + return sbi->vol_utbl[a] ? sbi->vol_utbl[a] : a; +} + +static unsigned short *exfat_wstrchr(unsigned short *str, unsigned short wchar) +{ + while (*str) { + if (*(str++) == wchar) + return str; + } + return NULL; +} + +int exfat_uniname_ncmp(struct super_block *sb, unsigned short *a, + unsigned short *b, unsigned int len) +{ + int i; + + for (i = 0; i < len; i++, a++, b++) + if (exfat_toupper(sb, *a) != exfat_toupper(sb, *b)) + return 1; + return 0; +} + +static int exfat_utf16_to_utf8(struct super_block *sb, + struct exfat_uni_name *p_uniname, unsigned char *p_cstring, + int buflen) +{ + int len; + const unsigned short *uniname = p_uniname->name; + + /* always len >= 0 */ + len = utf16s_to_utf8s(uniname, MAX_NAME_LENGTH, UTF16_HOST_ENDIAN, + p_cstring, buflen); + p_cstring[len] = '\0'; + return len; +} + +static int exfat_utf8_to_utf16(struct super_block *sb, + const unsigned char *p_cstring, const int len, + struct exfat_uni_name *p_uniname, int *p_lossy) +{ + int i, unilen, lossy = NLS_NAME_NO_LOSSY; + unsigned short upname[MAX_NAME_LENGTH + 1]; + unsigned short *uniname = p_uniname->name; + + WARN_ON(!len); + + unilen = utf8s_to_utf16s(p_cstring, len, UTF16_HOST_ENDIAN, + (wchar_t *)uniname, MAX_NAME_LENGTH + 2); + if (unilen < 0) { + exfat_err(sb, "failed to %s (err : %d) nls len : %d", + __func__, unilen, len); + return unilen; + } + + if (unilen > MAX_NAME_LENGTH) { + exfat_err(sb, "failed to %s (estr:ENAMETOOLONG) nls len : %d, unilen : %d > %d", + __func__, len, unilen, MAX_NAME_LENGTH); + return -ENAMETOOLONG; + } + + for (i = 0; i < unilen; i++) { + if (*uniname < 0x0020 || + exfat_wstrchr(bad_uni_chars, *uniname)) + lossy |= NLS_NAME_LOSSY; + + upname[i] = exfat_toupper(sb, *uniname); + uniname++; + } + + *uniname = '\0'; + p_uniname->name_len = unilen; + p_uniname->name_hash = exfat_calc_chksum16(upname, unilen << 1, 0, + CS_DEFAULT); + + if (p_lossy) + *p_lossy = lossy; + return unilen; +} + +#define SURROGATE_MASK 0xfffff800 +#define SURROGATE_PAIR 0x0000d800 +#define SURROGATE_LOW 0x00000400 + +static int __exfat_utf16_to_nls(struct super_block *sb, + struct exfat_uni_name *p_uniname, unsigned char *p_cstring, + int buflen) +{ + int i, j, len, out_len = 0; + unsigned char buf[MAX_CHARSET_SIZE]; + const unsigned short *uniname = p_uniname->name; + struct nls_table *nls = EXFAT_SB(sb)->nls_io; + + i = 0; + while (i < MAX_NAME_LENGTH && out_len < (buflen - 1)) { + if (*uniname == '\0') + break; + if ((*uniname & SURROGATE_MASK) != SURROGATE_PAIR) { + len = exfat_convert_ucs2_to_char(nls, *uniname, buf, + NULL); + } else { + /* Process UTF-16 surrogate pair as one character */ + if (!(*uniname & SURROGATE_LOW) && + i+1 < MAX_NAME_LENGTH && + (*(uniname+1) & SURROGATE_MASK) == SURROGATE_PAIR && + (*(uniname+1) & SURROGATE_LOW)) { + uniname++; + i++; + } + + /* + * UTF-16 surrogate pair encodes code points above + * U+FFFF. Code points above U+FFFF are not supported + * by kernel NLS framework therefore use replacement + * character + */ + len = 1; + buf[0] = '_'; + } + + if (out_len + len >= buflen) + len = buflen - 1 - out_len; + out_len += len; + + if (len > 1) { + for (j = 0; j < len; j++) + *p_cstring++ = buf[j]; + } else { /* len == 1 */ + *p_cstring++ = *buf; + } + + uniname++; + i++; + } + + *p_cstring = '\0'; + return out_len; +} + +static int exfat_nls_to_ucs2(struct super_block *sb, + const unsigned char *p_cstring, const int len, + struct exfat_uni_name *p_uniname, int *p_lossy) +{ + int i = 0, unilen = 0, lossy = NLS_NAME_NO_LOSSY; + unsigned short upname[MAX_NAME_LENGTH + 1]; + unsigned short *uniname = p_uniname->name; + struct nls_table *nls = EXFAT_SB(sb)->nls_io; + + WARN_ON(!len); + + while (unilen < MAX_NAME_LENGTH && i < len) { + i += exfat_convert_char_to_ucs2(nls, p_cstring + i, len - i, + uniname, &lossy); + + if (*uniname < 0x0020 || + exfat_wstrchr(bad_uni_chars, *uniname)) + lossy |= NLS_NAME_LOSSY; + + upname[unilen] = exfat_toupper(sb, *uniname); + uniname++; + unilen++; + } + + if (p_cstring[i] != '\0') + lossy |= NLS_NAME_OVERLEN; + + *uniname = '\0'; + p_uniname->name_len = unilen; + p_uniname->name_hash = exfat_calc_chksum16(upname, unilen << 1, 0, + CS_DEFAULT); + + if (p_lossy) + *p_lossy = lossy; + return unilen; +} + +int exfat_utf16_to_nls(struct super_block *sb, struct exfat_uni_name *uniname, + unsigned char *p_cstring, int buflen) +{ + if (EXFAT_SB(sb)->options.utf8) + return exfat_utf16_to_utf8(sb, uniname, p_cstring, + buflen); + return __exfat_utf16_to_nls(sb, uniname, p_cstring, buflen); +} + +int exfat_nls_to_utf16(struct super_block *sb, const unsigned char *p_cstring, + const int len, struct exfat_uni_name *uniname, int *p_lossy) +{ + if (EXFAT_SB(sb)->options.utf8) + return exfat_utf8_to_utf16(sb, p_cstring, len, + uniname, p_lossy); + return exfat_nls_to_ucs2(sb, p_cstring, len, uniname, p_lossy); +} + +static int exfat_load_upcase_table(struct super_block *sb, + sector_t sector, unsigned long long num_sectors, + unsigned int utbl_checksum) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + unsigned int sect_size = sb->s_blocksize; + unsigned int i, index = 0; + u32 chksum = 0; + int ret; + unsigned char skip = false; + unsigned short *upcase_table; + + upcase_table = kcalloc(UTBL_COUNT, sizeof(unsigned short), GFP_KERNEL); + if (!upcase_table) + return -ENOMEM; + + sbi->vol_utbl = upcase_table; + num_sectors += sector; + + while (sector < num_sectors) { + struct buffer_head *bh; + + bh = sb_bread(sb, sector); + if (!bh) { + exfat_err(sb, "failed to read sector(0x%llx)\n", + (unsigned long long)sector); + ret = -EIO; + goto free_table; + } + sector++; + for (i = 0; i < sect_size && index <= 0xFFFF; i += 2) { + unsigned short uni = get_unaligned_le16(bh->b_data + i); + + if (skip) { + index += uni; + skip = false; + } else if (uni == index) { + index++; + } else if (uni == 0xFFFF) { + skip = true; + } else { /* uni != index , uni != 0xFFFF */ + upcase_table[index] = uni; + index++; + } + } + chksum = exfat_calc_chksum32(bh->b_data, i, chksum, CS_DEFAULT); + brelse(bh); + } + + if (index >= 0xFFFF && utbl_checksum == chksum) + return 0; + + exfat_err(sb, "failed to load upcase table (idx : 0x%08x, chksum : 0x%08x, utbl_chksum : 0x%08x)", + index, chksum, utbl_checksum); + ret = -EINVAL; +free_table: + exfat_free_upcase_table(sbi); + return ret; +} + +static int exfat_load_default_upcase_table(struct super_block *sb) +{ + int i, ret = -EIO; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + unsigned char skip = false; + unsigned short uni = 0, *upcase_table; + unsigned int index = 0; + + upcase_table = kcalloc(UTBL_COUNT, sizeof(unsigned short), GFP_KERNEL); + if (!upcase_table) + return -ENOMEM; + + sbi->vol_utbl = upcase_table; + + for (i = 0; index <= 0xFFFF && i < EXFAT_NUM_UPCASE; i++) { + uni = uni_def_upcase[i]; + if (skip) { + index += uni; + skip = false; + } else if (uni == index) { + index++; + } else if (uni == 0xFFFF) { + skip = true; + } else { + upcase_table[index] = uni; + index++; + } + } + + if (index >= 0xFFFF) + return 0; + + /* FATAL error: default upcase table has error */ + exfat_free_upcase_table(sbi); + return ret; +} + +int exfat_create_upcase_table(struct super_block *sb) +{ + int i, ret; + unsigned int tbl_clu, type; + sector_t sector; + unsigned long long tbl_size, num_sectors; + unsigned char blksize_bits = sb->s_blocksize_bits; + struct exfat_chain clu; + struct exfat_dentry *ep; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct buffer_head *bh; + + clu.dir = sbi->root_dir; + clu.flags = ALLOC_FAT_CHAIN; + + while (clu.dir != EXFAT_EOF_CLUSTER) { + for (i = 0; i < sbi->dentries_per_clu; i++) { + ep = exfat_get_dentry(sb, &clu, i, &bh, NULL); + if (!ep) + return -EIO; + + type = exfat_get_entry_type(ep); + if (type == TYPE_UNUSED) { + brelse(bh); + break; + } + + if (type != TYPE_UPCASE) { + brelse(bh); + continue; + } + + tbl_clu = le32_to_cpu(ep->dentry.upcase.start_clu); + tbl_size = le64_to_cpu(ep->dentry.upcase.size); + + sector = exfat_cluster_to_sector(sbi, tbl_clu); + num_sectors = ((tbl_size - 1) >> blksize_bits) + 1; + ret = exfat_load_upcase_table(sb, sector, num_sectors, + le32_to_cpu(ep->dentry.upcase.checksum)); + + brelse(bh); + if (ret && ret != -EIO) + goto load_default; + + /* load successfully */ + return ret; + } + + if (exfat_get_next_cluster(sb, &(clu.dir))) + return -EIO; + } + +load_default: + /* load default upcase table */ + return exfat_load_default_upcase_table(sb); +} + +void exfat_free_upcase_table(struct exfat_sb_info *sbi) +{ + kfree(sbi->vol_utbl); +} diff --git a/fs/exfat/super.c b/fs/exfat/super.c new file mode 100644 index 000000000000..804bc4e9a3ac --- /dev/null +++ b/fs/exfat/super.c @@ -0,0 +1,864 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "exfat_fs.h" + +static int exfat_init_sb_info(struct super_block *sb); +static int exfat_parse_options(struct super_block *sb, char *options, int silent, + struct exfat_mount_options *opts); + +static char exfat_default_iocharset[] = CONFIG_EXFAT_DEFAULT_IOCHARSET; +static struct kmem_cache *exfat_inode_cachep; + +static void exfat_free_iocharset(struct exfat_sb_info *sbi) +{ + if (sbi->options.iocharset != exfat_default_iocharset) + kfree(sbi->options.iocharset); +} + +static void exfat_delayed_free(struct rcu_head *p) +{ + struct exfat_sb_info *sbi = container_of(p, struct exfat_sb_info, rcu); + + unload_nls(sbi->nls_io); + exfat_free_iocharset(sbi); + exfat_free_upcase_table(sbi); + kfree(sbi); +} + +static void exfat_put_super(struct super_block *sb) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + mutex_lock(&sbi->s_lock); + if (test_and_clear_bit(EXFAT_SB_DIRTY, &sbi->s_state)) + sync_blockdev(sb->s_bdev); + exfat_set_vol_flags(sb, VOL_CLEAN); + exfat_free_bitmap(sbi); + brelse(sbi->boot_bh); + mutex_unlock(&sbi->s_lock); + + call_rcu(&sbi->rcu, exfat_delayed_free); +} + +static int exfat_sync_fs(struct super_block *sb, int wait) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + int err = 0; + + /* If there are some dirty buffers in the bdev inode */ + mutex_lock(&sbi->s_lock); + if (test_and_clear_bit(EXFAT_SB_DIRTY, &sbi->s_state)) { + sync_blockdev(sb->s_bdev); + if (exfat_set_vol_flags(sb, VOL_CLEAN)) + err = -EIO; + } + mutex_unlock(&sbi->s_lock); + return err; +} + +static int exfat_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + struct super_block *sb = dentry->d_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + unsigned long long id = huge_encode_dev(sb->s_bdev->bd_dev); + + if (sbi->used_clusters == EXFAT_CLUSTERS_UNTRACKED) { + mutex_lock(&sbi->s_lock); + if (exfat_count_used_clusters(sb, &sbi->used_clusters)) { + mutex_unlock(&sbi->s_lock); + return -EIO; + } + mutex_unlock(&sbi->s_lock); + } + + buf->f_type = sb->s_magic; + buf->f_bsize = sbi->cluster_size; + buf->f_blocks = sbi->num_clusters - 2; /* clu 0 & 1 */ + buf->f_bfree = buf->f_blocks - sbi->used_clusters; + buf->f_bavail = buf->f_bfree; + buf->f_fsid.val[0] = (unsigned int)id; + buf->f_fsid.val[1] = (unsigned int)(id >> 32); + /* Unicode utf16 255 characters */ + buf->f_namelen = EXFAT_MAX_FILE_LEN * NLS_MAX_CHARSET_SIZE; + return 0; +} + +int exfat_set_vol_flags(struct super_block *sb, unsigned short new_flag) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct boot_sector *p_boot = (struct boot_sector *)sbi->boot_bh->b_data; + bool sync; + + /* flags are not changed */ + if (sbi->vol_flag == new_flag) + return 0; + + sbi->vol_flag = new_flag; + + /* skip updating volume dirty flag, + * if this volume has been mounted with read-only + */ + if (sb_rdonly(sb)) + return 0; + + p_boot->vol_flags = cpu_to_le16(new_flag); + + if (new_flag == VOL_DIRTY && !buffer_dirty(sbi->boot_bh)) + sync = true; + else + sync = false; + + set_buffer_uptodate(sbi->boot_bh); + mark_buffer_dirty(sbi->boot_bh); + + if (sync) + sync_dirty_buffer(sbi->boot_bh); + return 0; +} + +static int exfat_show_options(struct seq_file *m, struct dentry *root) +{ + struct super_block *sb = root->d_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_mount_options *opts = &sbi->options; + + /* Show partition info */ + if (!uid_eq(opts->fs_uid, GLOBAL_ROOT_UID)) + seq_printf(m, ",uid=%u", + from_kuid_munged(&init_user_ns, opts->fs_uid)); + if (!gid_eq(opts->fs_gid, GLOBAL_ROOT_GID)) + seq_printf(m, ",gid=%u", + from_kgid_munged(&init_user_ns, opts->fs_gid)); + seq_printf(m, ",fmask=%04o,dmask=%04o", opts->fs_fmask, opts->fs_dmask); + if (opts->allow_utime) + seq_printf(m, ",allow_utime=%04o", opts->allow_utime); + if (opts->quiet) + seq_puts(m, ",quiet"); + if (opts->utf8) + seq_puts(m, ",iocharset=utf8"); + else if (sbi->nls_io) + seq_printf(m, ",iocharset=%s", sbi->nls_io->charset); + if (opts->errors == EXFAT_ERRORS_CONT) + seq_puts(m, ",errors=continue"); + else if (opts->errors == EXFAT_ERRORS_PANIC) + seq_puts(m, ",errors=panic"); + else + seq_puts(m, ",errors=remount-ro"); + if (opts->discard) + seq_puts(m, ",discard"); + if (opts->time_offset) + seq_printf(m, ",time_offset=%d", opts->time_offset); + return 0; +} + +static struct inode *exfat_alloc_inode(struct super_block *sb) +{ + struct exfat_inode_info *ei; + + ei = kmem_cache_alloc(exfat_inode_cachep, GFP_NOFS); + if (!ei) + return NULL; + + init_rwsem(&ei->truncate_lock); + return &ei->vfs_inode; +} + +static void exfat_free_inode(struct inode *inode) +{ + kmem_cache_free(exfat_inode_cachep, EXFAT_I(inode)); +} + +static int exfat_remount(struct super_block *sb, int *flags, char *opt) +{ + int ret = 0; + + *flags |= SB_NODIRATIME; + + /* volume flag will be updated in exfat_sync_fs */ + sync_filesystem(sb); + + ret = exfat_parse_options(sb, opt, 0, &EXFAT_SB(sb)->options); + if (ret) + exfat_err(sb, "failed to parse options"); + + return ret; +} + +static const struct super_operations exfat_sops = { + .alloc_inode = exfat_alloc_inode, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) + .free_inode = exfat_free_inode, +#else + .destroy_inode = exfat_free_inode, +#endif + .write_inode = exfat_write_inode, + .evict_inode = exfat_evict_inode, + .put_super = exfat_put_super, + .sync_fs = exfat_sync_fs, + .statfs = exfat_statfs, + .show_options = exfat_show_options, + .remount_fs = exfat_remount, +}; + +enum { + Opt_uid, + Opt_gid, + Opt_umask, + Opt_dmask, + Opt_fmask, + Opt_allow_utime, + Opt_charset, + Opt_quiet, + Opt_err_cont, + Opt_err_panic, + Opt_err_ro, + Opt_discard, + Opt_time_offset, + + /* Deprecated options */ + Opt_utf8, + Opt_debug, + Opt_namecase, + Opt_codepage, +}; + +static const match_table_t exfat_tokens = { + {Opt_uid, "uid=%u"}, + {Opt_gid, "gid=%u"}, + {Opt_umask, "umask=%o"}, + {Opt_dmask, "dmask=%o"}, + {Opt_fmask, "fmask=%o"}, + {Opt_allow_utime, "allow_utime=%o"}, + {Opt_charset, "iocharset=%s"}, + {Opt_quiet, "quiet"}, + {Opt_err_cont, "errors=continue"}, + {Opt_err_panic, "errors=panic"}, + {Opt_err_ro, "errors=remount-ro"}, + {Opt_discard, "discard"}, + {Opt_time_offset, "time_offset=%d"}, + + /* Deprecated options */ + {Opt_utf8, "utf8"}, + {Opt_debug, "debug"}, + {Opt_namecase, "namecase=%u"}, + {Opt_codepage, "codepage=%u"}, +}; + +static int __exfat_parse_option(struct super_block *sb, char *p, substring_t *args, int token, int silent) +{ + struct exfat_sb_info *sbi = sb->s_fs_info; + struct exfat_mount_options *opts = &sbi->options; + int option; + char *tmpstr; + + switch (token) { + case Opt_uid: + if (match_int(&args[0], &option)) + return -EINVAL; + opts->fs_uid = make_kuid(current_user_ns(), option); + break; + case Opt_gid: + if (match_int(&args[0], &option)) + return -EINVAL; + opts->fs_gid = make_kgid(current_user_ns(), option); + break; + case Opt_umask: + case Opt_dmask: + case Opt_fmask: + if (match_octal(&args[0], &option)) + return -EINVAL; + if (token != Opt_dmask) + opts->fs_fmask = option; + if (token != Opt_fmask) + opts->fs_dmask = option; + break; + case Opt_allow_utime: + if (match_octal(&args[0], &option)) + return -EINVAL; + opts->allow_utime = option & (S_IWGRP | S_IWOTH); + break; + case Opt_charset: + exfat_free_iocharset(sbi); + tmpstr = match_strdup(&args[0]); + if (!tmpstr) + return -ENOMEM; + opts->iocharset = tmpstr; + break; + case Opt_quiet: + opts->quiet = 1; + break; + case Opt_err_cont: + opts->errors = EXFAT_ERRORS_CONT; + break; + case Opt_err_panic: + opts->errors = EXFAT_ERRORS_PANIC; + break; + case Opt_err_ro: + opts->errors = EXFAT_ERRORS_RO; + break; + case Opt_discard: + opts->discard = 1; + break; + case Opt_time_offset: + if (match_int(&args[0], &option)) + return -EINVAL; + /* + * Make the limit 24 just in case someone invents something + * unusual. + */ + if (option < -24 * 60 || option > 24 * 60) + return -EINVAL; + opts->time_offset = option; + break; + case Opt_utf8: + case Opt_debug: + case Opt_namecase: + case Opt_codepage: + if (!silent) + exfat_warn(sb, "deprecated mount option \"%s\" ", p); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int exfat_parse_options(struct super_block *sb, char *options, int silent, + struct exfat_mount_options *opts) +{ + char *p; + substring_t args[MAX_OPT_ARGS]; + int ret; + + if (!options) + goto out; + + while ((p = strsep(&options, ",")) != NULL) { + int token; + + if (!*p) + continue; + token = match_token(p, exfat_tokens, args); + ret = __exfat_parse_option(sb, p, args, token, silent); + if (ret < 0) { + if (ret == -EINVAL && !silent) { + exfat_msg(sb, KERN_ERR, + "unrecognized mount option \"%s\" " + "or missing value", p); + } + return ret; + } + } + + if (opts->allow_utime == (unsigned short)-1) + opts->allow_utime = ~opts->fs_dmask & 0022; + + if (opts->discard) { + struct request_queue *q = bdev_get_queue(sb->s_bdev); + + if (!blk_queue_discard(q)) { + exfat_warn(sb, "mounting with \"discard\" option, but the device does not support discard"); + opts->discard = 0; + } + } +out: + return 0; +} + +static void exfat_hash_init(struct super_block *sb) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + int i; + + spin_lock_init(&sbi->inode_hash_lock); + for (i = 0; i < EXFAT_HASH_SIZE; i++) + INIT_HLIST_HEAD(&sbi->inode_hashtable[i]); +} + +static int exfat_read_root(struct inode *inode) +{ + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_inode_info *ei = EXFAT_I(inode); + struct exfat_chain cdir; + int num_subdirs, num_clu = 0; + + exfat_chain_set(&ei->dir, sbi->root_dir, 0, ALLOC_FAT_CHAIN); + ei->entry = -1; + ei->start_clu = sbi->root_dir; + ei->flags = ALLOC_FAT_CHAIN; + ei->type = TYPE_DIR; + ei->version = 0; + ei->rwoffset = 0; + ei->hint_bmap.off = EXFAT_EOF_CLUSTER; + ei->hint_stat.eidx = 0; + ei->hint_stat.clu = sbi->root_dir; + ei->hint_femp.eidx = EXFAT_HINT_NONE; + + exfat_chain_set(&cdir, sbi->root_dir, 0, ALLOC_FAT_CHAIN); + if (exfat_count_num_clusters(sb, &cdir, &num_clu)) + return -EIO; + i_size_write(inode, num_clu << sbi->cluster_size_bits); + + num_subdirs = exfat_count_dir_entries(sb, &cdir); + if (num_subdirs < 0) + return -EIO; + set_nlink(inode, num_subdirs + EXFAT_MIN_SUBDIR); + + inode->i_uid = sbi->options.fs_uid; + inode->i_gid = sbi->options.fs_gid; + inode_inc_iversion(inode); + inode->i_generation = 0; + inode->i_mode = exfat_make_mode(sbi, ATTR_SUBDIR, 0777); + inode->i_op = &exfat_dir_inode_operations; + inode->i_fop = &exfat_dir_operations; + + inode->i_blocks = ((i_size_read(inode) + (sbi->cluster_size - 1)) + & ~(sbi->cluster_size - 1)) >> inode->i_blkbits; + EXFAT_I(inode)->i_pos = ((loff_t)sbi->root_dir << 32) | 0xffffffff; + EXFAT_I(inode)->i_size_aligned = i_size_read(inode); + EXFAT_I(inode)->i_size_ondisk = i_size_read(inode); + + exfat_save_attr(inode, ATTR_SUBDIR); + inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime = + current_time(inode); + exfat_truncate_atime(&inode->i_atime); + exfat_cache_init_inode(inode); + return 0; +} + +static int exfat_calibrate_blocksize(struct super_block *sb, int logical_sect) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + if (!is_power_of_2(logical_sect) || + logical_sect < 512 || logical_sect > 4096) { + exfat_err(sb, "bogus logical sector size %u", logical_sect); + return -EIO; + } + + if (logical_sect < sb->s_blocksize) { + exfat_err(sb, "logical sector size too small for device (logical sector size = %u)", + logical_sect); + return -EIO; + } + + if (logical_sect > sb->s_blocksize) { + brelse(sbi->boot_bh); + sbi->boot_bh = NULL; + + if (!sb_set_blocksize(sb, logical_sect)) { + exfat_err(sb, "unable to set blocksize %u", + logical_sect); + return -EIO; + } + sbi->boot_bh = sb_bread(sb, 0); + if (!sbi->boot_bh) { + exfat_err(sb, "unable to read boot sector (logical sector size = %lu)", + sb->s_blocksize); + return -EIO; + } + } + return 0; +} + +static int exfat_read_boot_sector(struct super_block *sb) +{ + struct boot_sector *p_boot; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + /* set block size to read super block */ + sb_min_blocksize(sb, 512); + + /* read boot sector */ + sbi->boot_bh = sb_bread(sb, 0); + if (!sbi->boot_bh) { + exfat_err(sb, "unable to read boot sector"); + return -EIO; + } + p_boot = (struct boot_sector *)sbi->boot_bh->b_data; + + /* check the validity of BOOT */ + if (le16_to_cpu((p_boot->signature)) != BOOT_SIGNATURE) { + exfat_err(sb, "invalid boot record signature"); + return -EINVAL; + } + + if (memcmp(p_boot->fs_name, STR_EXFAT, BOOTSEC_FS_NAME_LEN)) { + exfat_err(sb, "invalid fs_name"); /* fs_name may unprintable */ + return -EINVAL; + } + + /* + * must_be_zero field must be filled with zero to prevent mounting + * from FAT volume. + */ + if (memchr_inv(p_boot->must_be_zero, 0, sizeof(p_boot->must_be_zero))) + return -EINVAL; + + if (p_boot->num_fats != 1 && p_boot->num_fats != 2) { + exfat_err(sb, "bogus number of FAT structure"); + return -EINVAL; + } + + sbi->sect_per_clus = 1 << p_boot->sect_per_clus_bits; + sbi->sect_per_clus_bits = p_boot->sect_per_clus_bits; + sbi->cluster_size_bits = p_boot->sect_per_clus_bits + + p_boot->sect_size_bits; + sbi->cluster_size = 1 << sbi->cluster_size_bits; + sbi->num_FAT_sectors = le32_to_cpu(p_boot->fat_length); + sbi->FAT1_start_sector = le32_to_cpu(p_boot->fat_offset); + sbi->FAT2_start_sector = le32_to_cpu(p_boot->fat_offset); + if (p_boot->num_fats == 2) + sbi->FAT2_start_sector += sbi->num_FAT_sectors; + sbi->data_start_sector = le32_to_cpu(p_boot->clu_offset); + sbi->num_sectors = le64_to_cpu(p_boot->vol_length); + /* because the cluster index starts with 2 */ + sbi->num_clusters = le32_to_cpu(p_boot->clu_count) + + EXFAT_RESERVED_CLUSTERS; + + sbi->root_dir = le32_to_cpu(p_boot->root_cluster); + sbi->dentries_per_clu = 1 << + (sbi->cluster_size_bits - DENTRY_SIZE_BITS); + + sbi->vol_flag = le16_to_cpu(p_boot->vol_flags); + sbi->clu_srch_ptr = EXFAT_FIRST_CLUSTER; + sbi->used_clusters = EXFAT_CLUSTERS_UNTRACKED; + + /* check consistencies */ + if (sbi->num_FAT_sectors << p_boot->sect_size_bits < + sbi->num_clusters * 4) { + exfat_err(sb, "bogus fat length"); + return -EINVAL; + } + if (sbi->data_start_sector < + sbi->FAT1_start_sector + sbi->num_FAT_sectors * p_boot->num_fats) { + exfat_err(sb, "bogus data start sector"); + return -EINVAL; + } + if (sbi->vol_flag & VOL_DIRTY) + exfat_warn(sb, "Volume was not properly unmounted. Some data may be corrupt. Please run fsck."); + if (sbi->vol_flag & ERR_MEDIUM) + exfat_warn(sb, "Medium has reported failures. Some data may be lost."); + + /* exFAT file size is limited by a disk volume size */ + sb->s_maxbytes = (u64)(sbi->num_clusters - EXFAT_RESERVED_CLUSTERS) << + sbi->cluster_size_bits; + + /* check logical sector size */ + if (exfat_calibrate_blocksize(sb, 1 << p_boot->sect_size_bits)) + return -EIO; + + return 0; +} + +static int exfat_verify_boot_region(struct super_block *sb) +{ + struct buffer_head *bh = NULL; + u32 chksum = 0; + __le32 *p_sig, *p_chksum; + int sn, i; + + /* read boot sector sub-regions */ + for (sn = 0; sn < 11; sn++) { + bh = sb_bread(sb, sn); + if (!bh) + return -EIO; + + if (sn != 0 && sn <= 8) { + /* extended boot sector sub-regions */ + p_sig = (__le32 *)&bh->b_data[sb->s_blocksize - 4]; + if (le32_to_cpu(*p_sig) != EXBOOT_SIGNATURE) + exfat_warn(sb, "Invalid exboot-signature(sector = %d): 0x%08x", + sn, le32_to_cpu(*p_sig)); + } + + chksum = exfat_calc_chksum32(bh->b_data, sb->s_blocksize, + chksum, sn ? CS_DEFAULT : CS_BOOT_SECTOR); + brelse(bh); + } + + /* boot checksum sub-regions */ + bh = sb_bread(sb, sn); + if (!bh) + return -EIO; + + for (i = 0; i < sb->s_blocksize; i += sizeof(u32)) { + p_chksum = (__le32 *)&bh->b_data[i]; + if (le32_to_cpu(*p_chksum) != chksum) { + exfat_err(sb, "Invalid boot checksum (boot checksum : 0x%08x, checksum : 0x%08x)", + le32_to_cpu(*p_chksum), chksum); + brelse(bh); + return -EINVAL; + } + } + brelse(bh); + return 0; +} + +/* mount the file system volume */ +static int __exfat_fill_super(struct super_block *sb) +{ + int ret; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + ret = exfat_read_boot_sector(sb); + if (ret) { + exfat_err(sb, "failed to read boot sector"); + goto free_bh; + } + + ret = exfat_verify_boot_region(sb); + if (ret) { + exfat_err(sb, "invalid boot region"); + goto free_bh; + } + + ret = exfat_create_upcase_table(sb); + if (ret) { + exfat_err(sb, "failed to load upcase table"); + goto free_bh; + } + + ret = exfat_load_bitmap(sb); + if (ret) { + exfat_err(sb, "failed to load alloc-bitmap"); + goto free_upcase_table; + } + + ret = exfat_count_used_clusters(sb, &sbi->used_clusters); + if (ret) { + exfat_err(sb, "failed to scan clusters"); + goto free_alloc_bitmap; + } + + return 0; + +free_alloc_bitmap: + exfat_free_bitmap(sbi); +free_upcase_table: + exfat_free_upcase_table(sbi); +free_bh: + brelse(sbi->boot_bh); + return ret; +} + +static int exfat_fill_super(struct super_block *sb, void *data, int silent) +{ + struct exfat_sb_info *sbi; + struct exfat_mount_options *opts; + struct inode *root_inode; + int err; + + err = exfat_init_sb_info(sb); + if (err) { + exfat_err(sb, "failed to initialize superblock info"); + goto failed; + } + + sbi = sb->s_fs_info; + opts = &sbi->options; + + sb->s_flags |= SB_NODIRATIME; + sb->s_magic = EXFAT_SUPER_MAGIC; + sb->s_op = &exfat_sops; + sb->s_xattr = exfat_xattr_handlers; + + sb->s_time_gran = 10 * NSEC_PER_MSEC; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) + sb->s_time_min = EXFAT_MIN_TIMESTAMP_SECS; + sb->s_time_max = EXFAT_MAX_TIMESTAMP_SECS; +#endif + + err = exfat_parse_options(sb, data, silent, &sbi->options); + if (err) { + exfat_err(sb, "failed to parse options"); + goto check_nls_io; + } + + err = __exfat_fill_super(sb); + if (err) { + exfat_err(sb, "failed to recognize exfat type"); + goto check_nls_io; + } + + /* set up enough so that it can read an inode */ + exfat_hash_init(sb); + + if (!strcmp(sbi->options.iocharset, "utf8")) + opts->utf8 = 1; + else { + sbi->nls_io = load_nls(sbi->options.iocharset); + if (!sbi->nls_io) { + exfat_err(sb, "IO charset %s not found", + sbi->options.iocharset); + err = -EINVAL; + goto free_table; + } + } + + if (sbi->options.utf8) + sb->s_d_op = &exfat_utf8_dentry_ops; + else + sb->s_d_op = &exfat_dentry_ops; + + root_inode = new_inode(sb); + if (!root_inode) { + exfat_err(sb, "failed to allocate root inode"); + err = -ENOMEM; + goto free_table; + } + + root_inode->i_ino = EXFAT_ROOT_INO; + inode_set_iversion(root_inode, 1); + err = exfat_read_root(root_inode); + if (err) { + exfat_err(sb, "failed to initialize root inode"); + goto put_inode; + } + + exfat_hash_inode(root_inode, EXFAT_I(root_inode)->i_pos); + insert_inode_hash(root_inode); + + sb->s_root = d_make_root(root_inode); + if (!sb->s_root) { + exfat_err(sb, "failed to get the root dentry"); + err = -ENOMEM; + goto put_inode; + } + + return 0; + +put_inode: + iput(root_inode); + sb->s_root = NULL; + +free_table: + exfat_free_upcase_table(sbi); + exfat_free_bitmap(sbi); + brelse(sbi->boot_bh); + +check_nls_io: + unload_nls(sbi->nls_io); + exfat_free_iocharset(sbi); + sb->s_fs_info = NULL; + kfree(sbi); + +failed: + return err; +} + +static int exfat_init_sb_info(struct super_block *sb) +{ + struct exfat_sb_info *sbi; + + sbi = kzalloc(sizeof(struct exfat_sb_info), GFP_KERNEL); + if (!sbi) + return -ENOMEM; + + mutex_init(&sbi->s_lock); + ratelimit_state_init(&sbi->ratelimit, DEFAULT_RATELIMIT_INTERVAL, + DEFAULT_RATELIMIT_BURST); + + sbi->options.fs_uid = current_uid(); + sbi->options.fs_gid = current_gid(); + sbi->options.fs_fmask = current->fs->umask; + sbi->options.fs_dmask = current->fs->umask; + sbi->options.allow_utime = -1; + sbi->options.iocharset = exfat_default_iocharset; + sbi->options.errors = EXFAT_ERRORS_RO; + + sb->s_fs_info = sbi; + return 0; +} + +static struct dentry *exfat_fs_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data) +{ + return mount_bdev(fs_type, flags, dev_name, data, exfat_fill_super); +} + +static struct file_system_type exfat_fs_type = { + .owner = THIS_MODULE, + .name = "exfat", + .mount = exfat_fs_mount, + .kill_sb = kill_block_super, + .fs_flags = FS_REQUIRES_DEV, +}; + +static void exfat_inode_init_once(void *foo) +{ + struct exfat_inode_info *ei = (struct exfat_inode_info *)foo; + + INIT_HLIST_NODE(&ei->i_hash_fat); + inode_init_once(&ei->vfs_inode); +} + +static int __init init_exfat_fs(void) +{ + int err; + + pr_info("exFAT: file-system version %s\n", EXFAT_VERSION); + + err = exfat_cache_init(); + if (err) + return err; + + exfat_inode_cachep = kmem_cache_create("exfat_inode_cache", + sizeof(struct exfat_inode_info), + 0, SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, + exfat_inode_init_once); + if (!exfat_inode_cachep) { + err = -ENOMEM; + goto shutdown_cache; + } + + err = register_filesystem(&exfat_fs_type); + if (err) + goto destroy_cache; + + return 0; + +destroy_cache: + kmem_cache_destroy(exfat_inode_cachep); +shutdown_cache: + exfat_cache_shutdown(); + return err; +} + +static void __exit exit_exfat_fs(void) +{ + /* + * Make sure all delayed rcu free inodes are flushed before we + * destroy cache. + */ + rcu_barrier(); + kmem_cache_destroy(exfat_inode_cachep); + unregister_filesystem(&exfat_fs_type); + exfat_cache_shutdown(); +} + +module_init(init_exfat_fs); +module_exit(exit_exfat_fs); + +MODULE_ALIAS_FS("exfat"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("exFAT filesystem support"); +MODULE_AUTHOR("Samsung Electronics Co., Ltd."); diff --git a/fs/exfat/version.h b/fs/exfat/version.h new file mode 100644 index 000000000000..fb259ecd2099 --- /dev/null +++ b/fs/exfat/version.h @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#define EXFAT_BASE_VERSION "5.8" +#define EXFAT_EXTRAVERSION "2" +#define EXFAT_VARIANT "arter97" +#define EXFAT_VERSION EXFAT_BASE_VERSION "-" EXFAT_EXTRAVERSION EXFAT_VARIANT diff --git a/fs/exfat/xattr.c b/fs/exfat/xattr.c new file mode 100644 index 000000000000..833bdbd6cea4 --- /dev/null +++ b/fs/exfat/xattr.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * xattr.c: exFAT code for supporting xattr(Extended File Attributes) + */ + +#include "exfat_fs.h" + +#ifdef CONFIG_EXFAT_VIRTUAL_XATTR + +#include +#include +#include +#include + +#ifndef CONFIG_EXFAT_VIRTUAL_XATTR_SELINUX_LABEL +#define CONFIG_EXFAT_VIRTUAL_XATTR_SELINUX_LABEL ("undefined") +#endif + +static const char default_xattr[] = CONFIG_EXFAT_VIRTUAL_XATTR_SELINUX_LABEL; + +static int can_support(const char *name) +{ + if (!name || strcmp(name, "security.selinux")) + return -1; + return 0; +} + +ssize_t exfat_listxattr(struct dentry *dentry, char *list, size_t size) +{ + return 0; +} + +static int __exfat_xattr_check_support(const char *name) +{ + if (can_support(name)) + return -EOPNOTSUPP; + + return 0; +} + +ssize_t __exfat_getxattr(const char *name, void *value, size_t size) +{ + if (can_support(name)) + return -EOPNOTSUPP; + + if ((size > strlen(default_xattr)+1) && value) + strcpy(value, default_xattr); + + return strlen(default_xattr); +} + +static int exfat_xattr_get(const struct xattr_handler *handler, + struct dentry *dentry, struct inode *inode, + const char *name, void *buffer, size_t size) +{ + return __exfat_getxattr(name, buffer, size); +} + +static int exfat_xattr_set(const struct xattr_handler *handler, + struct dentry *dentry, struct inode *inode, + const char *name, const void *value, size_t size, + int flags) +{ + return __exfat_xattr_check_support(name); +} + +static const struct xattr_handler exfat_xattr_handler = { + .prefix = "", /* match anything */ + .get = exfat_xattr_get, + .set = exfat_xattr_set, +}; + +const struct xattr_handler *exfat_xattr_handlers[] = { + &exfat_xattr_handler, + NULL +}; + +#endif /* CONFIG_EXFAT_VIRTUAL_XATTR */ diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index f17715d140b5..aef3f4206540 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c @@ -110,8 +110,8 @@ static int pcol_try_alloc(struct page_collect *pcol) pages = exofs_max_io_pages(&pcol->sbi->layout, pcol->expected_pages); for (; pages; pages >>= 1) { - pcol->pages = kmalloc(pages * sizeof(struct page *), - GFP_KERNEL); + pcol->pages = kmalloc_array(pages, sizeof(struct page *), + GFP_KERNEL); if (likely(pcol->pages)) { pcol->alloc_pages = pages; return 0; diff --git a/fs/ext2/super.c b/fs/ext2/super.c index e3679cc9c0b9..f8fddba7e04b 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -1083,7 +1083,9 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) / EXT2_BLOCKS_PER_GROUP(sb)) + 1; db_count = (sbi->s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) / EXT2_DESC_PER_BLOCK(sb); - sbi->s_group_desc = kmalloc (db_count * sizeof (struct buffer_head *), GFP_KERNEL); + sbi->s_group_desc = kmalloc_array (db_count, + sizeof(struct buffer_head *), + GFP_KERNEL); if (sbi->s_group_desc == NULL) { ext2_msg(sb, KERN_ERR, "error: not enough memory"); goto failed_mount; diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index 6a5cbe0c4d20..c40e08632635 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -69,6 +69,7 @@ int __ext4_check_dir_entry(const char *function, unsigned int line, const char *error_msg = NULL; const int rlen = ext4_rec_len_from_disk(de->rec_len, dir->i_sb->s_blocksize); + const int next_offset = ((char *) de - buf) + rlen; if (unlikely(rlen < EXT4_DIR_REC_LEN(1))) error_msg = "rec_len is smaller than minimal"; @@ -76,13 +77,11 @@ int __ext4_check_dir_entry(const char *function, unsigned int line, error_msg = "rec_len % 4 != 0"; else if (unlikely(rlen < EXT4_DIR_REC_LEN(de->name_len))) error_msg = "rec_len is too small for name_len"; - else if (unlikely(((char *) de - buf) + rlen > size)) + else if (unlikely(next_offset > size)) error_msg = "directory entry overrun"; - else if (unlikely(((char *) de - buf) + rlen > - size - EXT4_DIR_REC_LEN(1) && - ((char *) de - buf) + rlen != size)) { + else if (unlikely(next_offset > size - EXT4_DIR_REC_LEN(1) && + next_offset != size)) error_msg = "directory entry too close to block end"; - } else if (unlikely(le32_to_cpu(de->inode) > le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count))) error_msg = "inode out of bounds"; diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index d487b5bc9478..909878ddbb1f 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -598,7 +598,7 @@ int ext4_ext_precache(struct inode *inode) down_read(&ei->i_data_sem); depth = ext_depth(inode); - path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1), + path = kcalloc(depth + 1, sizeof(struct ext4_ext_path), GFP_NOFS); if (path == NULL) { up_read(&ei->i_data_sem); @@ -906,7 +906,7 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block, } if (!path) { /* account possible depth increase */ - path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 2), + path = kcalloc(depth + 2, sizeof(struct ext4_ext_path), GFP_NOFS); if (unlikely(!path)) return ERR_PTR(-ENOMEM); @@ -1093,7 +1093,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, * We need this to handle errors and free blocks * upon them. */ - ablocks = kzalloc(sizeof(ext4_fsblk_t) * depth, GFP_NOFS); + ablocks = kcalloc(depth, sizeof(ext4_fsblk_t), GFP_NOFS); if (!ablocks) return -ENOMEM; @@ -2963,7 +2963,7 @@ again: path[k].p_block = le16_to_cpu(path[k].p_hdr->eh_entries)+1; } else { - path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1), + path = kcalloc(depth + 1, sizeof(struct ext4_ext_path), GFP_NOFS); if (path == NULL) { ext4_journal_stop(handle); diff --git a/fs/ext4/hash.c b/fs/ext4/hash.c index ed76a6d7a2d8..9adcadeceaa9 100644 --- a/fs/ext4/hash.c +++ b/fs/ext4/hash.c @@ -283,7 +283,7 @@ int ext4fs_dirhash(const struct inode *dir, const char *name, int len, struct qstr qstr = {.name = name, .len = len }; if (len && IS_CASEFOLDED(dir) && um) { - buff = kzalloc(sizeof(char) * PATH_MAX, GFP_KERNEL); + buff = kzalloc(PATH_MAX, GFP_KERNEL); if (!buff) return -ENOMEM; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index dfb890fd445d..1a5bfeabc0cd 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3791,6 +3791,11 @@ static ssize_t ext4_direct_IO_read(struct kiocb *iocb, struct iov_iter *iter) struct inode *inode = mapping->host; size_t count = iov_iter_count(iter); ssize_t ret; + loff_t offset = iocb->ki_pos; + loff_t size = i_size_read(inode); + + if (offset >= size) + return 0; /* * Shared inode_lock is enough for us - it protects against concurrent diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 19af346a6651..2b7534a5a4d2 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -234,12 +234,14 @@ static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned long flexbg_size) goto out2; flex_gd->count = flexbg_size; - flex_gd->groups = kmalloc(sizeof(struct ext4_new_group_data) * - flexbg_size, GFP_NOFS); + flex_gd->groups = kmalloc_array(flexbg_size, + sizeof(struct ext4_new_group_data), + GFP_NOFS); if (flex_gd->groups == NULL) goto out2; - flex_gd->bg_flags = kmalloc(flexbg_size * sizeof(__u16), GFP_NOFS); + flex_gd->bg_flags = kmalloc_array(flexbg_size, sizeof(__u16), + GFP_NOFS); if (flex_gd->bg_flags == NULL) goto out1; @@ -981,7 +983,7 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode, int res, i; int err; - primary = kmalloc(reserved_gdb * sizeof(*primary), GFP_NOFS); + primary = kmalloc_array(reserved_gdb, sizeof(*primary), GFP_NOFS); if (!primary) return -ENOMEM; diff --git a/fs/f2fs/Kconfig b/fs/f2fs/Kconfig index cb3a0e0652c5..3c5c9ef573df 100644 --- a/fs/f2fs/Kconfig +++ b/fs/f2fs/Kconfig @@ -148,3 +148,22 @@ config F2FS_FS_LZORLE default y help Support LZO-RLE compress algorithm, if unsure, say Y. + +config F2FS_REPORT_FAKE_KERNEL_VERSION + bool "Report fake kernel version to fsck.f2fs" + depends on F2FS_FS + help + fsck.f2fs forces a filesystem fix on boot if it detects that the current + kernel version differs from the one saved in the superblock, which results in + fsck taking a long time to run. This option provides a way to report a + constant fake kernel version to fsck to avoid triggering the version check. + + If unsure, say N. + +config F2FS_FAKE_KERNEL_RELEASE + string "Kernel release for fsck.f2fs" + depends on F2FS_REPORT_FAKE_KERNEL_VERSION + +config F2FS_FAKE_KERNEL_VERSION + string "Kernel version for fsck.f2fs" + depends on F2FS_REPORT_FAKE_KERNEL_VERSION diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index bd9d24189c14..1f1dbfb28b0b 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -576,8 +576,9 @@ static int f2fs_compress_pages(struct compress_ctx *cc) max_len = COMPRESS_HEADER_SIZE + cc->clen; cc->nr_cpages = DIV_ROUND_UP(max_len, PAGE_SIZE); - cc->cpages = f2fs_kzalloc(sbi, sizeof(struct page *) * - cc->nr_cpages, GFP_NOFS); + cc->cpages = f2fs_kzalloc(sbi, + array_size(sizeof(struct page *), cc->nr_cpages), + GFP_NOFS); if (!cc->cpages) { ret = -ENOMEM; goto destroy_compress_ctx; @@ -1450,8 +1451,9 @@ struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc) dic->rpages[i] = cc->rpages[i]; dic->nr_rpages = cc->cluster_size; - dic->cpages = f2fs_kzalloc(sbi, sizeof(struct page *) * - dic->nr_cpages, GFP_NOFS); + dic->cpages = f2fs_kzalloc(sbi, + array_size(sizeof(struct page *), dic->nr_cpages), + GFP_NOFS); if (!dic->cpages) goto out_free; diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index e22bdf35b540..c87e6e54cab2 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -3054,9 +3054,8 @@ static int init_blkz_info(struct f2fs_sb_info *sbi, int devi) if (nr_sectors & (bdev_zone_sectors(bdev) - 1)) FDEV(devi).nr_blkz++; - FDEV(devi).blkz_seq = f2fs_kvzalloc(sbi, - BITS_TO_LONGS(FDEV(devi).nr_blkz) - * sizeof(unsigned long), + FDEV(devi).blkz_seq = f2fs_kzalloc(sbi, + array_size(sizeof(unsigned long), BITS_TO_LONGS(FDEV(devi).nr_blkz)), GFP_KERNEL); if (!FDEV(devi).blkz_seq) return -ENOMEM; diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 2649759c478a..a49eef1363d6 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -664,7 +664,7 @@ static int vfat_add_entry(struct inode *dir, const struct qstr *qname, if (len == 0) return -ENOENT; - slots = kmalloc(sizeof(*slots) * MSDOS_SLOTS, GFP_NOFS); + slots = kmalloc_array(MSDOS_SLOTS, sizeof(*slots), GFP_NOFS); if (slots == NULL) return -ENOMEM; diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index bfd6353ef7fa..18a1b9b33f7d 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -66,9 +66,11 @@ static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags) pages = req->inline_pages; page_descs = req->inline_page_descs; } else { - pages = kmalloc(sizeof(struct page *) * npages, flags); - page_descs = kmalloc(sizeof(struct fuse_page_desc) * - npages, flags); + pages = kmalloc_array(npages, sizeof(struct page *), + flags); + page_descs = kmalloc_array(npages, + sizeof(struct fuse_page_desc), + flags); } if (!pages || !page_descs) { @@ -1388,7 +1390,8 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, if (!fud) return -EPERM; - bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); + bufs = kmalloc_array(pipe->buffers, sizeof(struct pipe_buffer), + GFP_KERNEL); if (!bufs) return -ENOMEM; @@ -1983,7 +1986,8 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, pipe_lock(pipe); - bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); + bufs = kmalloc_array(pipe->buffers, sizeof(struct pipe_buffer), + GFP_KERNEL); if (!bufs) { pipe_unlock(pipe); return -ENOMEM; diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 06a0d1947c77..f1e7fb36cf8d 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c @@ -1056,7 +1056,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) /* Change the pointers. Don't bother distinguishing stuffed from non-stuffed. This code is complicated enough already. */ - lp = kmalloc(half_len * sizeof(__be64), GFP_NOFS); + lp = kmalloc_array(half_len, sizeof(__be64), GFP_NOFS); if (!lp) { error = -ENOMEM; goto fail_brelse; @@ -1170,7 +1170,7 @@ static int dir_double_exhash(struct gfs2_inode *dip) if (IS_ERR(hc)) return PTR_ERR(hc); - hc2 = kmalloc(hsize_bytes * 2, GFP_NOFS | __GFP_NOWARN); + hc2 = kmalloc_array(hsize_bytes, 2, GFP_NOFS | __GFP_NOWARN); if (hc2 == NULL) hc2 = __vmalloc(hsize_bytes * 2, GFP_NOFS, PAGE_KERNEL); @@ -1597,7 +1597,7 @@ int gfs2_dir_read(struct inode *inode, struct dir_context *ctx, error = -ENOMEM; /* 96 is max number of dirents which can be stuffed into an inode */ - darr = kmalloc(96 * sizeof(struct gfs2_dirent *), GFP_NOFS); + darr = kmalloc_array(96, sizeof(struct gfs2_dirent *), GFP_NOFS); if (darr) { g.pdent = (const struct gfs2_dirent **)darr; g.offset = 0; diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index aea1ed0aebd0..25932a09aef5 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1307,7 +1307,8 @@ int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs) default: if (num_gh <= 4) break; - pph = kmalloc(num_gh * sizeof(struct gfs2_holder *), GFP_NOFS); + pph = kmalloc_array(num_gh, sizeof(struct gfs2_holder *), + GFP_NOFS); if (!pph) return -ENOMEM; } diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index a833e2e07167..e0c5bae00d8f 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -883,7 +883,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda) gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota), &data_blocks, &ind_blocks); - ghs = kmalloc(num_qd * sizeof(struct gfs2_holder), GFP_NOFS); + ghs = kmalloc_array(num_qd, sizeof(struct gfs2_holder), GFP_NOFS); if (!ghs) return -ENOMEM; diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 7cb0672294df..9c5325c1696d 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -2600,8 +2600,9 @@ void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, unsigned int state) { unsigned int x; - rlist->rl_ghs = kmalloc(rlist->rl_rgrps * sizeof(struct gfs2_holder), - GFP_NOFS | __GFP_NOFAIL); + rlist->rl_ghs = kmalloc_array(rlist->rl_rgrps, + sizeof(struct gfs2_holder), + GFP_NOFS | __GFP_NOFAIL); for (x = 0; x < rlist->rl_rgrps; x++) gfs2_holder_init(rlist->rl_rgd[x]->rd_gl, state, 0, diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index c3f3f1ae4e1b..329b93f1e6a8 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -1086,7 +1086,7 @@ static int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host int error = 0, err; memset(sc, 0, sizeof(struct gfs2_statfs_change_host)); - gha = kmalloc(slots * sizeof(struct gfs2_holder), GFP_KERNEL); + gha = kmalloc_array(slots, sizeof(struct gfs2_holder), GFP_KERNEL); if (!gha) return -ENOMEM; for (x = 0; x < slots; x++) diff --git a/fs/hpfs/dnode.c b/fs/hpfs/dnode.c index 3b834563b1f1..10cd5582844b 100644 --- a/fs/hpfs/dnode.c +++ b/fs/hpfs/dnode.c @@ -33,7 +33,7 @@ int hpfs_add_pos(struct inode *inode, loff_t *pos) if (hpfs_inode->i_rddir_off[i] == pos) return 0; if (!(i&0x0f)) { - if (!(ppos = kmalloc((i+0x11) * sizeof(loff_t*), GFP_NOFS))) { + if (!(ppos = kmalloc_array(i + 0x11, sizeof(loff_t *), GFP_NOFS))) { pr_err("out of memory for position list\n"); return -ENOMEM; } diff --git a/fs/hpfs/map.c b/fs/hpfs/map.c index e0e60b148400..f8834d932db2 100644 --- a/fs/hpfs/map.c +++ b/fs/hpfs/map.c @@ -115,7 +115,7 @@ __le32 *hpfs_load_bitmap_directory(struct super_block *s, secno bmp) int n = (hpfs_sb(s)->sb_fs_size + 0x200000 - 1) >> 21; int i; __le32 *b; - if (!(b = kmalloc(n * 512, GFP_KERNEL))) { + if (!(b = kmalloc_array(n, 512, GFP_KERNEL))) { pr_err("can't allocate memory for bitmap directory\n"); return NULL; } diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c index f9aefcda5854..939b4f629b4b 100644 --- a/fs/jbd2/revoke.c +++ b/fs/jbd2/revoke.c @@ -230,7 +230,7 @@ static struct jbd2_revoke_table_s *jbd2_journal_init_revoke_table(int hash_size) table->hash_size = hash_size; table->hash_shift = shift; table->hash_table = - kmalloc(hash_size * sizeof(struct list_head), GFP_KERNEL); + kmalloc_array(hash_size, sizeof(struct list_head), GFP_KERNEL); if (!table->hash_table) { kmem_cache_free(jbd2_revoke_table_cache, table); table = NULL; diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index 2cfe487708e0..c6821a509481 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c @@ -1208,7 +1208,7 @@ int jffs2_nand_flash_setup(struct jffs2_sb_info *c) if (!c->wbuf) return -ENOMEM; - c->oobbuf = kmalloc(NR_OOB_SCAN_PAGES * c->oobavail, GFP_KERNEL); + c->oobbuf = kmalloc_array(NR_OOB_SCAN_PAGES, c->oobavail, GFP_KERNEL); if (!c->oobbuf) { kfree(c->wbuf); return -ENOMEM; diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index 2d514c7affc2..49263e220dbc 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -1641,7 +1641,7 @@ s64 dbDiscardAG(struct inode *ip, int agno, s64 minlen) max_ranges = nblocks; do_div(max_ranges, minlen); range_cnt = min_t(u64, max_ranges + 1, 32 * 1024); - totrim = kmalloc(sizeof(struct range2trim) * range_cnt, GFP_NOFS); + totrim = kmalloc_array(range_cnt, sizeof(struct range2trim), GFP_NOFS); if (totrim == NULL) { jfs_error(bmp->db_ipbmap->i_sb, "no memory for trim array\n"); IWRITE_UNLOCK(ipbmap); diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c index de2bcb36e079..52bae3f5c914 100644 --- a/fs/jfs/jfs_dtree.c +++ b/fs/jfs/jfs_dtree.c @@ -594,7 +594,8 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data, struct component_name ciKey; struct super_block *sb = ip->i_sb; - ciKey.name = kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t), GFP_NOFS); + ciKey.name = kmalloc_array(JFS_NAME_MAX + 1, sizeof(wchar_t), + GFP_NOFS); if (!ciKey.name) { rc = -ENOMEM; goto dtSearch_Exit2; @@ -957,7 +958,7 @@ static int dtSplitUp(tid_t tid, smp = split->mp; sp = DT_PAGE(ip, smp); - key.name = kmalloc((JFS_NAME_MAX + 2) * sizeof(wchar_t), GFP_NOFS); + key.name = kmalloc_array(JFS_NAME_MAX + 2, sizeof(wchar_t), GFP_NOFS); if (!key.name) { DT_PUTPAGE(smp); rc = -ENOMEM; @@ -3779,12 +3780,12 @@ static int ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp, struct component_name lkey; struct component_name rkey; - lkey.name = kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t), + lkey.name = kmalloc_array(JFS_NAME_MAX + 1, sizeof(wchar_t), GFP_KERNEL); if (lkey.name == NULL) return -ENOMEM; - rkey.name = kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t), + rkey.name = kmalloc_array(JFS_NAME_MAX + 1, sizeof(wchar_t), GFP_KERNEL); if (rkey.name == NULL) { kfree(lkey.name); diff --git a/fs/jfs/jfs_unicode.c b/fs/jfs/jfs_unicode.c index c7de6f5bbefc..0148e2e4d97a 100644 --- a/fs/jfs/jfs_unicode.c +++ b/fs/jfs/jfs_unicode.c @@ -121,7 +121,7 @@ int get_UCSname(struct component_name * uniName, struct dentry *dentry) return -ENAMETOOLONG; uniName->name = - kmalloc((length + 1) * sizeof(wchar_t), GFP_NOFS); + kmalloc_array(length + 1, sizeof(wchar_t), GFP_NOFS); if (uniName->name == NULL) return -ENOMEM; diff --git a/fs/mbcache.c b/fs/mbcache.c index bf41e2e72c18..91dfe1abfccd 100644 --- a/fs/mbcache.c +++ b/fs/mbcache.c @@ -353,8 +353,9 @@ struct mb_cache *mb_cache_create(int bucket_bits) cache->c_max_entries = bucket_count << 4; INIT_LIST_HEAD(&cache->c_list); spin_lock_init(&cache->c_list_lock); - cache->c_hash = kmalloc(bucket_count * sizeof(struct hlist_bl_head), - GFP_KERNEL); + cache->c_hash = kmalloc_array(bucket_count, + sizeof(struct hlist_bl_head), + GFP_KERNEL); if (!cache->c_hash) { kfree(cache); goto err_out; diff --git a/fs/namei.c b/fs/namei.c index 6c933d1cc941..43a3b93e1781 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -572,12 +572,12 @@ static int __nd_alloc_stack(struct nameidata *nd) struct saved *p; if (nd->flags & LOOKUP_RCU) { - p= kmalloc(MAXSYMLINKS * sizeof(struct saved), + p= kmalloc_array(MAXSYMLINKS, sizeof(struct saved), GFP_ATOMIC); if (unlikely(!p)) return -ECHILD; } else { - p= kmalloc(MAXSYMLINKS * sizeof(struct saved), + p= kmalloc_array(MAXSYMLINKS, sizeof(struct saved), GFP_KERNEL); if (unlikely(!p)) return -ENOMEM; diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index 74f15498c9bf..69be69d93f76 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -461,7 +461,7 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh, fh_count = be32_to_cpup(p); fls->mirror_array[i]->fh_versions = - kzalloc(fh_count * sizeof(struct nfs_fh), + kcalloc(fh_count, sizeof(struct nfs_fh), gfp_flags); if (fls->mirror_array[i]->fh_versions == NULL) { rc = -ENOMEM; diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c index 2464b9b80698..8da239b6cc16 100644 --- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c +++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c @@ -99,7 +99,8 @@ nfs4_ff_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev, version_count = be32_to_cpup(p); dprintk("%s: version count %d\n", __func__, version_count); - ds_versions = kzalloc(version_count * sizeof(struct nfs4_ff_ds_version), + ds_versions = kcalloc(version_count, + sizeof(struct nfs4_ff_ds_version), gfp_flags); if (!ds_versions) goto out_scratch; diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 46b48dbbdd32..d299f91ac375 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -404,8 +404,9 @@ fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc) if (fsloc->locations_count == 0) return 0; - fsloc->locations = kzalloc(fsloc->locations_count - * sizeof(struct nfsd4_fs_location), GFP_KERNEL); + fsloc->locations = kcalloc(fsloc->locations_count, + sizeof(struct nfsd4_fs_location), + GFP_KERNEL); if (!fsloc->locations) return -ENOMEM; for (i=0; i < fsloc->locations_count; i++) { diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index dc9586feab31..5188f9f70c78 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -510,8 +510,9 @@ nfs4_legacy_state_init(struct net *net) struct nfsd_net *nn = net_generic(net, nfsd_net_id); int i; - nn->reclaim_str_hashtbl = kmalloc(sizeof(struct list_head) * - CLIENT_HASH_SIZE, GFP_KERNEL); + nn->reclaim_str_hashtbl = kmalloc_array(CLIENT_HASH_SIZE, + sizeof(struct list_head), + GFP_KERNEL); if (!nn->reclaim_str_hashtbl) return -ENOMEM; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index d5d1c70bb927..1d6b9feeb8a6 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1797,8 +1797,9 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name) clp->cl_name.data = kmemdup(name.data, name.len, GFP_KERNEL); if (clp->cl_name.data == NULL) goto err_no_name; - clp->cl_ownerstr_hashtbl = kmalloc(sizeof(struct list_head) * - OWNER_HASH_SIZE, GFP_KERNEL); + clp->cl_ownerstr_hashtbl = kmalloc_array(OWNER_HASH_SIZE, + sizeof(struct list_head), + GFP_KERNEL); if (!clp->cl_ownerstr_hashtbl) goto err_no_hashtbl; for (i = 0; i < OWNER_HASH_SIZE; i++) @@ -7098,16 +7099,19 @@ static int nfs4_state_create_net(struct net *net) struct nfsd_net *nn = net_generic(net, nfsd_net_id); int i; - nn->conf_id_hashtbl = kmalloc(sizeof(struct list_head) * - CLIENT_HASH_SIZE, GFP_KERNEL); + nn->conf_id_hashtbl = kmalloc_array(CLIENT_HASH_SIZE, + sizeof(struct list_head), + GFP_KERNEL); if (!nn->conf_id_hashtbl) goto err; - nn->unconf_id_hashtbl = kmalloc(sizeof(struct list_head) * - CLIENT_HASH_SIZE, GFP_KERNEL); + nn->unconf_id_hashtbl = kmalloc_array(CLIENT_HASH_SIZE, + sizeof(struct list_head), + GFP_KERNEL); if (!nn->unconf_id_hashtbl) goto err_unconf_id; - nn->sessionid_hashtbl = kmalloc(sizeof(struct list_head) * - SESSION_HASH_SIZE, GFP_KERNEL); + nn->sessionid_hashtbl = kmalloc_array(SESSION_HASH_SIZE, + sizeof(struct list_head), + GFP_KERNEL); if (!nn->sessionid_hashtbl) goto err_sessionid; diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index 334f2ad60704..6a9e09b64fb7 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c @@ -177,7 +177,7 @@ int nfsd_reply_cache_init(void) drc_hashtbl = kcalloc(hashsize, sizeof(*drc_hashtbl), GFP_KERNEL); if (!drc_hashtbl) { - drc_hashtbl = vzalloc(hashsize * sizeof(*drc_hashtbl)); + drc_hashtbl = vzalloc(array_size(hashsize, sizeof(*drc_hashtbl))); if (!drc_hashtbl) goto out_nomem; } diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c index f8eb04387ca4..fbd0090d7d0c 100644 --- a/fs/ntfs/compress.c +++ b/fs/ntfs/compress.c @@ -527,7 +527,7 @@ int ntfs_read_compressed_block(struct page *page) BUG_ON(ni->type != AT_DATA); BUG_ON(ni->name_len); - pages = kmalloc(nr_pages * sizeof(struct page *), GFP_NOFS); + pages = kmalloc_array(nr_pages, sizeof(struct page *), GFP_NOFS); /* Allocate memory to store the buffer heads we need. */ bhs_size = cb_size / block_size * sizeof(struct buffer_head *); diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 8d779227370a..23758118c532 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c @@ -1078,7 +1078,7 @@ int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, o2net_set_nst_sock_container(&nst, sc); veclen = caller_veclen + 1; - vec = kmalloc(sizeof(struct kvec) * veclen, GFP_ATOMIC); + vec = kmalloc_array(veclen, sizeof(struct kvec), GFP_ATOMIC); if (vec == NULL) { mlog(0, "failed to %zu element kvec!\n", veclen); ret = -ENOMEM; diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 6099a8034b17..32968549712b 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c @@ -86,7 +86,7 @@ static void dlm_free_pagevec(void **vec, int pages) static void **dlm_alloc_pagevec(int pages) { - void **vec = kmalloc(pages * sizeof(void *), GFP_KERNEL); + void **vec = kmalloc_array(pages, sizeof(void *), GFP_KERNEL); int i; if (!vec) diff --git a/fs/ocfs2/filecheck.c b/fs/ocfs2/filecheck.c index 2cabbcf2f28e..7a56c13f2fc6 100644 --- a/fs/ocfs2/filecheck.c +++ b/fs/ocfs2/filecheck.c @@ -222,7 +222,7 @@ int ocfs2_filecheck_create_sysfs(struct super_block *sb) if (!ocfs2_kset) return -ENOMEM; - attrs = kmalloc(sizeof(struct attribute *) * 4, GFP_NOFS); + attrs = kmalloc_array(4, sizeof(struct attribute *), GFP_NOFS); if (!attrs) { ret = -ENOMEM; goto error; diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 39bb80fb2934..405dbf0ab96e 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -1390,7 +1390,7 @@ static int __ocfs2_recovery_thread(void *arg) goto bail; } - rm_quota = kzalloc(osb->max_slots * sizeof(int), GFP_NOFS); + rm_quota = kcalloc(osb->max_slots, sizeof(int), GFP_NOFS); if (!rm_quota) { status = -ENOMEM; goto bail; diff --git a/fs/ocfs2/sysfile.c b/fs/ocfs2/sysfile.c index af155c183123..bef0932590ce 100644 --- a/fs/ocfs2/sysfile.c +++ b/fs/ocfs2/sysfile.c @@ -69,9 +69,7 @@ static struct inode **get_local_system_inode(struct ocfs2_super *osb, spin_unlock(&osb->osb_lock); if (unlikely(!local_system_inodes)) { - local_system_inodes = kzalloc(sizeof(struct inode *) * - NUM_LOCAL_SYSTEM_INODES * - osb->max_slots, + local_system_inodes = kzalloc(array3_size(sizeof(struct inode *), NUM_LOCAL_SYSTEM_INODES, osb->max_slots), GFP_NOFS); if (!local_system_inodes) { mlog_errno(-ENOMEM); diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index 6071196a7b63..098f6f0a2c2a 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -489,7 +489,7 @@ int ovl_get_index_name(struct dentry *origin, struct qstr *name) return PTR_ERR(fh); err = -ENOMEM; - n = kzalloc(fh->len * 2, GFP_KERNEL); + n = kcalloc(fh->len, 2, GFP_KERNEL); if (n) { s = bin2hex(n, fh, fh->len); *name = (struct qstr) QSTR_INIT(n, s - n); diff --git a/fs/proc/base.c b/fs/proc/base.c index 769ea7f7a9a6..9f2d19fbaa7e 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -376,7 +376,8 @@ static int proc_pid_stack(struct seq_file *m, struct pid_namespace *ns, if (!file_ns_capable(m->file, &init_user_ns, CAP_SYS_ADMIN)) return -EACCES; - entries = kmalloc(MAX_STACK_TRACE_DEPTH * sizeof(*entries), GFP_KERNEL); + entries = kmalloc_array(MAX_STACK_TRACE_DEPTH, sizeof(*entries), + GFP_KERNEL); if (!entries) return -ENOMEM; @@ -1027,7 +1028,7 @@ static int __set_oom_adj(struct file *file, int oom_adj, bool legacy) return -ESRCH; mutex_lock(&oom_adj_mutex); - if (legacy) { + if (unlikely(legacy)) { if (oom_adj < task->signal->oom_score_adj && !capable(CAP_SYS_RESOURCE)) { err = -EACCES; @@ -1066,7 +1067,7 @@ static int __set_oom_adj(struct file *file, int oom_adj, bool legacy) } task->signal->oom_score_adj = oom_adj; - if (!legacy && has_capability_noaudit(current, CAP_SYS_RESOURCE)) + if (likely(!legacy) && has_capability_noaudit(current, CAP_SYS_RESOURCE)) task->signal->oom_score_adj_min = (short)oom_adj; trace_oom_score_adj_update(task); @@ -1085,7 +1086,7 @@ static int __set_oom_adj(struct file *file, int oom_adj, bool legacy) task_lock(p); if (!p->vfork_done && process_shares_mm(p, mm)) { p->signal->oom_score_adj = oom_adj; - if (!legacy && has_capability_noaudit(current, CAP_SYS_RESOURCE)) + if (likely(!legacy) && has_capability_noaudit(current, CAP_SYS_RESOURCE)) p->signal->oom_score_adj_min = (short)oom_adj; } task_unlock(p); @@ -1638,6 +1639,58 @@ static const struct file_operations proc_pid_sched_group_id_operations = { .release = single_release, }; +static int sched_low_latency_show(struct seq_file *m, void *v) +{ + struct inode *inode = m->private; + struct task_struct *p; + bool low_latency; + + p = get_proc_task(inode); + if (!p) + return -ESRCH; + + low_latency = p->low_latency; + seq_printf(m, "%d\n", low_latency); + + put_task_struct(p); + + return 0; +} + +static ssize_t +sched_low_latency_write(struct file *file, const char __user *buf, + size_t count, loff_t *offset) +{ + struct task_struct *p = get_proc_task(file_inode(file)); + bool low_latency; + int err; + + if (!p) + return -ESRCH; + + err = kstrtobool_from_user(buf, count, &low_latency); + if (err) + goto out; + + p->low_latency = low_latency; +out: + put_task_struct(p); + return err < 0 ? err : count; +} + +static int sched_low_latency_open(struct inode *inode, struct file *filp) +{ + return single_open(filp, sched_low_latency_show, inode); +} + +static const struct file_operations proc_pid_sched_low_latency_operations = { + .open = sched_low_latency_open, + .read = seq_read, + .write = sched_low_latency_write, + .llseek = seq_lseek, + .release = single_release, +}; + #endif /* CONFIG_SCHED_WALT */ #ifdef CONFIG_SCHED_AUTOGROUP @@ -3037,7 +3090,7 @@ static ssize_t proc_sched_task_boost_write(struct file *file, err = kstrtoint(strstrip(buffer), 0, &sched_boost); if (err) goto out; - if (sched_boost < 0 || sched_boost > 2) { + if (sched_boost < TASK_BOOST_NONE || sched_boost >= TASK_BOOST_END) { err = -EINVAL; goto out; } @@ -3293,6 +3346,7 @@ static const struct pid_entry tgid_base_stuff[] = { REG("sched_group_id", 00666, proc_pid_sched_group_id_operations), REG("sched_boost", 0666, proc_task_boost_enabled_operations), REG("sched_boost_period_ms", 0666, proc_task_boost_period_operations), + REG("sched_low_latency", 00666, proc_pid_sched_low_latency_operations), #endif #ifdef CONFIG_SCHED_DEBUG REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 2d783e1a827f..370b9b04edcc 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -1420,7 +1420,7 @@ static int register_leaf_sysctl_tables(const char *path, char *pos, /* If there are mixed files and directories we need a new table */ if (nr_dirs && nr_files) { struct ctl_table *new; - files = kzalloc(sizeof(struct ctl_table) * (nr_files + 1), + files = kcalloc(nr_files + 1, sizeof(struct ctl_table), GFP_KERNEL); if (!files) goto out; diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index b3c5f6383dc3..b73693c522f4 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -1572,7 +1572,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, pm.show_pfn = file_ns_capable(file, &init_user_ns, CAP_SYS_ADMIN); pm.len = (PAGEMAP_WALK_SIZE >> PAGE_SHIFT); - pm.buffer = kmalloc(pm.len * PM_ENTRY_BYTES, GFP_KERNEL); + pm.buffer = kmalloc_array(pm.len, PM_ENTRY_BYTES, GFP_KERNEL); ret = -ENOMEM; if (!pm.buffer) goto out_mm; diff --git a/fs/read_write.c b/fs/read_write.c index 0da6e4f19d7f..635f0d7ced85 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -777,7 +777,7 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, goto out; } if (nr_segs > fast_segs) { - iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL); + iov = kmalloc_array(nr_segs, sizeof(struct iovec), GFP_KERNEL); if (iov == NULL) { ret = -ENOMEM; goto out; @@ -848,7 +848,7 @@ ssize_t compat_rw_copy_check_uvector(int type, goto out; if (nr_segs > fast_segs) { ret = -ENOMEM; - iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL); + iov = kmalloc_array(nr_segs, sizeof(struct iovec), GFP_KERNEL); if (iov == NULL) goto out; } diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index edc8ef78b63f..bf708ac287b4 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c @@ -1456,7 +1456,7 @@ int reiserfs_init_bitmap_cache(struct super_block *sb) struct reiserfs_bitmap_info *bitmap; unsigned int bmap_nr = reiserfs_bmap_count(sb); - bitmap = vmalloc(sizeof(*bitmap) * bmap_nr); + bitmap = vmalloc(array_size(bmap_nr, sizeof(*bitmap))); if (bitmap == NULL) return -ENOMEM; diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 683496322aa8..023cfd699eb3 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1044,7 +1044,8 @@ research: if (blocks_needed == 1) { un = &unf_single; } else { - un = kzalloc(min(blocks_needed, max_to_insert) * UNFM_P_SIZE, GFP_NOFS); + un = kcalloc(min(blocks_needed, max_to_insert), + UNFM_P_SIZE, GFP_NOFS); if (!un) { un = &unf_single; blocks_needed = 1; diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 2be907231375..19dff5c26d3d 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -350,7 +350,7 @@ static struct reiserfs_journal_cnode *allocate_cnodes(int num_cnodes) if (num_cnodes <= 0) { return NULL; } - head = vzalloc(num_cnodes * sizeof(struct reiserfs_journal_cnode)); + head = vzalloc(array_size(num_cnodes, sizeof(struct reiserfs_journal_cnode))); if (!head) { return NULL; } @@ -2192,10 +2192,12 @@ static int journal_read_transaction(struct super_block *sb, * now we know we've got a good transaction, and it was * inside the valid time ranges */ - log_blocks = kmalloc(get_desc_trans_len(desc) * - sizeof(struct buffer_head *), GFP_NOFS); - real_blocks = kmalloc(get_desc_trans_len(desc) * - sizeof(struct buffer_head *), GFP_NOFS); + log_blocks = kmalloc_array(get_desc_trans_len(desc), + sizeof(struct buffer_head *), + GFP_NOFS); + real_blocks = kmalloc_array(get_desc_trans_len(desc), + sizeof(struct buffer_head *), + GFP_NOFS); if (!log_blocks || !real_blocks) { brelse(c_bh); brelse(d_bh); diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c index 6052d323bc9a..38bac15d7be8 100644 --- a/fs/reiserfs/resize.c +++ b/fs/reiserfs/resize.c @@ -120,7 +120,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) * array of bitmap block pointers */ bitmap = - vzalloc(sizeof(struct reiserfs_bitmap_info) * bmap_nr_new); + vzalloc(array_size(bmap_nr_new, sizeof(struct reiserfs_bitmap_info))); if (!bitmap) { /* * Journal bitmaps are still supersized, but the diff --git a/fs/select.c b/fs/select.c index d027addc9b31..664c3fd499ca 100644 --- a/fs/select.c +++ b/fs/select.c @@ -1224,7 +1224,7 @@ static int compat_core_sys_select(int n, compat_ulong_t __user *inp, size = FDS_BYTES(n); bits = stack_fds; if (size > sizeof(stack_fds) / 6) { - bits = kmalloc(6 * size, GFP_KERNEL); + bits = kmalloc_array(6, size, GFP_KERNEL); ret = -ENOMEM; if (!bits) goto out_nofds; diff --git a/fs/splice.c b/fs/splice.c index c84ac7e97e21..6e9ef6fecba8 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -259,8 +259,9 @@ int splice_grow_spd(const struct pipe_inode_info *pipe, struct splice_pipe_desc if (buffers <= PIPE_DEF_BUFFERS) return 0; - spd->pages = kmalloc(buffers * sizeof(struct page *), GFP_KERNEL); - spd->partial = kmalloc(buffers * sizeof(struct partial_page), GFP_KERNEL); + spd->pages = kmalloc_array(buffers, sizeof(struct page *), GFP_KERNEL); + spd->partial = kmalloc_array(buffers, sizeof(struct partial_page), + GFP_KERNEL); if (spd->pages && spd->partial) return 0; @@ -395,7 +396,7 @@ static ssize_t default_file_splice_read(struct file *in, loff_t *ppos, vec = __vec; if (nr_pages > PIPE_DEF_BUFFERS) { - vec = kmalloc(nr_pages * sizeof(struct kvec), GFP_KERNEL); + vec = kmalloc_array(nr_pages, sizeof(struct kvec), GFP_KERNEL); if (unlikely(!vec)) { res = -ENOMEM; goto out; diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index 69051f7a9606..027363eb6870 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c @@ -1291,7 +1291,7 @@ static int truncate_data_node(const struct ubifs_info *c, const struct inode *in int err, dlen, compr_type, out_len, old_dlen; out_len = le32_to_cpu(dn->size); - buf = kmalloc(out_len * WORST_COMPR_FACTOR, GFP_NOFS); + buf = kmalloc_array(WORST_COMPR_FACTOR, out_len, GFP_NOFS); if (!buf) return -ENOMEM; diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c index 9a517109da0f..b229f699ae01 100644 --- a/fs/ubifs/lpt.c +++ b/fs/ubifs/lpt.c @@ -628,11 +628,11 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, /* Needed by 'ubifs_pack_lsave()' */ c->main_first = c->leb_cnt - *main_lebs; - lsave = kmalloc(sizeof(int) * c->lsave_cnt, GFP_KERNEL); + lsave = kmalloc_array(c->lsave_cnt, sizeof(int), GFP_KERNEL); pnode = kzalloc(sizeof(struct ubifs_pnode), GFP_KERNEL); nnode = kzalloc(sizeof(struct ubifs_nnode), GFP_KERNEL); buf = vmalloc(c->leb_size); - ltab = vmalloc(sizeof(struct ubifs_lpt_lprops) * c->lpt_lebs); + ltab = vmalloc(array_size(sizeof(struct ubifs_lpt_lprops), c->lpt_lebs)); if (!pnode || !nnode || !buf || !ltab || !lsave) { err = -ENOMEM; goto out; @@ -1626,7 +1626,7 @@ static int lpt_init_rd(struct ubifs_info *c) { int err, i; - c->ltab = vmalloc(sizeof(struct ubifs_lpt_lprops) * c->lpt_lebs); + c->ltab = vmalloc(array_size(sizeof(struct ubifs_lpt_lprops), c->lpt_lebs)); if (!c->ltab) return -ENOMEM; @@ -1636,15 +1636,17 @@ static int lpt_init_rd(struct ubifs_info *c) return -ENOMEM; for (i = 0; i < LPROPS_HEAP_CNT; i++) { - c->lpt_heap[i].arr = kmalloc(sizeof(void *) * LPT_HEAP_SZ, - GFP_KERNEL); + c->lpt_heap[i].arr = kmalloc_array(LPT_HEAP_SZ, + sizeof(void *), + GFP_KERNEL); if (!c->lpt_heap[i].arr) return -ENOMEM; c->lpt_heap[i].cnt = 0; c->lpt_heap[i].max_cnt = LPT_HEAP_SZ; } - c->dirty_idx.arr = kmalloc(sizeof(void *) * LPT_HEAP_SZ, GFP_KERNEL); + c->dirty_idx.arr = kmalloc_array(LPT_HEAP_SZ, sizeof(void *), + GFP_KERNEL); if (!c->dirty_idx.arr) return -ENOMEM; c->dirty_idx.cnt = 0; @@ -1688,7 +1690,7 @@ static int lpt_init_wr(struct ubifs_info *c) { int err, i; - c->ltab_cmt = vmalloc(sizeof(struct ubifs_lpt_lprops) * c->lpt_lebs); + c->ltab_cmt = vmalloc(array_size(sizeof(struct ubifs_lpt_lprops), c->lpt_lebs)); if (!c->ltab_cmt) return -ENOMEM; @@ -1697,7 +1699,7 @@ static int lpt_init_wr(struct ubifs_info *c) return -ENOMEM; if (c->big_lpt) { - c->lsave = kmalloc(sizeof(int) * c->lsave_cnt, GFP_NOFS); + c->lsave = kmalloc_array(c->lsave_cnt, sizeof(int), GFP_NOFS); if (!c->lsave) return -ENOMEM; err = read_lsave(c); @@ -1939,8 +1941,8 @@ int ubifs_lpt_scan_nolock(struct ubifs_info *c, int start_lnum, int end_lnum, return err; } - path = kmalloc(sizeof(struct lpt_scan_node) * (c->lpt_hght + 1), - GFP_NOFS); + path = kmalloc_array(c->lpt_hght + 1, sizeof(struct lpt_scan_node), + GFP_NOFS); if (!path) return -ENOMEM; diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 224ca552edb9..0bc04215eacf 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -1198,7 +1198,8 @@ static int mount_ubifs(struct ubifs_info *c) * never exceed 64. */ err = -ENOMEM; - c->bottom_up_buf = kmalloc(BOTTOM_UP_HEIGHT * sizeof(int), GFP_KERNEL); + c->bottom_up_buf = kmalloc_array(BOTTOM_UP_HEIGHT, sizeof(int), + GFP_KERNEL); if (!c->bottom_up_buf) goto out_free; diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index c7828db206bc..7be4d1eb37f2 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c @@ -1104,8 +1104,9 @@ static struct ubifs_znode *dirty_cow_bottom_up(struct ubifs_info *c, ubifs_assert(znode); if (c->zroot.znode->level > BOTTOM_UP_HEIGHT) { kfree(c->bottom_up_buf); - c->bottom_up_buf = kmalloc(c->zroot.znode->level * sizeof(int), - GFP_NOFS); + c->bottom_up_buf = kmalloc_array(c->zroot.znode->level, + sizeof(int), + GFP_NOFS); if (!c->bottom_up_buf) return ERR_PTR(-ENOMEM); path = c->bottom_up_buf; diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c index aa31f60220ef..a9df94ad46a3 100644 --- a/fs/ubifs/tnc_commit.c +++ b/fs/ubifs/tnc_commit.c @@ -366,7 +366,8 @@ static int layout_in_gaps(struct ubifs_info *c, int cnt) dbg_gc("%d znodes to write", cnt); - c->gap_lebs = kmalloc(sizeof(int) * (c->lst.idx_lebs + 1), GFP_NOFS); + c->gap_lebs = kmalloc_array(c->lst.idx_lebs + 1, sizeof(int), + GFP_NOFS); if (!c->gap_lebs) return -ENOMEM; @@ -674,7 +675,7 @@ static int alloc_idx_lebs(struct ubifs_info *c, int cnt) dbg_cmt("need about %d empty LEBS for TNC commit", leb_cnt); if (!leb_cnt) return 0; - c->ilebs = kmalloc(leb_cnt * sizeof(int), GFP_NOFS); + c->ilebs = kmalloc_array(leb_cnt, sizeof(int), GFP_NOFS); if (!c->ilebs) return -ENOMEM; for (i = 0; i < leb_cnt; i++) { diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 6440003f8ddc..9837c67dd032 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -540,7 +540,7 @@ static int ufs_read_cylinder_structures(struct super_block *sb) * Read cylinder group (we read only first fragment from block * at this time) and prepare internal data structures for cg caching. */ - if (!(sbi->s_ucg = kmalloc (sizeof(struct buffer_head *) * uspi->s_ncg, GFP_NOFS))) + if (!(sbi->s_ucg = kmalloc_array (uspi->s_ncg, sizeof(struct buffer_head *), GFP_NOFS))) goto failed; for (i = 0; i < uspi->s_ncg; i++) sbi->s_ucg[i] = NULL; diff --git a/fs/xfs/kmem.h b/fs/xfs/kmem.h index 4d85992d75b2..7509019ae922 100644 --- a/fs/xfs/kmem.h +++ b/fs/xfs/kmem.h @@ -104,7 +104,7 @@ kmem_zone_init(int size, char *zone_name) } static inline kmem_zone_t * -kmem_zone_init_flags(int size, char *zone_name, unsigned long flags, +kmem_zone_init_flags(int size, char *zone_name, slab_flags_t flags, void (*construct)(void *)) { return kmem_cache_create(zone_name, size, 0, flags, construct); diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 84245d210182..2b07dadc5916 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -761,12 +761,16 @@ xfs_bmap_extents_to_btree( *logflagsp = 0; if ((error = xfs_alloc_vextent(&args))) { xfs_iroot_realloc(ip, -1, whichfork); + ASSERT(ifp->if_broot == NULL); + XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); return error; } if (WARN_ON_ONCE(args.fsbno == NULLFSBLOCK)) { xfs_iroot_realloc(ip, -1, whichfork); + ASSERT(ifp->if_broot == NULL); + XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); return -ENOSPC; } diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 360e32220f93..0c0f70e6c7d9 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -2684,7 +2684,6 @@ xlog_state_do_callback( int funcdidcallbacks; /* flag: function did callbacks */ int repeats; /* for issuing console warnings if * looping too many times */ - int wake = 0; spin_lock(&log->l_icloglock); first_iclog = iclog = log->l_iclog; @@ -2886,11 +2885,9 @@ xlog_state_do_callback( #endif if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR)) - wake = 1; - spin_unlock(&log->l_icloglock); - - if (wake) wake_up_all(&log->l_flush_wait); + + spin_unlock(&log->l_icloglock); } @@ -4052,7 +4049,9 @@ xfs_log_force_umount( * item committed callback functions will do this again under lock to * avoid races. */ + spin_lock(&log->l_cilp->xc_push_lock); wake_up_all(&log->l_cilp->xc_commit_wait); + spin_unlock(&log->l_cilp->xc_push_lock); xlog_state_do_callback(log, XFS_LI_ABORTED, NULL); #ifdef XFSERRORDEBUG diff --git a/gen_headers_arm.bp b/gen_headers_arm.bp index d56ace0fe65a..e7035cc44ea7 100644 --- a/gen_headers_arm.bp +++ b/gen_headers_arm.bp @@ -927,6 +927,7 @@ gen_headers_out_arm = [ "linux/usb/g_printer.h", "linux/usb/gadgetfs.h", "linux/usb/midi.h", + "linux/usb/raw_gadget.h", "linux/usb/tmc.h", "linux/usb/usb_ctrl_qti.h", "linux/usb/video.h", diff --git a/gen_headers_arm64.bp b/gen_headers_arm64.bp index c2beed537f2f..f40413af7833 100644 --- a/gen_headers_arm64.bp +++ b/gen_headers_arm64.bp @@ -922,6 +922,7 @@ gen_headers_out_arm64 = [ "linux/usb/g_printer.h", "linux/usb/gadgetfs.h", "linux/usb/midi.h", + "linux/usb/raw_gadget.h", "linux/usb/tmc.h", "linux/usb/usb_ctrl_qti.h", "linux/usb/video.h", diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 3972a2a90268..e3c3900c74d5 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -253,7 +253,8 @@ #define PAGE_ALIGNED_DATA(page_align) \ . = ALIGN(page_align); \ - *(.data..page_aligned) + *(.data..page_aligned) \ + . = ALIGN(page_align); #define READ_MOSTLY_DATA(align) \ . = ALIGN(align); \ @@ -623,7 +624,9 @@ . = ALIGN(bss_align); \ .bss : AT(ADDR(.bss) - LOAD_OFFSET) { \ BSS_FIRST_SECTIONS \ + . = ALIGN(PAGE_SIZE); \ *(.bss..page_aligned) \ + . = ALIGN(PAGE_SIZE); \ *(.dynbss) \ *(BSS_MAIN) \ *(COMMON) \ diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index 611fe13446e7..4e7a46907b6d 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -139,7 +139,7 @@ extern int prepare_bprm_creds(struct linux_binprm *bprm); extern void install_exec_creds(struct linux_binprm *bprm); extern void set_binfmt(struct linux_binfmt *new); extern ssize_t read_code(struct file *, unsigned long, loff_t, size_t); -extern bool is_zygote_pid(pid_t pid); +extern bool task_is_zygote(struct task_struct *p); extern int do_execve(struct filename *, const char __user * const __user *, @@ -149,7 +149,6 @@ extern int do_execveat(int, struct filename *, const char __user * const __user *, int); -#ifndef CONFIG_CPU_BOOST static inline bool task_is_booster(struct task_struct *tsk) { char comm[sizeof(tsk->comm)]; @@ -164,5 +163,5 @@ static inline bool task_is_booster(struct task_struct *tsk) !strcmp(comm, "iop@") || !strcmp(comm, "init.qcom.post_"); } -#endif /* CONFIG_CPU_BOOST=n */ + #endif /* _LINUX_BINFMTS_H */ diff --git a/include/linux/cpu_input_boost.h b/include/linux/cpu_input_boost.h index a988039ffd7d..3c0860cc3c9b 100644 --- a/include/linux/cpu_input_boost.h +++ b/include/linux/cpu_input_boost.h @@ -6,12 +6,8 @@ #define _CPU_INPUT_BOOST_H_ #ifdef CONFIG_CPU_INPUT_BOOST -void cpu_input_boost_kick(void); void cpu_input_boost_kick_max(unsigned int duration_ms); #else -static inline void cpu_input_boost_kick(void) -{ -} static inline void cpu_input_boost_kick_max(unsigned int duration_ms) { } diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 63fbc5f2adfa..c1bd9854ed30 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -69,7 +69,6 @@ enum cpuhp_state { CPUHP_SLAB_PREPARE, CPUHP_MD_RAID5_PREPARE, CPUHP_RCUTREE_PREP, - CPUHP_CPUDEV_PM_PREPARE, CPUHP_HYP_CORE_CTL_ISOLATION_DEAD, CPUHP_CORE_CTL_ISOLATION_DEAD, CPUHP_CPUIDLE_COUPLED_PREPARE, diff --git a/include/linux/decompress/unzstd.h b/include/linux/decompress/unzstd.h new file mode 100644 index 000000000000..56d539ae880f --- /dev/null +++ b/include/linux/decompress/unzstd.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DECOMPRESS_UNZSTD_H +#define LINUX_DECOMPRESS_UNZSTD_H + +int unzstd(unsigned char *inbuf, long len, + long (*fill)(void*, unsigned long), + long (*flush)(void*, unsigned long), + unsigned char *output, + long *pos, + void (*error_fn)(char *x)); +#endif diff --git a/include/linux/device.h b/include/linux/device.h index b52773b0598d..b53d063c0cdf 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -27,6 +27,7 @@ #include #include #include +#include #include struct device; @@ -666,9 +667,12 @@ static inline void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp) static inline void *devm_kmalloc_array(struct device *dev, size_t n, size_t size, gfp_t flags) { - if (size != 0 && n > SIZE_MAX / size) + size_t bytes; + + if (unlikely(check_mul_overflow(n, size, &bytes))) return NULL; - return devm_kmalloc(dev, n * size, flags); + + return devm_kmalloc(dev, bytes, flags); } static inline void *devm_kcalloc(struct device *dev, size_t n, size_t size, gfp_t flags) diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h index 59e6a77064a3..562dbc88b3cf 100644 --- a/include/linux/diagchar.h +++ b/include/linux/diagchar.h @@ -149,7 +149,7 @@ * a new RANGE of SSIDs to the msg_mask_tbl. */ #define MSG_MASK_TBL_CNT 26 -#define APPS_EVENT_LAST_ID 0xCC2 +#define APPS_EVENT_LAST_ID 0xCCD #define MSG_SSID_0 0 #define MSG_SSID_0_LAST 134 @@ -928,7 +928,7 @@ static const uint32_t msg_bld_masks_25[] = { /* LOG CODES */ static const uint32_t log_code_last_tbl[] = { 0x0, /* EQUIP ID 0 */ - 0x1CDD, /* EQUIP ID 1 */ + 0x1CE8, /* EQUIP ID 1 */ 0x0, /* EQUIP ID 2 */ 0x0, /* EQUIP ID 3 */ 0x4910, /* EQUIP ID 4 */ diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 2c6f13b23484..422a132a51d8 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -24,7 +24,6 @@ struct vm_area_struct; #define ___GFP_HIGH 0x20u #define ___GFP_IO 0x40u #define ___GFP_FS 0x80u -#define ___GFP_COLD 0x100u #define ___GFP_NOWARN 0x200u #define ___GFP_RETRY_MAYFAIL 0x400u #define ___GFP_NOFAIL 0x800u @@ -193,16 +192,12 @@ struct vm_area_struct; /* * Action modifiers * - * __GFP_COLD indicates that the caller does not expect to be used in the near - * future. Where possible, a cache-cold page will be returned. - * * __GFP_NOWARN suppresses allocation failure reports. * * __GFP_COMP address compound page metadata. * * __GFP_ZERO returns a zeroed page on success. */ -#define __GFP_COLD ((__force gfp_t)___GFP_COLD) #define __GFP_NOWARN ((__force gfp_t)___GFP_NOWARN) #define __GFP_COMP ((__force gfp_t)___GFP_COMP) #define __GFP_ZERO ((__force gfp_t)___GFP_ZERO) diff --git a/include/linux/kasan.h b/include/linux/kasan.h index 6c5bf7e3cf44..fb01155e1adb 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -44,7 +44,7 @@ void kasan_alloc_pages(struct page *page, unsigned int order); void kasan_free_pages(struct page *page, unsigned int order); void kasan_cache_create(struct kmem_cache *cache, unsigned int *size, - unsigned long *flags); + slab_flags_t *flags); void kasan_poison_slab(struct page *page); void kasan_unpoison_object_data(struct kmem_cache *cache, void *object); @@ -98,7 +98,7 @@ static inline void kasan_free_pages(struct page *page, unsigned int order) {} static inline void kasan_cache_create(struct kmem_cache *cache, unsigned int *size, - unsigned long *flags) {} + slab_flags_t *flags) {} static inline void kasan_poison_slab(struct page *page) {} static inline void kasan_unpoison_object_data(struct kmem_cache *cache, diff --git a/include/linux/key.h b/include/linux/key.h index 8a15cabe928d..afe4d6b90cad 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -345,6 +345,9 @@ static inline key_serial_t key_serial(const struct key *key) extern void key_set_timeout(struct key *, unsigned); +extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags, + key_perm_t perm); + /* * The permissions required on a key that we're looking up. */ diff --git a/include/linux/kmemleak.h b/include/linux/kmemleak.h index 590343f6c1b1..5ac416e2d339 100644 --- a/include/linux/kmemleak.h +++ b/include/linux/kmemleak.h @@ -48,14 +48,14 @@ extern void kmemleak_not_leak_phys(phys_addr_t phys) __ref; extern void kmemleak_ignore_phys(phys_addr_t phys) __ref; static inline void kmemleak_alloc_recursive(const void *ptr, size_t size, - int min_count, unsigned long flags, + int min_count, slab_flags_t flags, gfp_t gfp) { if (!(flags & SLAB_NOLEAKTRACE)) kmemleak_alloc(ptr, size, min_count, gfp); } -static inline void kmemleak_free_recursive(const void *ptr, unsigned long flags) +static inline void kmemleak_free_recursive(const void *ptr, slab_flags_t flags) { if (!(flags & SLAB_NOLEAKTRACE)) kmemleak_free(ptr); @@ -76,7 +76,7 @@ static inline void kmemleak_alloc(const void *ptr, size_t size, int min_count, { } static inline void kmemleak_alloc_recursive(const void *ptr, size_t size, - int min_count, unsigned long flags, + int min_count, slab_flags_t flags, gfp_t gfp) { } @@ -94,7 +94,7 @@ static inline void kmemleak_free(const void *ptr) static inline void kmemleak_free_part(const void *ptr, size_t size) { } -static inline void kmemleak_free_recursive(const void *ptr, unsigned long flags) +static inline void kmemleak_free_recursive(const void *ptr, slab_flags_t flags) { } static inline void kmemleak_free_percpu(const void __percpu *ptr) diff --git a/include/linux/kthread.h b/include/linux/kthread.h index 144006195c5c..413b05795a65 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -187,6 +187,19 @@ extern void __kthread_init_worker(struct kthread_worker *worker, TIMER_IRQSAFE); \ } while (0) +/* + * Returns true when the work could not be queued at the moment. + * It happens when it is already pending in a worker list + * or when it is being cancelled. + */ +static inline bool queuing_blocked(struct kthread_worker *worker, + struct kthread_work *work) +{ + lockdep_assert_held(&worker->lock); + + return !list_empty(&work->node) || work->canceling; +} + int kthread_worker_fn(void *worker_ptr); __printf(2, 3) diff --git a/include/linux/mm.h b/include/linux/mm.h index 9acf06a68fc0..1cea7a72f4cc 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -25,6 +25,7 @@ #include #include #include +#include struct mempolicy; struct anon_vma; @@ -565,10 +566,17 @@ static inline void *kvzalloc(size_t size, gfp_t flags) static inline void *kvmalloc_array(size_t n, size_t size, gfp_t flags) { - if (size != 0 && n > SIZE_MAX / size) + size_t bytes; + + if (unlikely(check_mul_overflow(n, size, &bytes))) return NULL; - return kvmalloc(n * size, flags); + return kvmalloc(bytes, flags); +} + +static inline void *kvcalloc(size_t n, size_t size, gfp_t flags) +{ + return kvmalloc_array(n, size, flags | __GFP_ZERO); } extern void kvfree(const void *addr); diff --git a/include/linux/msm_dma_iommu_mapping.h b/include/linux/msm_dma_iommu_mapping.h index ae20f0990a98..32052cc8ed01 100644 --- a/include/linux/msm_dma_iommu_mapping.h +++ b/include/linux/msm_dma_iommu_mapping.h @@ -18,6 +18,12 @@ #include #include +struct msm_iommu_meta; +struct msm_iommu_data { + struct msm_iommu_meta *meta; + struct mutex lock; +}; + #ifdef CONFIG_QCOM_LAZY_MAPPING /* * This function is not taking a reference to the dma_buf here. It is expected @@ -71,7 +77,7 @@ int msm_dma_unmap_all_for_dev(struct device *dev); * Below is private function only to be called by framework (ION) and not by * clients. */ -void msm_dma_buf_freed(void *buffer); +void msm_dma_buf_freed(struct msm_iommu_data *data); #else /*CONFIG_QCOM_LAZY_MAPPING*/ @@ -117,7 +123,7 @@ static inline int msm_dma_unmap_all_for_dev(struct device *dev) return 0; } -static inline void msm_dma_buf_freed(void *buffer) {} +static inline void msm_dma_buf_freed(struct msm_iommu_data *data) {} #endif /*CONFIG_QCOM_LAZY_MAPPING*/ #endif diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index af3a946d19be..6eb08a0dbe3b 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -232,15 +232,9 @@ static inline struct page *page_cache_alloc(struct address_space *x) return __page_cache_alloc(mapping_gfp_mask(x)); } -static inline struct page *page_cache_alloc_cold(struct address_space *x) -{ - return __page_cache_alloc(mapping_gfp_mask(x)|__GFP_COLD); -} - static inline gfp_t readahead_gfp_mask(struct address_space *x) { - return mapping_gfp_mask(x) | - __GFP_COLD | __GFP_NORETRY | __GFP_NOWARN; + return mapping_gfp_mask(x) | __GFP_NORETRY | __GFP_NOWARN; } typedef int filler_t(struct file *, struct page *); diff --git a/include/linux/prandom.h b/include/linux/prandom.h new file mode 100644 index 000000000000..aa16e6468f91 --- /dev/null +++ b/include/linux/prandom.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * include/linux/prandom.h + * + * Include file for the fast pseudo-random 32-bit + * generation. + */ +#ifndef _LINUX_PRANDOM_H +#define _LINUX_PRANDOM_H + +#include +#include + +u32 prandom_u32(void); +void prandom_bytes(void *buf, size_t nbytes); +void prandom_seed(u32 seed); +void prandom_reseed_late(void); + +struct rnd_state { + __u32 s1, s2, s3, s4; +}; + +DECLARE_PER_CPU(struct rnd_state, net_rand_state); + +u32 prandom_u32_state(struct rnd_state *state); +void prandom_bytes_state(struct rnd_state *state, void *buf, size_t nbytes); +void prandom_seed_full_state(struct rnd_state __percpu *pcpu_state); + +#define prandom_init_once(pcpu_state) \ + DO_ONCE(prandom_seed_full_state, (pcpu_state)) + +/** + * prandom_u32_max - returns a pseudo-random number in interval [0, ep_ro) + * @ep_ro: right open interval endpoint + * + * Returns a pseudo-random number that is in interval [0, ep_ro). Note + * that the result depends on PRNG being well distributed in [0, ~0U] + * u32 space. Here we use maximally equidistributed combined Tausworthe + * generator, that is, prandom_u32(). This is useful when requesting a + * random index of an array containing ep_ro elements, for example. + * + * Returns: pseudo-random number in interval [0, ep_ro) + */ +static inline u32 prandom_u32_max(u32 ep_ro) +{ + return (u32)(((u64) prandom_u32() * ep_ro) >> 32); +} + +/* + * Handle minimum values for seeds + */ +static inline u32 __seed(u32 x, u32 m) +{ + return (x < m) ? x + m : x; +} + +/** + * prandom_seed_state - set seed for prandom_u32_state(). + * @state: pointer to state structure to receive the seed. + * @seed: arbitrary 64-bit value to use as a seed. + */ +static inline void prandom_seed_state(struct rnd_state *state, u64 seed) +{ + u32 i = (seed >> 32) ^ (seed << 10) ^ seed; + + state->s1 = __seed(i, 2U); + state->s2 = __seed(i, 8U); + state->s3 = __seed(i, 16U); + state->s4 = __seed(i, 128U); +} + +/* Pseudo random number generator from numerical recipes. */ +static inline u32 next_pseudo_random32(u32 seed) +{ + return seed * 1664525 + 1013904223; +} + +#endif diff --git a/include/linux/random.h b/include/linux/random.h index 4024f7d9c77d..8eda8c0cbba7 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -107,61 +107,12 @@ declare_get_random_var_wait(long) unsigned long randomize_page(unsigned long start, unsigned long range); -u32 prandom_u32(void); -void prandom_bytes(void *buf, size_t nbytes); -void prandom_seed(u32 seed); -void prandom_reseed_late(void); - -struct rnd_state { - __u32 s1, s2, s3, s4; -}; - -u32 prandom_u32_state(struct rnd_state *state); -void prandom_bytes_state(struct rnd_state *state, void *buf, size_t nbytes); -void prandom_seed_full_state(struct rnd_state __percpu *pcpu_state); - -#define prandom_init_once(pcpu_state) \ - DO_ONCE(prandom_seed_full_state, (pcpu_state)) - -/** - * prandom_u32_max - returns a pseudo-random number in interval [0, ep_ro) - * @ep_ro: right open interval endpoint - * - * Returns a pseudo-random number that is in interval [0, ep_ro). Note - * that the result depends on PRNG being well distributed in [0, ~0U] - * u32 space. Here we use maximally equidistributed combined Tausworthe - * generator, that is, prandom_u32(). This is useful when requesting a - * random index of an array containing ep_ro elements, for example. - * - * Returns: pseudo-random number in interval [0, ep_ro) - */ -static inline u32 prandom_u32_max(u32 ep_ro) -{ - return (u32)(((u64) prandom_u32() * ep_ro) >> 32); -} - /* - * Handle minimum values for seeds + * This is designed to be standalone for just prandom + * users, but for now we include it from + * for legacy reasons. */ -static inline u32 __seed(u32 x, u32 m) -{ - return (x < m) ? x + m : x; -} - -/** - * prandom_seed_state - set seed for prandom_u32_state(). - * @state: pointer to state structure to receive the seed. - * @seed: arbitrary 64-bit value to use as a seed. - */ -static inline void prandom_seed_state(struct rnd_state *state, u64 seed) -{ - u32 i = (seed >> 32) ^ (seed << 10) ^ seed; - - state->s1 = __seed(i, 2U); - state->s2 = __seed(i, 8U); - state->s3 = __seed(i, 16U); - state->s4 = __seed(i, 128U); -} +#include #ifdef CONFIG_ARCH_RANDOM # include @@ -192,10 +143,4 @@ static inline bool arch_has_random_seed(void) } #endif -/* Pseudo random number generator from numerical recipes. */ -static inline u32 next_pseudo_random32(u32 seed) -{ - return seed * 1664525 + 1013904223; -} - #endif /* _LINUX_RANDOM_H */ diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 8d570190e9b4..cad3693d41c4 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -847,7 +847,7 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) /** * kfree_rcu() - kfree an object after a grace period. * @ptr: pointer to kfree - * @rcu_head: the name of the struct rcu_head within the type of @ptr. + * @rhf: the name of the struct rcu_head within the type of @ptr. * * Many rcu callbacks functions just call kfree() on the base structure. * These functions are trivial, but their size adds up, and furthermore @@ -870,9 +870,13 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) * The BUILD_BUG_ON check must not involve any function calls, hence the * checks are done in macros here. */ -#define kfree_rcu(ptr, rcu_head) \ - __kfree_rcu(&((ptr)->rcu_head), offsetof(typeof(*(ptr)), rcu_head)) - +#define kfree_rcu(ptr, rhf) \ +do { \ + typeof (ptr) ___p = (ptr); \ + \ + if (___p) \ + __kfree_rcu(&((___p)->rhf), offsetof(typeof(*(ptr)), rhf)); \ +} while (0) /* * Place this after a lock-acquisition primitive to guarantee that diff --git a/include/linux/sched.h b/include/linux/sched.h index d7d9191133ab..6aed489d93ee 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -123,6 +123,14 @@ enum fps { FPS120 = 120, }; +enum task_boost_type { + TASK_BOOST_NONE = 0, + TASK_BOOST_ON_MID, + TASK_BOOST_ON_MAX, + TASK_BOOST_STRICT_MAX, + TASK_BOOST_END, +}; + #ifdef CONFIG_DEBUG_ATOMIC_SLEEP /* @@ -813,6 +821,7 @@ struct task_struct { u64 cpu_cycles; bool misfit; u32 unfilter; + bool low_latency; #endif #ifdef CONFIG_CGROUP_SCHED @@ -2012,10 +2021,4 @@ static inline void set_wake_up_idle(bool enabled) current->flags &= ~PF_WAKE_UP_IDLE; } -#ifdef CONFIG_DYNAMIC_STUNE_BOOST -int do_stune_boost(char *st_name, int boost, int *slot); -int do_stune_sched_boost(char *st_name, int *slot); -int reset_stune_boost(char *st_name, int slot); -#endif /* CONFIG_DYNAMIC_STUNE_BOOST */ - #endif diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 9578eb274918..6f1699871a96 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2722,7 +2722,7 @@ static inline struct page *__dev_alloc_pages(gfp_t gfp_mask, * 4. __GFP_MEMALLOC is ignored if __GFP_NOMEMALLOC is set due to * code in gfp_to_alloc_flags that should be enforcing this. */ - gfp_mask |= __GFP_COLD | __GFP_COMP | __GFP_MEMALLOC; + gfp_mask |= __GFP_COMP | __GFP_MEMALLOC; return alloc_pages_node(NUMA_NO_NODE, gfp_mask, order); } diff --git a/include/linux/slab.h b/include/linux/slab.h index 5921f381f5bc..2376ce8966cd 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -13,6 +13,7 @@ #define _LINUX_SLAB_H #include +#include #include #include @@ -21,13 +22,20 @@ * Flags to pass to kmem_cache_create(). * The ones marked DEBUG are only valid if CONFIG_DEBUG_SLAB is set. */ -#define SLAB_CONSISTENCY_CHECKS 0x00000100UL /* DEBUG: Perform (expensive) checks on alloc/free */ -#define SLAB_RED_ZONE 0x00000400UL /* DEBUG: Red zone objs in a cache */ -#define SLAB_POISON 0x00000800UL /* DEBUG: Poison objects */ -#define SLAB_HWCACHE_ALIGN 0x00002000UL /* Align objs on cache lines */ -#define SLAB_CACHE_DMA 0x00004000UL /* Use GFP_DMA memory */ -#define SLAB_STORE_USER 0x00010000UL /* DEBUG: Store the last owner for bug hunting */ -#define SLAB_PANIC 0x00040000UL /* Panic if kmem_cache_create() fails */ +/* DEBUG: Perform (expensive) checks on alloc/free */ +#define SLAB_CONSISTENCY_CHECKS ((slab_flags_t __force)0x00000100U) +/* DEBUG: Red zone objs in a cache */ +#define SLAB_RED_ZONE ((slab_flags_t __force)0x00000400U) +/* DEBUG: Poison objects */ +#define SLAB_POISON ((slab_flags_t __force)0x00000800U) +/* Align objs on cache lines */ +#define SLAB_HWCACHE_ALIGN ((slab_flags_t __force)0x00002000U) +/* Use GFP_DMA memory */ +#define SLAB_CACHE_DMA ((slab_flags_t __force)0x00004000U) +/* DEBUG: Store the last owner for bug hunting */ +#define SLAB_STORE_USER ((slab_flags_t __force)0x00010000U) +/* Panic if kmem_cache_create() fails */ +#define SLAB_PANIC ((slab_flags_t __force)0x00040000U) /* * SLAB_TYPESAFE_BY_RCU - **WARNING** READ THIS! * @@ -65,38 +73,44 @@ * * Note that SLAB_TYPESAFE_BY_RCU was originally named SLAB_DESTROY_BY_RCU. */ -#define SLAB_TYPESAFE_BY_RCU 0x00080000UL /* Defer freeing slabs to RCU */ -#define SLAB_MEM_SPREAD 0x00100000UL /* Spread some memory over cpuset */ -#define SLAB_TRACE 0x00200000UL /* Trace allocations and frees */ +/* Defer freeing slabs to RCU */ +#define SLAB_TYPESAFE_BY_RCU ((slab_flags_t __force)0x00080000U) +/* Spread some memory over cpuset */ +#define SLAB_MEM_SPREAD ((slab_flags_t __force)0x00100000U) +/* Trace allocations and frees */ +#define SLAB_TRACE ((slab_flags_t __force)0x00200000U) /* Flag to prevent checks on free */ #ifdef CONFIG_DEBUG_OBJECTS -# define SLAB_DEBUG_OBJECTS 0x00400000UL +# define SLAB_DEBUG_OBJECTS ((slab_flags_t __force)0x00400000U) #else -# define SLAB_DEBUG_OBJECTS 0x00000000UL +# define SLAB_DEBUG_OBJECTS 0 #endif -#define SLAB_NOLEAKTRACE 0x00800000UL /* Avoid kmemleak tracing */ +/* Avoid kmemleak tracing */ +#define SLAB_NOLEAKTRACE ((slab_flags_t __force)0x00800000U) #ifdef CONFIG_FAILSLAB -# define SLAB_FAILSLAB 0x02000000UL /* Fault injection mark */ +# define SLAB_FAILSLAB ((slab_flags_t __force)0x02000000U) #else -# define SLAB_FAILSLAB 0x00000000UL +# define SLAB_FAILSLAB 0 #endif +/* Account to memcg */ #if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB) -# define SLAB_ACCOUNT 0x04000000UL /* Account to memcg */ +# define SLAB_ACCOUNT ((slab_flags_t __force)0x04000000U) #else -# define SLAB_ACCOUNT 0x00000000UL +# define SLAB_ACCOUNT 0 #endif #ifdef CONFIG_KASAN -#define SLAB_KASAN 0x08000000UL +#define SLAB_KASAN ((slab_flags_t __force)0x08000000U) #else -#define SLAB_KASAN 0x00000000UL +#define SLAB_KASAN 0 #endif /* The following flags affect the page allocator grouping pages by mobility */ -#define SLAB_RECLAIM_ACCOUNT 0x00020000UL /* Objects are reclaimable */ +/* Objects are reclaimable */ +#define SLAB_RECLAIM_ACCOUNT ((slab_flags_t __force)0x00020000U) #define SLAB_TEMPORARY SLAB_RECLAIM_ACCOUNT /* Objects are short-lived */ /* * ZERO_SIZE_PTR will be returned for zero sized kmalloc requests. @@ -122,7 +136,7 @@ void __init kmem_cache_init(void); bool slab_is_available(void); struct kmem_cache *kmem_cache_create(const char *, size_t, size_t, - unsigned long, + slab_flags_t, void (*)(void *)); void kmem_cache_destroy(struct kmem_cache *); int kmem_cache_shrink(struct kmem_cache *); @@ -312,7 +326,7 @@ static __always_inline enum kmalloc_cache_type kmalloc_type(gfp_t flags) * 2 = 129 .. 192 bytes * n = 2^(n-1)+1 .. 2^n */ -static __always_inline int kmalloc_index(size_t size) +static __always_inline unsigned int kmalloc_index(size_t size) { if (!size) return 0; @@ -484,9 +498,6 @@ static __always_inline void *kmalloc_large(size_t size, gfp_t flags) * Also it is possible to set different flags by OR'ing * in one or more of the following additional @flags: * - * %__GFP_COLD - Request cache-cold pages instead of - * trying to return cache-warm pages. - * * %__GFP_HIGH - This allocation has high priority and may use emergency pools. * * %__GFP_NOFAIL - Indicate that this allocation is in no way allowed to fail @@ -531,11 +542,11 @@ static __always_inline void *kmalloc(size_t size, gfp_t flags) * return size or 0 if a kmalloc cache for that * size does not exist */ -static __always_inline int kmalloc_size(int n) +static __always_inline unsigned int kmalloc_size(unsigned int n) { #ifndef CONFIG_SLOB if (n > 2) - return 1 << n; + return 1U << n; if (n == 1 && KMALLOC_MIN_SIZE <= 32) return 96; @@ -551,7 +562,7 @@ static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) #ifndef CONFIG_SLOB if (__builtin_constant_p(size) && size <= KMALLOC_MAX_CACHE_SIZE) { - int i = kmalloc_index(size); + unsigned int i = kmalloc_index(size); if (!i) return ZERO_SIZE_PTR; @@ -634,11 +645,13 @@ int memcg_update_all_caches(int num_memcgs); */ static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) { - if (size != 0 && n > SIZE_MAX / size) + size_t bytes; + + if (unlikely(check_mul_overflow(n, size, &bytes))) return NULL; if (__builtin_constant_p(n) && __builtin_constant_p(size)) - return kmalloc(n * size, flags); - return __kmalloc(n * size, flags); + return kmalloc(bytes, flags); + return __kmalloc(bytes, flags); } /** @@ -664,6 +677,24 @@ extern void *__kmalloc_track_caller(size_t, gfp_t, unsigned long); #define kmalloc_track_caller(size, flags) \ __kmalloc_track_caller(size, flags, _RET_IP_) +static inline void *kmalloc_array_node(size_t n, size_t size, gfp_t flags, + int node) +{ + size_t bytes; + + if (unlikely(check_mul_overflow(n, size, &bytes))) + return NULL; + if (__builtin_constant_p(n) && __builtin_constant_p(size)) + return kmalloc_node(bytes, flags, node); + return __kmalloc_node(bytes, flags, node); +} + +static inline void *kcalloc_node(size_t n, size_t size, gfp_t flags, int node) +{ + return kmalloc_array_node(n, size, flags | __GFP_ZERO, node); +} + + #ifdef CONFIG_NUMA extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, unsigned long); #define kmalloc_node_track_caller(size, flags, node) \ diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h index b2932047163d..94217ef9baf3 100644 --- a/include/linux/slab_def.h +++ b/include/linux/slab_def.h @@ -20,7 +20,7 @@ struct kmem_cache { struct reciprocal_value reciprocal_buffer_size; /* 2) touched by every alloc & free from the backend */ - unsigned int flags; /* constant flags */ + slab_flags_t flags; /* constant flags */ unsigned int num; /* # of objs per slab */ /* 3) cache_grow/shrink */ diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index f8ced87a2efe..96895128c1b3 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h @@ -82,7 +82,7 @@ struct kmem_cache_order_objects { struct kmem_cache { struct kmem_cache_cpu __percpu *cpu_slab; /* Used for retriving partial slabs etc */ - unsigned long flags; + slab_flags_t flags; unsigned long min_partial; int size; /* The size of an object including meta data */ int object_size; /* The size of an object without meta data */ diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index 39c4005a0396..9ed7771ba212 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -200,5 +200,6 @@ struct plat_stmmacenet_data { (struct sk_buff *skb); bool early_eth; bool crc_strip_en; + bool phy_intr_en; }; #endif diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 60aea230dc6a..61eb40fef759 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -209,6 +209,8 @@ struct tcp_sock { u8 reord; /* reordering detected */ } rack; u16 advmss; /* Advertised MSS */ + u8 tlp_retrans:1, /* TLP is a retransmission */ + unused_1:7; u32 chrono_start; /* Start time in jiffies of a TCP chrono */ u32 chrono_stat[3]; /* Time in jiffies for chrono_stat stats */ u8 chrono_type:2, /* current chronograph type */ @@ -229,7 +231,7 @@ struct tcp_sock { syn_data_acked:1,/* data in SYN is acked by SYN-ACK */ save_syn:1, /* Save headers of SYN packet */ is_cwnd_limited:1;/* forward progress limited by snd_cwnd? */ - u32 tlp_high_seq; /* snd_nxt at the time of TLP retransmit. */ + u32 tlp_high_seq; /* snd_nxt at the time of TLP */ /* RTT measurement */ u64 tcp_mstamp; /* most recent packet received/sent */ diff --git a/include/linux/types.h b/include/linux/types.h index 3ce3d5a70e76..76d929bba9f9 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -160,6 +160,7 @@ typedef u32 dma_addr_t; #endif typedef unsigned __bitwise gfp_t; +typedef unsigned __bitwise slab_flags_t; typedef unsigned __bitwise fmode_t; #ifdef CONFIG_PHYS_ADDR_T_64BIT diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 266b2f3e5ac4..861531cb0b19 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -8,6 +8,7 @@ #include #include /* pgprot_t */ #include +#include struct vm_area_struct; /* vma defining user mapping in mm_types.h */ struct notifier_block; /* in notifier.h */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 9866157b52fc..cf0b6f9eff56 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -65,6 +65,9 @@ /* Indicate backport support for key configuration for Beacon protection*/ #define CFG80211_BIGTK_CONFIGURATION_SUPPORT 1 +/* Indicate backport support for sband iftype data */ +#define CFG80211_SBAND_IFTYPE_DATA_BACKPORT 1 + /** * DOC: Introduction * diff --git a/include/net/sock.h b/include/net/sock.h index 366fe76a1a30..a460e3ec35c8 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1131,7 +1131,7 @@ struct proto { struct kmem_cache *slab; unsigned int obj_size; - int slab_flags; + slab_flags_t slab_flags; struct percpu_counter *orphan_count; diff --git a/include/soc/qcom/msm_tz_smmu.h b/include/soc/qcom/msm_tz_smmu.h index 0a247be2d450..ed7407a0b6c3 100644 --- a/include/soc/qcom/msm_tz_smmu.h +++ b/include/soc/qcom/msm_tz_smmu.h @@ -62,11 +62,16 @@ extern void *get_smmu_from_addr(struct iommu_device *iommu, void __iomem *addr); extern void *arm_smmu_get_by_addr(void __iomem *addr); /* Donot write to smmu global space with CONFIG_MSM_TZ_SMMU */ #undef writel_relaxed +#undef writeq_relaxed #define writel_relaxed(v, c) do { \ if (!arm_smmu_skip_write(c)) \ ((void)__raw_writel((u32)cpu_to_le32(v), (c))); \ } while (0) +#define writeq_relaxed(v, c) do { \ + if (!arm_smmu_skip_write(c)) \ + ((void)__raw_writeq((u64)cpu_to_le64(v), (c))); \ + } while (0) #else static inline int msm_tz_smmu_atos_start(struct device *dev, int cb_num) diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h index 40b9cc3bfaf9..1a57a6fb2c86 100644 --- a/include/trace/events/mmflags.h +++ b/include/trace/events/mmflags.h @@ -32,7 +32,6 @@ {(unsigned long)__GFP_ATOMIC, "__GFP_ATOMIC"}, \ {(unsigned long)__GFP_IO, "__GFP_IO"}, \ {(unsigned long)__GFP_FS, "__GFP_FS"}, \ - {(unsigned long)__GFP_COLD, "__GFP_COLD"}, \ {(unsigned long)__GFP_NOWARN, "__GFP_NOWARN"}, \ {(unsigned long)__GFP_RETRY_MAYFAIL, "__GFP_RETRY_MAYFAIL"}, \ {(unsigned long)__GFP_NOFAIL, "__GFP_NOFAIL"}, \ diff --git a/include/uapi/linux/loop.h b/include/uapi/linux/loop.h index 080a8df134ef..24a1c45bd1ae 100644 --- a/include/uapi/linux/loop.h +++ b/include/uapi/linux/loop.h @@ -25,6 +25,16 @@ enum { LO_FLAGS_DIRECT_IO = 16, }; +/* LO_FLAGS that can be set using LOOP_SET_STATUS(64) */ +#define LOOP_SET_STATUS_SETTABLE_FLAGS (LO_FLAGS_AUTOCLEAR | LO_FLAGS_PARTSCAN) + +/* LO_FLAGS that can be cleared using LOOP_SET_STATUS(64) */ +#define LOOP_SET_STATUS_CLEARABLE_FLAGS (LO_FLAGS_AUTOCLEAR) + +/* LO_FLAGS that can be set using LOOP_CONFIGURE */ +#define LOOP_CONFIGURE_SETTABLE_FLAGS (LO_FLAGS_READ_ONLY | LO_FLAGS_AUTOCLEAR \ + | LO_FLAGS_PARTSCAN | LO_FLAGS_DIRECT_IO) + #include /* for __kernel_old_dev_t */ #include /* for __u64 */ @@ -37,7 +47,7 @@ struct loop_info { int lo_offset; int lo_encrypt_type; int lo_encrypt_key_size; /* ioctl w/o */ - int lo_flags; /* ioctl r/o */ + int lo_flags; char lo_name[LO_NAME_SIZE]; unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ unsigned long lo_init[2]; @@ -53,13 +63,29 @@ struct loop_info64 { __u32 lo_number; /* ioctl r/o */ __u32 lo_encrypt_type; __u32 lo_encrypt_key_size; /* ioctl w/o */ - __u32 lo_flags; /* ioctl r/o */ + __u32 lo_flags; __u8 lo_file_name[LO_NAME_SIZE]; __u8 lo_crypt_name[LO_NAME_SIZE]; __u8 lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ __u64 lo_init[2]; }; +/** + * struct loop_config - Complete configuration for a loop device. + * @fd: fd of the file to be used as a backing file for the loop device. + * @block_size: block size to use; ignored if 0. + * @info: struct loop_info64 to configure the loop device with. + * + * This structure is used with the LOOP_CONFIGURE ioctl, and can be used to + * atomically setup and configure all loop device parameters at once. + */ +struct loop_config { + __u32 fd; + __u32 block_size; + struct loop_info64 info; + __u64 __reserved[8]; +}; + /* * Loop filter types */ @@ -90,6 +116,7 @@ struct loop_info64 { #define LOOP_SET_CAPACITY 0x4C07 #define LOOP_SET_DIRECT_IO 0x4C08 #define LOOP_SET_BLOCK_SIZE 0x4C09 +#define LOOP_CONFIGURE 0x4C0A /* /dev/loop-control interface */ #define LOOP_CTL_ADD 0x4C80 diff --git a/include/uapi/linux/msm_ipa.h b/include/uapi/linux/msm_ipa.h index 497526feb0ca..00b293065977 100644 --- a/include/uapi/linux/msm_ipa.h +++ b/include/uapi/linux/msm_ipa.h @@ -1184,9 +1184,10 @@ enum ipa_hdr_proc_type { IPA_HDR_PROC_L2TP_HEADER_REMOVE, IPA_HDR_PROC_ETHII_TO_ETHII_EX, IPA_HDR_PROC_L2TP_UDP_HEADER_ADD, - IPA_HDR_PROC_L2TP_UDP_HEADER_REMOVE + IPA_HDR_PROC_L2TP_UDP_HEADER_REMOVE, + IPA_HDR_PROC_SET_DSCP, }; -#define IPA_HDR_PROC_MAX (IPA_HDR_PROC_L2TP_UDP_HEADER_REMOVE + 1) +#define IPA_HDR_PROC_MAX (IPA_HDR_PROC_SET_DSCP + 1) /** * struct ipa_rt_rule - attributes of a routing rule diff --git a/include/uapi/linux/wireless.h b/include/uapi/linux/wireless.h index 86eca3208b6b..a2c006a364e0 100644 --- a/include/uapi/linux/wireless.h +++ b/include/uapi/linux/wireless.h @@ -74,6 +74,8 @@ #include /* for "struct sockaddr" et al */ #include /* for IFNAMSIZ and co... */ +#include /* for offsetof */ + /***************************** VERSION *****************************/ /* * This constant is used to know the availability of the wireless @@ -1090,8 +1092,7 @@ struct iw_event { /* iw_point events are special. First, the payload (extra data) come at * the end of the event, so they are bigger than IW_EV_POINT_LEN. Second, * we omit the pointer, so start at an offset. */ -#define IW_EV_POINT_OFF (((char *) &(((struct iw_point *) NULL)->length)) - \ - (char *) NULL) +#define IW_EV_POINT_OFF offsetof(struct iw_point, length) #define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \ IW_EV_POINT_OFF) diff --git a/include/uapi/sound/compress_offload.h b/include/uapi/sound/compress_offload.h index 5f0fd5ebb94a..3a50f6ca1619 100644 --- a/include/uapi/sound/compress_offload.h +++ b/include/uapi/sound/compress_offload.h @@ -137,6 +137,7 @@ struct snd_compr_audio_info { #define SNDRV_COMPRESS_RENDER_MODE_AUDIO_MASTER 0 #define SNDRV_COMPRESS_RENDER_MODE_STC_MASTER 1 #define SNDRV_COMPRESS_RENDER_MODE_TTP 2 +#define SNDRV_COMPRESS_RENDER_MODE_TTP_PASS_THROUGH 3 #define SNDRV_COMPRESS_CLK_REC_MODE_NONE 0 #define SNDRV_COMPRESS_CLK_REC_MODE_AUTO 1 diff --git a/init/Kconfig b/init/Kconfig index 739dc7ddac5d..16ccb418ca32 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -2,6 +2,14 @@ config ARCH string option env="ARCH" +config VERSION + string + option env="VERSION" + +config PATCHLEVEL + string + option env="PATCHLEVEL" + config KERNELVERSION string option env="KERNELVERSION" @@ -1170,15 +1178,6 @@ config CPUSET_TOP_APP endif -config DYNAMIC_STUNE_BOOST - bool "Dynamic SchedTune boosting support" - depends on SCHED_TUNE - help - This option extends the SchedTune framework and provides APIs to - activate and reset SchedTune boosting from anywhere in the kernel. - - If unsure, say N. - config DEFAULT_USE_ENERGY_AWARE bool "Default to enabling the Energy Aware Scheduler feature" default n diff --git a/init/Makefile b/init/Makefile index 62d8be1cee07..e5dd3192ed35 100644 --- a/init/Makefile +++ b/init/Makefile @@ -19,7 +19,6 @@ mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o mounts-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o mounts-$(CONFIG_BLK_DEV_DM) += do_mounts_dm.o -mounts-$(CONFIG_BLK_DEV_DM) += do_mounts_verity.o # dependencies on generated files need to be listed explicitly $(obj)/version.o: include/generated/compile.h diff --git a/init/do_mounts.c b/init/do_mounts.c index 4977a57459cd..63c3591937cc 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -450,7 +450,6 @@ static int __init do_mount_root(char *name, char *fs, int flags, void *data) struct super_block *s; int err; - place_marker("M - DRIVER F/S Init"); err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, (unsigned long)flags, @@ -467,7 +466,6 @@ static int __init do_mount_root(char *name, char *fs, int flags, void *data) sb_rdonly(s) ? " readonly" : "", MAJOR(ROOT_DEV), MINOR(ROOT_DEV)); - place_marker("M - DRIVER F/S Ready"); return 0; } @@ -660,7 +658,6 @@ void __init prepare_namespace(void) md_run_setup(); dm_run_setup(); - dm_verity_setup(); // Try to mount partition labeled "system" first ROOT_DEV = name_to_dev_t("PARTLABEL=system"); @@ -669,8 +666,8 @@ void __init prepare_namespace(void) goto mount; } - if (initrd_load()) - goto out; + if (initrd_load()) + goto out; if (saved_root_name[0]) { root_device_name = saved_root_name; diff --git a/init/do_mounts.h b/init/do_mounts.h index 9dfd4138aca8..cd201124714b 100644 --- a/init/do_mounts.h +++ b/init/do_mounts.h @@ -8,8 +8,6 @@ #include #include #include -#include "uapi/linux/dm-ioctl.h" -#include void change_floppy(char *fmt, ...); void mount_block_root(char *name, int flags); @@ -73,15 +71,3 @@ void dm_run_setup(void); static inline void dm_run_setup(void) {} #endif - -#ifdef CONFIG_BLK_DEV_DM - -void dm_verity_setup(void); -extern int dm_ioctrl(uint cmd, struct dm_ioctl *param); -extern void dm_table_destroy(struct dm_table *t); - -#else - -static inline void dm_verity_setup(void) {} - -#endif diff --git a/init/do_mounts_verity.c b/init/do_mounts_verity.c deleted file mode 100644 index 5d7c8a2efec9..000000000000 --- a/init/do_mounts_verity.c +++ /dev/null @@ -1,285 +0,0 @@ -/* Copyright (c) 2019, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include "uapi/linux/dm-ioctl.h" -#include -#include -#include "do_mounts.h" - -#define DM_BUF_SIZE 4096 - -#define DM_MSG_PREFIX "verity" - -#define VERITY_COMMANDLINE_PARAM_LENGTH 32 -#define VERITY_ROOT_HASH_PARAM_LENGTH 65 -#define VERITY_SALT_PARAM_LENGTH 65 - -static char dm_name[VERITY_COMMANDLINE_PARAM_LENGTH]; -static char dm_version[VERITY_COMMANDLINE_PARAM_LENGTH]; -static char dm_data_device[VERITY_COMMANDLINE_PARAM_LENGTH]; -static char dm_hash_device[VERITY_COMMANDLINE_PARAM_LENGTH]; -static char dm_data_block_size[VERITY_COMMANDLINE_PARAM_LENGTH]; -static char dm_hash_block_size[VERITY_COMMANDLINE_PARAM_LENGTH]; -static char dm_number_of_data_blocks[VERITY_COMMANDLINE_PARAM_LENGTH]; -static char dm_hash_start_block[VERITY_COMMANDLINE_PARAM_LENGTH]; -static char dm_algorithm[VERITY_COMMANDLINE_PARAM_LENGTH]; -static char dm_digest[VERITY_ROOT_HASH_PARAM_LENGTH]; -static char dm_salt[VERITY_SALT_PARAM_LENGTH]; -static char dm_opt[VERITY_COMMANDLINE_PARAM_LENGTH]; - -static void __init init_param(struct dm_ioctl *param, const char *name) -{ - memset(param, 0, DM_BUF_SIZE); - param->data_size = DM_BUF_SIZE; - param->data_start = sizeof(struct dm_ioctl); - param->version[0] = 4; - param->version[1] = 0; - param->version[2] = 0; - param->flags = DM_READONLY_FLAG; - strlcpy(param->name, name, sizeof(param->name)); -} - -static int __init dm_name_param(char *line) -{ - strlcpy(dm_name, line, sizeof(dm_name)); - return 1; -} -__setup("dmname=", dm_name_param); - -static int __init dm_version_param(char *line) -{ - strlcpy(dm_version, line, sizeof(dm_version)); - return 1; -} -__setup("version=", dm_version_param); - -static int __init dm_data_device_param(char *line) -{ - strlcpy(dm_data_device, line, sizeof(dm_data_device)); - return 1; -} -__setup("data_device=", dm_data_device_param); - -static int __init dm_hash_device_param(char *line) -{ - strlcpy(dm_hash_device, line, sizeof(dm_hash_device)); - return 1; -} -__setup("hash_device=", dm_hash_device_param); - -static int __init dm_data_block_size_param(char *line) -{ - strlcpy(dm_data_block_size, line, sizeof(dm_data_block_size)); - return 1; -} -__setup("data_block_size=", dm_data_block_size_param); - -static int __init dm_hash_block_size_param(char *line) -{ - strlcpy(dm_hash_block_size, line, sizeof(dm_hash_block_size)); - return 1; -} -__setup("hash_block_size=", dm_hash_block_size_param); - -static int __init dm_number_of_data_blocks_param(char *line) -{ - strlcpy(dm_number_of_data_blocks, line, sizeof(dm_number_of_data_blocks)); - return 1; -} -__setup("number_of_data_blocks=", dm_number_of_data_blocks_param); - -static int __init dm_hash_start_block_param(char *line) -{ - strlcpy(dm_hash_start_block, line, sizeof(dm_hash_start_block)); - return 1; -} -__setup("hash_start_block=", dm_hash_start_block_param); - -static int __init dm_algorithm_param(char *line) -{ - strlcpy(dm_algorithm, line, sizeof(dm_algorithm)); - return 1; -} -__setup("algorithm=", dm_algorithm_param); - -static int __init dm_digest_param(char *line) -{ - strlcpy(dm_digest, line, sizeof(dm_digest)); - return 1; -} -__setup("digest=", dm_digest_param); - -static int __init dm_salt_param(char *line) -{ - strlcpy(dm_salt, line, sizeof(dm_salt)); - return 1; -} -__setup("salt=", dm_salt_param); - -static int __init dm_opt_param(char *line) -{ - strlcpy(dm_opt, line, sizeof(dm_opt)); - return 1; -} -__setup("opt=", dm_opt_param); - -static void __init dm_setup_drive(void) -{ - const char *name; - const char *version; - const char *data_device; - const char *hash_device; - const char *data_block_size; - const char *hash_block_size; - const char *number_of_data_blocks; - const char *hash_start_block; - const char *algorithm; - const char *digest; - const char *salt; - const char *opt; - unsigned long long data_blocks; - char dummy; - char *verity_params; - size_t bufsize; - char *buffer = kzalloc(DM_BUF_SIZE, GFP_KERNEL); - struct dm_ioctl *param = (struct dm_ioctl *) buffer; - size_t dm_sz = sizeof(struct dm_ioctl); - struct dm_target_spec *tgt = (struct dm_target_spec *) &buffer[dm_sz]; - - if (!buffer) - goto fail; - name = dm_name; - if (name == NULL) - goto fail; - DMDEBUG("(I) name=%s", name); - - if (strcmp(name, "disabled") == 0) { - pr_info("dm: dm-verity is disabled."); - kfree(buffer); - return; - } - - version = dm_version; - if (version == NULL) - goto fail; - DMDEBUG("(I) version=%s", version); - - data_device = dm_data_device; - if (data_device == NULL) - goto fail; - DMDEBUG("(I) data_device=%s", data_device); - - hash_device = dm_hash_device; - if (hash_device == NULL) - goto fail; - DMDEBUG("(I) hash_device=%s", hash_device); - - data_block_size = dm_data_block_size; - if (data_block_size == NULL) - goto fail; - DMDEBUG("(I) data_block_size=%s", data_block_size); - - hash_block_size = dm_hash_block_size; - if (hash_block_size == NULL) - goto fail; - DMDEBUG("(I) hash_block_size=%s", hash_block_size); - - number_of_data_blocks = dm_number_of_data_blocks; - if (number_of_data_blocks == NULL) - goto fail; - DMDEBUG("(I) number_of_data_blocks=%s", number_of_data_blocks); - - hash_start_block = dm_hash_start_block; - if (hash_start_block == NULL) - goto fail; - DMDEBUG("(I) hash_start_block=%s", hash_start_block); - - algorithm = dm_algorithm; - if (algorithm == NULL) - goto fail; - DMDEBUG("(I) algorithm=%s", algorithm); - - digest = dm_digest; - if (digest == NULL) - goto fail; - DMDEBUG("(I) digest=%s", digest); - - salt = dm_salt; - if (salt == NULL) - goto fail; - DMDEBUG("(I) salt=%s", salt); - - opt = dm_opt; - if (opt == NULL) - goto fail; - DMDEBUG("(I) opt=%s", opt); - - init_param(param, name); - if (dm_ioctrl(DM_DEV_CREATE_CMD, param)) { - DMERR("(E) failed to create the device"); - goto fail; - } - - init_param(param, name); - param->target_count = 1; - /* set tgt arguments */ - tgt->status = 0; - tgt->sector_start = 0; - if (sscanf(number_of_data_blocks, "%llu%c", &data_blocks, &dummy) != 1) { - DMERR("(E) invalid number of data blocks"); - goto fail; - } - - tgt->length = data_blocks*4096/512; /* size in sector(512b) of data dev */ - strlcpy(tgt->target_type, "verity", sizeof(tgt->target_type)); - /* build the verity params here */ - verity_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec); - bufsize = DM_BUF_SIZE - (verity_params - buffer); - - verity_params += snprintf(verity_params, bufsize, "%s %s %s %s %s %s %s %s %s %s 1 %s", - version, - data_device, hash_device, - data_block_size, hash_block_size, - number_of_data_blocks, hash_start_block, - algorithm, digest, salt, opt); - - tgt->next = verity_params - buffer; - if (dm_ioctrl(DM_TABLE_LOAD_CMD, param)) { - DMERR("(E) failed to load the device"); - goto fail; - } - - init_param(param, name); - if (dm_ioctrl(DM_DEV_SUSPEND_CMD, param)) { - DMERR("(E) failed to suspend the device"); - goto fail; - } - - pr_info("dm: dm-0 (%s) is ready", data_device); - kfree(buffer); - return; - -fail: - pr_info("dm: starting dm-0 failed"); - kfree(buffer); - return; - -} - -void __init dm_verity_setup(void) -{ - pr_info("dm: attempting early device configuration."); - dm_setup_drive(); -} diff --git a/init/main.c b/init/main.c index 805853c2fb63..8ff9f47c2a6a 100644 --- a/init/main.c +++ b/init/main.c @@ -1040,7 +1040,6 @@ static int __ref kernel_init(void *unused) numa_default_policy(); rcu_end_inkernel_boot(); - place_marker("M - DRIVER Kernel Boot Done"); if (ramdisk_execute_command) { ret = run_init_process(ramdisk_execute_command); diff --git a/ipc/sem.c b/ipc/sem.c index 6adc245f3e02..a6edae020250 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -1878,7 +1878,7 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops, if (nsops > ns->sc_semopm) return -E2BIG; if (nsops > SEMOPM_FAST) { - sops = kvmalloc(sizeof(*sops)*nsops, GFP_KERNEL); + sops = kvmalloc_array(nsops, sizeof(*sops), GFP_KERNEL); if (sops == NULL) return -ENOMEM; } diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index cb1b144a191c..adb302d04ab3 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c @@ -657,15 +657,20 @@ static void htab_elem_free_rcu(struct rcu_head *head) preempt_enable(); } -static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l) +static void htab_put_fd_value(struct bpf_htab *htab, struct htab_elem *l) { struct bpf_map *map = &htab->map; + void *ptr; if (map->ops->map_fd_put_ptr) { - void *ptr = fd_htab_map_get_ptr(map, l); - + ptr = fd_htab_map_get_ptr(map, l); map->ops->map_fd_put_ptr(ptr); } +} + +static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l) +{ + htab_put_fd_value(htab, l); if (htab_is_prealloc(htab)) { __pcpu_freelist_push(&htab->freelist, &l->fnode); @@ -726,6 +731,7 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key, */ pl_new = this_cpu_ptr(htab->extra_elems); l_new = *pl_new; + htab_put_fd_value(htab, old_elem); *pl_new = old_elem; } else { struct pcpu_freelist_node *l; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 0af81da04e66..d8d4f77337ef 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -4560,7 +4560,7 @@ static int adjust_insn_aux_data(struct bpf_verifier_env *env, u32 prog_len, if (cnt == 1) return 0; - new_data = vzalloc(sizeof(struct bpf_insn_aux_data) * prog_len); + new_data = vzalloc(array_size(prog_len, sizeof(struct bpf_insn_aux_data))); if (!new_data) return -ENOMEM; memcpy(new_data, old_data, sizeof(struct bpf_insn_aux_data) * off); @@ -5012,8 +5012,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr) if (!env) return -ENOMEM; - env->insn_aux_data = vzalloc(sizeof(struct bpf_insn_aux_data) * - (*prog)->len); + env->insn_aux_data = vzalloc(array_size(sizeof(struct bpf_insn_aux_data), (*prog)->len)); ret = -ENOMEM; if (!env->insn_aux_data) goto err_free_env; @@ -5147,8 +5146,7 @@ int bpf_analyzer(struct bpf_prog *prog, const struct bpf_ext_analyzer_ops *ops, if (!env) return -ENOMEM; - env->insn_aux_data = vzalloc(sizeof(struct bpf_insn_aux_data) * - prog->len); + env->insn_aux_data = vzalloc(array_size(sizeof(struct bpf_insn_aux_data), prog->len)); ret = -ENOMEM; if (!env->insn_aux_data) goto err_free_env; diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c index 226d0d47e13f..6a3e34f07b36 100644 --- a/kernel/cgroup/cgroup-v1.c +++ b/kernel/cgroup/cgroup-v1.c @@ -197,9 +197,9 @@ struct cgroup_pidlist { static void *pidlist_allocate(int count) { if (PIDLIST_TOO_LARGE(count)) - return vmalloc(count * sizeof(pid_t)); + return vmalloc(array_size(count, sizeof(pid_t))); else - return kmalloc(count * sizeof(pid_t), GFP_KERNEL); + return kmalloc_array(count, sizeof(pid_t), GFP_KERNEL); } static void pidlist_free(void *p) @@ -554,11 +554,9 @@ static ssize_t __cgroup1_procs_write(struct kernfs_open_file *of, ret = cgroup_attach_task(cgrp, task, threadgroup); /* This covers boosting for app launches and app transitions */ - if (!ret && !threadgroup && - !memcmp(of->kn->parent->name, "top-app", sizeof("top-app")) && - is_zygote_pid(task->parent->pid)) { + if (!ret && !threadgroup && !strcmp(of->kn->parent->name, "top-app") && + task_is_zygote(task->parent)) cpu_input_boost_kick_max(1000); - } out_finish: cgroup_procs_write_finish(task); diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 44ea596376f8..3a5ea06b28b7 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -4894,8 +4894,8 @@ static struct cgroup *cgroup_create(struct cgroup *parent) int ret; /* allocate the cgroup and its ID, 0 is reserved for the root */ - cgrp = kzalloc(sizeof(*cgrp) + - sizeof(cgrp->ancestor_ids[0]) * (level + 1), GFP_KERNEL); + cgrp = kzalloc(struct_size(cgrp, ancestor_ids, (level + 1)), + GFP_KERNEL); if (!cgrp) return ERR_PTR(-ENOMEM); diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index 8ef030828e9d..84e3543548cc 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -703,7 +703,7 @@ static int generate_sched_domains(cpumask_var_t **domains, goto done; } - csa = kmalloc(nr_cpusets() * sizeof(cp), GFP_KERNEL); + csa = kmalloc_array(nr_cpusets(), sizeof(cp), GFP_KERNEL); if (!csa) goto done; csn = 0; @@ -772,7 +772,8 @@ restart: * The rest of the code, including the scheduler, can deal with * dattr==NULL case. No need to abort if alloc fails. */ - dattr = kmalloc(ndoms * sizeof(struct sched_domain_attr), GFP_KERNEL); + dattr = kmalloc_array(ndoms, sizeof(struct sched_domain_attr), + GFP_KERNEL); for (nslot = 0, i = 0; i < csn; i++) { struct cpuset *a = csa[i]; diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 90bd7895dc85..3f29db30bae9 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -691,7 +691,7 @@ static int kdb_defcmd2(const char *cmdstr, const char *argv0) } if (!s->usable) return KDB_NOTIMP; - s->command = kzalloc((s->count + 1) * sizeof(*(s->command)), GFP_KDB); + s->command = kcalloc(s->count + 1, sizeof(*(s->command)), GFP_KDB); if (!s->command) { kdb_printf("Could not allocate new kdb_defcmd table for %s\n", cmdstr); @@ -729,8 +729,8 @@ static int kdb_defcmd(int argc, const char **argv) kdb_printf("Command only available during kdb_init()\n"); return KDB_NOTIMP; } - defcmd_set = kmalloc((defcmd_set_count + 1) * sizeof(*defcmd_set), - GFP_KDB); + defcmd_set = kmalloc_array(defcmd_set_count + 1, sizeof(*defcmd_set), + GFP_KDB); if (!defcmd_set) goto fail_defcmd; memcpy(defcmd_set, save_defcmd_set, @@ -2731,8 +2731,9 @@ int kdb_register_flags(char *cmd, } if (i >= kdb_max_commands) { - kdbtab_t *new = kmalloc((kdb_max_commands - KDB_BASE_CMD_MAX + - kdb_command_extend) * sizeof(*new), GFP_KDB); + kdbtab_t *new = kmalloc_array(kdb_max_commands - KDB_BASE_CMD_MAX + kdb_command_extend, + sizeof(*new), + GFP_KDB); if (!new) { kdb_printf("Could not allocate new kdb_command " "table\n"); diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c index 20f6a50fb40b..2a5ff6e6e02d 100644 --- a/kernel/events/ring_buffer.c +++ b/kernel/events/ring_buffer.c @@ -635,7 +635,8 @@ int rb_alloc_aux(struct ring_buffer *rb, struct perf_event *event, } } - rb->aux_pages = kzalloc_node(nr_pages * sizeof(void *), GFP_KERNEL, node); + rb->aux_pages = kcalloc_node(nr_pages, sizeof(void *), GFP_KERNEL, + node); if (!rb->aux_pages) return -ENOMEM; diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index f08ba79ee5d1..ef435f77ecf1 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -1188,7 +1188,8 @@ static struct xol_area *__create_xol_area(unsigned long vaddr) if (unlikely(!area)) goto out; - area->bitmap = kzalloc(BITS_TO_LONGS(UINSNS_PER_PAGE) * sizeof(long), GFP_KERNEL); + area->bitmap = kcalloc(BITS_TO_LONGS(UINSNS_PER_PAGE), sizeof(long), + GFP_KERNEL); if (!area->bitmap) goto free_area; diff --git a/kernel/fork.c b/kernel/fork.c index 2e3225a6d286..e4e47a9a8be6 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -94,9 +94,8 @@ #include #include #include -#include -#include #include +#include #include #include @@ -2208,12 +2207,9 @@ long _do_fork(unsigned long clone_flags, int trace = 0; long nr; - /* Boost CPU to the max for 150 ms when userspace launches an app */ - if (is_zygote_pid(current->pid)) { - cpu_input_boost_kick_max(150); - devfreq_boost_kick_max(DEVFREQ_MSM_CPUBW, 150); - devfreq_boost_kick_max(DEVFREQ_MSM_LLCCBW, 150); - } + /* Boost CPU to the max for 3000 ms when userspace launches an app */ + if (task_is_zygote(current)) + cpu_input_boost_kick_max(3000); /* * Determine whether and which event to report to ptracer. When diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 92784b290564..1305e57ddd2d 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -25,25 +25,10 @@ static struct lock_class_key irq_desc_lock_class; #if defined(CONFIG_SMP) -static int __init irq_affinity_setup(char *str) -{ - alloc_bootmem_cpumask_var(&irq_default_affinity); - cpulist_parse(str, irq_default_affinity); - /* - * Set at least the boot cpu. We don't want to end up with - * bugreports caused by random comandline masks - */ - cpumask_set_cpu(smp_processor_id(), irq_default_affinity); - return 1; -} -__setup("irqaffinity=", irq_affinity_setup); - static void __init init_irq_default_affinity(void) { - if (!cpumask_available(irq_default_affinity)) - zalloc_cpumask_var(&irq_default_affinity, GFP_NOWAIT); - if (cpumask_empty(irq_default_affinity)) - cpumask_setall(irq_default_affinity); + zalloc_cpumask_var(&irq_default_affinity, GFP_NOWAIT); + cpumask_set_cpu(0, irq_default_affinity); } #else static void __init init_irq_default_affinity(void) diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 3fe3ccd0eea9..639a6de48b4c 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -341,6 +341,8 @@ irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify) raw_spin_unlock_irqrestore(&desc->lock, flags); if (old_notify) { + if (notify) + WARN(1, "overwriting previous IRQ affinity notifier\n"); if (cancel_work_sync(&old_notify->work)) { /* Pending work had a ref, put that one too */ kref_put(&old_notify->kref, old_notify->release); diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index 9f48f4412297..5eb030ab3004 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -660,7 +660,7 @@ static int __kexec_load_purgatory(struct kimage *image, unsigned long min, * ->sh_offset fields to keep track of permanent and temporary * locations of sections. */ - sechdrs = vzalloc(pi->ehdr->e_shnum * sizeof(Elf_Shdr)); + sechdrs = vzalloc(array_size(sizeof(Elf_Shdr), pi->ehdr->e_shnum)); if (!sechdrs) return -ENOMEM; diff --git a/kernel/kthread.c b/kernel/kthread.c index 993384401c9a..a6d8ba28f5ab 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -746,19 +746,6 @@ kthread_create_worker_on_cpu(int cpu, unsigned int flags, } EXPORT_SYMBOL(kthread_create_worker_on_cpu); -/* - * Returns true when the work could not be queued at the moment. - * It happens when it is already pending in a worker list - * or when it is being cancelled. - */ -static inline bool queuing_blocked(struct kthread_worker *worker, - struct kthread_work *work) -{ - lockdep_assert_held(&worker->lock); - - return !list_empty(&work->node) || work->canceling; -} - static void kthread_insert_work_sanity_check(struct kthread_worker *worker, struct kthread_work *work) { diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 03e3ab61a2ed..524da96ad908 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -5141,7 +5141,7 @@ void lockdep_init_task(struct task_struct *task) task->hist_id_save[i] = 0; } - task->xhlocks = kzalloc(sizeof(struct hist_lock) * MAX_XHLOCKS_NR, + task->xhlocks = kcalloc(MAX_XHLOCKS_NR, sizeof(struct hist_lock), GFP_KERNEL); } diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c index 838e25a6f3d2..ac730bba45d0 100644 --- a/kernel/locking/locktorture.c +++ b/kernel/locking/locktorture.c @@ -929,7 +929,9 @@ static int __init lock_torture_init(void) /* Initialize the statistics so that each run gets its own numbers. */ if (nwriters_stress) { lock_is_write_held = 0; - cxt.lwsa = kmalloc(sizeof(*cxt.lwsa) * cxt.nrealwriters_stress, GFP_KERNEL); + cxt.lwsa = kmalloc_array(cxt.nrealwriters_stress, + sizeof(*cxt.lwsa), + GFP_KERNEL); if (cxt.lwsa == NULL) { VERBOSE_TOROUT_STRING("cxt.lwsa: Out of memory"); firsterr = -ENOMEM; @@ -958,7 +960,9 @@ static int __init lock_torture_init(void) if (nreaders_stress) { lock_is_read_held = 0; - cxt.lrsa = kmalloc(sizeof(*cxt.lrsa) * cxt.nrealreaders_stress, GFP_KERNEL); + cxt.lrsa = kmalloc_array(cxt.nrealreaders_stress, + sizeof(*cxt.lrsa), + GFP_KERNEL); if (cxt.lrsa == NULL) { VERBOSE_TOROUT_STRING("cxt.lrsa: Out of memory"); firsterr = -ENOMEM; @@ -1001,7 +1005,8 @@ static int __init lock_torture_init(void) } if (nwriters_stress) { - writer_tasks = kzalloc(cxt.nrealwriters_stress * sizeof(writer_tasks[0]), + writer_tasks = kcalloc(cxt.nrealwriters_stress, + sizeof(writer_tasks[0]), GFP_KERNEL); if (writer_tasks == NULL) { VERBOSE_TOROUT_ERRSTRING("writer_tasks: Out of memory"); @@ -1011,7 +1016,8 @@ static int __init lock_torture_init(void) } if (cxt.cur_ops->readlock) { - reader_tasks = kzalloc(cxt.nrealreaders_stress * sizeof(reader_tasks[0]), + reader_tasks = kcalloc(cxt.nrealreaders_stress, + sizeof(reader_tasks[0]), GFP_KERNEL); if (reader_tasks == NULL) { VERBOSE_TOROUT_ERRSTRING("reader_tasks: Out of memory"); diff --git a/kernel/module.c b/kernel/module.c index 71a744ed22fe..8ae34b071d38 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1599,8 +1599,7 @@ static void add_notes_attrs(struct module *mod, const struct load_info *info) if (notes == 0) return; - notes_attrs = kzalloc(sizeof(*notes_attrs) - + notes * sizeof(notes_attrs->attrs[0]), + notes_attrs = kzalloc(struct_size(notes_attrs, attrs, notes), GFP_KERNEL); if (notes_attrs == NULL) return; diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 4b007fd99af2..9be5dfdf5b4e 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -335,7 +335,6 @@ static int create_image(int platform_mode) Platform_finish: platform_finish(platform_mode); - place_marker("M - Hibernation: start device resume"); dpm_resume_start(in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); @@ -411,7 +410,6 @@ int hibernation_snapshot(int platform_mode) resume_console(); dpm_complete(msg); - place_marker("M - Hibernation: end device resume"); Close: platform_end(platform_mode); return error; @@ -751,7 +749,6 @@ int hibernate(void) in_suspend = 0; pm_restore_gfp_mask(); } else { - place_marker("M - PM: Image restored!"); pm_pr_dbg("Image restored successfully.\n"); } @@ -766,7 +763,6 @@ int hibernate(void) error = load_image_and_restore(); } thaw_processes(); - place_marker("M - Hibernation: processes thaw done"); /* Don't bother checking whether freezer_test_done is true */ freezer_test_done = false; @@ -776,7 +772,6 @@ int hibernate(void) atomic_inc(&snapshot_device_available); Unlock: unlock_system_sleep(); - place_marker("M - PM: Hibernation Exit!"); pr_info("hibernation exit\n"); return error; @@ -906,7 +901,6 @@ static int software_resume(void) error = load_image_and_restore(); thaw_processes(); - place_marker("M - PM: Thaw processes completed!"); Finish: __pm_notifier_call_chain(PM_POST_RESTORE, nr_calls, NULL); pm_restore_console(); diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index d4dbe4a6d78f..06f2efd8742f 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c @@ -1924,7 +1924,7 @@ static int enough_free_mem(unsigned int nr_pages, unsigned int nr_highmem) */ static inline int get_highmem_buffer(int safe_needed) { - buffer = get_image_page(GFP_ATOMIC | __GFP_COLD, safe_needed); + buffer = get_image_page(GFP_ATOMIC, safe_needed); return buffer ? 0 : -ENOMEM; } @@ -1985,7 +1985,7 @@ static int swsusp_alloc(struct memory_bitmap *copy_bm, while (nr_pages-- > 0) { struct page *page; - page = alloc_image_page(GFP_ATOMIC | __GFP_COLD); + page = alloc_image_page(GFP_ATOMIC); if (!page) goto err_out; memory_bm_set_bit(copy_bm, page_to_pfn(page)); diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 75164e041b8e..d93e9e4db1f9 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -699,7 +699,7 @@ static int save_image_lzo(struct swap_map_handle *handle, goto out_clean; } - data = vmalloc(sizeof(*data) * nr_threads); + data = vmalloc(array_size(nr_threads, sizeof(*data))); if (!data) { printk(KERN_ERR "PM: Failed to allocate LZO data\n"); ret = -ENOMEM; @@ -1190,14 +1190,14 @@ static int load_image_lzo(struct swap_map_handle *handle, nr_threads = num_online_cpus() - 1; nr_threads = clamp_val(nr_threads, 1, LZO_THREADS); - page = vmalloc(sizeof(*page) * LZO_MAX_RD_PAGES); + page = vmalloc(array_size(LZO_MAX_RD_PAGES, sizeof(*page))); if (!page) { printk(KERN_ERR "PM: Failed to allocate LZO page\n"); ret = -ENOMEM; goto out_clean; } - data = vmalloc(sizeof(*data) * nr_threads); + data = vmalloc(array_size(nr_threads, sizeof(*data))); if (!data) { printk(KERN_ERR "PM: Failed to allocate LZO data\n"); ret = -ENOMEM; diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index f0c599bf4058..be72b5140343 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -830,8 +830,7 @@ rcu_torture_cbflood(void *arg) cbflood_intra_holdoff > 0 && cur_ops->call && cur_ops->cb_barrier) { - rhp = vmalloc(sizeof(*rhp) * - cbflood_n_burst * cbflood_n_per_burst); + rhp = vmalloc(array3_size(cbflood_n_burst, cbflood_n_per_burst, sizeof(*rhp))); err = !rhp; } if (err) { @@ -1549,10 +1548,10 @@ static int rcu_torture_barrier_init(void) atomic_set(&barrier_cbs_count, 0); atomic_set(&barrier_cbs_invoked, 0); barrier_cbs_tasks = - kzalloc(n_barrier_cbs * sizeof(barrier_cbs_tasks[0]), + kcalloc(n_barrier_cbs, sizeof(barrier_cbs_tasks[0]), GFP_KERNEL); barrier_cbs_wq = - kzalloc(n_barrier_cbs * sizeof(barrier_cbs_wq[0]), + kcalloc(n_barrier_cbs, sizeof(barrier_cbs_wq[0]), GFP_KERNEL); if (barrier_cbs_tasks == NULL || !barrier_cbs_wq) return -ENOMEM; @@ -1796,7 +1795,7 @@ rcu_torture_init(void) if (firsterr) goto unwind; if (nfakewriters > 0) { - fakewriter_tasks = kzalloc(nfakewriters * + fakewriter_tasks = kcalloc(nfakewriters, sizeof(fakewriter_tasks[0]), GFP_KERNEL); if (fakewriter_tasks == NULL) { @@ -1811,7 +1810,7 @@ rcu_torture_init(void) if (firsterr) goto unwind; } - reader_tasks = kzalloc(nrealreaders * sizeof(reader_tasks[0]), + reader_tasks = kcalloc(nrealreaders, sizeof(reader_tasks[0]), GFP_KERNEL); if (reader_tasks == NULL) { VERBOSE_TOROUT_ERRSTRING("out of memory"); diff --git a/kernel/relay.c b/kernel/relay.c index b141ce697679..813823080a08 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -169,7 +169,8 @@ static struct rchan_buf *relay_create_buf(struct rchan *chan) buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL); if (!buf) return NULL; - buf->padding = kmalloc(chan->n_subbufs * sizeof(size_t *), GFP_KERNEL); + buf->padding = kmalloc_array(chan->n_subbufs, sizeof(size_t *), + GFP_KERNEL); if (!buf->padding) goto free_buf; diff --git a/kernel/sched/boost.c b/kernel/sched/boost.c index 5c08acaf30f1..c3c29e1796b8 100644 --- a/kernel/sched/boost.c +++ b/kernel/sched/boost.c @@ -16,10 +16,6 @@ #include #include -#ifdef CONFIG_DYNAMIC_STUNE_BOOST -static int boost_slot; -#endif // CONFIG_DYNAMIC_STUNE_BOOST - /* * Scheduler boost is a mechanism to temporarily place tasks on CPUs * with higher capacity than those where a task would have normally @@ -218,14 +214,6 @@ static void sched_boost_disable_all(void) static void _sched_set_boost(int type) { - -#ifdef CONFIG_DYNAMIC_STUNE_BOOST - if (type > 0) - do_stune_sched_boost("top-app", &boost_slot); - else - reset_stune_boost("top-app", boost_slot); -#endif // CONFIG_DYNAMIC_STUNE_BOOST - if (type == 0) sched_boost_disable_all(); else if (type > 0) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 01d0ab93cedb..4c60f9ee77aa 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -2316,6 +2316,9 @@ static void __sched_fork(unsigned long clone_flags, struct task_struct *p) p->boost_expires = 0; p->boost_period = 0; +#ifdef CONFIG_SCHED_WALT + p->low_latency = 0; +#endif INIT_LIST_HEAD(&p->se.group_node); #ifdef CONFIG_FAIR_GROUP_SCHED @@ -7389,7 +7392,7 @@ const u32 sched_prio_to_wmult[40] = { */ int set_task_boost(int boost, u64 period) { - if (boost < 0 || boost > 2) + if (boost < TASK_BOOST_NONE || boost >= TASK_BOOST_END) return -EINVAL; if (boost) { current->boost = boost; diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index be341e726c4f..156d87de575e 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -1048,9 +1048,9 @@ static int sugov_init(struct cpufreq_policy *policy) } tunables->up_rate_limit_us = - cpufreq_policy_transition_delay_us(policy); + CONFIG_SCHEDUTIL_UP_RATE_LIMIT; tunables->down_rate_limit_us = - cpufreq_policy_transition_delay_us(policy); + CONFIG_SCHEDUTIL_DOWN_RATE_LIMIT; tunables->hispeed_load = DEFAULT_HISPEED_LOAD; tunables->hispeed_freq = 0; tunables->iowait_boost_enable = false; diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index ac8a967d81ed..6df300ecde0e 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -3947,6 +3947,20 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) thresh >>= 1; vruntime -= thresh; + if (entity_is_task(se)) { + if (per_task_boost(task_of(se)) == + TASK_BOOST_STRICT_MAX) + vruntime -= sysctl_sched_latency; +#ifdef CONFIG_SCHED_WALT + else if (unlikely(task_of(se)->low_latency)) { + vruntime -= sysctl_sched_latency; + vruntime -= thresh; + se->vruntime = min_vruntime(vruntime, + se->vruntime); + return; + } +#endif + } } /* ensure we never gain time by being placed backwards. */ @@ -7335,7 +7349,7 @@ static inline bool task_fits_max(struct task_struct *p, int cpu) walt_should_kick_upmigrate(p, cpu)) return false; } else { /* mid cap cpu */ - if (task_boost > 1) + if (task_boost > TASK_BOOST_ON_MID) return false; } @@ -7361,6 +7375,7 @@ struct find_best_target_env { int fastpath; int skip_cpu; int start_cpu; + bool strict_max; }; static inline bool prefer_spread_on_idle(int cpu) @@ -7420,8 +7435,10 @@ static int get_start_cpu(struct task_struct *p) { struct root_domain *rd = cpu_rq(smp_processor_id())->rd; int start_cpu = rd->min_cap_orig_cpu; + int task_boost = per_task_boost(p); bool boosted = schedtune_task_boost(p) > 0 || - task_boost_policy(p) == SCHED_BOOST_ON_BIG; + task_boost_policy(p) == SCHED_BOOST_ON_BIG || + task_boost == TASK_BOOST_ON_MID; bool task_skip_min = (sched_boost() != CONSERVATIVE_BOOST) && get_rtg_status(p) && p->unfilter; @@ -7434,6 +7451,12 @@ static int get_start_cpu(struct task_struct *p) start_cpu = rd->mid_cap_orig_cpu == -1 ? rd->max_cap_orig_cpu : rd->mid_cap_orig_cpu; } + + if (task_boost > TASK_BOOST_ON_MID) { + start_cpu = rd->max_cap_orig_cpu; + return start_cpu; + } + if (start_cpu == -1 || start_cpu == rd->max_cap_orig_cpu) return start_cpu; @@ -7495,6 +7518,9 @@ static inline int find_best_target(struct task_struct *p, int *backup_cpu, if (prefer_idle && boosted) target_capacity = 0; + if (fbt_env->strict_max) + most_spare_wake_cap = LONG_MIN; + /* Find start CPU based on boost value */ start_cpu = fbt_env->start_cpu; /* Find SD for the start CPU */ @@ -7814,7 +7840,8 @@ static inline int find_best_target(struct task_struct *p, int *backup_cpu, * accommodated in the higher capacity CPUs. */ if ((prefer_idle && best_idle_cpu != -1) || - (boosted && (best_idle_cpu != -1 || target_cpu != -1))) { + (boosted && (best_idle_cpu != -1 || target_cpu != -1 || + (fbt_env->strict_max && most_spare_cap_cpu != -1)))) { if (boosted) { if (!next_group_higher_cap) break; @@ -7983,7 +8010,8 @@ static inline void alloc_eenv(void) for_each_possible_cpu(cpu) { struct energy_env *eenv = &per_cpu(eenv_cache, cpu); - eenv->cpu = kmalloc(sizeof(struct eenv_cpu) * cpu_count, GFP_KERNEL); + eenv->cpu = kmalloc_array(cpu_count, sizeof(struct eenv_cpu), + GFP_KERNEL); eenv->eenv_cpu_count = cpu_count; #ifdef DEBUG_EENV_DECISIONS eenv->debug = (struct _eenv_debug *)kmalloc(eenv_debug_size(), GFP_KERNEL); @@ -8115,7 +8143,8 @@ static int find_energy_efficient_cpu(struct sched_domain *sd, int placement_boost = task_boost_policy(p); u64 start_t = 0; int next_cpu = -1, backup_cpu = -1; - int boosted = (schedtune_task_boost(p) > 0 || per_task_boost(p) > 0); + int task_boost = per_task_boost(p); + int boosted = (schedtune_task_boost(p) > 0) || (task_boost > 0); int start_cpu; if (is_many_wakeup(sibling_count_hint) && prev_cpu != cpu && @@ -8201,6 +8230,8 @@ static int find_energy_efficient_cpu(struct sched_domain *sd, fbt_env.boosted = boosted; fbt_env.skip_cpu = is_many_wakeup(sibling_count_hint) ? cpu : -1; + fbt_env.strict_max = is_rtg && + (task_boost == TASK_BOOST_STRICT_MAX); /* Find a cpu with sufficient capacity */ target_cpu = find_best_target(p, &eenv->cpu[EAS_CPU_BKP].cpu_id, @@ -9113,6 +9144,16 @@ static inline int migrate_degrades_locality(struct task_struct *p, } #endif +static inline bool can_migrate_boosted_task(struct task_struct *p, + int src_cpu, int dst_cpu) +{ + if (per_task_boost(p) == TASK_BOOST_STRICT_MAX && + task_in_related_thread_group(p) && + (capacity_orig_of(dst_cpu) < capacity_orig_of(src_cpu))) + return false; + return true; +} + /* * can_migrate_task - may task p from runqueue rq be migrated to this_cpu? */ @@ -9133,6 +9174,12 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env) if (throttled_lb_pair(task_group(p), env->src_cpu, env->dst_cpu)) return 0; + /* + * don't allow pull boost task to smaller cores. + */ + if (!can_migrate_boosted_task(p, env->src_cpu, env->dst_cpu)) + return 0; + if (!cpumask_test_cpu(env->dst_cpu, &p->cpus_allowed)) { int cpu; @@ -9287,17 +9334,21 @@ static int detach_tasks(struct lb_env *env) unsigned long load = 0; int detached = 0; int orig_loop = env->loop; + u64 start_t = rq_clock(env->src_rq); lockdep_assert_held(&env->src_rq->lock); if (env->imbalance <= 0) return 0; - if (!same_cluster(env->dst_cpu, env->src_cpu)) - env->flags |= LBF_IGNORE_PREFERRED_CLUSTER_TASKS; + if (env->src_rq->nr_running < 32) { + if (!same_cluster(env->dst_cpu, env->src_cpu)) + env->flags |= LBF_IGNORE_PREFERRED_CLUSTER_TASKS; - if (capacity_orig_of(env->dst_cpu) < capacity_orig_of(env->src_cpu)) - env->flags |= LBF_IGNORE_BIG_TASKS; + if (capacity_orig_of(env->dst_cpu) < + capacity_orig_of(env->src_cpu)) + env->flags |= LBF_IGNORE_BIG_TASKS; + } redo: while (!list_empty(tasks)) { @@ -9315,6 +9366,10 @@ redo: if (env->loop > env->loop_max) break; + /* Abort the loop, if we spent more than 5 msec */ + if (rq_clock(env->src_rq) - start_t > 5000000) + break; + /* take a breather every nr_migrate tasks */ if (env->loop > env->loop_break) { env->loop_break += sched_nr_migrate_break; @@ -11193,7 +11248,10 @@ no_move: * if the curr task on busiest cpu can't be * moved to this_cpu */ - if (!cpumask_test_cpu(this_cpu, &busiest->curr->cpus_allowed)) { + if (!cpumask_test_cpu(this_cpu, + &busiest->curr->cpus_allowed) + || !can_migrate_boosted_task(busiest->curr, + cpu_of(busiest), this_cpu)) { raw_spin_unlock_irqrestore(&busiest->lock, flags); env.flags |= LBF_ALL_PINNED; @@ -12504,10 +12562,10 @@ int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent) struct cfs_rq *cfs_rq; int i; - tg->cfs_rq = kzalloc(sizeof(cfs_rq) * nr_cpu_ids, GFP_KERNEL); + tg->cfs_rq = kcalloc(nr_cpu_ids, sizeof(cfs_rq), GFP_KERNEL); if (!tg->cfs_rq) goto err; - tg->se = kzalloc(sizeof(se) * nr_cpu_ids, GFP_KERNEL); + tg->se = kcalloc(nr_cpu_ids, sizeof(se), GFP_KERNEL); if (!tg->se) goto err; diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index d869bf8c2a1f..6815c8d68c21 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -191,10 +191,10 @@ int alloc_rt_sched_group(struct task_group *tg, struct task_group *parent) struct sched_rt_entity *rt_se; int i; - tg->rt_rq = kzalloc(sizeof(rt_rq) * nr_cpu_ids, GFP_KERNEL); + tg->rt_rq = kcalloc(nr_cpu_ids, sizeof(rt_rq), GFP_KERNEL); if (!tg->rt_rq) goto err; - tg->rt_se = kzalloc(sizeof(rt_se) * nr_cpu_ids, GFP_KERNEL); + tg->rt_se = kcalloc(nr_cpu_ids, sizeof(rt_se), GFP_KERNEL); if (!tg->rt_se) goto err; diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index de7a0384ca03..345d4f0b859d 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -2647,15 +2647,14 @@ extern void clear_top_tasks_bitmap(unsigned long *bitmap); #if defined(CONFIG_SCHED_TUNE) extern bool task_sched_boost(struct task_struct *p); extern int sync_cgroup_colocation(struct task_struct *p, bool insert); -extern bool same_schedtune(struct task_struct *tsk1, struct task_struct *tsk2); +extern bool schedtune_task_colocated(struct task_struct *p); extern void update_cgroup_boost_settings(void); extern void restore_cgroup_boost_settings(void); #else -static inline bool -same_schedtune(struct task_struct *tsk1, struct task_struct *tsk2) +static inline bool schedtune_task_colocated(struct task_struct *p) { - return true; + return false; } static inline bool task_sched_boost(struct task_struct *p) diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c index b034b186f255..79919ba439ce 100644 --- a/kernel/sched/topology.c +++ b/kernel/sched/topology.c @@ -1958,7 +1958,7 @@ cpumask_var_t *alloc_sched_domains(unsigned int ndoms) int i; cpumask_var_t *doms; - doms = kmalloc(sizeof(*doms) * ndoms, GFP_KERNEL); + doms = kmalloc_array(ndoms, sizeof(*doms), GFP_KERNEL); if (!doms) return NULL; for (i = 0; i < ndoms; i++) { diff --git a/kernel/sched/tune.c b/kernel/sched/tune.c index 4a278bc12587..9a43df878e21 100644 --- a/kernel/sched/tune.c +++ b/kernel/sched/tune.c @@ -7,7 +7,6 @@ #include #include -#include #include "sched.h" #include "tune.h" @@ -18,18 +17,6 @@ extern struct reciprocal_value schedtune_spc_rdiv; /* We hold schedtune boost in effect for at least this long */ #define SCHEDTUNE_BOOST_HOLD_NS 50000000ULL -#ifdef CONFIG_DYNAMIC_STUNE_BOOST -#define DYNAMIC_BOOST_SLOTS_COUNT 5 -static DEFINE_MUTEX(boost_slot_mutex); -static DEFINE_MUTEX(stune_boost_mutex); -static struct schedtune *getSchedtune(char *st_name); -static int dynamic_boost(struct schedtune *st, int boost); -struct boost_slot { - struct list_head list; - int idx; -}; -#endif /* CONFIG_DYNAMIC_STUNE_BOOST */ - /* * EAS scheduler tunables for task groups. */ @@ -69,27 +56,6 @@ struct schedtune { /* Hint to bias scheduling of tasks on that SchedTune CGroup * towards idle CPUs */ int prefer_idle; - -#ifdef CONFIG_DYNAMIC_STUNE_BOOST - /* - * This tracks the default boost value and is used to restore - * the value when Dynamic SchedTune Boost is reset. - */ - int boost_default; - - /* Sched Boost value for tasks on that SchedTune CGroup */ - int sched_boost; - - /* Number of ongoing boosts for this SchedTune CGroup */ - int boost_count; - - /* Lists of active and available boost slots */ - struct boost_slot active_boost_slots; - struct boost_slot available_boost_slots; - - /* Array of tracked boost values of each slot */ - int slot_boost[DYNAMIC_BOOST_SLOTS_COUNT]; -#endif /* CONFIG_DYNAMIC_STUNE_BOOST */ }; static inline struct schedtune *css_st(struct cgroup_subsys_state *css) @@ -126,20 +92,6 @@ root_schedtune = { .colocate_update_disabled = false, #endif .prefer_idle = 0, -#ifdef CONFIG_DYNAMIC_STUNE_BOOST - .boost_default = 0, - .sched_boost = 0, - .boost_count = 0, - .active_boost_slots = { - .list = LIST_HEAD_INIT(root_schedtune.active_boost_slots.list), - .idx = 0, - }, - .available_boost_slots = { - .list = LIST_HEAD_INIT(root_schedtune.available_boost_slots.list), - .idx = 0, - }, - .slot_boost = {0}, -#endif /* CONFIG_DYNAMIC_STUNE_BOOST */ }; /* @@ -198,11 +150,6 @@ static inline void init_sched_boost(struct schedtune *st) st->colocate_update_disabled = false; } -bool same_schedtune(struct task_struct *tsk1, struct task_struct *tsk2) -{ - return task_schedtune(tsk1) == task_schedtune(tsk2); -} - void update_cgroup_boost_settings(void) { int i; @@ -530,6 +477,23 @@ static int sched_colocate_write(struct cgroup_subsys_state *css, return 0; } +bool schedtune_task_colocated(struct task_struct *p) +{ + struct schedtune *st; + bool colocated; + + if (unlikely(!schedtune_initialized)) + return false; + + /* Get task boost value */ + rcu_read_lock(); + st = task_schedtune(p); + colocated = st->colocate; + rcu_read_unlock(); + + return colocated; +} + #else /* CONFIG_SCHED_WALT */ static inline void init_sched_boost(struct schedtune *st) { } @@ -685,9 +649,6 @@ boost_write(struct cgroup_subsys_state *css, struct cftype *cft, return -EINVAL; st->boost = boost; -#ifdef CONFIG_DYNAMIC_STUNE_BOOST - st->boost_default = boost; -#endif /* CONFIG_DYNAMIC_STUNE_BOOST */ /* Update CPU boost */ schedtune_boostgroup_update(st->idx, st->boost); @@ -695,63 +656,6 @@ boost_write(struct cgroup_subsys_state *css, struct cftype *cft, return 0; } -#ifdef CONFIG_DYNAMIC_STUNE_BOOST -static s64 -sched_boost_read(struct cgroup_subsys_state *css, struct cftype *cft) -{ - struct schedtune *st = css_st(css); - - return st->sched_boost; -} - -static int -sched_boost_write(struct cgroup_subsys_state *css, struct cftype *cft, - s64 sched_boost) -{ - struct schedtune *st = css_st(css); - st->sched_boost = sched_boost; - - return 0; -} - -static void -boost_slots_init(struct schedtune *st) -{ - int i; - struct boost_slot *slot; - - /* Initialize boost slots */ - INIT_LIST_HEAD(&(st->active_boost_slots.list)); - INIT_LIST_HEAD(&(st->available_boost_slots.list)); - - /* Populate available_boost_slots */ - for (i = 0; i < DYNAMIC_BOOST_SLOTS_COUNT; ++i) { - slot = kmalloc(sizeof(*slot), GFP_KERNEL); - slot->idx = i; - list_add_tail(&(slot->list), &(st->available_boost_slots.list)); - } -} - -static void -boost_slots_release(struct schedtune *st) -{ - struct boost_slot *slot, *next_slot; - - list_for_each_entry_safe(slot, next_slot, - &(st->available_boost_slots.list), list) { - list_del(&slot->list); - pr_info("STUNE: freed!\n"); - kfree(slot); - } - list_for_each_entry_safe(slot, next_slot, - &(st->active_boost_slots.list), list) { - list_del(&slot->list); - pr_info("STUNE: freed!\n"); - kfree(slot); - } -} -#endif // CONFIG_DYNAMIC_STUNE_BOOST - static struct cftype files[] = { #ifdef CONFIG_SCHED_WALT { @@ -775,13 +679,6 @@ static struct cftype files[] = { .read_u64 = prefer_idle_read, .write_u64 = prefer_idle_write, }, -#ifdef CONFIG_DYNAMIC_STUNE_BOOST - { - .name = "sched_boost", - .read_s64 = sched_boost_read, - .write_s64 = sched_boost_write, - }, -#endif // CONFIG_DYNAMIC_STUNE_BOOST { } /* terminate */ }; @@ -802,10 +699,6 @@ schedtune_boostgroup_init(struct schedtune *st) bg->group[st->idx].ts = 0; } -#ifdef CONFIG_DYNAMIC_STUNE_BOOST - boost_slots_init(st); -#endif // CONFIG_DYNAMIC_STUNE_BOOST - return 0; } @@ -855,10 +748,6 @@ out: static void schedtune_boostgroup_release(struct schedtune *st) { -#ifdef CONFIG_DYNAMIC_STUNE_BOOST - /* Free dynamic boost slots */ - boost_slots_release(st); -#endif // CONFIG_DYNAMIC_STUNE_BOOST /* Reset this boost group */ schedtune_boostgroup_update(st->idx, 0); @@ -904,224 +793,6 @@ schedtune_init_cgroups(void) schedtune_initialized = true; } -#ifdef CONFIG_DYNAMIC_STUNE_BOOST -static struct schedtune *getSchedtune(char *st_name) -{ - int idx; - - for (idx = 1; idx < BOOSTGROUPS_COUNT; ++idx) { - char name_buf[NAME_MAX + 1]; - struct schedtune *st = allocated_group[idx]; - - if (!st) { - pr_warn("SCHEDTUNE: Could not find %s\n", st_name); - break; - } - - cgroup_name(st->css.cgroup, name_buf, sizeof(name_buf)); - if (strncmp(name_buf, st_name, strlen(st_name)) == 0) - return st; - } - - return NULL; -} - -static int dynamic_boost(struct schedtune *st, int boost) -{ - int ret; - /* Backup boost_default */ - int boost_default_backup = st->boost_default; - - ret = boost_write(&st->css, NULL, boost); - - /* Restore boost_default */ - st->boost_default = boost_default_backup; - - return ret; -} - -static inline bool is_valid_boost_slot(int slot) -{ - return slot >= 0 && slot < DYNAMIC_BOOST_SLOTS_COUNT; -} - -static int activate_boost_slot(struct schedtune *st, int boost, int *slot) -{ - int ret = 0; - struct boost_slot *curr_slot; - struct list_head *head; - *slot = -1; - - mutex_lock(&boost_slot_mutex); - - /* Check for slots in available_boost_slots */ - if (list_empty(&(st->available_boost_slots.list))) { - ret = -EINVAL; - goto exit; - } - - /* - * Move one slot from available_boost_slots to active_boost_slots - */ - - /* Get first slot from available_boost_slots */ - head = &(st->available_boost_slots.list); - curr_slot = list_first_entry(head, struct boost_slot, list); - - /* Store slot value and boost value*/ - *slot = curr_slot->idx; - st->slot_boost[*slot] = boost; - - /* Delete slot from available_boost_slots */ - list_del(&curr_slot->list); - kfree(curr_slot); - - /* Create new slot with same value at tail of active_boost_slots */ - curr_slot = kmalloc(sizeof(*curr_slot), GFP_KERNEL); - curr_slot->idx = *slot; - list_add_tail(&(curr_slot->list), - &(st->active_boost_slots.list)); - -exit: - mutex_unlock(&boost_slot_mutex); - return ret; -} - -static int deactivate_boost_slot(struct schedtune *st, int slot) -{ - int ret = 0; - struct boost_slot *curr_slot, *next_slot; - - mutex_lock(&boost_slot_mutex); - - if (!is_valid_boost_slot(slot)) { - ret = -EINVAL; - goto exit; - } - - /* Delete slot from active_boost_slots */ - list_for_each_entry_safe(curr_slot, next_slot, - &(st->active_boost_slots.list), list) { - if (curr_slot->idx == slot) { - st->slot_boost[slot] = 0; - list_del(&curr_slot->list); - kfree(curr_slot); - - /* Create same slot at tail of available_boost_slots */ - curr_slot = kmalloc(sizeof(*curr_slot), GFP_KERNEL); - curr_slot->idx = slot; - list_add_tail(&(curr_slot->list), - &(st->available_boost_slots.list)); - - goto exit; - } - } - - /* Reaching here means that we did not find the slot to delete */ - ret = -EINVAL; - -exit: - mutex_unlock(&boost_slot_mutex); - return ret; -} - -static int max_active_boost(struct schedtune *st) -{ - struct boost_slot *slot; - int max_boost; - - mutex_lock(&boost_slot_mutex); - mutex_lock(&stune_boost_mutex); - - /* Set initial value to default boost */ - max_boost = st->boost_default; - - /* Check for active boosts */ - if (list_empty(&(st->active_boost_slots.list))) { - goto exit; - } - - /* Get largest boost value */ - list_for_each_entry(slot, &(st->active_boost_slots.list), list) { - int boost = st->slot_boost[slot->idx]; - if (boost > max_boost) - max_boost = boost; - } - -exit: - mutex_unlock(&stune_boost_mutex); - mutex_unlock(&boost_slot_mutex); - - return max_boost; -} - -static int _do_stune_boost(struct schedtune *st, int boost, int *slot) -{ - int ret = 0; - - /* Try to obtain boost slot */ - ret = activate_boost_slot(st, boost, slot); - - /* Check if boost slot obtained successfully */ - if (ret) - return -EINVAL; - - /* Boost if new value is greater than current */ - mutex_lock(&stune_boost_mutex); - if (boost > st->boost) - ret = dynamic_boost(st, boost); - mutex_unlock(&stune_boost_mutex); - - return ret; -} - -int reset_stune_boost(char *st_name, int slot) -{ - int ret = 0; - int boost = 0; - struct schedtune *st = getSchedtune(st_name); - - if (!st) - return -EINVAL; - - ret = deactivate_boost_slot(st, slot); - if (ret) { - return -EINVAL; - } - /* Find next largest active boost or reset to default */ - boost = max_active_boost(st); - - mutex_lock(&stune_boost_mutex); - /* Boost only if value changed */ - if (boost != st->boost) - ret = dynamic_boost(st, boost); - mutex_unlock(&stune_boost_mutex); - - return ret; -} - -int do_stune_sched_boost(char *st_name, int *slot) -{ - struct schedtune *st = getSchedtune(st_name); - - if (!st) - return -EINVAL; - - return _do_stune_boost(st, st->sched_boost, slot); -} - -int do_stune_boost(char *st_name, int boost, int *slot) -{ - struct schedtune *st = getSchedtune(st_name); - - if (!st) - return -EINVAL; - - return _do_stune_boost(st, boost, slot); -} - -#endif /* CONFIG_DYNAMIC_STUNE_BOOST */ - /* * Initialize the cgroup structures */ diff --git a/kernel/sched/walt.c b/kernel/sched/walt.c index b1b30867460f..407d4a8a47c0 100644 --- a/kernel/sched/walt.c +++ b/kernel/sched/walt.c @@ -432,22 +432,27 @@ void sched_account_irqtime(int cpu, struct task_struct *curr, u64 delta, u64 wallclock) { struct rq *rq = cpu_rq(cpu); - unsigned long flags, nr_windows; + unsigned long nr_windows; u64 cur_jiffies_ts; - raw_spin_lock_irqsave(&rq->lock, flags); - /* - * cputime (wallclock) uses sched_clock so use the same here for - * consistency. + * We called with interrupts disabled. Take the rq lock only + * if we are in idle context in which case update_task_ravg() + * call is needed. */ - delta += sched_clock() - wallclock; - cur_jiffies_ts = get_jiffies_64(); - - if (is_idle_task(curr)) + if (is_idle_task(curr)) { + raw_spin_lock(&rq->lock); + /* + * cputime (wallclock) uses sched_clock so use the same here + * for consistency. + */ + delta += sched_clock() - wallclock; update_task_ravg(curr, rq, IRQ_UPDATE, sched_ktime_clock(), delta); + raw_spin_unlock(&rq->lock); + } + cur_jiffies_ts = get_jiffies_64(); nr_windows = cur_jiffies_ts - rq->irqload_ts; if (nr_windows) { @@ -465,7 +470,6 @@ void sched_account_irqtime(int cpu, struct task_struct *curr, rq->cur_irqload += delta; rq->irqload_ts = cur_jiffies_ts; - raw_spin_unlock_irqrestore(&rq->lock, flags); } /* @@ -2658,7 +2662,6 @@ static void transfer_busy_time(struct rq *rq, struct related_thread_group *grp, * Enable colocation and frequency aggregation for all threads in a process. * The children inherits the group id from the parent. */ -unsigned int __read_mostly sysctl_sched_enable_thread_grouping; unsigned int __read_mostly sysctl_sched_coloc_downmigrate_ns; struct related_thread_group *related_thread_groups[MAX_NUM_CGROUP_COLOC_ID]; @@ -2930,34 +2933,25 @@ void add_new_task_to_grp(struct task_struct *new) { unsigned long flags; struct related_thread_group *grp; - struct task_struct *leader = new->group_leader; - unsigned int leader_grp_id = sched_get_group_id(leader); - if (!sysctl_sched_enable_thread_grouping && - leader_grp_id != DEFAULT_CGROUP_COLOC_ID) + /* + * If the task does not belong to colocated schedtune + * cgroup, nothing to do. We are checking this without + * lock. Even if there is a race, it will be added + * to the co-located cgroup via cgroup attach. + */ + if (!schedtune_task_colocated(new)) return; - if (thread_group_leader(new)) - return; - - if (leader_grp_id == DEFAULT_CGROUP_COLOC_ID) { - if (!same_schedtune(new, leader)) - return; - } - + grp = lookup_related_thread_group(DEFAULT_CGROUP_COLOC_ID); write_lock_irqsave(&related_thread_group_lock, flags); - rcu_read_lock(); - grp = task_related_thread_group(leader); - rcu_read_unlock(); - /* * It's possible that someone already added the new task to the - * group. A leader's thread group is updated prior to calling - * this function. It's also possible that the leader has exited - * the group. In either case, there is nothing else to do. + * group. or it might have taken out from the colocated schedtune + * cgroup. check these conditions under lock. */ - if (!grp || new->grp) { + if (!schedtune_task_colocated(new) || new->grp) { write_unlock_irqrestore(&related_thread_group_lock, flags); return; } @@ -3562,6 +3556,9 @@ int walt_proc_group_thresholds_handler(struct ctl_table *table, int write, struct rq *rq = cpu_rq(cpumask_first(cpu_possible_mask)); unsigned long flags; + if (unlikely(num_sched_clusters <= 0)) + return -EPERM; + mutex_lock(&mutex); ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); if (ret || !write) { diff --git a/kernel/sys.c b/kernel/sys.c index a08073ebf19a..60d18b36c6d6 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1182,6 +1182,28 @@ static int override_release(char __user *release, size_t len) return ret; } +static int override_version(struct new_utsname __user *name) +{ +#ifdef CONFIG_F2FS_REPORT_FAKE_KERNEL_VERSION + int ret; + + if (strcmp(current->comm, "fsck.f2fs")) + return 0; + + ret = copy_to_user(name->release, CONFIG_F2FS_FAKE_KERNEL_RELEASE, + strlen(CONFIG_F2FS_FAKE_KERNEL_RELEASE) + 1); + if (ret) + return ret; + + ret = copy_to_user(name->version, CONFIG_F2FS_FAKE_KERNEL_VERSION, + strlen(CONFIG_F2FS_FAKE_KERNEL_VERSION) + 1); + + return ret; +#else + return 0; +#endif +} + SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name) { struct new_utsname tmp; @@ -1196,6 +1218,8 @@ SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name) return -EFAULT; if (override_architecture(name)) return -EFAULT; + if (override_version(name)) + return -EFAULT; return 0; } diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 743e3885c7dd..4446802629a8 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -3385,7 +3385,8 @@ int proc_do_large_bitmap(struct ctl_table *table, int write, if (IS_ERR(kbuf)) return PTR_ERR(kbuf); - tmp_bitmap = kzalloc(BITS_TO_LONGS(bitmap_len) * sizeof(unsigned long), + tmp_bitmap = kcalloc(BITS_TO_LONGS(bitmap_len), + sizeof(unsigned long), GFP_KERNEL); if (!tmp_bitmap) { kfree(kbuf); diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index f5ba5d99c349..6b063bc295cb 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -102,7 +102,6 @@ static int alarmtimer_rtc_add_device(struct device *dev, struct class_interface *class_intf) { unsigned long flags; - int err = 0; struct rtc_device *rtc = to_rtc_device(dev); struct wakeup_source *__ws; int ret = 0; @@ -122,8 +121,8 @@ static int alarmtimer_rtc_add_device(struct device *dev, goto rtc_irq_reg_err; } - err = rtc_irq_register(rtc, &alarmtimer_rtc_task); - if (err) + ret = rtc_irq_register(rtc, &alarmtimer_rtc_task); + if (ret) goto rtc_irq_reg_err; rtcdev = rtc; @@ -137,7 +136,7 @@ rtc_irq_reg_err: spin_unlock_irqrestore(&rtcdev_lock, flags); wakeup_source_unregister(__ws); - return err; + return ret; } static void alarmtimer_rtc_remove_device(struct device *dev, diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 9b700833b810..ba5a2bc2c7de 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -1648,6 +1649,13 @@ void update_process_times(int user_tick) scheduler_tick(); if (IS_ENABLED(CONFIG_POSIX_TIMERS)) run_posix_cpu_timers(p); + + /* The current CPU might make use of net randoms without receiving IRQs + * to renew them often enough. Let's update the net_rand_state from a + * non-constant value that's not affine to the number of calls to make + * sure it's updated when there's some activity (we don't care in idle). + */ + this_cpu_add(net_rand_state.s1, rol32(jiffies, 24) + user_tick); } /** diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 5cc253f8fbf7..03eed9b1a717 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -759,7 +759,7 @@ static int ftrace_profile_init_cpu(int cpu) */ size = FTRACE_PROFILE_HASH_SIZE; - stat->hash = kzalloc(sizeof(struct hlist_head) * size, GFP_KERNEL); + stat->hash = kcalloc(size, sizeof(struct hlist_head), GFP_KERNEL); if (!stat->hash) return -ENOMEM; @@ -6631,9 +6631,9 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list) struct task_struct *g, *t; for (i = 0; i < FTRACE_RETSTACK_ALLOC_SIZE; i++) { - ret_stack_list[i] = kmalloc(FTRACE_RETFUNC_DEPTH - * sizeof(struct ftrace_ret_stack), - GFP_KERNEL); + ret_stack_list[i] = kmalloc_array(FTRACE_RETFUNC_DEPTH, + sizeof(struct ftrace_ret_stack), + GFP_KERNEL); if (!ret_stack_list[i]) { start = 0; end = i; @@ -6705,9 +6705,9 @@ static int start_graph_tracing(void) struct ftrace_ret_stack **ret_stack_list; int ret, cpu; - ret_stack_list = kmalloc(FTRACE_RETSTACK_ALLOC_SIZE * - sizeof(struct ftrace_ret_stack *), - GFP_KERNEL); + ret_stack_list = kmalloc_array(FTRACE_RETSTACK_ALLOC_SIZE, + sizeof(struct ftrace_ret_stack *), + GFP_KERNEL); if (!ret_stack_list) return -ENOMEM; @@ -6889,9 +6889,9 @@ void ftrace_graph_init_idle_task(struct task_struct *t, int cpu) ret_stack = per_cpu(idle_ret_stack, cpu); if (!ret_stack) { - ret_stack = kmalloc(FTRACE_RETFUNC_DEPTH - * sizeof(struct ftrace_ret_stack), - GFP_KERNEL); + ret_stack = kmalloc_array(FTRACE_RETFUNC_DEPTH, + sizeof(struct ftrace_ret_stack), + GFP_KERNEL); if (!ret_stack) return; per_cpu(idle_ret_stack, cpu) = ret_stack; @@ -6910,9 +6910,9 @@ void ftrace_graph_init_task(struct task_struct *t) if (ftrace_graph_active) { struct ftrace_ret_stack *ret_stack; - ret_stack = kmalloc(FTRACE_RETFUNC_DEPTH - * sizeof(struct ftrace_ret_stack), - GFP_KERNEL); + ret_stack = kmalloc_array(FTRACE_RETFUNC_DEPTH, + sizeof(struct ftrace_ret_stack), + GFP_KERNEL); if (!ret_stack) return; graph_init_task(t, ret_stack); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 9e93ef4969e7..f0f9cccf5981 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1754,12 +1754,13 @@ static inline void set_cmdline(int idx, const char *cmdline) static int allocate_cmdlines_buffer(unsigned int val, struct saved_cmdlines_buffer *s) { - s->map_cmdline_to_pid = kmalloc(val * sizeof(*s->map_cmdline_to_pid), - GFP_KERNEL); + s->map_cmdline_to_pid = kmalloc_array(val, + sizeof(*s->map_cmdline_to_pid), + GFP_KERNEL); if (!s->map_cmdline_to_pid) return -ENOMEM; - s->saved_cmdlines = kmalloc(val * TASK_COMM_LEN, GFP_KERNEL); + s->saved_cmdlines = kmalloc_array(TASK_COMM_LEN, val, GFP_KERNEL); if (!s->saved_cmdlines) { kfree(s->map_cmdline_to_pid); return -ENOMEM; @@ -4399,7 +4400,8 @@ int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled) if (mask == TRACE_ITER_RECORD_TGID) { if (!tgid_map) - tgid_map = kzalloc((PID_MAX_DEFAULT + 1) * sizeof(*tgid_map), + tgid_map = kcalloc(PID_MAX_DEFAULT + 1, + sizeof(*tgid_map), GFP_KERNEL); if (!tgid_map) { tr->trace_flags &= ~TRACE_ITER_RECORD_TGID; @@ -5105,7 +5107,7 @@ trace_insert_eval_map_file(struct module *mod, struct trace_eval_map **start, * where the head holds the module and length of array, and the * tail holds a pointer to the next list. */ - map_array = kmalloc(sizeof(*map_array) * (len + 2), GFP_KERNEL); + map_array = kmalloc_array(len + 2, sizeof(*map_array), GFP_KERNEL); if (!map_array) { pr_warn("Unable to allocate trace eval mapping\n"); return; diff --git a/kernel/trace/tracing_map.c b/kernel/trace/tracing_map.c index 35b2ba07f3c6..300a97a90dcd 100644 --- a/kernel/trace/tracing_map.c +++ b/kernel/trace/tracing_map.c @@ -1003,7 +1003,7 @@ int tracing_map_sort_entries(struct tracing_map *map, struct tracing_map_sort_entry *sort_entry, **entries; int i, n_entries, ret; - entries = vmalloc(map->max_elts * sizeof(sort_entry)); + entries = vmalloc(array_size(sizeof(sort_entry), map->max_elts)); if (!entries) return -ENOMEM; diff --git a/kernel/workqueue.c b/kernel/workqueue.c index f93f40dd7aaf..7a51c266e082 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -3713,8 +3713,7 @@ apply_wqattrs_prepare(struct workqueue_struct *wq, lockdep_assert_held(&wq_pool_mutex); - ctx = kzalloc(sizeof(*ctx) + nr_node_ids * sizeof(ctx->pwq_tbl[0]), - GFP_KERNEL); + ctx = kzalloc(struct_size(ctx, pwq_tbl, nr_node_ids), GFP_KERNEL); new_attrs = alloc_workqueue_attrs(GFP_KERNEL); tmp_attrs = alloc_workqueue_attrs(GFP_KERNEL); @@ -5626,7 +5625,7 @@ static void __init wq_numa_init(void) * available. Build one from cpu_to_node() which should have been * fully initialized by now. */ - tbl = kzalloc(nr_node_ids * sizeof(tbl[0]), GFP_KERNEL); + tbl = kcalloc(nr_node_ids, sizeof(tbl[0]), GFP_KERNEL); BUG_ON(!tbl); for_each_node(node) diff --git a/lib/Kconfig b/lib/Kconfig index eec1142136dc..4c3d414495ef 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -285,6 +285,10 @@ config DECOMPRESS_LZ4 select LZ4_DECOMPRESS tristate +config DECOMPRESS_ZSTD + select ZSTD_DECOMPRESS + tristate + # # Generic allocator support is selected if needed # diff --git a/lib/Makefile b/lib/Makefile index 4cfeba73334b..6ae07fbc71f6 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -148,6 +148,7 @@ lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o lib-$(CONFIG_DECOMPRESS_XZ) += decompress_unxz.o lib-$(CONFIG_DECOMPRESS_LZO) += decompress_unlzo.o lib-$(CONFIG_DECOMPRESS_LZ4) += decompress_unlz4.o +lib-$(CONFIG_DECOMPRESS_ZSTD) += decompress_unzstd.o obj-$(CONFIG_TEXTSEARCH) += textsearch.o obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o diff --git a/lib/argv_split.c b/lib/argv_split.c index 5c35752a9414..1a19a0a93dc1 100644 --- a/lib/argv_split.c +++ b/lib/argv_split.c @@ -69,7 +69,7 @@ char **argv_split(gfp_t gfp, const char *str, int *argcp) return NULL; argc = count_argc(argv_str); - argv = kmalloc(sizeof(*argv) * (argc + 2), gfp); + argv = kmalloc_array(argc + 2, sizeof(*argv), gfp); if (!argv) { kfree(argv_str); return NULL; diff --git a/lib/decompress.c b/lib/decompress.c index 857ab1af1ef3..ab3fc90ffc64 100644 --- a/lib/decompress.c +++ b/lib/decompress.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,9 @@ #ifndef CONFIG_DECOMPRESS_LZ4 # define unlz4 NULL #endif +#ifndef CONFIG_DECOMPRESS_ZSTD +# define unzstd NULL +#endif struct compress_format { unsigned char magic[2]; @@ -52,6 +56,7 @@ static const struct compress_format compressed_formats[] __initconst = { { {0xfd, 0x37}, "xz", unxz }, { {0x89, 0x4c}, "lzo", unlzo }, { {0x02, 0x21}, "lz4", unlz4 }, + { {0x28, 0xb5}, "zstd", unzstd }, { {0, 0}, NULL, NULL } }; diff --git a/lib/decompress_unzstd.c b/lib/decompress_unzstd.c new file mode 100644 index 000000000000..0ad2c15479ed --- /dev/null +++ b/lib/decompress_unzstd.c @@ -0,0 +1,345 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Important notes about in-place decompression + * + * At least on x86, the kernel is decompressed in place: the compressed data + * is placed to the end of the output buffer, and the decompressor overwrites + * most of the compressed data. There must be enough safety margin to + * guarantee that the write position is always behind the read position. + * + * The safety margin for ZSTD with a 128 KB block size is calculated below. + * Note that the margin with ZSTD is bigger than with GZIP or XZ! + * + * The worst case for in-place decompression is that the beginning of + * the file is compressed extremely well, and the rest of the file is + * uncompressible. Thus, we must look for worst-case expansion when the + * compressor is encoding uncompressible data. + * + * The structure of the .zst file in case of a compresed kernel is as follows. + * Maximum sizes (as bytes) of the fields are in parenthesis. + * + * Frame Header: (18) + * Blocks: (N) + * Checksum: (4) + * + * The frame header and checksum overhead is at most 22 bytes. + * + * ZSTD stores the data in blocks. Each block has a header whose size is + * a 3 bytes. After the block header, there is up to 128 KB of payload. + * The maximum uncompressed size of the payload is 128 KB. The minimum + * uncompressed size of the payload is never less than the payload size + * (excluding the block header). + * + * The assumption, that the uncompressed size of the payload is never + * smaller than the payload itself, is valid only when talking about + * the payload as a whole. It is possible that the payload has parts where + * the decompressor consumes more input than it produces output. Calculating + * the worst case for this would be tricky. Instead of trying to do that, + * let's simply make sure that the decompressor never overwrites any bytes + * of the payload which it is currently reading. + * + * Now we have enough information to calculate the safety margin. We need + * - 22 bytes for the .zst file format headers; + * - 3 bytes per every 128 KiB of uncompressed size (one block header per + * block); and + * - 128 KiB (biggest possible zstd block size) to make sure that the + * decompressor never overwrites anything from the block it is currently + * reading. + * + * We get the following formula: + * + * safety_margin = 22 + uncompressed_size * 3 / 131072 + 131072 + * <= 22 + (uncompressed_size >> 15) + 131072 + */ + +/* + * Preboot environments #include "path/to/decompress_unzstd.c". + * All of the source files we depend on must be #included. + * zstd's only source dependeny is xxhash, which has no source + * dependencies. + * + * When UNZSTD_PREBOOT is defined we declare __decompress(), which is + * used for kernel decompression, instead of unzstd(). + * + * Define __DISABLE_EXPORTS in preboot environments to prevent symbols + * from xxhash and zstd from being exported by the EXPORT_SYMBOL macro. + */ +#ifdef STATIC +# define UNZSTD_PREBOOT +# include "xxhash.c" +# include "zstd/entropy_common.c" +# include "zstd/fse_decompress.c" +# include "zstd/huf_decompress.c" +# include "zstd/zstd_common.c" +# include "zstd/decompress.c" +#endif + +#include +#include +#include + +/* 128MB is the maximum window size supported by zstd. */ +#define ZSTD_WINDOWSIZE_MAX (1 << ZSTD_WINDOWLOG_MAX) +/* + * Size of the input and output buffers in multi-call mode. + * Pick a larger size because it isn't used during kernel decompression, + * since that is single pass, and we have to allocate a large buffer for + * zstd's window anyway. The larger size speeds up initramfs decompression. + */ +#define ZSTD_IOBUF_SIZE (1 << 17) + +static int INIT handle_zstd_error(size_t ret, void (*error)(char *x)) +{ + const int err = ZSTD_getErrorCode(ret); + + if (!ZSTD_isError(ret)) + return 0; + + switch (err) { + case ZSTD_error_memory_allocation: + error("ZSTD decompressor ran out of memory"); + break; + case ZSTD_error_prefix_unknown: + error("Input is not in the ZSTD format (wrong magic bytes)"); + break; + case ZSTD_error_dstSize_tooSmall: + case ZSTD_error_corruption_detected: + case ZSTD_error_checksum_wrong: + error("ZSTD-compressed data is corrupt"); + break; + default: + error("ZSTD-compressed data is probably corrupt"); + break; + } + return -1; +} + +/* + * Handle the case where we have the entire input and output in one segment. + * We can allocate less memory (no circular buffer for the sliding window), + * and avoid some memcpy() calls. + */ +static int INIT decompress_single(const u8 *in_buf, long in_len, u8 *out_buf, + long out_len, long *in_pos, + void (*error)(char *x)) +{ + const size_t wksp_size = ZSTD_DCtxWorkspaceBound(); + void *wksp = large_malloc(wksp_size); + ZSTD_DCtx *dctx = ZSTD_initDCtx(wksp, wksp_size); + int err; + size_t ret; + + if (dctx == NULL) { + error("Out of memory while allocating ZSTD_DCtx"); + err = -1; + goto out; + } + /* + * Find out how large the frame actually is, there may be junk at + * the end of the frame that ZSTD_decompressDCtx() can't handle. + */ + ret = ZSTD_findFrameCompressedSize(in_buf, in_len); + err = handle_zstd_error(ret, error); + if (err) + goto out; + in_len = (long)ret; + + ret = ZSTD_decompressDCtx(dctx, out_buf, out_len, in_buf, in_len); + err = handle_zstd_error(ret, error); + if (err) + goto out; + + if (in_pos != NULL) + *in_pos = in_len; + + err = 0; +out: + if (wksp != NULL) + large_free(wksp); + return err; +} + +static int INIT __unzstd(unsigned char *in_buf, long in_len, + long (*fill)(void*, unsigned long), + long (*flush)(void*, unsigned long), + unsigned char *out_buf, long out_len, + long *in_pos, + void (*error)(char *x)) +{ + ZSTD_inBuffer in; + ZSTD_outBuffer out; + ZSTD_frameParams params; + void *in_allocated = NULL; + void *out_allocated = NULL; + void *wksp = NULL; + size_t wksp_size; + ZSTD_DStream *dstream; + int err; + size_t ret; + + if (out_len == 0) + out_len = LONG_MAX; /* no limit */ + + if (fill == NULL && flush == NULL) + /* + * We can decompress faster and with less memory when we have a + * single chunk. + */ + return decompress_single(in_buf, in_len, out_buf, out_len, + in_pos, error); + + /* + * If in_buf is not provided, we must be using fill(), so allocate + * a large enough buffer. If it is provided, it must be at least + * ZSTD_IOBUF_SIZE large. + */ + if (in_buf == NULL) { + in_allocated = large_malloc(ZSTD_IOBUF_SIZE); + if (in_allocated == NULL) { + error("Out of memory while allocating input buffer"); + err = -1; + goto out; + } + in_buf = in_allocated; + in_len = 0; + } + /* Read the first chunk, since we need to decode the frame header. */ + if (fill != NULL) + in_len = fill(in_buf, ZSTD_IOBUF_SIZE); + if (in_len < 0) { + error("ZSTD-compressed data is truncated"); + err = -1; + goto out; + } + /* Set the first non-empty input buffer. */ + in.src = in_buf; + in.pos = 0; + in.size = in_len; + /* Allocate the output buffer if we are using flush(). */ + if (flush != NULL) { + out_allocated = large_malloc(ZSTD_IOBUF_SIZE); + if (out_allocated == NULL) { + error("Out of memory while allocating output buffer"); + err = -1; + goto out; + } + out_buf = out_allocated; + out_len = ZSTD_IOBUF_SIZE; + } + /* Set the output buffer. */ + out.dst = out_buf; + out.pos = 0; + out.size = out_len; + + /* + * We need to know the window size to allocate the ZSTD_DStream. + * Since we are streaming, we need to allocate a buffer for the sliding + * window. The window size varies from 1 KB to ZSTD_WINDOWSIZE_MAX + * (8 MB), so it is important to use the actual value so as not to + * waste memory when it is smaller. + */ + ret = ZSTD_getFrameParams(¶ms, in.src, in.size); + err = handle_zstd_error(ret, error); + if (err) + goto out; + if (ret != 0) { + error("ZSTD-compressed data has an incomplete frame header"); + err = -1; + goto out; + } + if (params.windowSize > ZSTD_WINDOWSIZE_MAX) { + error("ZSTD-compressed data has too large a window size"); + err = -1; + goto out; + } + + /* + * Allocate the ZSTD_DStream now that we know how much memory is + * required. + */ + wksp_size = ZSTD_DStreamWorkspaceBound(params.windowSize); + wksp = large_malloc(wksp_size); + dstream = ZSTD_initDStream(params.windowSize, wksp, wksp_size); + if (dstream == NULL) { + error("Out of memory while allocating ZSTD_DStream"); + err = -1; + goto out; + } + + /* + * Decompression loop: + * Read more data if necessary (error if no more data can be read). + * Call the decompression function, which returns 0 when finished. + * Flush any data produced if using flush(). + */ + if (in_pos != NULL) + *in_pos = 0; + do { + /* + * If we need to reload data, either we have fill() and can + * try to get more data, or we don't and the input is truncated. + */ + if (in.pos == in.size) { + if (in_pos != NULL) + *in_pos += in.pos; + in_len = fill ? fill(in_buf, ZSTD_IOBUF_SIZE) : -1; + if (in_len < 0) { + error("ZSTD-compressed data is truncated"); + err = -1; + goto out; + } + in.pos = 0; + in.size = in_len; + } + /* Returns zero when the frame is complete. */ + ret = ZSTD_decompressStream(dstream, &out, &in); + err = handle_zstd_error(ret, error); + if (err) + goto out; + /* Flush all of the data produced if using flush(). */ + if (flush != NULL && out.pos > 0) { + if (out.pos != flush(out.dst, out.pos)) { + error("Failed to flush()"); + err = -1; + goto out; + } + out.pos = 0; + } + } while (ret != 0); + + if (in_pos != NULL) + *in_pos += in.pos; + + err = 0; +out: + if (in_allocated != NULL) + large_free(in_allocated); + if (out_allocated != NULL) + large_free(out_allocated); + if (wksp != NULL) + large_free(wksp); + return err; +} + +#ifndef UNZSTD_PREBOOT +STATIC int INIT unzstd(unsigned char *buf, long len, + long (*fill)(void*, unsigned long), + long (*flush)(void*, unsigned long), + unsigned char *out_buf, + long *pos, + void (*error)(char *x)) +{ + return __unzstd(buf, len, fill, flush, out_buf, 0, pos, error); +} +#else +STATIC int INIT __decompress(unsigned char *buf, long len, + long (*fill)(void*, unsigned long), + long (*flush)(void*, unsigned long), + unsigned char *out_buf, long out_len, + long *pos, + void (*error)(char *x)) +{ + return __unzstd(buf, len, fill, flush, out_buf, out_len, pos, error); +} +#endif diff --git a/lib/interval_tree_test.c b/lib/interval_tree_test.c index 835242e74aaa..75509a1511a3 100644 --- a/lib/interval_tree_test.c +++ b/lib/interval_tree_test.c @@ -64,11 +64,12 @@ static int interval_tree_test_init(void) unsigned long results; cycles_t time1, time2, time; - nodes = kmalloc(nnodes * sizeof(struct interval_tree_node), GFP_KERNEL); + nodes = kmalloc_array(nnodes, sizeof(struct interval_tree_node), + GFP_KERNEL); if (!nodes) return -ENOMEM; - queries = kmalloc(nsearches * sizeof(int), GFP_KERNEL); + queries = kmalloc_array(nsearches, sizeof(int), GFP_KERNEL); if (!queries) { kfree(nodes); return -ENOMEM; diff --git a/lib/kfifo.c b/lib/kfifo.c index a94227c55551..6cfca1be8e6f 100644 --- a/lib/kfifo.c +++ b/lib/kfifo.c @@ -54,7 +54,7 @@ int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, return -EINVAL; } - fifo->data = kmalloc(size * esize, gfp_mask); + fifo->data = kmalloc_array(esize, size, gfp_mask); if (!fifo->data) { fifo->mask = 0; diff --git a/lib/lru_cache.c b/lib/lru_cache.c index 28ba40b99337..2b10a4024c35 100644 --- a/lib/lru_cache.c +++ b/lib/lru_cache.c @@ -119,7 +119,7 @@ struct lru_cache *lc_create(const char *name, struct kmem_cache *cache, slot = kcalloc(e_count, sizeof(struct hlist_head), GFP_KERNEL); if (!slot) goto out_fail; - element = kzalloc(e_count * sizeof(struct lc_element *), GFP_KERNEL); + element = kcalloc(e_count, sizeof(struct lc_element *), GFP_KERNEL); if (!element) goto out_fail; diff --git a/lib/lz4/lz4_compress.c b/lib/lz4/lz4_compress.c index 187ecdfae375..aa09d3cae270 100644 --- a/lib/lz4/lz4_compress.c +++ b/lib/lz4/lz4_compress.c @@ -395,7 +395,7 @@ _last_literals: *op++ = (BYTE)(lastRun << ML_BITS); } - memcpy(op, anchor, lastRun); + LZ4_memcpy(op, anchor, lastRun); op += lastRun; } diff --git a/lib/lz4/lz4_decompress.c b/lib/lz4/lz4_decompress.c index 0aa27c80a9f2..72869743fca4 100644 --- a/lib/lz4/lz4_decompress.c +++ b/lib/lz4/lz4_decompress.c @@ -149,7 +149,7 @@ static FORCE_INLINE int LZ4_decompress_generic( && likely((endOnInput ? ip < shortiend : 1) & (op <= shortoend))) { /* Copy the literals */ - memcpy(op, ip, endOnInput ? 16 : 8); + LZ4_memcpy(op, ip, endOnInput ? 16 : 8); op += length; ip += length; /* @@ -168,9 +168,9 @@ static FORCE_INLINE int LZ4_decompress_generic( (offset >= 8) && (dict == withPrefix64k || match >= lowPrefix)) { /* Copy the match. */ - memcpy(op + 0, match + 0, 8); - memcpy(op + 8, match + 8, 8); - memcpy(op + 16, match + 16, 2); + LZ4_memcpy(op + 0, match + 0, 8); + LZ4_memcpy(op + 8, match + 8, 8); + LZ4_memcpy(op + 16, match + 16, 2); op += length + MINMATCH; /* Both stages worked, load the next token. */ continue; @@ -259,7 +259,7 @@ static FORCE_INLINE int LZ4_decompress_generic( } } - memcpy(op, ip, length); + LZ4_memcpy(op, ip, length); ip += length; op += length; @@ -340,7 +340,7 @@ _copy_match: while (op < copyEnd) *op++ = *match++; } else { - memcpy(op, match, mlen); + LZ4_memcpy(op, match, mlen); } op = copyEnd; if (op == oend) @@ -354,7 +354,7 @@ _copy_match: op[2] = match[2]; op[3] = match[3]; match += inc32table[offset]; - memcpy(op + 4, match, 4); + LZ4_memcpy(op + 4, match, 4); match -= dec64table[offset]; } else { LZ4_copy8(op, match); diff --git a/lib/lz4/lz4defs.h b/lib/lz4/lz4defs.h index bfb9ba5181a8..49e637d7bdbe 100644 --- a/lib/lz4/lz4defs.h +++ b/lib/lz4/lz4defs.h @@ -137,6 +137,16 @@ static FORCE_INLINE void LZ4_writeLE16(void *memPtr, U16 value) return put_unaligned_le16(value, memPtr); } +/* + * LZ4 relies on memcpy with a constant size being inlined. In freestanding + * environments, the compiler can't assume the implementation of memcpy() is + * standard compliant, so apply its specialized memcpy() inlining logic. When + * possible, use __builtin_memcpy() to tell the compiler to analyze memcpy() + * as-if it were standard compliant, so it can inline it in freestanding + * environments. This is needed when decompressing the Linux Kernel, for example. + */ +#define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size) + static FORCE_INLINE void LZ4_copy8(void *dst, const void *src) { #if LZ4_ARCH64 diff --git a/lib/lz4/lz4hc_compress.c b/lib/lz4/lz4hc_compress.c index a67c8e5f765f..be8bfa09a74a 100644 --- a/lib/lz4/lz4hc_compress.c +++ b/lib/lz4/lz4hc_compress.c @@ -570,7 +570,7 @@ _Search3: *op++ = (BYTE) lastRun; } else *op++ = (BYTE)(lastRun<d) { - p = kmalloc(nlimbs * sizeof(mpi_limb_t), GFP_KERNEL); + p = kmalloc_array(nlimbs, sizeof(mpi_limb_t), GFP_KERNEL); if (!p) return -ENOMEM; memcpy(p, a->d, a->alloced * sizeof(mpi_limb_t)); kzfree(a->d); a->d = p; } else { - a->d = kzalloc(nlimbs * sizeof(mpi_limb_t), GFP_KERNEL); + a->d = kcalloc(nlimbs, sizeof(mpi_limb_t), GFP_KERNEL); if (!a->d) return -ENOMEM; } diff --git a/lib/random32.c b/lib/random32.c index 0a90cb0e0fb6..6e2c48ab8072 100644 --- a/lib/random32.c +++ b/lib/random32.c @@ -48,7 +48,7 @@ static inline void prandom_state_selftest(void) } #endif -static DEFINE_PER_CPU(struct rnd_state, net_rand_state) __latent_entropy; +DEFINE_PER_CPU(struct rnd_state, net_rand_state); /** * prandom_u32_state - seeded pseudo-random number generator. diff --git a/lib/rbtree_test.c b/lib/rbtree_test.c index 7d36c1e27ff6..b7055b2a07d3 100644 --- a/lib/rbtree_test.c +++ b/lib/rbtree_test.c @@ -247,7 +247,7 @@ static int __init rbtree_test_init(void) cycles_t time1, time2, time; struct rb_node *node; - nodes = kmalloc(nnodes * sizeof(*nodes), GFP_KERNEL); + nodes = kmalloc_array(nnodes, sizeof(*nodes), GFP_KERNEL); if (!nodes) return -ENOMEM; diff --git a/lib/reed_solomon/reed_solomon.c b/lib/reed_solomon/reed_solomon.c index 3a1022a80a7b..e99b43f74645 100644 --- a/lib/reed_solomon/reed_solomon.c +++ b/lib/reed_solomon/reed_solomon.c @@ -85,15 +85,15 @@ static struct rs_control *rs_init(int symsize, int gfpoly, int (*gffunc)(int), rs->gffunc = gffunc; /* Allocate the arrays */ - rs->alpha_to = kmalloc(sizeof(uint16_t) * (rs->nn + 1), GFP_KERNEL); + rs->alpha_to = kmalloc_array(rs->nn + 1, sizeof(uint16_t), GFP_KERNEL); if (rs->alpha_to == NULL) goto errrs; - rs->index_of = kmalloc(sizeof(uint16_t) * (rs->nn + 1), GFP_KERNEL); + rs->index_of = kmalloc_array(rs->nn + 1, sizeof(uint16_t), GFP_KERNEL); if (rs->index_of == NULL) goto erralp; - rs->genpoly = kmalloc(sizeof(uint16_t) * (rs->nroots + 1), GFP_KERNEL); + rs->genpoly = kmalloc_array(rs->nroots + 1, sizeof(uint16_t), GFP_KERNEL); if(rs->genpoly == NULL) goto erridx; diff --git a/lib/rhashtable.c b/lib/rhashtable.c index cb577ca65fa9..5300fd900e12 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c @@ -87,7 +87,8 @@ static int alloc_bucket_locks(struct rhashtable *ht, struct bucket_table *tbl, if (sizeof(spinlock_t) != 0) { if (gfpflags_allow_blocking(gfp)) - tbl->locks = kvmalloc(size * sizeof(spinlock_t), gfp); + tbl->locks = kvmalloc_array(size, sizeof(spinlock_t), + gfp); else tbl->locks = kmalloc_array(size, sizeof(spinlock_t), gfp); diff --git a/lib/sbitmap.c b/lib/sbitmap.c index 5abaa9a3ba29..4dadde573b24 100644 --- a/lib/sbitmap.c +++ b/lib/sbitmap.c @@ -52,7 +52,7 @@ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift, return 0; } - sb->map = kzalloc_node(sb->map_nr * sizeof(*sb->map), flags, node); + sb->map = kcalloc_node(sb->map_nr, sizeof(*sb->map), flags, node); if (!sb->map) return -ENOMEM; diff --git a/lib/scatterlist.c b/lib/scatterlist.c index a11127d47b33..59c02cca45da 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -163,7 +163,7 @@ EXPORT_SYMBOL(sg_init_one); */ static struct scatterlist *sg_kmalloc(unsigned int nents, gfp_t gfp_mask) { - return kmalloc(nents * sizeof(struct scatterlist), gfp_mask); + return kmalloc_array(nents, sizeof(struct scatterlist), gfp_mask); } static void sg_kfree(struct scatterlist *sg, unsigned int nents) diff --git a/lib/seq_buf.c b/lib/seq_buf.c index 6aabb609dd87..767958cc4c68 100644 --- a/lib/seq_buf.c +++ b/lib/seq_buf.c @@ -91,6 +91,7 @@ int seq_buf_printf(struct seq_buf *s, const char *fmt, ...) return ret; } +EXPORT_SYMBOL_GPL(seq_buf_printf); #ifdef CONFIG_BINARY_PRINTF /** diff --git a/lib/strncpy_from_user.c b/lib/strncpy_from_user.c index 56a5981ba968..0dae80047372 100644 --- a/lib/strncpy_from_user.c +++ b/lib/strncpy_from_user.c @@ -98,6 +98,7 @@ long strncpy_from_user(char *dst, const char __user *src, long count) { unsigned long max_addr, src_addr; + might_fault(); if (unlikely(count <= 0)) return 0; diff --git a/lib/test_firmware.c b/lib/test_firmware.c index 2e5e18bbfd28..b31c7c82ce55 100644 --- a/lib/test_firmware.c +++ b/lib/test_firmware.c @@ -621,8 +621,7 @@ static ssize_t trigger_batched_requests_store(struct device *dev, mutex_lock(&test_fw_mutex); - test_fw_config->reqs = vzalloc(sizeof(struct test_batched_req) * - test_fw_config->num_requests * 2); + test_fw_config->reqs = vzalloc(array3_size(sizeof(struct test_batched_req), test_fw_config->num_requests, 2)); if (!test_fw_config->reqs) { rc = -ENOMEM; goto out_unlock; @@ -723,8 +722,7 @@ ssize_t trigger_batched_requests_async_store(struct device *dev, mutex_lock(&test_fw_mutex); - test_fw_config->reqs = vzalloc(sizeof(struct test_batched_req) * - test_fw_config->num_requests * 2); + test_fw_config->reqs = vzalloc(array3_size(sizeof(struct test_batched_req), test_fw_config->num_requests, 2)); if (!test_fw_config->reqs) { rc = -ENOMEM; goto out; diff --git a/lib/test_kmod.c b/lib/test_kmod.c index cf619795a182..dc1c2248ceda 100644 --- a/lib/test_kmod.c +++ b/lib/test_kmod.c @@ -781,8 +781,7 @@ static int kmod_config_sync_info(struct kmod_test_device *test_dev) struct test_config *config = &test_dev->config; free_test_dev_info(test_dev); - test_dev->info = vzalloc(config->num_threads * - sizeof(struct kmod_test_device_info)); + test_dev->info = vzalloc(array_size(sizeof(struct kmod_test_device_info), config->num_threads)); if (!test_dev->info) { dev_err(test_dev->dev, "Cannot alloc test_dev info\n"); return -ENOMEM; diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c index 0ffca990a833..ed60c452e639 100644 --- a/lib/test_rhashtable.c +++ b/lib/test_rhashtable.c @@ -383,10 +383,10 @@ static int __init test_rht_init(void) pr_info("Testing concurrent rhashtable access from %d threads\n", tcount); sema_init(&prestart_sem, 1 - tcount); - tdata = vzalloc(tcount * sizeof(struct thread_data)); + tdata = vzalloc(array_size(tcount, sizeof(struct thread_data))); if (!tdata) return -ENOMEM; - objs = vzalloc(tcount * entries * sizeof(struct test_obj)); + objs = vzalloc(array_size(sizeof(struct test_obj), (tcount * entries))); if (!objs) { vfree(tdata); return -ENOMEM; diff --git a/lib/zstd/fse_decompress.c b/lib/zstd/fse_decompress.c index a84300e5a013..0b353530fb3f 100644 --- a/lib/zstd/fse_decompress.c +++ b/lib/zstd/fse_decompress.c @@ -47,6 +47,7 @@ ****************************************************************/ #include "bitstream.h" #include "fse.h" +#include "zstd_internal.h" #include #include #include /* memcpy, memset */ @@ -60,14 +61,6 @@ enum { FSE_static_assert = 1 / (int)(!!(c)) }; \ } /* use only *after* variable declarations */ -/* check and forward error code */ -#define CHECK_F(f) \ - { \ - size_t const e = f; \ - if (FSE_isError(e)) \ - return e; \ - } - /* ************************************************************** * Templates ****************************************************************/ diff --git a/lib/zstd/zstd_internal.h b/lib/zstd/zstd_internal.h index 1a79fab9e13a..dac753397f86 100644 --- a/lib/zstd/zstd_internal.h +++ b/lib/zstd/zstd_internal.h @@ -127,7 +127,14 @@ static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG; * Shared functions to include for inlining *********************************************/ ZSTD_STATIC void ZSTD_copy8(void *dst, const void *src) { - memcpy(dst, src, 8); + /* + * zstd relies heavily on gcc being able to analyze and inline this + * memcpy() call, since it is called in a tight loop. Preboot mode + * is compiled in freestanding mode, which stops gcc from analyzing + * memcpy(). Use __builtin_memcpy() to tell gcc to analyze this as a + * regular memcpy(). + */ + __builtin_memcpy(dst, src, 8); } /*! ZSTD_wildcopy() : * custom version of memcpy(), can copy up to 7 bytes too many (8 bytes if length==0) */ @@ -137,13 +144,16 @@ ZSTD_STATIC void ZSTD_wildcopy(void *dst, const void *src, ptrdiff_t length) const BYTE* ip = (const BYTE*)src; BYTE* op = (BYTE*)dst; BYTE* const oend = op + length; - /* Work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81388. +#if defined(GCC_VERSION) && GCC_VERSION >= 70000 && GCC_VERSION < 70200 + /* + * Work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81388. * Avoid the bad case where the loop only runs once by handling the * special case separately. This doesn't trigger the bug because it * doesn't involve pointer/integer overflow. */ if (length <= 8) return ZSTD_copy8(dst, src); +#endif do { ZSTD_copy8(op, ip); op += 8; diff --git a/mm/filemap.c b/mm/filemap.c index e2ee462c8891..6128cdf0c798 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2223,7 +2223,7 @@ no_cached_page: * Ok, it wasn't cached, so we need to create a new * page.. */ - page = page_cache_alloc_cold(mapping); + page = page_cache_alloc(mapping); if (!page) { error = -ENOMEM; goto out; @@ -2795,7 +2795,7 @@ static struct page *do_read_cache_page(struct address_space *mapping, repeat: page = find_get_page(mapping, index); if (!page) { - page = __page_cache_alloc(gfp | __GFP_COLD); + page = __page_cache_alloc(gfp); if (!page) return ERR_PTR(-ENOMEM); err = add_to_page_cache_lru(page, mapping, index, gfp); diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 7ad06ed9048e..86e8675494bb 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1138,8 +1138,8 @@ static int do_huge_pmd_wp_page_fallback(struct vm_fault *vmf, pmd_t orig_pmd, unsigned long mmun_start; /* For mmu_notifiers */ unsigned long mmun_end; /* For mmu_notifiers */ - pages = kmalloc(sizeof(struct page *) * HPAGE_PMD_NR, - GFP_KERNEL); + pages = kmalloc_array(HPAGE_PMD_NR, sizeof(struct page *), + GFP_KERNEL); if (unlikely(!pages)) { ret |= VM_FAULT_OOM; goto out; diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 9ac4f76310cf..c99bdbed5af4 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -2808,7 +2808,8 @@ static int __init hugetlb_init(void) num_fault_mutexes = 1; #endif hugetlb_fault_mutex_table = - kmalloc(sizeof(struct mutex) * num_fault_mutexes, GFP_KERNEL); + kmalloc_array(num_fault_mutexes, sizeof(struct mutex), + GFP_KERNEL); BUG_ON(!hugetlb_fault_mutex_table); for (i = 0; i < num_fault_mutexes; i++) diff --git a/mm/kasan/common.c b/mm/kasan/common.c index 46ef2ea7293a..b1d791b36eca 100644 --- a/mm/kasan/common.c +++ b/mm/kasan/common.c @@ -261,7 +261,7 @@ static inline unsigned int optimal_redzone(unsigned int object_size) } void kasan_cache_create(struct kmem_cache *cache, unsigned int *size, - unsigned long *flags) + slab_flags_t *flags) { unsigned int orig_size = *size; unsigned int redzone_size; diff --git a/mm/list_lru.c b/mm/list_lru.c index d67348afd1dc..b7bb34c2be8f 100644 --- a/mm/list_lru.c +++ b/mm/list_lru.c @@ -321,7 +321,7 @@ static int memcg_init_list_lru_node(struct list_lru_node *nlru) { int size = memcg_nr_cache_ids; - nlru->memcg_lrus = kvmalloc(size * sizeof(void *), GFP_KERNEL); + nlru->memcg_lrus = kvmalloc_array(size, sizeof(void *), GFP_KERNEL); if (!nlru->memcg_lrus) return -ENOMEM; @@ -347,7 +347,7 @@ static int memcg_update_list_lru_node(struct list_lru_node *nlru, BUG_ON(old_size > new_size); old = nlru->memcg_lrus; - new = kvmalloc(new_size * sizeof(void *), GFP_KERNEL); + new = kvmalloc_array(new_size, sizeof(void *), GFP_KERNEL); if (!new) return -ENOMEM; diff --git a/mm/mempool.c b/mm/mempool.c index 6fb1c0bd2870..3076ab3f7bc4 100644 --- a/mm/mempool.c +++ b/mm/mempool.c @@ -189,7 +189,7 @@ mempool_t *mempool_create_node(int min_nr, mempool_alloc_t *alloc_fn, pool = kzalloc_node(sizeof(*pool), gfp_mask, node_id); if (!pool) return NULL; - pool->elements = kmalloc_node(min_nr * sizeof(void *), + pool->elements = kmalloc_array_node(min_nr, sizeof(void *), gfp_mask, node_id); if (!pool->elements) { kfree(pool); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a187d347eeb5..0717332cc43a 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -69,7 +69,6 @@ #include #include #include -#include #include #include @@ -2413,7 +2412,7 @@ static inline struct page *__rmqueue_cma(struct zone *zone, unsigned int order) */ static int rmqueue_bulk(struct zone *zone, unsigned int order, unsigned long count, struct list_head *list, - int migratetype, bool cold) + int migratetype) { int i, alloced = 0; @@ -2446,10 +2445,7 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order, * merge IO requests if the physical pages are ordered * properly. */ - if (likely(!cold)) - list_add(&page->lru, list); - else - list_add_tail(&page->lru, list); + list_add(&page->lru, list); list = &page->lru; alloced++; if (is_migrate_cma(get_pcppage_migratetype(page))) @@ -2475,14 +2471,14 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order, */ static struct list_head *get_populated_pcp_list(struct zone *zone, unsigned int order, struct per_cpu_pages *pcp, - int migratetype, int cold) + int migratetype) { struct list_head *list = &pcp->lists[migratetype]; if (list_empty(list)) { pcp->count += rmqueue_bulk(zone, order, pcp->batch, list, - migratetype, cold); + migratetype); if (list_empty(list)) list = NULL; @@ -2876,7 +2872,7 @@ static inline void zone_statistics(struct zone *preferred_zone, struct zone *z) /* Remove page from the per-cpu list, caller must protect the list */ static struct page *__rmqueue_pcplist(struct zone *zone, int migratetype, - bool cold, struct per_cpu_pages *pcp, + struct per_cpu_pages *pcp, gfp_t gfp_flags) { struct page *page = NULL; @@ -2887,7 +2883,7 @@ static struct page *__rmqueue_pcplist(struct zone *zone, int migratetype, if (migratetype == MIGRATE_MOVABLE && gfp_flags & __GFP_CMA) { list = get_populated_pcp_list(zone, 0, pcp, - get_cma_migrate_type(), cold); + get_cma_migrate_type()); } if (list == NULL) { @@ -2896,18 +2892,14 @@ static struct page *__rmqueue_pcplist(struct zone *zone, int migratetype, * free CMA pages. */ list = get_populated_pcp_list(zone, 0, pcp, - migratetype, cold); + migratetype); if (unlikely(list == NULL) || unlikely(list_empty(list))) return NULL; } - if (cold) - page = list_last_entry(list, struct page, lru); - else - page = list_first_entry(list, struct page, lru); - + page = list_first_entry(list, struct page, lru); list_del(&page->lru); pcp->count--; } while (check_new_pcp(page)); @@ -2921,13 +2913,12 @@ static struct page *rmqueue_pcplist(struct zone *preferred_zone, gfp_t gfp_flags, int migratetype) { struct per_cpu_pages *pcp; - bool cold = ((gfp_flags & __GFP_COLD) != 0); struct page *page; unsigned long flags; local_irq_save(flags); pcp = &this_cpu_ptr(zone->pageset)->pcp; - page = __rmqueue_pcplist(zone, migratetype, cold, pcp, + page = __rmqueue_pcplist(zone, migratetype, pcp, gfp_flags); if (page) { __count_zid_vm_events(PGALLOC, page_zonenum(page), 1 << order); @@ -4224,7 +4215,6 @@ retry: goto nopage; /* Boost when memory is low so allocation latency doesn't get too bad */ - cpu_input_boost_kick_max(100); devfreq_boost_kick_max(DEVFREQ_MSM_LLCCBW, 100); devfreq_boost_kick_max(DEVFREQ_MSM_CPUBW, 100); diff --git a/mm/percpu-stats.c b/mm/percpu-stats.c index 7a58460bfd27..702acbea8a11 100644 --- a/mm/percpu-stats.c +++ b/mm/percpu-stats.c @@ -144,7 +144,7 @@ alloc_buffer: spin_unlock_irq(&pcpu_lock); /* there can be at most this many free and allocated fragments */ - buffer = vmalloc((2 * max_nr_alloc + 1) * sizeof(int)); + buffer = vmalloc(array_size(sizeof(int), (2 * max_nr_alloc + 1))); if (!buffer) return -ENOMEM; diff --git a/mm/percpu-vm.c b/mm/percpu-vm.c index f48ff9fc86fe..0af71eb2fff0 100644 --- a/mm/percpu-vm.c +++ b/mm/percpu-vm.c @@ -86,7 +86,7 @@ static int pcpu_alloc_pages(struct pcpu_chunk *chunk, unsigned int cpu, tcpu; int i; - gfp |= GFP_KERNEL | __GFP_HIGHMEM | __GFP_COLD; + gfp |= GFP_KERNEL | __GFP_HIGHMEM; for_each_possible_cpu(cpu) { for (i = page_start; i < page_end; i++) { diff --git a/mm/slab.c b/mm/slab.c index 5dd23f6fd451..fdf56c95efa9 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -251,8 +251,8 @@ static void kmem_cache_node_init(struct kmem_cache_node *parent) MAKE_LIST((cachep), (&(ptr)->slabs_free), slabs_free, nodeid); \ } while (0) -#define CFLGS_OBJFREELIST_SLAB (0x40000000UL) -#define CFLGS_OFF_SLAB (0x80000000UL) +#define CFLGS_OBJFREELIST_SLAB ((slab_flags_t __force)0x40000000U) +#define CFLGS_OFF_SLAB ((slab_flags_t __force)0x80000000U) #define OBJFREELIST_SLAB(x) ((x)->flags & CFLGS_OBJFREELIST_SLAB) #define OFF_SLAB(x) ((x)->flags & CFLGS_OFF_SLAB) @@ -427,7 +427,7 @@ static inline struct array_cache *cpu_cache_get(struct kmem_cache *cachep) * Calculate the number of objects and left-over bytes for a given buffer size. */ static unsigned int cache_estimate(unsigned long gfporder, size_t buffer_size, - unsigned long flags, size_t *left_over) + slab_flags_t flags, size_t *left_over) { unsigned int num; size_t slab_size = PAGE_SIZE << gfporder; @@ -1737,7 +1737,7 @@ static void slabs_destroy(struct kmem_cache *cachep, struct list_head *list) * towards high-order requests, this should be changed. */ static size_t calculate_slab_order(struct kmem_cache *cachep, - size_t size, unsigned long flags) + size_t size, slab_flags_t flags) { size_t left_over = 0; int gfporder; @@ -1864,8 +1864,8 @@ static int __ref setup_cpu_cache(struct kmem_cache *cachep, gfp_t gfp) return 0; } -unsigned long kmem_cache_flags(unsigned long object_size, - unsigned long flags, const char *name, +slab_flags_t kmem_cache_flags(unsigned long object_size, + slab_flags_t flags, const char *name, void (*ctor)(void *)) { return flags; @@ -1873,7 +1873,7 @@ unsigned long kmem_cache_flags(unsigned long object_size, struct kmem_cache * __kmem_cache_alias(const char *name, size_t size, size_t align, - unsigned long flags, void (*ctor)(void *)) + slab_flags_t flags, void (*ctor)(void *)) { struct kmem_cache *cachep; @@ -1891,7 +1891,7 @@ __kmem_cache_alias(const char *name, size_t size, size_t align, } static bool set_objfreelist_slab_cache(struct kmem_cache *cachep, - size_t size, unsigned long flags) + size_t size, slab_flags_t flags) { size_t left; @@ -1922,7 +1922,7 @@ static bool set_objfreelist_slab_cache(struct kmem_cache *cachep, } static bool set_off_slab_cache(struct kmem_cache *cachep, - size_t size, unsigned long flags) + size_t size, slab_flags_t flags) { size_t left; @@ -1956,7 +1956,7 @@ static bool set_off_slab_cache(struct kmem_cache *cachep, } static bool set_on_slab_cache(struct kmem_cache *cachep, - size_t size, unsigned long flags) + size_t size, slab_flags_t flags) { size_t left; @@ -1992,8 +1992,7 @@ static bool set_on_slab_cache(struct kmem_cache *cachep, * cacheline. This can be beneficial if you're counting cycles as closely * as davem. */ -int -__kmem_cache_create (struct kmem_cache *cachep, unsigned long flags) +int __kmem_cache_create(struct kmem_cache *cachep, slab_flags_t flags) { size_t ralign = BYTES_PER_WORD; gfp_t gfp; @@ -4357,7 +4356,8 @@ static int leaks_show(struct seq_file *m, void *p) if (x[0] == x[1]) { /* Increase the buffer size */ mutex_unlock(&slab_mutex); - m->private = kzalloc(x[0] * 4 * sizeof(unsigned long), GFP_KERNEL); + m->private = kcalloc(x[0] * 4, sizeof(unsigned long), + GFP_KERNEL); if (!m->private) { /* Too bad, we are really out */ m->private = x; diff --git a/mm/slab.h b/mm/slab.h index 20ee67d11bb4..ecb84c5568db 100644 --- a/mm/slab.h +++ b/mm/slab.h @@ -21,7 +21,7 @@ struct kmem_cache { unsigned int object_size;/* The original size of the object */ unsigned int size; /* The aligned/padded/added on size */ unsigned int align; /* Alignment as calculated */ - unsigned long flags; /* Active flags on the slab */ + slab_flags_t flags; /* Active flags on the slab */ const char *name; /* Slab name for sysfs */ int refcount; /* Use counter */ void (*ctor)(void *); /* Called on object slot creation */ @@ -78,13 +78,13 @@ extern const struct kmalloc_info_struct { unsigned long size; } kmalloc_info[]; -unsigned long calculate_alignment(unsigned long flags, +unsigned long calculate_alignment(slab_flags_t flags, unsigned long align, unsigned long size); #ifndef CONFIG_SLOB /* Kmalloc array related functions */ void setup_kmalloc_cache_index_table(void); -void create_kmalloc_caches(unsigned long); +void create_kmalloc_caches(slab_flags_t); /* Find the kmalloc slab corresponding for a certain size */ struct kmem_cache *kmalloc_slab(size_t, gfp_t); @@ -92,32 +92,32 @@ struct kmem_cache *kmalloc_slab(size_t, gfp_t); /* Functions provided by the slab allocators */ -extern int __kmem_cache_create(struct kmem_cache *, unsigned long flags); +int __kmem_cache_create(struct kmem_cache *, slab_flags_t flags); extern struct kmem_cache *create_kmalloc_cache(const char *name, size_t size, - unsigned long flags); + slab_flags_t flags); extern void create_boot_cache(struct kmem_cache *, const char *name, - size_t size, unsigned long flags); + size_t size, slab_flags_t flags); int slab_unmergeable(struct kmem_cache *s); struct kmem_cache *find_mergeable(size_t size, size_t align, - unsigned long flags, const char *name, void (*ctor)(void *)); + slab_flags_t flags, const char *name, void (*ctor)(void *)); #ifndef CONFIG_SLOB struct kmem_cache * __kmem_cache_alias(const char *name, size_t size, size_t align, - unsigned long flags, void (*ctor)(void *)); + slab_flags_t flags, void (*ctor)(void *)); -unsigned long kmem_cache_flags(unsigned long object_size, - unsigned long flags, const char *name, +slab_flags_t kmem_cache_flags(unsigned long object_size, + slab_flags_t flags, const char *name, void (*ctor)(void *)); #else static inline struct kmem_cache * __kmem_cache_alias(const char *name, size_t size, size_t align, - unsigned long flags, void (*ctor)(void *)) + slab_flags_t flags, void (*ctor)(void *)) { return NULL; } -static inline unsigned long kmem_cache_flags(unsigned long object_size, - unsigned long flags, const char *name, +static inline slab_flags_t kmem_cache_flags(unsigned long object_size, + slab_flags_t flags, const char *name, void (*ctor)(void *)) { return flags; diff --git a/mm/slab_common.c b/mm/slab_common.c index b873a85bbea1..8354bc72a669 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -291,7 +291,7 @@ int slab_unmergeable(struct kmem_cache *s) } struct kmem_cache *find_mergeable(size_t size, size_t align, - unsigned long flags, const char *name, void (*ctor)(void *)) + slab_flags_t flags, const char *name, void (*ctor)(void *)) { struct kmem_cache *s; @@ -341,7 +341,7 @@ struct kmem_cache *find_mergeable(size_t size, size_t align, * Figure out what the alignment of the objects will be given a set of * flags, a user specified alignment and the size of the objects. */ -unsigned long calculate_alignment(unsigned long flags, +unsigned long calculate_alignment(slab_flags_t flags, unsigned long align, unsigned long size) { /* @@ -366,7 +366,7 @@ unsigned long calculate_alignment(unsigned long flags, static struct kmem_cache *create_cache(const char *name, size_t object_size, size_t size, size_t align, - unsigned long flags, void (*ctor)(void *), + slab_flags_t flags, void (*ctor)(void *), struct mem_cgroup *memcg, struct kmem_cache *root_cache) { struct kmem_cache *s; @@ -431,7 +431,7 @@ out_free_cache: */ struct kmem_cache * kmem_cache_create(const char *name, size_t size, size_t align, - unsigned long flags, void (*ctor)(void *)) + slab_flags_t flags, void (*ctor)(void *)) { struct kmem_cache *s = NULL; const char *cache_name; @@ -462,9 +462,6 @@ kmem_cache_create(const char *name, size_t size, size_t align, */ flags &= CACHE_CREATE_MASK; - /* Embrace davem */ - flags |= SLAB_HWCACHE_ALIGN; - s = __kmem_cache_alias(name, size, align, flags, ctor); if (s) goto out_unlock; @@ -886,7 +883,7 @@ bool slab_is_available(void) #ifndef CONFIG_SLOB /* Create a cache during boot when no slab services are available yet */ void __init create_boot_cache(struct kmem_cache *s, const char *name, size_t size, - unsigned long flags) + slab_flags_t flags) { int err; @@ -906,7 +903,7 @@ void __init create_boot_cache(struct kmem_cache *s, const char *name, size_t siz } struct kmem_cache *__init create_kmalloc_cache(const char *name, size_t size, - unsigned long flags) + slab_flags_t flags) { struct kmem_cache *s = kmem_cache_zalloc(kmem_cache, GFP_NOWAIT); @@ -1071,7 +1068,7 @@ kmalloc_cache_name(const char *prefix, unsigned int size) } static void __init -new_kmalloc_cache(int idx, int type, unsigned long flags) +new_kmalloc_cache(int idx, int type, slab_flags_t flags) { const char *name; @@ -1093,7 +1090,7 @@ new_kmalloc_cache(int idx, int type, unsigned long flags) * may already have been created because they were needed to * enable allocations for slab creation. */ -void __init create_kmalloc_caches(unsigned long flags) +void __init create_kmalloc_caches(slab_flags_t flags) { int i, type; @@ -1124,7 +1121,7 @@ void __init create_kmalloc_caches(unsigned long flags) struct kmem_cache *s = kmalloc_caches[KMALLOC_NORMAL][i]; if (s) { - int size = kmalloc_size(i); + unsigned int size = kmalloc_size(i); const char *n = kmalloc_cache_name("dma-kmalloc", size); BUG_ON(!n); diff --git a/mm/slob.c b/mm/slob.c index 10249160b693..839a52bc3fd5 100644 --- a/mm/slob.c +++ b/mm/slob.c @@ -524,7 +524,7 @@ size_t ksize(const void *block) } EXPORT_SYMBOL(ksize); -int __kmem_cache_create(struct kmem_cache *c, unsigned long flags) +int __kmem_cache_create(struct kmem_cache *c, slab_flags_t flags) { if (flags & SLAB_TYPESAFE_BY_RCU) { /* leave room for rcu footer at the end of object */ diff --git a/mm/slub.c b/mm/slub.c index f950312acfde..7cf688e9f5b6 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -192,8 +192,10 @@ static inline bool kmem_cache_has_cpu_partial(struct kmem_cache *s) #define MAX_OBJS_PER_PAGE 32767 /* since page.objects is u15 */ /* Internal SLUB flags */ -#define __OBJECT_POISON 0x80000000UL /* Poison object */ -#define __CMPXCHG_DOUBLE 0x40000000UL /* Use cmpxchg_double */ +/* Poison object */ +#define __OBJECT_POISON ((slab_flags_t __force)0x80000000U) +/* Use cmpxchg_double */ +#define __CMPXCHG_DOUBLE ((slab_flags_t __force)0x40000000U) /* * Tracking user of a slab. @@ -489,9 +491,9 @@ static inline void *restore_red_left(struct kmem_cache *s, void *p) * Debug settings: */ #if defined(CONFIG_SLUB_DEBUG_ON) -static int slub_debug = DEBUG_DEFAULT_FLAGS; +static slab_flags_t slub_debug = DEBUG_DEFAULT_FLAGS; #else -static int slub_debug; +static slab_flags_t slub_debug; #endif static char *slub_debug_slabs; @@ -1334,8 +1336,8 @@ out: __setup("slub_debug", setup_slub_debug); -unsigned long kmem_cache_flags(unsigned long object_size, - unsigned long flags, const char *name, +slab_flags_t kmem_cache_flags(unsigned long object_size, + slab_flags_t flags, const char *name, void (*ctor)(void *)) { /* @@ -1369,8 +1371,8 @@ static inline void add_full(struct kmem_cache *s, struct kmem_cache_node *n, struct page *page) {} static inline void remove_full(struct kmem_cache *s, struct kmem_cache_node *n, struct page *page) {} -unsigned long kmem_cache_flags(unsigned long object_size, - unsigned long flags, const char *name, +slab_flags_t kmem_cache_flags(unsigned long object_size, + slab_flags_t flags, const char *name, void (*ctor)(void *)) { return flags; @@ -3591,7 +3593,7 @@ static void set_cpu_partial(struct kmem_cache *s) */ static int calculate_sizes(struct kmem_cache *s, int forced_order) { - unsigned long flags = s->flags; + slab_flags_t flags = s->flags; unsigned int size = s->object_size; int order; @@ -3707,7 +3709,7 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order) return !!oo_objects(s->oo); } -static int kmem_cache_open(struct kmem_cache *s, unsigned long flags) +static int kmem_cache_open(struct kmem_cache *s, slab_flags_t flags) { s->flags = kmem_cache_flags(s->size, flags, s->name, s->ctor); s->reserved = 0; @@ -3769,7 +3771,7 @@ error: if (flags & SLAB_PANIC) panic("Cannot create slab %s size=%lu realsize=%u order=%u offset=%u flags=%lx\n", s->name, (unsigned long)s->size, s->size, - oo_order(s->oo), s->offset, flags); + oo_order(s->oo), s->offset, (unsigned long)flags); return -EINVAL; } @@ -3779,8 +3781,9 @@ static void list_slab_objects(struct kmem_cache *s, struct page *page, #ifdef CONFIG_SLUB_DEBUG void *addr = page_address(page); void *p; - unsigned long *map = kzalloc(BITS_TO_LONGS(page->objects) * - sizeof(long), GFP_ATOMIC); + unsigned long *map = kcalloc(BITS_TO_LONGS(page->objects), + sizeof(long), + GFP_ATOMIC); if (!map) return; slab_err(s, page, text, s->name); @@ -4372,7 +4375,7 @@ void __init kmem_cache_init_late(void) struct kmem_cache * __kmem_cache_alias(const char *name, size_t size, size_t align, - unsigned long flags, void (*ctor)(void *)) + slab_flags_t flags, void (*ctor)(void *)) { struct kmem_cache *s, *c; @@ -4402,7 +4405,7 @@ __kmem_cache_alias(const char *name, size_t size, size_t align, return s; } -int __kmem_cache_create(struct kmem_cache *s, unsigned long flags) +int __kmem_cache_create(struct kmem_cache *s, slab_flags_t flags) { int err; @@ -4559,8 +4562,9 @@ static long validate_slab_cache(struct kmem_cache *s) { int node; unsigned long count = 0; - unsigned long *map = kmalloc(BITS_TO_LONGS(oo_objects(s->max)) * - sizeof(unsigned long), GFP_KERNEL); + unsigned long *map = kmalloc_array(BITS_TO_LONGS(oo_objects(s->max)), + sizeof(unsigned long), + GFP_KERNEL); struct kmem_cache_node *n; if (!map) @@ -4720,8 +4724,9 @@ static int list_locations(struct kmem_cache *s, char *buf, unsigned long i; struct loc_track t = { 0, 0, NULL }; int node; - unsigned long *map = kmalloc(BITS_TO_LONGS(oo_objects(s->max)) * - sizeof(unsigned long), GFP_KERNEL); + unsigned long *map = kmalloc_array(BITS_TO_LONGS(oo_objects(s->max)), + sizeof(unsigned long), + GFP_KERNEL); struct kmem_cache_node *n; if (!map || !alloc_loc_track(&t, PAGE_SIZE / sizeof(struct location), @@ -4898,7 +4903,7 @@ static ssize_t show_slab_objects(struct kmem_cache *s, int x; unsigned long *nodes; - nodes = kzalloc(sizeof(unsigned long) * nr_node_ids, GFP_KERNEL); + nodes = kcalloc(nr_node_ids, sizeof(unsigned long), GFP_KERNEL); if (!nodes) return -ENOMEM; @@ -5453,7 +5458,7 @@ static int show_stat(struct kmem_cache *s, char *buf, enum stat_item si) unsigned long sum = 0; int cpu; int len; - int *data = kmalloc(nr_cpu_ids * sizeof(int), GFP_KERNEL); + int *data = kmalloc_array(nr_cpu_ids, sizeof(int), GFP_KERNEL); if (!data) return -ENOMEM; diff --git a/mm/swap_slots.c b/mm/swap_slots.c index f778aa38127e..652d5f760d6c 100644 --- a/mm/swap_slots.c +++ b/mm/swap_slots.c @@ -124,12 +124,12 @@ static int alloc_swap_slot_cache(unsigned int cpu) * as kvzalloc could trigger reclaim and get_swap_page, * which can lock swap_slots_cache_mutex. */ - slots = kvzalloc(sizeof(swp_entry_t) * SWAP_SLOTS_CACHE_SIZE, + slots = kvcalloc(SWAP_SLOTS_CACHE_SIZE, sizeof(swp_entry_t), GFP_KERNEL); if (!slots) return -ENOMEM; - slots_ret = kvzalloc(sizeof(swp_entry_t) * SWAP_SLOTS_CACHE_SIZE, + slots_ret = kvcalloc(SWAP_SLOTS_CACHE_SIZE, sizeof(swp_entry_t), GFP_KERNEL); if (!slots_ret) { kvfree(slots); diff --git a/mm/swap_state.c b/mm/swap_state.c index 8787c1b675bb..a1a3a81d489e 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c @@ -626,7 +626,7 @@ int init_swap_address_space(unsigned int type, unsigned long nr_pages) unsigned int i, nr; nr = DIV_ROUND_UP(nr_pages, SWAP_ADDRESS_SPACE_PAGES); - spaces = kvzalloc(sizeof(struct address_space) * nr, GFP_KERNEL); + spaces = kvcalloc(nr, sizeof(struct address_space), GFP_KERNEL); if (!spaces) return -ENOMEM; for (i = 0; i < nr; i++) { diff --git a/mm/swapfile.c b/mm/swapfile.c index 72c0a28a0e10..bfd75fe3f2db 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -3235,7 +3235,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) p->cluster_next = 1 + (prandom_u32() % p->highest_bit); nr_cluster = DIV_ROUND_UP(maxpages, SWAPFILE_CLUSTER); - cluster_info = kvzalloc(nr_cluster * sizeof(*cluster_info), + cluster_info = kvcalloc(nr_cluster, sizeof(*cluster_info), GFP_KERNEL); if (!cluster_info) { error = -ENOMEM; @@ -3270,7 +3270,8 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) } /* frontswap enabled? set up bit-per-page map for frontswap */ if (IS_ENABLED(CONFIG_FRONTSWAP)) - frontswap_map = kvzalloc(BITS_TO_LONGS(maxpages) * sizeof(long), + frontswap_map = kvcalloc(BITS_TO_LONGS(maxpages), + sizeof(long), GFP_KERNEL); if (p->bdev &&(swap_flags & SWAP_FLAG_DISCARD) && swap_discardable(p)) { diff --git a/net/9p/protocol.c b/net/9p/protocol.c index 1885403c9a3e..f44d17eef206 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c @@ -247,8 +247,9 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt, "w", nwname); if (!errcode) { *wnames = - kmalloc(sizeof(char *) * *nwname, - GFP_NOFS); + kmalloc_array(*nwname, + sizeof(char *), + GFP_NOFS); if (!*wnames) errcode = -ENOMEM; } @@ -290,9 +291,9 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt, p9pdu_readf(pdu, proto_version, "w", nwqid); if (!errcode) { *wqids = - kmalloc(*nwqid * - sizeof(struct p9_qid), - GFP_NOFS); + kmalloc_array(*nwqid, + sizeof(struct p9_qid), + GFP_NOFS); if (*wqids == NULL) errcode = -ENOMEM; } diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index a9c65f13b7f5..32de8afbfbf8 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -301,7 +301,6 @@ static void p9_read_work(struct work_struct *work) { int n, err; struct p9_conn *m; - int status = REQ_STATUS_ERROR; m = container_of(work, struct p9_conn, rq); @@ -381,11 +380,21 @@ static void p9_read_work(struct work_struct *work) if ((m->req) && (m->rc.offset == m->rc.capacity)) { p9_debug(P9_DEBUG_TRANS, "got new packet\n"); spin_lock(&m->client->lock); - if (m->req->status != REQ_STATUS_ERROR) - status = REQ_STATUS_RCVD; - list_del(&m->req->req_list); - /* update req->status while holding client->lock */ - p9_client_cb(m->client, m->req, status); + if (m->req->status == REQ_STATUS_SENT) { + list_del(&m->req->req_list); + p9_client_cb(m->client, m->req, REQ_STATUS_RCVD); + } else if (m->req->status == REQ_STATUS_FLSHD) { + /* Ignore replies associated with a cancelled request. */ + p9_debug(P9_DEBUG_TRANS, + "Ignore replies associated with a cancelled request\n"); + } else { + spin_unlock(&m->client->lock); + p9_debug(P9_DEBUG_ERROR, + "Request tag %d errored out while we were reading the reply\n", + m->rc.tag); + err = -EIO; + goto error; + } spin_unlock(&m->client->lock); m->rc.sdata = NULL; m->rc.offset = 0; @@ -712,11 +721,20 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req) { p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req); + spin_lock(&client->lock); + /* Ignore cancelled request if message has been received + * before lock. + */ + if (req->status == REQ_STATUS_RCVD) { + spin_unlock(&client->lock); + return 0; + } + /* we haven't received a response for oldreq, * remove it from the list. */ - spin_lock(&client->lock); list_del(&req->req_list); + req->status = REQ_STATUS_FLSHD; spin_unlock(&client->lock); return 0; diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index f88911cffa1a..2cab31203e8f 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c @@ -362,7 +362,8 @@ static int p9_get_mapped_pages(struct virtio_chan *chan, nr_pages = DIV_ROUND_UP((unsigned long)p + len, PAGE_SIZE) - (unsigned long)p / PAGE_SIZE; - *pages = kmalloc(sizeof(struct page *) * nr_pages, GFP_NOFS); + *pages = kmalloc_array(nr_pages, sizeof(struct page *), + GFP_NOFS); if (!*pages) return -ENOMEM; diff --git a/net/atm/mpc.c b/net/atm/mpc.c index db9a1838687c..2622f779b599 100644 --- a/net/atm/mpc.c +++ b/net/atm/mpc.c @@ -472,7 +472,7 @@ static const uint8_t *copy_macs(struct mpoa_client *mpc, if (mpc->number_of_mps_macs != 0) kfree(mpc->mps_macs); mpc->number_of_mps_macs = 0; - mpc->mps_macs = kmalloc(num_macs * ETH_ALEN, GFP_KERNEL); + mpc->mps_macs = kmalloc_array(ETH_ALEN, num_macs, GFP_KERNEL); if (mpc->mps_macs == NULL) { pr_info("(%s) out of mem\n", mpc->dev->name); return NULL; diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 89d074ce10fc..6915eebc7a4a 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -1191,7 +1191,10 @@ static int __must_check ax25_connect(struct socket *sock, if (addr_len > sizeof(struct sockaddr_ax25) && fsa->fsa_ax25.sax25_ndigis != 0) { /* Valid number of digipeaters ? */ - if (fsa->fsa_ax25.sax25_ndigis < 1 || fsa->fsa_ax25.sax25_ndigis > AX25_MAX_DIGIS) { + if (fsa->fsa_ax25.sax25_ndigis < 1 || + fsa->fsa_ax25.sax25_ndigis > AX25_MAX_DIGIS || + addr_len < sizeof(struct sockaddr_ax25) + + sizeof(ax25_address) * fsa->fsa_ax25.sax25_ndigis) { err = -EINVAL; goto out_release; } @@ -1511,7 +1514,10 @@ static int ax25_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)usax; /* Valid number of digipeaters ? */ - if (usax->sax25_ndigis < 1 || usax->sax25_ndigis > AX25_MAX_DIGIS) { + if (usax->sax25_ndigis < 1 || + usax->sax25_ndigis > AX25_MAX_DIGIS || + addr_len < sizeof(struct sockaddr_ax25) + + sizeof(ax25_address) * usax->sax25_ndigis) { err = -EINVAL; goto out; } diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index ff80a9d41ce1..9cb3d1674981 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1290,7 +1290,7 @@ int hci_inquiry(void __user *arg) /* cache_dump can't sleep. Therefore we allocate temp buffer and then * copy it to the user space. */ - buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); + buf = kmalloc_array(max_rsp, sizeof(struct inquiry_info), GFP_KERNEL); if (!buf) { err = -ENOMEM; goto done; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index ebdf1b0e576a..0d84d1f820d4 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -331,7 +331,7 @@ static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size) */ alloc_size = roundup_pow_of_two(size); - seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL); + seq_list->list = kmalloc_array(alloc_size, sizeof(u16), GFP_KERNEL); if (!seq_list->list) return -ENOMEM; diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index b24782d53474..c9b9ca8e8d4f 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -332,7 +332,7 @@ static int br_mdb_rehash(struct net_bridge_mdb_htable __rcu **mdbp, int max, mdb->max = max; mdb->old = old; - mdb->mhash = kzalloc(max * sizeof(*mdb->mhash), GFP_ATOMIC); + mdb->mhash = kcalloc(max, sizeof(*mdb->mhash), GFP_ATOMIC); if (!mdb->mhash) { kfree(mdb); return -ENOMEM; diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index a1834ad7422c..e94c52812ca1 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -873,12 +873,12 @@ static int translate_table(struct net *net, const char *name, * if an error occurs */ newinfo->chainstack = - vmalloc(nr_cpu_ids * sizeof(*(newinfo->chainstack))); + vmalloc(array_size(nr_cpu_ids, sizeof(*(newinfo->chainstack)))); if (!newinfo->chainstack) return -ENOMEM; for_each_possible_cpu(i) { newinfo->chainstack[i] = - vmalloc(udc_cnt * sizeof(*(newinfo->chainstack[0]))); + vmalloc(array_size(udc_cnt, sizeof(*(newinfo->chainstack[0])))); if (!newinfo->chainstack[i]) { while (i) vfree(newinfo->chainstack[--i]); @@ -888,7 +888,7 @@ static int translate_table(struct net *net, const char *name, } } - cl_s = vmalloc(udc_cnt * sizeof(*cl_s)); + cl_s = vmalloc(array_size(udc_cnt, sizeof(*cl_s))); if (!cl_s) return -ENOMEM; i = 0; /* the i'th udc */ @@ -1273,7 +1273,7 @@ static int do_update_counters(struct net *net, const char *name, if (num_counters == 0) return -EINVAL; - tmp = vmalloc(num_counters * sizeof(*tmp)); + tmp = vmalloc(array_size(num_counters, sizeof(*tmp))); if (!tmp) return -ENOMEM; @@ -1409,7 +1409,7 @@ static int copy_counters_to_user(struct ebt_table *t, if (num_counters != nentries) return -EINVAL; - counterstmp = vmalloc(nentries * sizeof(*counterstmp)); + counterstmp = vmalloc(array_size(nentries, sizeof(*counterstmp))); if (!counterstmp) return -ENOMEM; diff --git a/net/can/bcm.c b/net/can/bcm.c index 12d851c4604d..dd45a8e4f3fb 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -959,8 +959,9 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, /* create array for CAN frames and copy the data */ if (msg_head->nframes > 1) { - op->frames = kmalloc(msg_head->nframes * op->cfsiz, - GFP_KERNEL); + op->frames = kmalloc_array(msg_head->nframes, + op->cfsiz, + GFP_KERNEL); if (!op->frames) { kfree(op); return -ENOMEM; @@ -1135,15 +1136,17 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, if (msg_head->nframes > 1) { /* create array for CAN frames and copy the data */ - op->frames = kmalloc(msg_head->nframes * op->cfsiz, - GFP_KERNEL); + op->frames = kmalloc_array(msg_head->nframes, + op->cfsiz, + GFP_KERNEL); if (!op->frames) { kfree(op); return -ENOMEM; } /* create and init array for received CAN frames */ - op->last_frames = kzalloc(msg_head->nframes * op->cfsiz, + op->last_frames = kcalloc(msg_head->nframes, + op->cfsiz, GFP_KERNEL); if (!op->last_frames) { kfree(op->frames); diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c index daca0af59942..30def9d1220c 100644 --- a/net/ceph/mon_client.c +++ b/net/ceph/mon_client.c @@ -62,7 +62,7 @@ struct ceph_monmap *ceph_monmap_decode(void *p, void *end) if (num_mon >= CEPH_MAX_MON) goto bad; - m = kmalloc(sizeof(*m) + sizeof(m->mon_inst[0])*num_mon, GFP_NOFS); + m = kmalloc(struct_size(m, mon_inst, num_mon), GFP_NOFS); if (m == NULL) return ERR_PTR(-ENOMEM); m->fsid = fsid; diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index b026128a89d7..2a52ebb1a9e2 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -527,8 +527,7 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc, req = kmem_cache_alloc(ceph_osd_request_cache, gfp_flags); } else { BUG_ON(num_ops > CEPH_OSD_MAX_OPS); - req = kmalloc(sizeof(*req) + num_ops * sizeof(req->r_ops[0]), - gfp_flags); + req = kmalloc(struct_size(req, r_ops, num_ops), gfp_flags); } if (unlikely(!req)) return NULL; diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index 0da27c66349a..190b6ed27aea 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c @@ -1300,8 +1300,9 @@ static int set_primary_affinity(struct ceph_osdmap *map, int osd, u32 aff) if (!map->osd_primary_affinity) { int i; - map->osd_primary_affinity = kmalloc(map->max_osd*sizeof(u32), - GFP_NOFS); + map->osd_primary_affinity = kmalloc_array(map->max_osd, + sizeof(u32), + GFP_NOFS); if (!map->osd_primary_affinity) return -ENOMEM; diff --git a/net/ceph/pagevec.c b/net/ceph/pagevec.c index ee43bc13221c..dc0f5d250ff7 100644 --- a/net/ceph/pagevec.c +++ b/net/ceph/pagevec.c @@ -20,7 +20,7 @@ struct page **ceph_get_direct_page_vector(const void __user *data, int got = 0; int rc = 0; - pages = kmalloc(sizeof(*pages) * num_pages, GFP_NOFS); + pages = kmalloc_array(num_pages, sizeof(*pages), GFP_NOFS); if (!pages) return ERR_PTR(-ENOMEM); @@ -74,7 +74,7 @@ struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags) struct page **pages; int i; - pages = kmalloc(sizeof(*pages) * num_pages, flags); + pages = kmalloc_array(num_pages, sizeof(*pages), flags); if (!pages) return ERR_PTR(-ENOMEM); for (i = 0; i < num_pages; i++) { diff --git a/net/core/dev.c b/net/core/dev.c index 4af3fa399e22..03e66b52c992 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4666,7 +4666,7 @@ static void flush_backlog(struct work_struct *work) skb_queue_walk_safe(&sd->input_pkt_queue, skb, tmp) { if (skb->dev->reg_state == NETREG_UNREGISTERING) { __skb_unlink(skb, &sd->input_pkt_queue); - kfree_skb(skb); + dev_kfree_skb_irq(skb); input_queue_head_incr(sd); } } @@ -8602,7 +8602,7 @@ static struct hlist_head * __net_init netdev_create_hash(void) int i; struct hlist_head *hash; - hash = kmalloc(sizeof(*hash) * NETDEV_HASHENTRIES, GFP_KERNEL); + hash = kmalloc_array(NETDEV_HASHENTRIES, sizeof(*hash), GFP_KERNEL); if (hash != NULL) for (i = 0; i < NETDEV_HASHENTRIES; i++) INIT_HLIST_HEAD(&hash[i]); diff --git a/net/core/ethtool.c b/net/core/ethtool.c index b234ff5e5a86..0f63b9077460 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -930,7 +930,7 @@ static noinline_for_stack int ethtool_get_sset_info(struct net_device *dev, memset(&info, 0, sizeof(info)); info.cmd = ETHTOOL_GSSET_INFO; - info_buf = kzalloc(n_bits * sizeof(u32), GFP_USER); + info_buf = kcalloc(n_bits, sizeof(u32), GFP_USER); if (!info_buf) return -ENOMEM; @@ -1022,7 +1022,7 @@ static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev, if (info.cmd == ETHTOOL_GRXCLSRLALL) { if (info.rule_cnt > 0) { if (info.rule_cnt <= KMALLOC_MAX_SIZE / sizeof(u32)) - rule_buf = kzalloc(info.rule_cnt * sizeof(u32), + rule_buf = kcalloc(info.rule_cnt, sizeof(u32), GFP_USER); if (!rule_buf) return -ENOMEM; @@ -1795,7 +1795,7 @@ static int ethtool_self_test(struct net_device *dev, char __user *useraddr) return -EFAULT; test.len = test_len; - data = kmalloc(test_len * sizeof(u64), GFP_USER); + data = kmalloc_array(test_len, sizeof(u64), GFP_USER); if (!data) return -ENOMEM; @@ -1832,7 +1832,7 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr) gstrings.len = ret; if (gstrings.len) { - data = vzalloc(gstrings.len * ETH_GSTRING_LEN); + data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN)); if (!data) return -ENOMEM; @@ -1936,7 +1936,7 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) stats.n_stats = n_stats; if (n_stats) { - data = vzalloc(n_stats * sizeof(u64)); + data = vzalloc(array_size(n_stats, sizeof(u64))); if (!data) return -ENOMEM; ops->get_ethtool_stats(dev, &stats, data); @@ -1979,7 +1979,7 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr) stats.n_stats = n_stats; if (n_stats) { - data = vzalloc(n_stats * sizeof(u64)); + data = vzalloc(array_size(n_stats, sizeof(u64))); if (!data) return -ENOMEM; diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index baf771d2d088..9d012255cedc 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -1028,7 +1028,7 @@ static ssize_t tx_timeout_show(struct netdev_queue *queue, char *buf) trans_timeout = queue->trans_timeout; spin_unlock_irq(&queue->_xmit_lock); - return sprintf(buf, "%lu", trans_timeout); + return sprintf(buf, fmt_ulong, trans_timeout); } static unsigned int get_netdev_queue_index(struct netdev_queue *queue) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index bd98819b9c75..d8df2189145a 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -3696,7 +3696,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) return -ENOMEM; strcpy(pkt_dev->odevname, ifname); - pkt_dev->flows = vzalloc_node(MAX_CFLOWS * sizeof(struct flow_state), + pkt_dev->flows = vzalloc_node(array_size(MAX_CFLOWS, sizeof(struct flow_state)), node); if (pkt_dev->flows == NULL) { kfree(pkt_dev); diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index cb15338cfda4..0168c700a201 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -2733,7 +2733,8 @@ replay: */ if (err < 0) { /* If device is not registered at all, free it now */ - if (dev->reg_state == NETREG_UNINITIALIZED) + if (dev->reg_state == NETREG_UNINITIALIZED || + dev->reg_state == NETREG_UNREGISTERED) free_netdev(dev); goto out; } diff --git a/net/core/skbuff.c b/net/core/skbuff.c index eb54fbb09cc5..50f27c2d3066 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -361,7 +361,7 @@ void *netdev_alloc_frag(unsigned int fragsz) { fragsz = SKB_DATA_ALIGN(fragsz); - return __netdev_alloc_frag(fragsz, GFP_ATOMIC | __GFP_COLD); + return __netdev_alloc_frag(fragsz, GFP_ATOMIC); } EXPORT_SYMBOL(netdev_alloc_frag); @@ -376,7 +376,7 @@ void *napi_alloc_frag(unsigned int fragsz) { fragsz = SKB_DATA_ALIGN(fragsz); - return __napi_alloc_frag(fragsz, GFP_ATOMIC | __GFP_COLD); + return __napi_alloc_frag(fragsz, GFP_ATOMIC); } EXPORT_SYMBOL(napi_alloc_frag); diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index fbeacbc2be5d..23ddee4036ff 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -983,7 +983,8 @@ static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb, */ err = ops->peer_getappinfo(netdev, &info, &app_count); if (!err && app_count) { - table = kmalloc(sizeof(struct dcb_app) * app_count, GFP_KERNEL); + table = kmalloc_array(app_count, sizeof(struct dcb_app), + GFP_KERNEL); if (!table) return -ENOMEM; diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index fc31c02d616c..6946ee7ce3a9 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -46,7 +46,8 @@ static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hc) return -ENOMEM; /* allocate buffer and initialize linked list */ - seqp = kmalloc(CCID2_SEQBUF_LEN * sizeof(struct ccid2_seq), gfp_any()); + seqp = kmalloc_array(CCID2_SEQBUF_LEN, sizeof(struct ccid2_seq), + gfp_any()); if (seqp == NULL) return -ENOMEM; diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c index dc2960be51e0..b231e40f006a 100644 --- a/net/ieee802154/nl-phy.c +++ b/net/ieee802154/nl-phy.c @@ -38,7 +38,7 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 portid, { void *hdr; int i, pages = 0; - uint32_t *buf = kzalloc(32 * sizeof(uint32_t), GFP_KERNEL); + uint32_t *buf = kcalloc(32, sizeof(uint32_t), GFP_KERNEL); pr_debug("%s\n", __func__); diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index ff499000f6cd..d56350f42eb9 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -542,7 +542,7 @@ static int rtentry_to_fib_config(struct net *net, int cmd, struct rtentry *rt, struct nlattr *mx; int len = 0; - mx = kzalloc(3 * nla_total_size(4), GFP_KERNEL); + mx = kcalloc(3, nla_total_size(4), GFP_KERNEL); if (!mx) return -ENOMEM; diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c index d5b1e0b3f687..f803e06ef789 100644 --- a/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c @@ -448,7 +448,7 @@ static unsigned char asn1_oid_decode(struct asn1_ctx *ctx, if (size < 2 || size > ULONG_MAX/sizeof(unsigned long)) return 0; - *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); + *oid = kmalloc_array(size, sizeof(unsigned long), GFP_ATOMIC); if (*oid == NULL) return 0; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a894adbb6c9b..ab2252174433 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -665,7 +665,7 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw, hash = rcu_dereference(nh->nh_exceptions); if (!hash) { - hash = kzalloc(FNHE_HASH_SIZE * sizeof(*hash), GFP_ATOMIC); + hash = kcalloc(FNHE_HASH_SIZE, sizeof(*hash), GFP_ATOMIC); if (!hash) goto out_unlock; rcu_assign_pointer(nh->nh_exceptions, hash); @@ -3094,7 +3094,8 @@ int __init ip_rt_init(void) int rc = 0; int cpu; - ip_idents = kmalloc(IP_IDENTS_SZ * sizeof(*ip_idents), GFP_KERNEL); + ip_idents = kmalloc_array(IP_IDENTS_SZ, sizeof(*ip_idents), + GFP_KERNEL); if (!ip_idents) panic("IP: failed to allocate ip_idents\n"); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index ed24caa1aebf..ef7722e495a0 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3534,10 +3534,8 @@ static void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq) } } -/* This routine deals with acks during a TLP episode. - * We mark the end of a TLP episode on receiving TLP dupack or when - * ack is after tlp_high_seq. - * Ref: loss detection algorithm in draft-dukkipati-tcpm-tcp-loss-probe. +/* This routine deals with acks during a TLP episode and ends an episode by + * resetting tlp_high_seq. Ref: TLP algorithm in draft-ietf-tcpm-rack */ static void tcp_process_tlp_ack(struct sock *sk, u32 ack, int flag) { @@ -3546,7 +3544,10 @@ static void tcp_process_tlp_ack(struct sock *sk, u32 ack, int flag) if (before(ack, tp->tlp_high_seq)) return; - if (flag & FLAG_DSACKING_ACK) { + if (!tp->tlp_retrans) { + /* TLP of new data has been acknowledged */ + tp->tlp_high_seq = 0; + } else if (flag & FLAG_DSACKING_ACK) { /* This DSACK means original and TLP probe arrived; no loss */ tp->tlp_high_seq = 0; } else if (after(ack, tp->tlp_high_seq)) { diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 0b6186dd8119..5159ab8682c9 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2485,6 +2485,11 @@ void tcp_send_loss_probe(struct sock *sk) int pcount; int mss = tcp_current_mss(sk); + /* At most one outstanding TLP */ + if (tp->tlp_high_seq) + goto rearm_timer; + + tp->tlp_retrans = 0; skb = tcp_send_head(sk); if (skb) { if (tcp_snd_wnd_test(tp, skb, mss)) { @@ -2507,10 +2512,6 @@ void tcp_send_loss_probe(struct sock *sk) return; } - /* At most one outstanding TLP retransmission. */ - if (tp->tlp_high_seq) - goto rearm_timer; - if (skb_still_in_host_queue(sk, skb)) goto rearm_timer; @@ -2531,10 +2532,12 @@ void tcp_send_loss_probe(struct sock *sk) if (__tcp_retransmit_skb(sk, skb, 1)) goto rearm_timer; + tp->tlp_retrans = 1; + +probe_sent: /* Record snd_nxt for loss detection. */ tp->tlp_high_seq = tp->snd_nxt; -probe_sent: NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPLOSSPROBES); /* Reset s.t. tcp_rearm_rto will restart timer from now */ inet_csk(sk)->icsk_pending = 0; diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 422744aa1544..0dfd2e86e542 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1962,7 +1962,7 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) /* * UDP-Lite specific tests, ignored on UDP sockets */ - if ((is_udplite & UDPLITE_RECV_CC) && UDP_SKB_CB(skb)->partial_cov) { + if ((up->pcflag & UDPLITE_RECV_CC) && UDP_SKB_CB(skb)->partial_cov) { /* * MIB statistics other than incrementing the error count are diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index c5f2b17b7ee1..0fbc1553646d 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -966,7 +966,7 @@ static int __net_init icmpv6_sk_init(struct net *net) int err, i, j; net->ipv6.icmp_sk = - kzalloc(nr_cpu_ids * sizeof(struct sock *), GFP_KERNEL); + kcalloc(nr_cpu_ids, sizeof(struct sock *), GFP_KERNEL); if (!net->ipv6.icmp_sk) return -ENOMEM; diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c index 3123b9de91b5..536872f4152e 100644 --- a/net/ipv6/ila/ila_xlat.c +++ b/net/ipv6/ila/ila_xlat.c @@ -42,7 +42,8 @@ static int alloc_ila_locks(struct ila_net *ilan) size = roundup_pow_of_two(nr_pcpus * LOCKS_PER_CPU); if (sizeof(spinlock_t) != 0) { - ilan->locks = kvmalloc(size * sizeof(spinlock_t), GFP_KERNEL); + ilan->locks = kvmalloc_array(size, sizeof(spinlock_t), + GFP_KERNEL); if (!ilan->locks) return -ENOMEM; for (i = 0; i < size; i++) diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index e07cc2cfc1a6..802457c0a121 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -1169,15 +1169,16 @@ static void ip6gre_destroy_tunnels(struct net *net, struct list_head *head) static int __net_init ip6gre_init_net(struct net *net) { struct ip6gre_net *ign = net_generic(net, ip6gre_net_id); + struct net_device *ndev; int err; - ign->fb_tunnel_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6gre0", - NET_NAME_UNKNOWN, - ip6gre_tunnel_setup); - if (!ign->fb_tunnel_dev) { + ndev = alloc_netdev(sizeof(struct ip6_tnl), "ip6gre0", + NET_NAME_UNKNOWN, ip6gre_tunnel_setup); + if (!ndev) { err = -ENOMEM; goto err_alloc_dev; } + ign->fb_tunnel_dev = ndev; dev_net_set(ign->fb_tunnel_dev, net); /* FB netdevice is special: we have one, and only one per netns. * Allowing to move it to another netns is clearly unsafe. @@ -1197,7 +1198,7 @@ static int __net_init ip6gre_init_net(struct net *net) return 0; err_reg_dev: - free_netdev(ign->fb_tunnel_dev); + free_netdev(ndev); err_alloc_dev: return err; } diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 98ab1564aade..49358f7e4f80 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1828,7 +1828,7 @@ static int ip6_convert_metrics(struct mx6_config *mxc, if (!cfg->fc_mx) return 0; - mp = kzalloc(sizeof(u32) * RTAX_MAX, GFP_KERNEL); + mp = kcalloc(RTAX_MAX, sizeof(u32), GFP_KERNEL); if (unlikely(!mp)) return -ENOMEM; diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index feedd8d6a568..f7555b694f38 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -632,7 +632,7 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) /* * UDP-Lite specific tests, ignored on UDP sockets (see net/ipv4/udp.c). */ - if ((is_udplite & UDPLITE_RECV_CC) && UDP_SKB_CB(skb)->partial_cov) { + if ((up->pcflag & UDPLITE_RECV_CC) && UDP_SKB_CB(skb)->partial_cov) { if (up->pcrlen == 0) { /* full coverage was set */ net_dbg_ratelimited("UDPLITE6: partial coverage %d while full coverage %d requested\n", diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index b1484b8316e8..c883cb67b731 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1997,6 +1997,7 @@ static int ieee80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev) ieee80211_stop_mesh(sdata); mutex_lock(&sdata->local->mtx); ieee80211_vif_release_channel(sdata); + kfree(sdata->u.mesh.ie); mutex_unlock(&sdata->local->mtx); return 0; diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 89178b46b32f..d9558ffb8acf 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -1186,7 +1186,7 @@ static int ieee80211_chsw_switch_vifs(struct ieee80211_local *local, lockdep_assert_held(&local->mtx); lockdep_assert_held(&local->chanctx_mtx); - vif_chsw = kzalloc(sizeof(vif_chsw[0]) * n_vifs, GFP_KERNEL); + vif_chsw = kcalloc(n_vifs, sizeof(vif_chsw[0]), GFP_KERNEL); if (!vif_chsw) return -ENOMEM; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 8a51f94ec1ce..5199a3015593 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -781,7 +781,7 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local) if (have_mfp) n_suites += 4; - suites = kmalloc(sizeof(u32) * n_suites, GFP_KERNEL); + suites = kmalloc_array(n_suites, sizeof(u32), GFP_KERNEL); if (!suites) return -ENOMEM; diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 130022091205..933f26e2ff8b 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -554,6 +554,7 @@ static void mesh_path_free_rcu(struct mesh_table *tbl, del_timer_sync(&mpath->timer); atomic_dec(&sdata->u.mesh.mpaths); atomic_dec(&tbl->entries); + mesh_path_flush_pending(mpath); kfree_rcu(mpath, rcu); } diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 9766c1cc4b0a..7b20e6f6a4fc 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c @@ -592,11 +592,11 @@ minstrel_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) max_rates = sband->n_bitrates; } - mi->r = kzalloc(sizeof(struct minstrel_rate) * max_rates, gfp); + mi->r = kcalloc(max_rates, sizeof(struct minstrel_rate), gfp); if (!mi->r) goto error; - mi->sample_table = kmalloc(SAMPLE_COLUMNS * max_rates, gfp); + mi->sample_table = kmalloc_array(max_rates, SAMPLE_COLUMNS, gfp); if (!mi->sample_table) goto error1; diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 7ba4272642c9..d108a7c8bcee 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -1317,11 +1317,11 @@ minstrel_ht_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) if (!msp) return NULL; - msp->ratelist = kzalloc(sizeof(struct minstrel_rate) * max_rates, gfp); + msp->ratelist = kcalloc(max_rates, sizeof(struct minstrel_rate), gfp); if (!msp->ratelist) goto error; - msp->sample_table = kmalloc(SAMPLE_COLUMNS * max_rates, gfp); + msp->sample_table = kmalloc_array(max_rates, SAMPLE_COLUMNS, gfp); if (!msp->sample_table) goto error1; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 04ae9de55d74..2c08d8a83b4e 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2230,7 +2230,7 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx, bool *port_control) if (!sdata->u.mgd.use_4addr) return -1; - else + else if (!ether_addr_equal(hdr->addr1, sdata->vif.addr)) check_port_control = true; } diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 47d2ed570470..af9ef59a0513 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -1136,7 +1136,7 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, } } - ie = kzalloc(num_bands * iebufsz, GFP_KERNEL); + ie = kcalloc(iebufsz, num_bands, GFP_KERNEL); if (!ie) { ret = -ENOMEM; goto out; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index cd3cdd1a0b57..c3a798f95684 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1768,8 +1768,9 @@ static int ieee80211_reconfig_nan(struct ieee80211_sub_if_data *sdata) if (WARN_ON(res)) return res; - funcs = kzalloc((sdata->local->hw.max_nan_de_entries + 1) * - sizeof(*funcs), GFP_KERNEL); + funcs = kcalloc(sdata->local->hw.max_nan_de_entries + 1, + sizeof(*funcs), + GFP_KERNEL); if (!funcs) return -ENOMEM; diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index 3d2ac71a83ec..39c5c31622e8 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c @@ -1412,7 +1412,7 @@ int __init ip_vs_conn_init(void) /* * Allocate the connection hash table and initialize its list heads */ - ip_vs_conn_tab = vmalloc(ip_vs_conn_tab_size * sizeof(*ip_vs_conn_tab)); + ip_vs_conn_tab = vmalloc(array_size(ip_vs_conn_tab_size, sizeof(*ip_vs_conn_tab))); if (!ip_vs_conn_tab) return -ENOMEM; diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index b3e489c859ec..ed3d9b3d6609 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -322,9 +322,9 @@ int nf_ct_l4proto_register_one(struct nf_conntrack_l4proto *l4proto) struct nf_conntrack_l4proto __rcu **proto_array; int i; - proto_array = kmalloc(MAX_NF_CT_PROTO * - sizeof(struct nf_conntrack_l4proto *), - GFP_KERNEL); + proto_array = kmalloc_array(MAX_NF_CT_PROTO, + sizeof(struct nf_conntrack_l4proto *), + GFP_KERNEL); if (proto_array == NULL) { ret = -ENOMEM; goto out_unlock; diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c index ed0ea64b8d04..0c989bf8791a 100644 --- a/net/netfilter/nf_nat_core.c +++ b/net/netfilter/nf_nat_core.c @@ -589,8 +589,9 @@ int nf_nat_l4proto_register(u8 l3proto, const struct nf_nat_l4proto *l4proto) mutex_lock(&nf_nat_proto_mutex); if (nf_nat_l4protos[l3proto] == NULL) { - l4protos = kmalloc(IPPROTO_MAX * sizeof(struct nf_nat_l4proto *), - GFP_KERNEL); + l4protos = kmalloc_array(IPPROTO_MAX, + sizeof(struct nf_nat_l4proto *), + GFP_KERNEL); if (l4protos == NULL) { ret = -ENOMEM; goto out; diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 5b8d5bfeb7ac..3c71099cb4c1 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -5958,8 +5958,8 @@ static int __init nf_tables_module_init(void) { int err; - info = kmalloc(sizeof(struct nft_expr_info) * NFT_RULE_MAXEXPRS, - GFP_KERNEL); + info = kmalloc_array(NFT_RULE_MAXEXPRS, sizeof(struct nft_expr_info), + GFP_KERNEL); if (info == NULL) { err = -ENOMEM; goto err1; diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c index dfe4e6787219..8d8dcb005775 100644 --- a/net/netfilter/nfnetlink_cthelper.c +++ b/net/netfilter/nfnetlink_cthelper.c @@ -190,8 +190,9 @@ nfnl_cthelper_parse_expect_policy(struct nf_conntrack_helper *helper, if (class_max > NF_CT_MAX_EXPECT_CLASSES) return -EOVERFLOW; - expect_policy = kzalloc(sizeof(struct nf_conntrack_expect_policy) * - class_max, GFP_KERNEL); + expect_policy = kcalloc(class_max, + sizeof(struct nf_conntrack_expect_policy), + GFP_KERNEL); if (expect_policy == NULL) return -ENOMEM; diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c index cf96d230e5a3..441a70b043f4 100644 --- a/net/netfilter/xt_recent.c +++ b/net/netfilter/xt_recent.c @@ -184,8 +184,7 @@ recent_entry_init(struct recent_table *t, const union nf_inet_addr *addr, } nstamps_max += 1; - e = kmalloc(sizeof(*e) + sizeof(e->stamps[0]) * nstamps_max, - GFP_ATOMIC); + e = kmalloc(struct_size(e, stamps, nstamps_max), GFP_ATOMIC); if (e == NULL) return NULL; memcpy(&e->addr, addr, sizeof(e->addr)); diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 7bc631bfb101..ede73ecfb1f5 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -352,8 +352,9 @@ int genl_register_family(struct genl_family *family) } if (family->maxattr && !family->parallel_ops) { - family->attrbuf = kmalloc((family->maxattr+1) * - sizeof(struct nlattr *), GFP_KERNEL); + family->attrbuf = kmalloc_array(family->maxattr + 1, + sizeof(struct nlattr *), + GFP_KERNEL); if (family->attrbuf == NULL) { err = -ENOMEM; goto errout_locked; @@ -567,8 +568,9 @@ static int genl_family_rcv_msg(const struct genl_family *family, return -EOPNOTSUPP; if (family->maxattr && family->parallel_ops) { - attrbuf = kmalloc((family->maxattr+1) * - sizeof(struct nlattr *), GFP_KERNEL); + attrbuf = kmalloc_array(family->maxattr + 1, + sizeof(struct nlattr *), + GFP_KERNEL); if (attrbuf == NULL) return -ENOMEM; } else diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index aebc804c10aa..c244133a7e70 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -1414,7 +1414,7 @@ static int __init nr_proto_init(void) return -1; } - dev_nr = kzalloc(nr_ndevs * sizeof(struct net_device *), GFP_KERNEL); + dev_nr = kcalloc(nr_ndevs, sizeof(struct net_device *), GFP_KERNEL); if (dev_nr == NULL) { printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device array\n"); return -1; diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 3248cf04d0b3..c82e3b9ad488 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -1616,8 +1616,9 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) goto err_destroy_table; } - dp->ports = kmalloc(DP_VPORT_HASH_BUCKETS * sizeof(struct hlist_head), - GFP_KERNEL); + dp->ports = kmalloc_array(DP_VPORT_HASH_BUCKETS, + sizeof(struct hlist_head), + GFP_KERNEL); if (!dp->ports) { err = -ENOMEM; goto err_destroy_percpu; diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index b6c8524032a0..da2a77c67b4c 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c @@ -47,7 +47,7 @@ static struct hlist_head *dev_table; */ int ovs_vport_init(void) { - dev_table = kzalloc(VPORT_HASH_BUCKETS * sizeof(struct hlist_head), + dev_table = kcalloc(VPORT_HASH_BUCKETS, sizeof(struct hlist_head), GFP_KERNEL); if (!dev_table) return -ENOMEM; diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 42ee9a5bfc5c..6ee5988b44f8 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -4265,7 +4265,7 @@ static char *alloc_one_pg_vec_page(unsigned long order) return buffer; /* __get_free_pages failed, fall back to vmalloc */ - buffer = vzalloc((1 << order) * PAGE_SIZE); + buffer = vzalloc(array_size((1 << order), PAGE_SIZE)); if (buffer) return buffer; diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index b84dbc4421c7..514445b1741a 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -1543,7 +1543,7 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) if (addr->sq_port != QRTR_PORT_CTRL && qrtr_local_nid != QRTR_NODE_BCAST) { release_sock(sk); - return -EINVAL; + return -ENOTCONN; } enqueue_fn = qrtr_bcast_enqueue; } else if (addr->sq_node == ipc->us.sq_node) { diff --git a/net/rds/ib.c b/net/rds/ib.c index e723146cec29..21f8923a556e 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -164,7 +164,8 @@ static void rds_ib_add_one(struct ib_device *device) rds_ibdev->max_initiator_depth = device->attrs.max_qp_init_rd_atom; rds_ibdev->max_responder_resources = device->attrs.max_qp_rd_atom; - rds_ibdev->vector_load = kzalloc(sizeof(int) * device->num_comp_vectors, + rds_ibdev->vector_load = kcalloc(device->num_comp_vectors, + sizeof(int), GFP_KERNEL); if (!rds_ibdev->vector_load) { pr_err("RDS/IB: %s failed to allocate vector memory\n", diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index e086395a2355..c56101219a5b 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -525,7 +525,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) goto recv_hdrs_dma_out; } - ic->i_sends = vzalloc_node(ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work), + ic->i_sends = vzalloc_node(array_size(sizeof(struct rds_ib_send_work), ic->i_send_ring.w_nr), ibdev_to_node(dev)); if (!ic->i_sends) { ret = -ENOMEM; @@ -533,7 +533,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) goto ack_dma_out; } - ic->i_recvs = vzalloc_node(ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work), + ic->i_recvs = vzalloc_node(array_size(sizeof(struct rds_ib_recv_work), ic->i_recv_ring.w_nr), ibdev_to_node(dev)); if (!ic->i_recvs) { ret = -ENOMEM; diff --git a/net/rds/ib_fmr.c b/net/rds/ib_fmr.c index 353b59d3bd44..01e764f8f224 100644 --- a/net/rds/ib_fmr.c +++ b/net/rds/ib_fmr.c @@ -150,8 +150,8 @@ static int rds_ib_map_fmr(struct rds_ib_device *rds_ibdev, return -EINVAL; } - dma_pages = kmalloc_node(sizeof(u64) * page_cnt, GFP_ATOMIC, - rdsibdev_to_node(rds_ibdev)); + dma_pages = kmalloc_array_node(sizeof(u64), page_cnt, GFP_ATOMIC, + rdsibdev_to_node(rds_ibdev)); if (!dma_pages) { ib_dma_unmap_sg(dev, sg, nents, DMA_BIDIRECTIONAL); return -ENOMEM; diff --git a/net/rds/info.c b/net/rds/info.c index 140a44a5f7b7..e367a97a18c8 100644 --- a/net/rds/info.c +++ b/net/rds/info.c @@ -188,7 +188,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval, nr_pages = (PAGE_ALIGN(start + len) - (start & PAGE_MASK)) >> PAGE_SHIFT; - pages = kmalloc(nr_pages * sizeof(struct page *), GFP_KERNEL); + pages = kmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL); if (!pages) { ret = -ENOMEM; goto out; diff --git a/net/rds/recv.c b/net/rds/recv.c index c27cceae52e1..ef022d24f87a 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c @@ -453,12 +453,13 @@ static int rds_still_queued(struct rds_sock *rs, struct rds_incoming *inc, int rds_notify_queue_get(struct rds_sock *rs, struct msghdr *msghdr) { struct rds_notifier *notifier; - struct rds_rdma_notify cmsg = { 0 }; /* fill holes with zero */ + struct rds_rdma_notify cmsg; unsigned int count = 0, max_messages = ~0U; unsigned long flags; LIST_HEAD(copy); int err = 0; + memset(&cmsg, 0, sizeof(cmsg)); /* fill holes with zero */ /* put_cmsg copies to user space and thus may sleep. We can't do this * with rs_lock held, so first grab as many notifications as we can stuff diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 6a5c4992cf61..685e38044368 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -1528,7 +1528,8 @@ static int __init rose_proto_init(void) rose_callsign = null_ax25_address; - dev_rose = kzalloc(rose_ndevs * sizeof(struct net_device *), GFP_KERNEL); + dev_rose = kcalloc(rose_ndevs, sizeof(struct net_device *), + GFP_KERNEL); if (dev_rose == NULL) { printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate device structure\n"); rc = -ENOMEM; diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c index b74cde2fd214..e82e91fe6178 100644 --- a/net/rxrpc/recvmsg.c +++ b/net/rxrpc/recvmsg.c @@ -445,7 +445,7 @@ try_again: list_empty(&rx->recvmsg_q) && rx->sk.sk_state != RXRPC_SERVER_LISTENING) { release_sock(&rx->sk); - return -ENODATA; + return -EAGAIN; } if (list_empty(&rx->recvmsg_q)) { diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c index 48fad9ba8601..09487b9f9dd3 100644 --- a/net/rxrpc/rxkad.c +++ b/net/rxrpc/rxkad.c @@ -432,7 +432,7 @@ static int rxkad_verify_packet_2(struct rxrpc_call *call, struct sk_buff *skb, sg = _sg; if (unlikely(nsg > 4)) { - sg = kmalloc(sizeof(*sg) * nsg, GFP_NOIO); + sg = kmalloc_array(nsg, sizeof(*sg), GFP_NOIO); if (!sg) goto nomem; } diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c index a980b49d7a4f..f4386ad975cf 100644 --- a/net/rxrpc/sendmsg.c +++ b/net/rxrpc/sendmsg.c @@ -222,7 +222,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx, /* this should be in poll */ sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); - if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) + if (sk->sk_shutdown & SEND_SHUTDOWN) return -EPIPE; more = msg->msg_flags & MSG_MORE; diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 0c9bc29dcf97..eaf01c381f49 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -735,7 +735,8 @@ static u32 gen_new_kid(struct tc_u_hnode *ht, u32 handle) { struct tc_u_knode *n; unsigned long i; - unsigned long *bitmap = kzalloc(BITS_TO_LONGS(NR_U32_NODE) * sizeof(unsigned long), + unsigned long *bitmap = kcalloc(BITS_TO_LONGS(NR_U32_NODE), + sizeof(unsigned long), GFP_KERNEL); if (!bitmap) return handle | 0xFFF; diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c index 4faa631139af..490ca6d366fb 100644 --- a/net/sched/sch_fq_codel.c +++ b/net/sched/sch_fq_codel.c @@ -486,11 +486,12 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt) return err; if (!q->flows) { - q->flows = kvzalloc(q->flows_cnt * - sizeof(struct fq_codel_flow), GFP_KERNEL); + q->flows = kvcalloc(q->flows_cnt, + sizeof(struct fq_codel_flow), + GFP_KERNEL); if (!q->flows) return -ENOMEM; - q->backlogs = kvzalloc(q->flows_cnt * sizeof(u32), GFP_KERNEL); + q->backlogs = kvcalloc(q->flows_cnt, sizeof(u32), GFP_KERNEL); if (!q->backlogs) return -ENOMEM; for (i = 0; i < q->flows_cnt; i++) { diff --git a/net/sched/sch_hhf.c b/net/sched/sch_hhf.c index c73475c3a464..b9b77ad65a7e 100644 --- a/net/sched/sch_hhf.c +++ b/net/sched/sch_hhf.c @@ -597,8 +597,8 @@ static int hhf_init(struct Qdisc *sch, struct nlattr *opt) if (!q->hh_flows) { /* Initialize heavy-hitter flow table. */ - q->hh_flows = kvzalloc(HH_FLOWS_CNT * - sizeof(struct list_head), GFP_KERNEL); + q->hh_flows = kvcalloc(HH_FLOWS_CNT, sizeof(struct list_head), + GFP_KERNEL); if (!q->hh_flows) return -ENOMEM; for (i = 0; i < HH_FLOWS_CNT; i++) @@ -612,8 +612,9 @@ static int hhf_init(struct Qdisc *sch, struct nlattr *opt) /* Initialize heavy-hitter filter arrays. */ for (i = 0; i < HHF_ARRAYS_CNT; i++) { - q->hhf_arrays[i] = kvzalloc(HHF_ARRAYS_LEN * - sizeof(u32), GFP_KERNEL); + q->hhf_arrays[i] = kvcalloc(HHF_ARRAYS_LEN, + sizeof(u32), + GFP_KERNEL); if (!q->hhf_arrays[i]) { /* Note: hhf_destroy() will be called * by our caller. diff --git a/net/sctp/auth.c b/net/sctp/auth.c index 00667c50efa7..9b133db2d4dc 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c @@ -461,8 +461,9 @@ int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp) return 0; /* Allocated the array of pointers to transorms */ - ep->auth_hmacs = kzalloc(sizeof(struct crypto_shash *) * - SCTP_AUTH_NUM_HMACS, gfp); + ep->auth_hmacs = kcalloc(SCTP_AUTH_NUM_HMACS, + sizeof(struct crypto_shash *), + gfp); if (!ep->auth_hmacs) return -ENOMEM; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 8fe9c0646205..549c95313c6a 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -1456,7 +1456,7 @@ static __init int sctp_init(void) /* Allocate and initialize the endpoint hash table. */ sctp_ep_hashsize = 64; sctp_ep_hashtable = - kmalloc(64 * sizeof(struct sctp_hashbucket), GFP_KERNEL); + kmalloc_array(64, sizeof(struct sctp_hashbucket), GFP_KERNEL); if (!sctp_ep_hashtable) { pr_err("Failed endpoint_hash alloc\n"); status = -ENOMEM; diff --git a/net/smc/smc_wr.c b/net/smc/smc_wr.c index ed6736a1a112..5cdebdbb8f13 100644 --- a/net/smc/smc_wr.c +++ b/net/smc/smc_wr.c @@ -597,9 +597,9 @@ int smc_wr_alloc_link_mem(struct smc_link *link) GFP_KERNEL); if (!link->wr_rx_sges) goto no_mem_wr_tx_sges; - link->wr_tx_mask = kzalloc( - BITS_TO_LONGS(SMC_WR_BUF_CNT) * sizeof(*link->wr_tx_mask), - GFP_KERNEL); + link->wr_tx_mask = kcalloc(BITS_TO_LONGS(SMC_WR_BUF_CNT), + sizeof(*link->wr_tx_mask), + GFP_KERNEL); if (!link->wr_tx_mask) goto no_mem_wr_rx_sges; link->wr_tx_pends = kcalloc(SMC_WR_BUF_CNT, diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 1281b967dbf9..27e2b2230d03 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -1757,7 +1757,8 @@ alloc_enc_pages(struct rpc_rqst *rqstp) last = (snd_buf->page_base + snd_buf->page_len - 1) >> PAGE_SHIFT; rqstp->rq_enc_pages_num = last - first + 1 + 1; rqstp->rq_enc_pages - = kmalloc(rqstp->rq_enc_pages_num * sizeof(struct page *), + = kmalloc_array(rqstp->rq_enc_pages_num, + sizeof(struct page *), GFP_NOFS); if (!rqstp->rq_enc_pages) goto out; diff --git a/net/sunrpc/auth_gss/gss_rpc_upcall.c b/net/sunrpc/auth_gss/gss_rpc_upcall.c index 46b295e4f2b8..d58bd058b09b 100644 --- a/net/sunrpc/auth_gss/gss_rpc_upcall.c +++ b/net/sunrpc/auth_gss/gss_rpc_upcall.c @@ -224,7 +224,7 @@ static void gssp_free_receive_pages(struct gssx_arg_accept_sec_context *arg) static int gssp_alloc_receive_pages(struct gssx_arg_accept_sec_context *arg) { arg->npages = DIV_ROUND_UP(NGROUPS_MAX * 4, PAGE_SIZE); - arg->pages = kzalloc(arg->npages * sizeof(struct page *), GFP_KERNEL); + arg->pages = kcalloc(arg->npages, sizeof(struct page *), GFP_KERNEL); /* * XXX: actual pages are allocated by xdr layer in * xdr_partial_copy_from_skb. diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 556989b0b5fc..c6f5343f8c81 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -1688,7 +1688,7 @@ struct cache_detail *cache_create_net(struct cache_detail *tmpl, struct net *net if (cd == NULL) return ERR_PTR(-ENOMEM); - cd->hash_table = kzalloc(cd->hash_size * sizeof(struct hlist_head), + cd->hash_table = kcalloc(cd->hash_size, sizeof(struct hlist_head), GFP_KERNEL); if (cd->hash_table == NULL) { kfree(cd); diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index fa0522cd683e..d8e1c328046e 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -307,8 +307,9 @@ static int __tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd, if (err) goto trans_out; - attrbuf = kmalloc((tipc_genl_family.maxattr + 1) * - sizeof(struct nlattr *), GFP_KERNEL); + attrbuf = kmalloc_array(tipc_genl_family.maxattr + 1, + sizeof(struct nlattr *), + GFP_KERNEL); if (!attrbuf) { err = -ENOMEM; goto trans_out; diff --git a/net/wireguard/src/compat/ptr_ring/include/linux/ptr_ring.h b/net/wireguard/src/compat/ptr_ring/include/linux/ptr_ring.h index 9d514bac1388..32aed2b21b33 100644 --- a/net/wireguard/src/compat/ptr_ring/include/linux/ptr_ring.h +++ b/net/wireguard/src/compat/ptr_ring/include/linux/ptr_ring.h @@ -468,7 +468,7 @@ static inline void **__ptr_ring_init_queue_alloc(unsigned int size, gfp_t gfp) { if (size > KMALLOC_MAX_SIZE / sizeof(void *)) return NULL; - return kvmalloc(size * sizeof(void *), gfp | __GFP_ZERO); + return kvmalloc_array(size, sizeof(void *), gfp | __GFP_ZERO); } static inline void __ptr_ring_set_size(struct ptr_ring *r, int size) diff --git a/net/wireguard/src/ratelimiter.c b/net/wireguard/src/ratelimiter.c index e33ec72a9642..ecee41f528a5 100644 --- a/net/wireguard/src/ratelimiter.c +++ b/net/wireguard/src/ratelimiter.c @@ -188,12 +188,12 @@ int wg_ratelimiter_init(void) (1U << 14) / sizeof(struct hlist_head))); max_entries = table_size * 8; - table_v4 = kvzalloc(table_size * sizeof(*table_v4), GFP_KERNEL); + table_v4 = kvcalloc(table_size, sizeof(*table_v4), GFP_KERNEL); if (unlikely(!table_v4)) goto err_kmemcache; #if IS_ENABLED(CONFIG_IPV6) - table_v6 = kvzalloc(table_size * sizeof(*table_v6), GFP_KERNEL); + table_v6 = kvcalloc(table_size, sizeof(*table_v6), GFP_KERNEL); if (unlikely(!table_v6)) { kvfree(table_v4); goto err_kmemcache; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 09ee36ab0ef8..04e021398fce 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -10737,7 +10737,7 @@ static int nl80211_parse_wowlan_nd(struct cfg80211_registered_device *rdev, struct nlattr **tb; int err; - tb = kzalloc(NUM_NL80211_ATTR * sizeof(*tb), GFP_KERNEL); + tb = kcalloc(NUM_NL80211_ATTR, sizeof(*tb), GFP_KERNEL); if (!tb) return -ENOMEM; @@ -11712,7 +11712,7 @@ static int nl80211_nan_add_func(struct sk_buff *skb, func->srf_num_macs = n_entries; func->srf_macs = - kzalloc(sizeof(*func->srf_macs) * n_entries, + kcalloc(n_entries, sizeof(*func->srf_macs), GFP_KERNEL); if (!func->srf_macs) { err = -ENOMEM; diff --git a/net/x25/x25_subr.c b/net/x25/x25_subr.c index db0b1315d577..a946c1cfb5a2 100644 --- a/net/x25/x25_subr.c +++ b/net/x25/x25_subr.c @@ -363,6 +363,12 @@ void x25_disconnect(struct sock *sk, int reason, unsigned char cause, sk->sk_state_change(sk); sock_set_flag(sk, SOCK_DEAD); } + if (x25->neighbour) { + read_lock_bh(&x25_list_lock); + x25_neigh_put(x25->neighbour); + x25->neighbour = NULL; + read_unlock_bh(&x25_list_lock); + } } /* diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh index 67d131447631..b5115c6b22f6 100755 --- a/scripts/kconfig/merge_config.sh +++ b/scripts/kconfig/merge_config.sh @@ -151,7 +151,7 @@ fi # Use the merged file as the starting point for: # alldefconfig: Fills in any missing symbols with Kconfig default # allnoconfig: Fills in any missing symbols with # CONFIG_* is not set -make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET +make $MAKE_ARGS KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET # Check all specified config values took (might have missed-dependency issues) diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c index 2cef8d4404cc..5e4233afd20a 100644 --- a/security/apparmor/policy_unpack.c +++ b/security/apparmor/policy_unpack.c @@ -458,7 +458,7 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile) /* currently 4 exec bits and entries 0-3 are reserved iupcx */ if (size > 16 - 4) goto fail; - profile->file.trans.table = kzalloc(sizeof(char *) * size, + profile->file.trans.table = kcalloc(size, sizeof(char *), GFP_KERNEL); if (!profile->file.trans.table) goto fail; diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig index 2728517339a1..325df76b23f6 100644 --- a/security/selinux/Kconfig +++ b/security/selinux/Kconfig @@ -111,3 +111,14 @@ config SECURITY_SELINUX_SIDTAB_HASH_BITS collisions may be viewed at /sys/fs/selinux/ss/sidtab_hash_stats. If chain lengths are high (e.g. > 20) then selecting a higher value here will ensure that lookups times are short and stable. + +config SECURITY_SELINUX_SID2STR_CACHE_SIZE + int "NSA SELinux SID to context string translation cache size" + depends on SECURITY_SELINUX + default 256 + help + This option defines the size of the internal SID -> context string + cache, which improves the performance of context to string + conversion. Setting this option to 0 disables the cache completely. + + If unsure, keep the default value. diff --git a/security/selinux/avc.c b/security/selinux/avc.c index d10b03f36823..60b1a6b1d0ad 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -766,6 +766,21 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) audit_log_format(ab, " permissive=%u", ad->selinux_audit_data->result ? 0 : 1); } + + /* in case of invalid context report also the actual context string */ + rc = security_sid_to_context_inval(sad->state, sad->ssid, &scontext, + &scontext_len); + if (!rc && scontext) { + audit_log_format(ab, " srawcon=%s", scontext); + kfree(scontext); + } + + rc = security_sid_to_context_inval(sad->state, sad->tsid, &scontext, + &scontext_len); + if (!rc && scontext) { + audit_log_format(ab, " trawcon=%s", scontext); + kfree(scontext); + } } diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index be3cfd006179..197e0818516e 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -37,7 +37,7 @@ struct task_security_struct { u32 create_sid; /* fscreate SID */ u32 keycreate_sid; /* keycreate SID */ u32 sockcreate_sid; /* fscreate SID */ -}; +} __randomize_layout; /* * get the subjective security ID of the current task diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index cf7cc432f90b..7bf2c7adec2d 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -106,7 +106,7 @@ struct selinux_state { bool android_netlink_route; struct selinux_avc *avc; struct selinux_ss *ss; -}; +} __randomize_layout; void selinux_ss_init(struct selinux_ss **ss); void selinux_avc_init(struct selinux_avc **avc); @@ -262,6 +262,9 @@ int security_sid_to_context(struct selinux_state *state, u32 sid, int security_sid_to_context_force(struct selinux_state *state, u32 sid, char **scontext, u32 *scontext_len); +int security_sid_to_context_inval(struct selinux_state *state, + u32 sid, char **scontext, u32 *scontext_len); + int security_context_to_sid(struct selinux_state *state, const char *scontext, u32 scontext_len, u32 *out_sid, gfp_t gfp); diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c index a2c9148b0662..4bd3ffe5e5f8 100644 --- a/security/selinux/ss/avtab.c +++ b/security/selinux/ss/avtab.c @@ -93,12 +93,10 @@ avtab_insert_node(struct avtab *h, int hvalue, newnode->next = prev->next; prev->next = newnode; } else { - newnode->next = flex_array_get_ptr(h->htable, hvalue); - if (flex_array_put_ptr(h->htable, hvalue, newnode, - GFP_KERNEL|__GFP_ZERO)) { - kmem_cache_free(avtab_node_cachep, newnode); - return NULL; - } + struct avtab_node **n = &h->htable[hvalue]; + + newnode->next = *n; + *n = newnode; } h->nel++; @@ -111,11 +109,11 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat struct avtab_node *prev, *cur, *newnode; u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); - if (!h || !h->htable) + if (!h) return -EINVAL; hvalue = avtab_hash(key, h->mask); - for (prev = NULL, cur = flex_array_get_ptr(h->htable, hvalue); + for (prev = NULL, cur = h->htable[hvalue]; cur; prev = cur, cur = cur->next) { if (key->source_type == cur->key.source_type && @@ -156,10 +154,10 @@ avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, struct avtab_datu struct avtab_node *prev, *cur; u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); - if (!h || !h->htable) + if (!h) return NULL; hvalue = avtab_hash(key, h->mask); - for (prev = NULL, cur = flex_array_get_ptr(h->htable, hvalue); + for (prev = NULL, cur = h->htable[hvalue]; cur; prev = cur, cur = cur->next) { if (key->source_type == cur->key.source_type && @@ -186,11 +184,11 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key) struct avtab_node *cur; u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); - if (!h || !h->htable) + if (!h) return NULL; hvalue = avtab_hash(key, h->mask); - for (cur = flex_array_get_ptr(h->htable, hvalue); cur; + for (cur = h->htable[hvalue]; cur; cur = cur->next) { if (key->source_type == cur->key.source_type && key->target_type == cur->key.target_type && @@ -222,11 +220,11 @@ avtab_search_node(struct avtab *h, struct avtab_key *key) struct avtab_node *cur; u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); - if (!h || !h->htable) + if (!h) return NULL; hvalue = avtab_hash(key, h->mask); - for (cur = flex_array_get_ptr(h->htable, hvalue); cur; + for (cur = h->htable[hvalue]; cur; cur = cur->next) { if (key->source_type == cur->key.source_type && key->target_type == cur->key.target_type && @@ -281,11 +279,11 @@ void avtab_destroy(struct avtab *h) int i; struct avtab_node *cur, *temp; - if (!h || !h->htable) + if (!h) return; for (i = 0; i < h->nslot; i++) { - cur = flex_array_get_ptr(h->htable, i); + cur = h->htable[i]; while (cur) { temp = cur; cur = cur->next; @@ -295,7 +293,7 @@ void avtab_destroy(struct avtab *h) kmem_cache_free(avtab_node_cachep, temp); } } - flex_array_free(h->htable); + kvfree(h->htable); h->htable = NULL; h->nslot = 0; h->mask = 0; @@ -303,6 +301,7 @@ void avtab_destroy(struct avtab *h) int avtab_init(struct avtab *h) { + kvfree(h->htable); h->htable = NULL; h->nel = 0; return 0; @@ -329,8 +328,7 @@ int avtab_alloc(struct avtab *h, u32 nrules) nslot = MAX_AVTAB_HASH_BUCKETS; mask = nslot - 1; - h->htable = flex_array_alloc(sizeof(struct avtab_node *), nslot, - GFP_KERNEL | __GFP_ZERO); + h->htable = kvcalloc(nslot, sizeof(void *), GFP_KERNEL); if (!h->htable) return -ENOMEM; @@ -353,7 +351,7 @@ void avtab_hash_eval(struct avtab *h, char *tag) max_chain_len = 0; chain2_len_sum = 0; for (i = 0; i < h->nslot; i++) { - cur = flex_array_get_ptr(h->htable, i); + cur = h->htable[i]; if (cur) { slots_used++; chain_len = 0; @@ -645,7 +643,7 @@ int avtab_write(struct policydb *p, struct avtab *a, void *fp) return rc; for (i = 0; i < a->nslot; i++) { - for (cur = flex_array_get_ptr(a->htable, i); cur; + for (cur = a->htable[i]; cur; cur = cur->next) { rc = avtab_write_item(p, cur, fp); if (rc) diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h index 0d652fad5319..de16673b2314 100644 --- a/security/selinux/ss/avtab.h +++ b/security/selinux/ss/avtab.h @@ -24,7 +24,6 @@ #define _SS_AVTAB_H_ #include "security.h" -#include struct avtab_key { u16 source_type; /* source type */ @@ -84,11 +83,10 @@ struct avtab_node { }; struct avtab { - struct flex_array *htable; + struct avtab_node **htable; u32 nel; /* number of elements */ u32 nslot; /* number of hash slots */ u32 mask; /* mask to compute hash func */ - }; int avtab_init(struct avtab *); diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c index 771c96afe1d5..850956fe5703 100644 --- a/security/selinux/ss/conditional.c +++ b/security/selinux/ss/conditional.c @@ -195,7 +195,6 @@ int cond_index_bool(void *key, void *datum, void *datap) { struct policydb *p; struct cond_bool_datum *booldatum; - struct flex_array *fa; booldatum = datum; p = datap; @@ -203,10 +202,7 @@ int cond_index_bool(void *key, void *datum, void *datap) if (!booldatum->value || booldatum->value > p->p_bools.nprim) return -EINVAL; - fa = p->sym_val_to_name[SYM_BOOLS]; - if (flex_array_put_ptr(fa, booldatum->value - 1, key, - GFP_KERNEL | __GFP_ZERO)) - BUG(); + p->sym_val_to_name[SYM_BOOLS][booldatum->value - 1] = key; p->bool_val_to_struct[booldatum->value - 1] = booldatum; return 0; diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 2472b2a66f70..a83bba47efe1 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -36,7 +36,6 @@ #include #include #include -#include #include "security.h" #include "policydb.h" @@ -346,17 +345,14 @@ static int common_index(void *key, void *datum, void *datap) { struct policydb *p; struct common_datum *comdatum; - struct flex_array *fa; comdatum = datum; p = datap; if (!comdatum->value || comdatum->value > p->p_commons.nprim) return -EINVAL; - fa = p->sym_val_to_name[SYM_COMMONS]; - if (flex_array_put_ptr(fa, comdatum->value - 1, key, - GFP_KERNEL | __GFP_ZERO)) - BUG(); + p->sym_val_to_name[SYM_COMMONS][comdatum->value - 1] = key; + return 0; } @@ -364,16 +360,13 @@ static int class_index(void *key, void *datum, void *datap) { struct policydb *p; struct class_datum *cladatum; - struct flex_array *fa; cladatum = datum; p = datap; if (!cladatum->value || cladatum->value > p->p_classes.nprim) return -EINVAL; - fa = p->sym_val_to_name[SYM_CLASSES]; - if (flex_array_put_ptr(fa, cladatum->value - 1, key, - GFP_KERNEL | __GFP_ZERO)) - BUG(); + + p->sym_val_to_name[SYM_CLASSES][cladatum->value - 1] = key; p->class_val_to_struct[cladatum->value - 1] = cladatum; return 0; } @@ -382,7 +375,6 @@ static int role_index(void *key, void *datum, void *datap) { struct policydb *p; struct role_datum *role; - struct flex_array *fa; role = datum; p = datap; @@ -391,10 +383,7 @@ static int role_index(void *key, void *datum, void *datap) || role->bounds > p->p_roles.nprim) return -EINVAL; - fa = p->sym_val_to_name[SYM_ROLES]; - if (flex_array_put_ptr(fa, role->value - 1, key, - GFP_KERNEL | __GFP_ZERO)) - BUG(); + p->sym_val_to_name[SYM_ROLES][role->value - 1] = key; p->role_val_to_struct[role->value - 1] = role; return 0; } @@ -403,7 +392,6 @@ static int type_index(void *key, void *datum, void *datap) { struct policydb *p; struct type_datum *typdatum; - struct flex_array *fa; typdatum = datum; p = datap; @@ -413,15 +401,8 @@ static int type_index(void *key, void *datum, void *datap) || typdatum->value > p->p_types.nprim || typdatum->bounds > p->p_types.nprim) return -EINVAL; - fa = p->sym_val_to_name[SYM_TYPES]; - if (flex_array_put_ptr(fa, typdatum->value - 1, key, - GFP_KERNEL | __GFP_ZERO)) - BUG(); - - fa = p->type_val_to_struct_array; - if (flex_array_put_ptr(fa, typdatum->value - 1, typdatum, - GFP_KERNEL | __GFP_ZERO)) - BUG(); + p->sym_val_to_name[SYM_TYPES][typdatum->value - 1] = key; + p->type_val_to_struct_array[typdatum->value - 1] = typdatum; } return 0; @@ -431,7 +412,6 @@ static int user_index(void *key, void *datum, void *datap) { struct policydb *p; struct user_datum *usrdatum; - struct flex_array *fa; usrdatum = datum; p = datap; @@ -440,10 +420,7 @@ static int user_index(void *key, void *datum, void *datap) || usrdatum->bounds > p->p_users.nprim) return -EINVAL; - fa = p->sym_val_to_name[SYM_USERS]; - if (flex_array_put_ptr(fa, usrdatum->value - 1, key, - GFP_KERNEL | __GFP_ZERO)) - BUG(); + p->sym_val_to_name[SYM_USERS][usrdatum->value - 1] = key; p->user_val_to_struct[usrdatum->value - 1] = usrdatum; return 0; } @@ -452,7 +429,6 @@ static int sens_index(void *key, void *datum, void *datap) { struct policydb *p; struct level_datum *levdatum; - struct flex_array *fa; levdatum = datum; p = datap; @@ -461,10 +437,8 @@ static int sens_index(void *key, void *datum, void *datap) if (!levdatum->level->sens || levdatum->level->sens > p->p_levels.nprim) return -EINVAL; - fa = p->sym_val_to_name[SYM_LEVELS]; - if (flex_array_put_ptr(fa, levdatum->level->sens - 1, key, - GFP_KERNEL | __GFP_ZERO)) - BUG(); + + p->sym_val_to_name[SYM_LEVELS][levdatum->level->sens - 1] = key; } return 0; @@ -474,7 +448,6 @@ static int cat_index(void *key, void *datum, void *datap) { struct policydb *p; struct cat_datum *catdatum; - struct flex_array *fa; catdatum = datum; p = datap; @@ -482,10 +455,8 @@ static int cat_index(void *key, void *datum, void *datap) if (!catdatum->isalias) { if (!catdatum->value || catdatum->value > p->p_cats.nprim) return -EINVAL; - fa = p->sym_val_to_name[SYM_CATS]; - if (flex_array_put_ptr(fa, catdatum->value - 1, key, - GFP_KERNEL | __GFP_ZERO)) - BUG(); + + p->sym_val_to_name[SYM_CATS][catdatum->value - 1] = key; } return 0; @@ -571,35 +542,23 @@ static int policydb_index(struct policydb *p) if (!p->user_val_to_struct) return -ENOMEM; - /* Yes, I want the sizeof the pointer, not the structure */ - p->type_val_to_struct_array = flex_array_alloc(sizeof(struct type_datum *), - p->p_types.nprim, - GFP_KERNEL | __GFP_ZERO); + p->type_val_to_struct_array = kvcalloc(p->p_types.nprim, + sizeof(*p->type_val_to_struct_array), + GFP_KERNEL); if (!p->type_val_to_struct_array) return -ENOMEM; - rc = flex_array_prealloc(p->type_val_to_struct_array, 0, - p->p_types.nprim, GFP_KERNEL | __GFP_ZERO); - if (rc) - goto out; - rc = cond_init_bool_indexes(p); if (rc) goto out; for (i = 0; i < SYM_NUM; i++) { - p->sym_val_to_name[i] = flex_array_alloc(sizeof(char *), - p->symtab[i].nprim, - GFP_KERNEL | __GFP_ZERO); + p->sym_val_to_name[i] = kvcalloc(p->symtab[i].nprim, + sizeof(char *), + GFP_KERNEL); if (!p->sym_val_to_name[i]) return -ENOMEM; - rc = flex_array_prealloc(p->sym_val_to_name[i], - 0, p->symtab[i].nprim, - GFP_KERNEL | __GFP_ZERO); - if (rc) - goto out; - rc = hashtab_map(p->symtab[i].table, index_f[i], p); if (rc) goto out; @@ -813,16 +772,13 @@ void policydb_destroy(struct policydb *p) hashtab_destroy(p->symtab[i].table); } - for (i = 0; i < SYM_NUM; i++) { - if (p->sym_val_to_name[i]) - flex_array_free(p->sym_val_to_name[i]); - } + for (i = 0; i < SYM_NUM; i++) + kvfree(p->sym_val_to_name[i]); kfree(p->class_val_to_struct); kfree(p->role_val_to_struct); kfree(p->user_val_to_struct); - if (p->type_val_to_struct_array) - flex_array_free(p->type_val_to_struct_array); + kvfree(p->type_val_to_struct_array); avtab_destroy(&p->te_avtab); @@ -875,17 +831,9 @@ void policydb_destroy(struct policydb *p) hashtab_map(p->range_tr, range_tr_destroy, NULL); hashtab_destroy(p->range_tr); - if (p->type_attr_map_array) { - for (i = 0; i < p->p_types.nprim; i++) { - struct ebitmap *e; - - e = flex_array_get(p->type_attr_map_array, i); - if (!e) - continue; - ebitmap_destroy(e); - } - flex_array_free(p->type_attr_map_array); - } + for (i = 0; i < p->p_types.nprim; i++) + ebitmap_destroy(&p->type_attr_map_array[i]); + kvfree(p->type_attr_map_array); ebitmap_destroy(&p->filename_trans_ttypes); ebitmap_destroy(&p->policycaps); @@ -1779,8 +1727,7 @@ static int type_bounds_sanity_check(void *key, void *datum, void *datap) return -EINVAL; } - upper = flex_array_get_ptr(p->type_val_to_struct_array, - upper->bounds - 1); + upper = p->type_val_to_struct_array[upper->bounds - 1]; BUG_ON(!upper); if (upper->attribute) { @@ -2556,23 +2503,15 @@ int policydb_read(struct policydb *p, void *fp) if (rc) goto bad; - rc = -ENOMEM; - p->type_attr_map_array = flex_array_alloc(sizeof(struct ebitmap), - p->p_types.nprim, - GFP_KERNEL | __GFP_ZERO); + p->type_attr_map_array = kvcalloc(p->p_types.nprim, + sizeof(*p->type_attr_map_array), + GFP_KERNEL); if (!p->type_attr_map_array) goto bad; - /* preallocate so we don't have to worry about the put ever failing */ - rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim, - GFP_KERNEL | __GFP_ZERO); - if (rc) - goto bad; - for (i = 0; i < p->p_types.nprim; i++) { - struct ebitmap *e = flex_array_get(p->type_attr_map_array, i); + struct ebitmap *e = &p->type_attr_map_array[i]; - BUG_ON(!e); ebitmap_init(e); if (p->policyvers >= POLICYDB_VERSION_AVTAB) { rc = ebitmap_read(e, fp); @@ -3567,9 +3506,8 @@ int policydb_write(struct policydb *p, void *fp) return rc; for (i = 0; i < p->p_types.nprim; i++) { - struct ebitmap *e = flex_array_get(p->type_attr_map_array, i); + struct ebitmap *e = &p->type_attr_map_array[i]; - BUG_ON(!e); rc = ebitmap_write(e, fp); if (rc) return rc; diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index dbb0ed57ed8b..4fab84f1a5e5 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h @@ -24,8 +24,6 @@ #ifndef _SS_POLICYDB_H_ #define _SS_POLICYDB_H_ -#include - #include "symtab.h" #include "avtab.h" #include "sidtab.h" @@ -252,13 +250,13 @@ struct policydb { #define p_cats symtab[SYM_CATS] /* symbol names indexed by (value - 1) */ - struct flex_array *sym_val_to_name[SYM_NUM]; + char **sym_val_to_name[SYM_NUM]; /* class, role, and user attributes indexed by (value - 1) */ struct class_datum **class_val_to_struct; struct role_datum **role_val_to_struct; struct user_datum **user_val_to_struct; - struct flex_array *type_val_to_struct_array; + struct type_datum **type_val_to_struct_array; /* type enforcement access vectors and transitions */ struct avtab te_avtab; @@ -295,7 +293,7 @@ struct policydb { struct hashtab *range_tr; /* type -> attribute reverse mapping */ - struct flex_array *type_attr_map_array; + struct ebitmap *type_attr_map_array; struct ebitmap policycaps; @@ -311,7 +309,7 @@ struct policydb { u16 process_class; u32 process_trans_perms; -}; +} __randomize_layout; extern void policydb_destroy(struct policydb *p); extern int policydb_load_isids(struct policydb *p, struct sidtab *s); @@ -371,9 +369,7 @@ static inline int put_entry(const void *buf, size_t bytes, int num, struct polic static inline char *sym_name(struct policydb *p, unsigned int sym_num, unsigned int element_nr) { - struct flex_array *fa = p->sym_val_to_name[sym_num]; - - return flex_array_get_ptr(fa, element_nr); + return p->sym_val_to_name[sym_num][element_nr]; } extern u16 string_to_security_class(struct policydb *p, const char *name); diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index eef2b7f31492..398206f25eac 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include @@ -95,6 +94,12 @@ static int context_struct_to_string(struct policydb *policydb, char **scontext, u32 *scontext_len); +static int sidtab_entry_to_string(struct policydb *policydb, + struct sidtab *sidtab, + struct sidtab_entry *entry, + char **scontext, + u32 *scontext_len); + static void context_struct_compute_av(struct policydb *policydb, struct context *scontext, struct context *tcontext, @@ -546,15 +551,13 @@ static void type_attribute_bounds_av(struct policydb *policydb, struct type_datum *target; u32 masked = 0; - source = flex_array_get_ptr(policydb->type_val_to_struct_array, - scontext->type - 1); + source = policydb->type_val_to_struct_array[scontext->type - 1]; BUG_ON(!source); if (!source->bounds) return; - target = flex_array_get_ptr(policydb->type_val_to_struct_array, - tcontext->type - 1); + target = policydb->type_val_to_struct_array[tcontext->type - 1]; BUG_ON(!target); memset(&lo_avd, 0, sizeof(lo_avd)); @@ -654,11 +657,9 @@ static void context_struct_compute_av(struct policydb *policydb, */ avkey.target_class = tclass; avkey.specified = AVTAB_AV | AVTAB_XPERMS; - sattr = flex_array_get(policydb->type_attr_map_array, - scontext->type - 1); + sattr = &policydb->type_attr_map_array[scontext->type - 1]; BUG_ON(!sattr); - tattr = flex_array_get(policydb->type_attr_map_array, - tcontext->type - 1); + tattr = &policydb->type_attr_map_array[tcontext->type - 1]; BUG_ON(!tattr); ebitmap_for_each_positive_bit(sattr, snode, i) { ebitmap_for_each_positive_bit(tattr, tnode, j) { @@ -726,20 +727,21 @@ static void context_struct_compute_av(struct policydb *policydb, } static int security_validtrans_handle_fail(struct selinux_state *state, - struct context *ocontext, - struct context *ncontext, - struct context *tcontext, + struct sidtab_entry *oentry, + struct sidtab_entry *nentry, + struct sidtab_entry *tentry, u16 tclass) { struct policydb *p = &state->ss->policydb; + struct sidtab *sidtab = state->ss->sidtab; char *o = NULL, *n = NULL, *t = NULL; u32 olen, nlen, tlen; - if (context_struct_to_string(p, ocontext, &o, &olen)) + if (sidtab_entry_to_string(p, sidtab, oentry, &o, &olen)) goto out; - if (context_struct_to_string(p, ncontext, &n, &nlen)) + if (sidtab_entry_to_string(p, sidtab, nentry, &n, &nlen)) goto out; - if (context_struct_to_string(p, tcontext, &t, &tlen)) + if (sidtab_entry_to_string(p, sidtab, tentry, &t, &tlen)) goto out; audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, "op=security_validate_transition seresult=denied" @@ -761,9 +763,9 @@ static int security_compute_validatetrans(struct selinux_state *state, { struct policydb *policydb; struct sidtab *sidtab; - struct context *ocontext; - struct context *ncontext; - struct context *tcontext; + struct sidtab_entry *oentry; + struct sidtab_entry *nentry; + struct sidtab_entry *tentry; struct class_datum *tclass_datum; struct constraint_node *constraint; u16 tclass; @@ -789,24 +791,24 @@ static int security_compute_validatetrans(struct selinux_state *state, } tclass_datum = policydb->class_val_to_struct[tclass - 1]; - ocontext = sidtab_search(sidtab, oldsid); - if (!ocontext) { + oentry = sidtab_search_entry(sidtab, oldsid); + if (!oentry) { pr_err("SELinux: %s: unrecognized SID %d\n", __func__, oldsid); rc = -EINVAL; goto out; } - ncontext = sidtab_search(sidtab, newsid); - if (!ncontext) { + nentry = sidtab_search_entry(sidtab, newsid); + if (!nentry) { pr_err("SELinux: %s: unrecognized SID %d\n", __func__, newsid); rc = -EINVAL; goto out; } - tcontext = sidtab_search(sidtab, tasksid); - if (!tcontext) { + tentry = sidtab_search_entry(sidtab, tasksid); + if (!tentry) { pr_err("SELinux: %s: unrecognized SID %d\n", __func__, tasksid); rc = -EINVAL; @@ -815,15 +817,16 @@ static int security_compute_validatetrans(struct selinux_state *state, constraint = tclass_datum->validatetrans; while (constraint) { - if (!constraint_expr_eval(policydb, ocontext, ncontext, - tcontext, constraint->expr)) { + if (!constraint_expr_eval(policydb, &oentry->context, + &nentry->context, &tentry->context, + constraint->expr)) { if (user) rc = -EPERM; else rc = security_validtrans_handle_fail(state, - ocontext, - ncontext, - tcontext, + oentry, + nentry, + tentry, tclass); goto out; } @@ -865,7 +868,7 @@ int security_bounded_transition(struct selinux_state *state, { struct policydb *policydb; struct sidtab *sidtab; - struct context *old_context, *new_context; + struct sidtab_entry *old_entry, *new_entry; struct type_datum *type; int index; int rc; @@ -879,16 +882,16 @@ int security_bounded_transition(struct selinux_state *state, sidtab = state->ss->sidtab; rc = -EINVAL; - old_context = sidtab_search(sidtab, old_sid); - if (!old_context) { + old_entry = sidtab_search_entry(sidtab, old_sid); + if (!old_entry) { pr_err("SELinux: %s: unrecognized SID %u\n", __func__, old_sid); goto out; } rc = -EINVAL; - new_context = sidtab_search(sidtab, new_sid); - if (!new_context) { + new_entry = sidtab_search_entry(sidtab, new_sid); + if (!new_entry) { pr_err("SELinux: %s: unrecognized SID %u\n", __func__, new_sid); goto out; @@ -896,13 +899,12 @@ int security_bounded_transition(struct selinux_state *state, rc = 0; /* type/domain unchanged */ - if (old_context->type == new_context->type) + if (old_entry->context.type == new_entry->context.type) goto out; - index = new_context->type; + index = new_entry->context.type; while (true) { - type = flex_array_get_ptr(policydb->type_val_to_struct_array, - index - 1); + type = policydb->type_val_to_struct_array[index - 1]; BUG_ON(!type); /* not bounded anymore */ @@ -912,7 +914,7 @@ int security_bounded_transition(struct selinux_state *state, /* @newsid is bounded by @oldsid */ rc = 0; - if (type->bounds == old_context->type) + if (type->bounds == old_entry->context.type) break; index = type->bounds; @@ -923,10 +925,10 @@ int security_bounded_transition(struct selinux_state *state, char *new_name = NULL; u32 length; - if (!context_struct_to_string(policydb, old_context, - &old_name, &length) && - !context_struct_to_string(policydb, new_context, - &new_name, &length)) { + if (!sidtab_entry_to_string(policydb, sidtab, old_entry, + &old_name, &length) && + !sidtab_entry_to_string(policydb, sidtab, new_entry, + &new_name, &length)) { audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, "op=security_bounded_transition " @@ -1065,11 +1067,9 @@ void security_compute_xperms_decision(struct selinux_state *state, avkey.target_class = tclass; avkey.specified = AVTAB_XPERMS; - sattr = flex_array_get(policydb->type_attr_map_array, - scontext->type - 1); + sattr = &policydb->type_attr_map_array[scontext->type - 1]; BUG_ON(!sattr); - tattr = flex_array_get(policydb->type_attr_map_array, - tcontext->type - 1); + tattr = &policydb->type_attr_map_array[tcontext->type - 1]; BUG_ON(!tattr); ebitmap_for_each_positive_bit(sattr, snode, i) { ebitmap_for_each_positive_bit(tattr, tnode, j) { @@ -1270,12 +1270,35 @@ static int context_struct_to_string(struct policydb *p, return 0; } +static int sidtab_entry_to_string(struct policydb *p, + struct sidtab *sidtab, + struct sidtab_entry *entry, + char **scontext, u32 *scontext_len) +{ + int rc = sidtab_sid2str_get(sidtab, entry, scontext, scontext_len); + + if (rc != -ENOENT) + return rc; + + rc = context_struct_to_string(p, &entry->context, scontext, + scontext_len); + if (!rc && scontext) + sidtab_sid2str_put(sidtab, entry, *scontext, *scontext_len); + return rc; +} + #include "initial_sid_to_string.h" int security_sidtab_hash_stats(struct selinux_state *state, char *page) { int rc; + if (!state->initialized) { + pr_err("SELinux: %s: called before initial load_policy\n", + __func__); + return -EINVAL; + } + read_lock(&state->ss->policy_rwlock); rc = sidtab_hash_stats(state->ss->sidtab, page); read_unlock(&state->ss->policy_rwlock); @@ -1292,11 +1315,12 @@ const char *security_get_initial_sid_context(u32 sid) static int security_sid_to_context_core(struct selinux_state *state, u32 sid, char **scontext, - u32 *scontext_len, int force) + u32 *scontext_len, int force, + int only_invalid) { struct policydb *policydb; struct sidtab *sidtab; - struct context *context; + struct sidtab_entry *entry; int rc = 0; if (scontext) @@ -1327,18 +1351,23 @@ static int security_sid_to_context_core(struct selinux_state *state, read_lock(&state->ss->policy_rwlock); policydb = &state->ss->policydb; sidtab = state->ss->sidtab; + if (force) - context = sidtab_search_force(sidtab, sid); + entry = sidtab_search_entry_force(sidtab, sid); else - context = sidtab_search(sidtab, sid); - if (!context) { + entry = sidtab_search_entry(sidtab, sid); + if (!entry) { pr_err("SELinux: %s: unrecognized SID %d\n", __func__, sid); rc = -EINVAL; goto out_unlock; } - rc = context_struct_to_string(policydb, context, scontext, - scontext_len); + if (only_invalid && !entry->context.len) + goto out_unlock; + + rc = sidtab_entry_to_string(policydb, sidtab, entry, scontext, + scontext_len); + out_unlock: read_unlock(&state->ss->policy_rwlock); out: @@ -1360,14 +1389,34 @@ int security_sid_to_context(struct selinux_state *state, u32 sid, char **scontext, u32 *scontext_len) { return security_sid_to_context_core(state, sid, scontext, - scontext_len, 0); + scontext_len, 0, 0); } int security_sid_to_context_force(struct selinux_state *state, u32 sid, char **scontext, u32 *scontext_len) { return security_sid_to_context_core(state, sid, scontext, - scontext_len, 1); + scontext_len, 1, 0); +} + +/** + * security_sid_to_context_inval - Obtain a context for a given SID if it + * is invalid. + * @sid: security identifier, SID + * @scontext: security context + * @scontext_len: length in bytes + * + * Write the string representation of the context associated with @sid + * into a dynamically allocated string of the correct size, but only if the + * context is invalid in the current policy. Set @scontext to point to + * this string (or NULL if the context is valid) and set @scontext_len to + * the length of the string (or 0 if the context is valid). + */ +int security_sid_to_context_inval(struct selinux_state *state, u32 sid, + char **scontext, u32 *scontext_len) +{ + return security_sid_to_context_core(state, sid, scontext, + scontext_len, 1, 1); } /* @@ -1612,18 +1661,19 @@ int security_context_to_sid_force(struct selinux_state *state, static int compute_sid_handle_invalid_context( struct selinux_state *state, - struct context *scontext, - struct context *tcontext, + struct sidtab_entry *sentry, + struct sidtab_entry *tentry, u16 tclass, struct context *newcontext) { struct policydb *policydb = &state->ss->policydb; + struct sidtab *sidtab = state->ss->sidtab; char *s = NULL, *t = NULL, *n = NULL; u32 slen, tlen, nlen; - if (context_struct_to_string(policydb, scontext, &s, &slen)) + if (sidtab_entry_to_string(policydb, sidtab, sentry, &s, &slen)) goto out; - if (context_struct_to_string(policydb, tcontext, &t, &tlen)) + if (sidtab_entry_to_string(policydb, sidtab, tentry, &t, &tlen)) goto out; if (context_struct_to_string(policydb, newcontext, &n, &nlen)) goto out; @@ -1680,7 +1730,8 @@ static int security_compute_sid(struct selinux_state *state, struct policydb *policydb; struct sidtab *sidtab; struct class_datum *cladatum = NULL; - struct context *scontext = NULL, *tcontext = NULL, newcontext; + struct context *scontext, *tcontext, newcontext; + struct sidtab_entry *sentry, *tentry; struct role_trans *roletr = NULL; struct avtab_key avkey; struct avtab_datum *avdatum; @@ -1717,21 +1768,24 @@ static int security_compute_sid(struct selinux_state *state, policydb = &state->ss->policydb; sidtab = state->ss->sidtab; - scontext = sidtab_search(sidtab, ssid); - if (!scontext) { + sentry = sidtab_search_entry(sidtab, ssid); + if (!sentry) { pr_err("SELinux: %s: unrecognized SID %d\n", __func__, ssid); rc = -EINVAL; goto out_unlock; } - tcontext = sidtab_search(sidtab, tsid); - if (!tcontext) { + tentry = sidtab_search_entry(sidtab, tsid); + if (!tentry) { pr_err("SELinux: %s: unrecognized SID %d\n", __func__, tsid); rc = -EINVAL; goto out_unlock; } + scontext = &sentry->context; + tcontext = &tentry->context; + if (tclass && tclass <= policydb->p_classes.nprim) cladatum = policydb->class_val_to_struct[tclass - 1]; @@ -1832,10 +1886,8 @@ static int security_compute_sid(struct selinux_state *state, /* Check the validity of the context. */ if (!policydb_context_isvalid(policydb, &newcontext)) { - rc = compute_sid_handle_invalid_context(state, scontext, - tcontext, - tclass, - &newcontext); + rc = compute_sid_handle_invalid_context(state, sentry, tentry, + tclass, &newcontext); if (rc) goto out_unlock; } @@ -2138,7 +2190,7 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len) int rc = 0; struct policy_file file = { data, len }, *fp = &file; - oldpolicydb = kzalloc(2 * sizeof(*oldpolicydb), GFP_KERNEL); + oldpolicydb = kcalloc(2, sizeof(*oldpolicydb), GFP_KERNEL); if (!oldpolicydb) { rc = -ENOMEM; goto out; @@ -2304,14 +2356,12 @@ int security_port_sid(struct selinux_state *state, u8 protocol, u16 port, u32 *out_sid) { struct policydb *policydb; - struct sidtab *sidtab; struct ocontext *c; int rc = 0; read_lock(&state->ss->policy_rwlock); policydb = &state->ss->policydb; - sidtab = state->ss->sidtab; c = policydb->ocontexts[OCON_PORT]; while (c) { @@ -2393,14 +2443,12 @@ int security_ib_endport_sid(struct selinux_state *state, const char *dev_name, u8 port_num, u32 *out_sid) { struct policydb *policydb; - struct sidtab *sidtab; struct ocontext *c; int rc = 0; read_lock(&state->ss->policy_rwlock); policydb = &state->ss->policydb; - sidtab = state->ss->sidtab; c = policydb->ocontexts[OCON_IBENDPORT]; while (c) { @@ -2438,14 +2486,12 @@ int security_netif_sid(struct selinux_state *state, char *name, u32 *if_sid) { struct policydb *policydb; - struct sidtab *sidtab; int rc = 0; struct ocontext *c; read_lock(&state->ss->policy_rwlock); policydb = &state->ss->policydb; - sidtab = state->ss->sidtab; c = policydb->ocontexts[OCON_NETIF]; while (c) { @@ -2789,7 +2835,6 @@ int security_genfs_sid(struct selinux_state *state, int security_fs_use(struct selinux_state *state, struct super_block *sb) { struct policydb *policydb; - struct sidtab *sidtab; int rc = 0; struct ocontext *c; struct superblock_security_struct *sbsec = sb->s_security; @@ -2798,7 +2843,6 @@ int security_fs_use(struct selinux_state *state, struct super_block *sb) read_lock(&state->ss->policy_rwlock); policydb = &state->ss->policydb; - sidtab = state->ss->sidtab; c = policydb->ocontexts[OCON_FSUSE]; while (c) { diff --git a/security/selinux/ss/services.h b/security/selinux/ss/services.h index fc40640a9725..c5896f39e8f6 100644 --- a/security/selinux/ss/services.h +++ b/security/selinux/ss/services.h @@ -31,7 +31,7 @@ struct selinux_ss { struct selinux_map map; struct page *status_page; struct mutex status_lock; -}; +} __randomize_layout; void services_compute_xperms_drivers(struct extended_perms *xperms, struct avtab_node *node); diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c index d9d8599e8e63..f511ffccb131 100644 --- a/security/selinux/ss/sidtab.c +++ b/security/selinux/ss/sidtab.c @@ -9,6 +9,8 @@ */ #include #include +#include +#include #include #include #include @@ -17,6 +19,14 @@ #include "security.h" #include "sidtab.h" +struct sidtab_str_cache { + struct rcu_head rcu_member; + struct list_head lru_member; + struct sidtab_entry *parent; + u32 len; + char str[]; +}; + #define index_to_sid(index) (index + SECINITSID_NUM + 1) #define sid_to_index(sid) (sid - (SECINITSID_NUM + 1)) @@ -34,12 +44,19 @@ int sidtab_init(struct sidtab *s) hash_init(s->context_to_sid); spin_lock_init(&s->lock); + +#if CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 + s->cache_free_slots = CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE; + INIT_LIST_HEAD(&s->cache_lru_list); + spin_lock_init(&s->cache_lock); +#endif + return 0; } static u32 context_to_sid(struct sidtab *s, struct context *context) { - struct sidtab_entry_leaf *entry; + struct sidtab_entry *entry; u32 sid = 0; rcu_read_lock(); @@ -56,19 +73,22 @@ static u32 context_to_sid(struct sidtab *s, struct context *context) int sidtab_set_initial(struct sidtab *s, u32 sid, struct context *context) { - struct sidtab_isid_entry *entry; + struct sidtab_isid_entry *isid; int rc; if (sid == 0 || sid > SECINITSID_NUM) return -EINVAL; - entry = &s->isids[sid - 1]; + isid = &s->isids[sid - 1]; - rc = context_cpy(&entry->leaf.context, context); + rc = context_cpy(&isid->entry.context, context); if (rc) return rc; - entry->set = 1; +#if CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 + isid->entry.cache = NULL; +#endif + isid->set = 1; /* * Multiple initial sids may map to the same context. Check that this @@ -77,8 +97,8 @@ int sidtab_set_initial(struct sidtab *s, u32 sid, struct context *context) * collision. */ if (!context_to_sid(s, context)) { - entry->leaf.sid = sid; - hash_add(s->context_to_sid, &entry->leaf.list, context->hash); + isid->entry.sid = sid; + hash_add(s->context_to_sid, &isid->entry.list, context->hash); } return 0; @@ -92,7 +112,7 @@ int sidtab_hash_stats(struct sidtab *sidtab, char *page) int entries = 0; int max_chain_len = 0; int cur_bucket = 0; - struct sidtab_entry_leaf *entry; + struct sidtab_entry *entry; rcu_read_lock(); hash_for_each_rcu(sidtab->context_to_sid, i, entry, list) { @@ -151,8 +171,8 @@ static int sidtab_alloc_roots(struct sidtab *s, u32 level) return 0; } -static struct sidtab_entry_leaf *sidtab_do_lookup(struct sidtab *s, u32 index, - int alloc) +static struct sidtab_entry *sidtab_do_lookup(struct sidtab *s, u32 index, + int alloc) { union sidtab_entry_inner *entry; u32 level, capacity_shift, leaf_index = index / SIDTAB_LEAF_ENTRIES; @@ -192,7 +212,7 @@ static struct sidtab_entry_leaf *sidtab_do_lookup(struct sidtab *s, u32 index, return &entry->ptr_leaf->entries[index % SIDTAB_LEAF_ENTRIES]; } -static struct context *sidtab_lookup(struct sidtab *s, u32 index) +static struct sidtab_entry *sidtab_lookup(struct sidtab *s, u32 index) { /* read entries only after reading count */ u32 count = smp_load_acquire(&s->count); @@ -200,36 +220,37 @@ static struct context *sidtab_lookup(struct sidtab *s, u32 index) if (index >= count) return NULL; - return &sidtab_do_lookup(s, index, 0)->context; + return sidtab_do_lookup(s, index, 0); } -static struct context *sidtab_lookup_initial(struct sidtab *s, u32 sid) +static struct sidtab_entry *sidtab_lookup_initial(struct sidtab *s, u32 sid) { - return s->isids[sid - 1].set ? &s->isids[sid - 1].leaf.context : NULL; + return s->isids[sid - 1].set ? &s->isids[sid - 1].entry : NULL; } -static struct context *sidtab_search_core(struct sidtab *s, u32 sid, int force) +static struct sidtab_entry *sidtab_search_core(struct sidtab *s, u32 sid, + int force) { - struct context *context; - if (sid != 0) { + struct sidtab_entry *entry; + if (sid > SECINITSID_NUM) - context = sidtab_lookup(s, sid_to_index(sid)); + entry = sidtab_lookup(s, sid_to_index(sid)); else - context = sidtab_lookup_initial(s, sid); - if (context && (!context->len || force)) - return context; + entry = sidtab_lookup_initial(s, sid); + if (entry && (!entry->context.len || force)) + return entry; } return sidtab_lookup_initial(s, SECINITSID_UNLABELED); } -struct context *sidtab_search(struct sidtab *s, u32 sid) +struct sidtab_entry *sidtab_search_entry(struct sidtab *s, u32 sid) { return sidtab_search_core(s, sid, 0); } -struct context *sidtab_search_force(struct sidtab *s, u32 sid) +struct sidtab_entry *sidtab_search_entry_force(struct sidtab *s, u32 sid) { return sidtab_search_core(s, sid, 1); } @@ -240,7 +261,7 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context, unsigned long flags; u32 count; struct sidtab_convert_params *convert; - struct sidtab_entry_leaf *dst, *dst_convert; + struct sidtab_entry *dst, *dst_convert; int rc; *sid = context_to_sid(s, context); @@ -289,7 +310,7 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context, } rc = convert->func(context, &dst_convert->context, - convert->args); + convert->args); if (rc) { context_destroy(&dst->context); goto out_unlock; @@ -298,7 +319,7 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context, convert->target->count = count + 1; hash_add_rcu(convert->target->context_to_sid, - &dst_convert->list, dst_convert->context.hash); + &dst_convert->list, dst_convert->context.hash); } if (context->len) @@ -319,7 +340,7 @@ out_unlock: static void sidtab_convert_hashtable(struct sidtab *s, u32 count) { - struct sidtab_entry_leaf *entry; + struct sidtab_entry *entry; u32 i; for (i = 0; i < count; i++) { @@ -327,7 +348,7 @@ static void sidtab_convert_hashtable(struct sidtab *s, u32 count) entry->sid = index_to_sid(i); hash_add_rcu(s->context_to_sid, &entry->list, - entry->context.hash); + entry->context.hash); } } @@ -376,7 +397,6 @@ static int sidtab_convert_tree(union sidtab_entry_inner *edst, } cond_resched(); } - return 0; } @@ -439,6 +459,14 @@ int sidtab_convert(struct sidtab *s, struct sidtab_convert_params *params) return 0; } +static void sidtab_destroy_entry(struct sidtab_entry *entry) +{ + context_destroy(&entry->context); +#if CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 + kfree(rcu_dereference_raw(entry->cache)); +#endif +} + static void sidtab_destroy_tree(union sidtab_entry_inner entry, u32 level) { u32 i; @@ -459,7 +487,7 @@ static void sidtab_destroy_tree(union sidtab_entry_inner entry, u32 level) return; for (i = 0; i < SIDTAB_LEAF_ENTRIES; i++) - context_destroy(&node->entries[i].context); + sidtab_destroy_entry(&node->entries[i]); kfree(node); } } @@ -470,7 +498,7 @@ void sidtab_destroy(struct sidtab *s) for (i = 0; i < SECINITSID_NUM; i++) if (s->isids[i].set) - context_destroy(&s->isids[i].leaf.context); + sidtab_destroy_entry(&s->isids[i].entry); level = SIDTAB_MAX_LEVEL; while (level && !s->roots[level].ptr_inner) @@ -483,3 +511,82 @@ void sidtab_destroy(struct sidtab *s) * to be cleaned up here. */ } + +#if CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 + +void sidtab_sid2str_put(struct sidtab *s, struct sidtab_entry *entry, + const char *str, u32 str_len) +{ + struct sidtab_str_cache *cache, *victim = NULL; + unsigned long flags; + + /* do not cache invalid contexts */ + if (entry->context.len) + return; + + spin_lock_irqsave(&s->cache_lock, flags); + + cache = rcu_dereference_protected(entry->cache, + lockdep_is_held(&s->cache_lock)); + if (cache) { + /* entry in cache - just bump to the head of LRU list */ + list_move(&cache->lru_member, &s->cache_lru_list); + goto out_unlock; + } + + cache = kmalloc(sizeof(struct sidtab_str_cache) + str_len, GFP_ATOMIC); + if (!cache) + goto out_unlock; + + if (s->cache_free_slots == 0) { + /* pop a cache entry from the tail and free it */ + victim = container_of(s->cache_lru_list.prev, + struct sidtab_str_cache, lru_member); + list_del(&victim->lru_member); + rcu_assign_pointer(victim->parent->cache, NULL); + } else { + s->cache_free_slots--; + } + cache->parent = entry; + cache->len = str_len; + memcpy(cache->str, str, str_len); + list_add(&cache->lru_member, &s->cache_lru_list); + + rcu_assign_pointer(entry->cache, cache); + +out_unlock: + spin_unlock_irqrestore(&s->cache_lock, flags); + kfree_rcu(victim, rcu_member); +} + +int sidtab_sid2str_get(struct sidtab *s, struct sidtab_entry *entry, + char **out, u32 *out_len) +{ + struct sidtab_str_cache *cache; + int rc = 0; + + if (entry->context.len) + return -ENOENT; /* do not cache invalid contexts */ + + rcu_read_lock(); + + cache = rcu_dereference(entry->cache); + if (!cache) { + rc = -ENOENT; + } else { + *out_len = cache->len; + if (out) { + *out = kmemdup(cache->str, cache->len, GFP_ATOMIC); + if (!*out) + rc = -ENOMEM; + } + } + + rcu_read_unlock(); + + if (!rc && out) + sidtab_sid2str_put(s, entry, *out, *out_len); + return rc; +} + +#endif /* CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 */ diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h index 8564ec0f3599..7702ca8fae8f 100644 --- a/security/selinux/ss/sidtab.h +++ b/security/selinux/ss/sidtab.h @@ -18,15 +18,15 @@ #include "context.h" #include "flask.h" -struct sidtab_entry_leaf { +struct sidtab_entry { u32 sid; struct context context; +#if CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 + struct sidtab_str_cache __rcu *cache; +#endif struct hlist_node list; }; -struct sidtab_node_inner; -struct sidtab_node_leaf; - union sidtab_entry_inner { struct sidtab_node_inner *ptr_inner; struct sidtab_node_leaf *ptr_leaf; @@ -42,7 +42,7 @@ union sidtab_entry_inner { (SIDTAB_NODE_ALLOC_SHIFT - size_to_shift(sizeof(union sidtab_entry_inner))) #define SIDTAB_INNER_ENTRIES ((size_t)1 << SIDTAB_INNER_SHIFT) #define SIDTAB_LEAF_ENTRIES \ - (SIDTAB_NODE_ALLOC_SIZE / sizeof(struct sidtab_entry_leaf)) + (SIDTAB_NODE_ALLOC_SIZE / sizeof(struct sidtab_entry)) #define SIDTAB_MAX_BITS 32 #define SIDTAB_MAX U32_MAX @@ -52,7 +52,7 @@ union sidtab_entry_inner { SIDTAB_INNER_SHIFT) struct sidtab_node_leaf { - struct sidtab_entry_leaf entries[SIDTAB_LEAF_ENTRIES]; + struct sidtab_entry entries[SIDTAB_LEAF_ENTRIES]; }; struct sidtab_node_inner { @@ -61,7 +61,7 @@ struct sidtab_node_inner { struct sidtab_isid_entry { int set; - struct sidtab_entry_leaf leaf; + struct sidtab_entry entry; }; struct sidtab_convert_params { @@ -88,6 +88,13 @@ struct sidtab { struct sidtab_convert_params *convert; spinlock_t lock; +#if CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 + /* SID -> context string cache */ + u32 cache_free_slots; + struct list_head cache_lru_list; + spinlock_t cache_lock; +#endif + /* index == SID - 1 (no entry for SECSID_NULL) */ struct sidtab_isid_entry isids[SECINITSID_NUM]; @@ -97,8 +104,22 @@ struct sidtab { int sidtab_init(struct sidtab *s); int sidtab_set_initial(struct sidtab *s, u32 sid, struct context *context); -struct context *sidtab_search(struct sidtab *s, u32 sid); -struct context *sidtab_search_force(struct sidtab *s, u32 sid); +struct sidtab_entry *sidtab_search_entry(struct sidtab *s, u32 sid); +struct sidtab_entry *sidtab_search_entry_force(struct sidtab *s, u32 sid); + +static inline struct context *sidtab_search(struct sidtab *s, u32 sid) +{ + struct sidtab_entry *entry = sidtab_search_entry(s, sid); + + return entry ? &entry->context : NULL; +} + +static inline struct context *sidtab_search_force(struct sidtab *s, u32 sid) +{ + struct sidtab_entry *entry = sidtab_search_entry_force(s, sid); + + return entry ? &entry->context : NULL; +} int sidtab_convert(struct sidtab *s, struct sidtab_convert_params *params); @@ -108,6 +129,25 @@ void sidtab_destroy(struct sidtab *s); int sidtab_hash_stats(struct sidtab *sidtab, char *page); +#if CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 +void sidtab_sid2str_put(struct sidtab *s, struct sidtab_entry *entry, + const char *str, u32 str_len); +int sidtab_sid2str_get(struct sidtab *s, struct sidtab_entry *entry, + char **out, u32 *out_len); +#else +static inline void sidtab_sid2str_put(struct sidtab *s, + struct sidtab_entry *entry, + const char *str, u32 str_len) +{ +} +static inline int sidtab_sid2str_get(struct sidtab *s, + struct sidtab_entry *entry, + char **out, u32 *out_len) +{ + return -ENOENT; +} +#endif /* CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 */ + #endif /* _SS_SIDTAB_H_ */ diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c index ca3d9ac05bc9..8c03e29f6718 100644 --- a/sound/core/pcm_compat.c +++ b/sound/core/pcm_compat.c @@ -432,7 +432,7 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream, get_user(frames, &data32->frames)) return -EFAULT; bufptr = compat_ptr(buf); - bufs = kmalloc(sizeof(void __user *) * ch, GFP_KERNEL); + bufs = kmalloc_array(ch, sizeof(void __user *), GFP_KERNEL); if (bufs == NULL) return -ENOMEM; for (i = 0; i < ch; i++) { diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index dc582c29abf7..c93f451d12e0 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -3171,7 +3171,7 @@ static ssize_t snd_pcm_readv(struct kiocb *iocb, struct iov_iter *to) if (!frame_aligned(runtime, to->iov->iov_len)) return -EINVAL; frames = bytes_to_samples(runtime, to->iov->iov_len); - bufs = kmalloc(sizeof(void *) * to->nr_segs, GFP_KERNEL); + bufs = kmalloc_array(to->nr_segs, sizeof(void *), GFP_KERNEL); if (bufs == NULL) return -ENOMEM; for (i = 0; i < to->nr_segs; ++i) @@ -3206,7 +3206,7 @@ static ssize_t snd_pcm_writev(struct kiocb *iocb, struct iov_iter *from) !frame_aligned(runtime, from->iov->iov_len)) return -EINVAL; frames = bytes_to_samples(runtime, from->iov->iov_len); - bufs = kmalloc(sizeof(void *) * from->nr_segs, GFP_KERNEL); + bufs = kmalloc_array(from->nr_segs, sizeof(void *), GFP_KERNEL); if (bufs == NULL) return -ENOMEM; for (i = 0; i < from->nr_segs; ++i) diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c index ab1112e90f88..148ffaaeace4 100644 --- a/sound/core/seq/seq_memory.c +++ b/sound/core/seq/seq_memory.c @@ -389,7 +389,7 @@ int snd_seq_pool_init(struct snd_seq_pool *pool) if (snd_BUG_ON(!pool)) return -EINVAL; - cellptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size); + cellptr = vmalloc(array_size(sizeof(struct snd_seq_event_cell), pool->size)); if (!cellptr) return -ENOMEM; diff --git a/sound/core/seq/seq_midi_emul.c b/sound/core/seq/seq_midi_emul.c index 9e2912e3e80f..288f839a554b 100644 --- a/sound/core/seq/seq_midi_emul.c +++ b/sound/core/seq/seq_midi_emul.c @@ -657,7 +657,7 @@ static struct snd_midi_channel *snd_midi_channel_init_set(int n) struct snd_midi_channel *chan; int i; - chan = kmalloc(n * sizeof(struct snd_midi_channel), GFP_KERNEL); + chan = kmalloc_array(n, sizeof(struct snd_midi_channel), GFP_KERNEL); if (chan) { for (i = 0; i < n; i++) snd_midi_channel_init(chan+i, i); diff --git a/sound/firewire/fireface/ff-protocol-ff400.c b/sound/firewire/fireface/ff-protocol-ff400.c index bb0c1abf4718..4d191172fe3f 100644 --- a/sound/firewire/fireface/ff-protocol-ff400.c +++ b/sound/firewire/fireface/ff-protocol-ff400.c @@ -148,7 +148,7 @@ static int ff400_switch_fetching_mode(struct snd_ff *ff, bool enable) int i; int err; - reg = kzalloc(sizeof(__le32) * 18, GFP_KERNEL); + reg = kcalloc(18, sizeof(__le32), GFP_KERNEL); if (reg == NULL) return -ENOMEM; diff --git a/sound/firewire/packets-buffer.c b/sound/firewire/packets-buffer.c index 3b09b8ef3a09..715cd99f28de 100644 --- a/sound/firewire/packets-buffer.c +++ b/sound/firewire/packets-buffer.c @@ -27,7 +27,7 @@ int iso_packets_buffer_init(struct iso_packets_buffer *b, struct fw_unit *unit, void *p; int err; - b->packets = kmalloc(count * sizeof(*b->packets), GFP_KERNEL); + b->packets = kmalloc_array(count, sizeof(*b->packets), GFP_KERNEL); if (!b->packets) { err = -ENOMEM; goto error; diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c index fb3bbceb1fef..5d51d88aea98 100644 --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -420,7 +420,7 @@ static int sq_allocate_buffers(struct sound_queue *sq, int num, int size) return 0; sq->numBufs = num; sq->bufSize = size; - sq->buffers = kmalloc (num * sizeof(char *), GFP_KERNEL); + sq->buffers = kmalloc_array (num, sizeof(char *), GFP_KERNEL); if (!sq->buffers) return -ENOMEM; for (i = 0; i < num; i++) { diff --git a/sound/oss/sequencer.c b/sound/oss/sequencer.c index f19da4b47c1d..5c8f62a5aaa6 100644 --- a/sound/oss/sequencer.c +++ b/sound/oss/sequencer.c @@ -1636,13 +1636,13 @@ void sequencer_init(void) { if (sequencer_ok) return; - queue = vmalloc(SEQ_MAX_QUEUE * EV_SZ); + queue = vmalloc(array_size(EV_SZ, SEQ_MAX_QUEUE)); if (queue == NULL) { printk(KERN_ERR "sequencer: Can't allocate memory for sequencer output queue\n"); return; } - iqueue = vmalloc(SEQ_MAX_QUEUE * IEV_SZ); + iqueue = vmalloc(array_size(IEV_SZ, SEQ_MAX_QUEUE)); if (iqueue == NULL) { printk(KERN_ERR "sequencer: Can't allocate memory for sequencer input queue\n"); diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c index 97899352b15f..2f6942cf6e08 100644 --- a/sound/oss/swarm_cs4297a.c +++ b/sound/oss/swarm_cs4297a.c @@ -630,7 +630,8 @@ static int init_serdma(serdma_t *dma) /* Descriptors */ dma->ringsz = DMA_DESCR; - dma->descrtab = kzalloc(dma->ringsz * sizeof(serdma_descr_t), GFP_KERNEL); + dma->descrtab = kcalloc(dma->ringsz, sizeof(serdma_descr_t), + GFP_KERNEL); if (!dma->descrtab) { printk(KERN_ERR "cs4297a: kzalloc descrtab failed\n"); return -1; diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 0020fd0efc46..97dfd9757b86 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -460,7 +460,7 @@ static int load_firmware(struct snd_cs46xx *chip, entry->size = le32_to_cpu(fwdat[fwlen++]); if (fwlen + entry->size > fwsize) goto error_inval; - entry->data = kmalloc(entry->size * 4, GFP_KERNEL); + entry->data = kmalloc_array(entry->size, 4, GFP_KERNEL); if (!entry->data) goto error; memcpy_le32(entry->data, &fwdat[fwlen], entry->size * 4); @@ -4036,8 +4036,9 @@ int snd_cs46xx_create(struct snd_card *card, snd_cs46xx_proc_init(card, chip); #ifdef CONFIG_PM_SLEEP - chip->saved_regs = kmalloc(sizeof(*chip->saved_regs) * - ARRAY_SIZE(saved_regs), GFP_KERNEL); + chip->saved_regs = kmalloc_array(ARRAY_SIZE(saved_regs), + sizeof(*chip->saved_regs), + GFP_KERNEL); if (!chip->saved_regs) { snd_cs46xx_free(chip); return -ENOMEM; diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c index f03bbd0eb027..4cc2500588e1 100644 --- a/sound/pci/cs46xx/dsp_spos.c +++ b/sound/pci/cs46xx/dsp_spos.c @@ -240,10 +240,11 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip) return NULL; /* better to use vmalloc for this big table */ - ins->symbol_table.symbols = vmalloc(sizeof(struct dsp_symbol_entry) * - DSP_MAX_SYMBOLS); + ins->symbol_table.symbols = vmalloc(array_size(DSP_MAX_SYMBOLS, sizeof(struct dsp_symbol_entry))); ins->code.data = kmalloc(DSP_CODE_BYTE_SIZE, GFP_KERNEL); - ins->modules = kmalloc(sizeof(struct dsp_module_desc) * DSP_MAX_MODULES, GFP_KERNEL); + ins->modules = kmalloc_array(DSP_MAX_MODULES, + sizeof(struct dsp_module_desc), + GFP_KERNEL); if (!ins->symbol_table.symbols || !ins->code.data || !ins->modules) { cs46xx_dsp_spos_destroy(chip); goto error; diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 908658a00377..2ada8444abd9 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -275,7 +275,7 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) /* Get AMIXER resource */ n_amixer = (n_amixer < 2) ? 2 : n_amixer; - apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL); + apcm->amixers = kcalloc(n_amixer, sizeof(void *), GFP_KERNEL); if (!apcm->amixers) { err = -ENOMEM; goto error1; @@ -543,18 +543,18 @@ atc_pcm_capture_get_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm) } if (n_srcc) { - apcm->srccs = kzalloc(sizeof(void *)*n_srcc, GFP_KERNEL); + apcm->srccs = kcalloc(n_srcc, sizeof(void *), GFP_KERNEL); if (!apcm->srccs) return -ENOMEM; } if (n_amixer) { - apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL); + apcm->amixers = kcalloc(n_amixer, sizeof(void *), GFP_KERNEL); if (!apcm->amixers) { err = -ENOMEM; goto error1; } } - apcm->srcimps = kzalloc(sizeof(void *)*n_srcimp, GFP_KERNEL); + apcm->srcimps = kcalloc(n_srcimp, sizeof(void *), GFP_KERNEL); if (!apcm->srcimps) { err = -ENOMEM; goto error1; @@ -819,7 +819,7 @@ static int spdif_passthru_playback_get_resources(struct ct_atc *atc, /* Get AMIXER resource */ n_amixer = (n_amixer < 2) ? 2 : n_amixer; - apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL); + apcm->amixers = kcalloc(n_amixer, sizeof(void *), GFP_KERNEL); if (!apcm->amixers) { err = -ENOMEM; goto error1; @@ -1378,19 +1378,19 @@ static int atc_get_resources(struct ct_atc *atc) num_daios = ((atc->model == CTSB1270) ? 8 : 7); num_srcs = ((atc->model == CTSB1270) ? 6 : 4); - atc->daios = kzalloc(sizeof(void *)*num_daios, GFP_KERNEL); + atc->daios = kcalloc(num_daios, sizeof(void *), GFP_KERNEL); if (!atc->daios) return -ENOMEM; - atc->srcs = kzalloc(sizeof(void *)*num_srcs, GFP_KERNEL); + atc->srcs = kcalloc(num_srcs, sizeof(void *), GFP_KERNEL); if (!atc->srcs) return -ENOMEM; - atc->srcimps = kzalloc(sizeof(void *)*num_srcs, GFP_KERNEL); + atc->srcimps = kcalloc(num_srcs, sizeof(void *), GFP_KERNEL); if (!atc->srcimps) return -ENOMEM; - atc->pcm = kzalloc(sizeof(void *)*(2*4), GFP_KERNEL); + atc->pcm = kcalloc(2 * 4, sizeof(void *), GFP_KERNEL); if (!atc->pcm) return -ENOMEM; diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c index 7f089cb433e1..f35a7341e446 100644 --- a/sound/pci/ctxfi/ctdaio.c +++ b/sound/pci/ctxfi/ctdaio.c @@ -398,7 +398,8 @@ static int dao_rsc_init(struct dao *dao, if (err) return err; - dao->imappers = kzalloc(sizeof(void *)*desc->msr*2, GFP_KERNEL); + dao->imappers = kzalloc(array3_size(sizeof(void *), desc->msr, 2), + GFP_KERNEL); if (!dao->imappers) { err = -ENOMEM; goto error1; diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c index 4f4a2a5dedb8..db710d0a609f 100644 --- a/sound/pci/ctxfi/ctmixer.c +++ b/sound/pci/ctxfi/ctmixer.c @@ -910,13 +910,14 @@ static int ct_mixer_get_mem(struct ct_mixer **rmixer) if (!mixer) return -ENOMEM; - mixer->amixers = kzalloc(sizeof(void *)*(NUM_CT_AMIXERS*CHN_NUM), + mixer->amixers = kcalloc(NUM_CT_AMIXERS * CHN_NUM, sizeof(void *), GFP_KERNEL); if (!mixer->amixers) { err = -ENOMEM; goto error1; } - mixer->sums = kzalloc(sizeof(void *)*(NUM_CT_SUMS*CHN_NUM), GFP_KERNEL); + mixer->sums = kcalloc(NUM_CT_SUMS * CHN_NUM, sizeof(void *), + GFP_KERNEL); if (!mixer->sums) { err = -ENOMEM; goto error2; diff --git a/sound/pci/ctxfi/ctsrc.c b/sound/pci/ctxfi/ctsrc.c index bb4c9c3c89ae..a4fc10723fc6 100644 --- a/sound/pci/ctxfi/ctsrc.c +++ b/sound/pci/ctxfi/ctsrc.c @@ -679,7 +679,7 @@ static int srcimp_rsc_init(struct srcimp *srcimp, return err; /* Reserve memory for imapper nodes */ - srcimp->imappers = kzalloc(sizeof(struct imapper)*desc->msr, + srcimp->imappers = kcalloc(desc->msr, sizeof(struct imapper), GFP_KERNEL); if (!srcimp->imappers) { err = -ENOMEM; diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index ccf4415a1c7b..027e3f7b23c9 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -1906,9 +1906,8 @@ int snd_emu10k1_create(struct snd_card *card, goto error; } - emu->page_ptr_table = vmalloc(emu->max_cache_pages * sizeof(void *)); - emu->page_addr_table = vmalloc(emu->max_cache_pages * - sizeof(unsigned long)); + emu->page_ptr_table = vmalloc(array_size(sizeof(void *), emu->max_cache_pages)); + emu->page_addr_table = vmalloc(array_size(sizeof(unsigned long), emu->max_cache_pages)); if (emu->page_ptr_table == NULL || emu->page_addr_table == NULL) { err = -ENOMEM; goto error; @@ -2064,7 +2063,7 @@ static int alloc_pm_buffer(struct snd_emu10k1 *emu) size = ARRAY_SIZE(saved_regs); if (emu->audigy) size += ARRAY_SIZE(saved_regs_audigy); - emu->saved_ptr = vmalloc(4 * NUM_G * size); + emu->saved_ptr = vmalloc(array3_size(4, NUM_G, size)); if (!emu->saved_ptr) return -ENOMEM; if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0) diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 5c00e3536767..d403c67d737b 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -2695,16 +2695,16 @@ int snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu) int len; len = emu->audigy ? 0x200 : 0x100; - emu->saved_gpr = kmalloc(len * 4, GFP_KERNEL); + emu->saved_gpr = kmalloc_array(len, 4, GFP_KERNEL); if (! emu->saved_gpr) return -ENOMEM; len = emu->audigy ? 0x100 : 0xa0; - emu->tram_val_saved = kmalloc(len * 4, GFP_KERNEL); - emu->tram_addr_saved = kmalloc(len * 4, GFP_KERNEL); + emu->tram_val_saved = kmalloc_array(len, 4, GFP_KERNEL); + emu->tram_addr_saved = kmalloc_array(len, 4, GFP_KERNEL); if (! emu->tram_val_saved || ! emu->tram_addr_saved) return -ENOMEM; len = emu->audigy ? 2 * 1024 : 2 * 512; - emu->saved_icode = vmalloc(len * 4); + emu->saved_icode = vmalloc(array_size(len, 4)); if (! emu->saved_icode) return -ENOMEM; return 0; diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index a30da78a95b7..4948b95f6665 100644 --- a/sound/pci/emu10k1/p16v.c +++ b/sound/pci/emu10k1/p16v.c @@ -874,7 +874,7 @@ int snd_p16v_mixer(struct snd_emu10k1 *emu) int snd_p16v_alloc_pm_buffer(struct snd_emu10k1 *emu) { - emu->p16v_saved = vmalloc(NUM_CHS * 4 * 0x80); + emu->p16v_saved = vmalloc(array_size(NUM_CHS * 4, 0x80)); if (! emu->p16v_saved) return -ENOMEM; return 0; diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 7d65fe31c825..5b5dce9a89c7 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -158,7 +158,7 @@ static int read_and_add_raw_conns(struct hda_codec *codec, hda_nid_t nid) len = snd_hda_get_raw_connections(codec, nid, list, ARRAY_SIZE(list)); if (len == -ENOSPC) { len = snd_hda_get_num_raw_conns(codec, nid); - result = kmalloc(sizeof(hda_nid_t) * len, GFP_KERNEL); + result = kmalloc_array(len, sizeof(hda_nid_t), GFP_KERNEL); if (!result) return -ENOMEM; len = snd_hda_get_raw_connections(codec, nid, result, len); @@ -438,7 +438,7 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node) int i; hda_nid_t nid; - codec->wcaps = kmalloc(codec->core.num_nodes * 4, GFP_KERNEL); + codec->wcaps = kmalloc_array(codec->core.num_nodes, 4, GFP_KERNEL); if (!codec->wcaps) return -ENOMEM; nid = codec->core.start_nid; diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 033aa84365b9..c6b778b2580c 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c @@ -825,8 +825,9 @@ static void print_codec_info(struct snd_info_entry *entry, if (wid_caps & AC_WCAP_CONN_LIST) { conn_len = snd_hda_get_num_raw_conns(codec, nid); if (conn_len > 0) { - conn = kmalloc(sizeof(hda_nid_t) * conn_len, - GFP_KERNEL); + conn = kmalloc_array(conn_len, + sizeof(hda_nid_t), + GFP_KERNEL); if (!conn) return; if (snd_hda_get_raw_connections(codec, nid, conn, diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 92f5f452bee2..31d693bb6139 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -4703,7 +4703,9 @@ static int ca0132_prepare_verbs(struct hda_codec *codec) struct ca0132_spec *spec = codec->spec; spec->chip_init_verbs = ca0132_init_verbs0; - spec->spec_init_verbs = kzalloc(sizeof(struct hda_verb) * NUM_SPEC_VERBS, GFP_KERNEL); + spec->spec_init_verbs = kcalloc(NUM_SPEC_VERBS, + sizeof(struct hda_verb), + GFP_KERNEL); if (!spec->spec_init_verbs) return -ENOMEM; diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 8f20dec97843..1bf81ad221ff 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -2657,7 +2657,7 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, chip->irq = pci->irq; #ifdef CONFIG_PM_SLEEP - chip->suspend_mem = vmalloc(sizeof(u16) * (REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH)); + chip->suspend_mem = vmalloc(array_size(sizeof(u16), (REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH))); if (chip->suspend_mem == NULL) dev_warn(card->dev, "can't allocate apm buffer\n"); #endif diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index eabd84d9ffee..c802f655efbb 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -3362,7 +3362,7 @@ static int snd_trident_tlb_alloc(struct snd_trident *trident) trident->tlb.entries = (unsigned int*)ALIGN((unsigned long)trident->tlb.buffer.area, SNDRV_TRIDENT_MAX_PAGES * 4); trident->tlb.entries_dmaaddr = ALIGN(trident->tlb.buffer.addr, SNDRV_TRIDENT_MAX_PAGES * 4); /* allocate shadow TLB page table (virtual addresses) */ - trident->tlb.shadow_entries = vmalloc(SNDRV_TRIDENT_MAX_PAGES*sizeof(unsigned long)); + trident->tlb.shadow_entries = vmalloc(array_size(SNDRV_TRIDENT_MAX_PAGES, sizeof(unsigned long))); if (!trident->tlb.shadow_entries) return -ENOMEM; diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 3a1c0b8b4ea2..c488c5afa195 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -439,7 +439,9 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre return -ENOMEM; } if (! dev->idx_table) { - dev->idx_table = kmalloc(sizeof(*dev->idx_table) * VIA_TABLE_SIZE, GFP_KERNEL); + dev->idx_table = kmalloc_array(VIA_TABLE_SIZE, + sizeof(*dev->idx_table), + GFP_KERNEL); if (! dev->idx_table) return -ENOMEM; } diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 8a69221c1b86..b13c8688cc8d 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c @@ -292,7 +292,9 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre return -ENOMEM; } if (! dev->idx_table) { - dev->idx_table = kmalloc(sizeof(*dev->idx_table) * VIA_TABLE_SIZE, GFP_KERNEL); + dev->idx_table = kmalloc_array(VIA_TABLE_SIZE, + sizeof(*dev->idx_table), + GFP_KERNEL); if (! dev->idx_table) return -ENOMEM; } diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 8ca2e41e5827..6f81396aadc9 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -2435,8 +2435,8 @@ int snd_ymfpci_create(struct snd_card *card, goto free_chip; #ifdef CONFIG_PM_SLEEP - chip->saved_regs = kmalloc(YDSXGR_NUM_SAVED_REGS * sizeof(u32), - GFP_KERNEL); + chip->saved_regs = kmalloc_array(YDSXGR_NUM_SAVED_REGS, sizeof(u32), + GFP_KERNEL); if (chip->saved_regs == NULL) { err = -ENOMEM; goto free_chip; diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c index 6a035ca0f521..42e6e6f89411 100644 --- a/sound/soc/au1x/dbdma2.c +++ b/sound/soc/au1x/dbdma2.c @@ -336,8 +336,8 @@ static int au1xpsc_pcm_drvprobe(struct platform_device *pdev) { struct au1xpsc_audio_dmadata *dmadata; - dmadata = devm_kzalloc(&pdev->dev, - 2 * sizeof(struct au1xpsc_audio_dmadata), + dmadata = devm_kcalloc(&pdev->dev, + 2, sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL); if (!dmadata) return -ENOMEM; diff --git a/sound/soc/blackfin/bf5xx-sport.c b/sound/soc/blackfin/bf5xx-sport.c index 9dfa1241ea66..dce1c84f70bc 100644 --- a/sound/soc/blackfin/bf5xx-sport.c +++ b/sound/soc/blackfin/bf5xx-sport.c @@ -929,7 +929,7 @@ struct sport_device *sport_init(struct platform_device *pdev, if (L1_DATA_A_LENGTH) sport->dummy_buf = l1_data_sram_zalloc(param.dummy_count * 2); else - sport->dummy_buf = kzalloc(param.dummy_count * 2, GFP_KERNEL); + sport->dummy_buf = kcalloc(param.dummy_count, 2, GFP_KERNEL); if (sport->dummy_buf == NULL) { dev_err(dev, "failed to allocate dummy buffer\n"); goto __error1; diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index e00f5f49f21d..9195573b01a8 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -774,7 +774,7 @@ static int hdmi_codec_probe(struct platform_device *pdev) hcp->hcd = *hcd; mutex_init(&hcp->current_stream_lock); - hcp->daidrv = devm_kzalloc(dev, dai_count * sizeof(*hcp->daidrv), + hcp->daidrv = devm_kcalloc(dev, dai_count, sizeof(*hcp->daidrv), GFP_KERNEL); if (!hcp->daidrv) return -ENOMEM; diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index a98647ac497c..1000b50bd435 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3383,8 +3383,9 @@ static int rt5645_probe(struct snd_soc_codec *codec) snd_soc_dapm_sync(dapm); } - rt5645->eq_param = devm_kzalloc(codec->dev, - RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s), GFP_KERNEL); + rt5645->eq_param = devm_kcalloc(codec->dev, + RT5645_HWEQ_NUM, sizeof(struct rt5645_eq_param_s), + GFP_KERNEL); return 0; } diff --git a/sound/soc/codecs/tfa98xx.c b/sound/soc/codecs/tfa98xx.c index 15e9a0c6cf5e..ed31bc4fa5a4 100644 --- a/sound/soc/codecs/tfa98xx.c +++ b/sound/soc/codecs/tfa98xx.c @@ -1428,8 +1428,8 @@ static int tfa98xx_create_controls(struct tfa98xx *tfa98xx) nr_controls++; /* Playback Volume control */ } - tfa98xx_controls = devm_kzalloc(tfa98xx->codec->dev, - nr_controls * sizeof(tfa98xx_controls[0]), GFP_KERNEL); + tfa98xx_controls = devm_kcalloc(tfa98xx->codec->dev, + nr_controls, sizeof(tfa98xx_controls[0]), GFP_KERNEL); if (!tfa98xx_controls) return -ENOMEM; diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 4fd350e8420d..3acaef24f184 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -2023,8 +2023,9 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec) wm8904_get_drc_enum, wm8904_put_drc_enum); /* We need an array of texts for the enum API */ - wm8904->drc_texts = kmalloc(sizeof(char *) - * pdata->num_drc_cfgs, GFP_KERNEL); + wm8904->drc_texts = kmalloc_array(pdata->num_drc_cfgs, + sizeof(char *), + GFP_KERNEL); if (!wm8904->drc_texts) return; diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 6b864c0fc2b6..9038740d2a1c 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c @@ -932,8 +932,9 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) }; /* We need an array of texts for the enum API */ - wm8994->mbc_texts = kmalloc(sizeof(char *) - * pdata->num_mbc_cfgs, GFP_KERNEL); + wm8994->mbc_texts = kmalloc_array(pdata->num_mbc_cfgs, + sizeof(char *), + GFP_KERNEL); if (!wm8994->mbc_texts) return; @@ -957,8 +958,9 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) }; /* We need an array of texts for the enum API */ - wm8994->vss_texts = kmalloc(sizeof(char *) - * pdata->num_vss_cfgs, GFP_KERNEL); + wm8994->vss_texts = kmalloc_array(pdata->num_vss_cfgs, + sizeof(char *), + GFP_KERNEL); if (!wm8994->vss_texts) return; @@ -983,8 +985,9 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) }; /* We need an array of texts for the enum API */ - wm8994->vss_hpf_texts = kmalloc(sizeof(char *) - * pdata->num_vss_hpf_cfgs, GFP_KERNEL); + wm8994->vss_hpf_texts = kmalloc_array(pdata->num_vss_hpf_cfgs, + sizeof(char *), + GFP_KERNEL); if (!wm8994->vss_hpf_texts) return; @@ -1010,8 +1013,9 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) }; /* We need an array of texts for the enum API */ - wm8994->enh_eq_texts = kmalloc(sizeof(char *) - * pdata->num_enh_eq_cfgs, GFP_KERNEL); + wm8994->enh_eq_texts = kmalloc_array(pdata->num_enh_eq_cfgs, + sizeof(char *), + GFP_KERNEL); if (!wm8994->enh_eq_texts) return; diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index f289762cd676..fb7e77e51441 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3297,8 +3297,8 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) }; /* We need an array of texts for the enum API */ - wm8994->drc_texts = devm_kzalloc(wm8994->hubs.codec->dev, - sizeof(char *) * pdata->num_drc_cfgs, GFP_KERNEL); + wm8994->drc_texts = devm_kcalloc(wm8994->hubs.codec->dev, + pdata->num_drc_cfgs, sizeof(char *), GFP_KERNEL); if (!wm8994->drc_texts) return; diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 158ce68bc9bf..feecbc2caae1 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -1895,7 +1895,7 @@ static void *wm_adsp_read_algs(struct wm_adsp *dsp, size_t n_algs, adsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbedead\n", pos + len, be32_to_cpu(val)); - alg = kzalloc(len * 2, GFP_KERNEL | GFP_DMA); + alg = kcalloc(len, 2, GFP_KERNEL | GFP_DMA); if (!alg) return ERR_PTR(-ENOMEM); diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 6991718d7c8a..08af1d925f28 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -1877,8 +1877,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev) mcasp->num_serializer = pdata->num_serializer; #ifdef CONFIG_PM_SLEEP - mcasp->context.xrsr_regs = devm_kzalloc(&pdev->dev, - sizeof(u32) * mcasp->num_serializer, + mcasp->context.xrsr_regs = devm_kcalloc(&pdev->dev, + mcasp->num_serializer, sizeof(u32), GFP_KERNEL); if (!mcasp->context.xrsr_regs) { ret = -ENOMEM; @@ -2013,13 +2013,15 @@ static int davinci_mcasp_probe(struct platform_device *pdev) * bytes. */ mcasp->chconstr[SNDRV_PCM_STREAM_PLAYBACK].list = - devm_kzalloc(mcasp->dev, sizeof(unsigned int) * - (32 + mcasp->num_serializer - 1), + devm_kcalloc(mcasp->dev, + 32 + mcasp->num_serializer - 1, + sizeof(unsigned int), GFP_KERNEL); mcasp->chconstr[SNDRV_PCM_STREAM_CAPTURE].list = - devm_kzalloc(mcasp->dev, sizeof(unsigned int) * - (32 + mcasp->num_serializer - 1), + devm_kcalloc(mcasp->dev, + 32 + mcasp->num_serializer - 1, + sizeof(unsigned int), GFP_KERNEL); if (!mcasp->chconstr[SNDRV_PCM_STREAM_PLAYBACK].list || diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 488c52f9405f..a31bbef377e5 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -265,8 +265,8 @@ static int asoc_graph_card_probe(struct platform_device *pdev) if (num == 0) return -EINVAL; - dai_props = devm_kzalloc(dev, sizeof(*dai_props) * num, GFP_KERNEL); - dai_link = devm_kzalloc(dev, sizeof(*dai_link) * num, GFP_KERNEL); + dai_props = devm_kcalloc(dev, num, sizeof(*dai_props), GFP_KERNEL); + dai_link = devm_kcalloc(dev, num, sizeof(*dai_link), GFP_KERNEL); if (!dai_props || !dai_link) return -ENOMEM; diff --git a/sound/soc/generic/audio-graph-scu-card.c b/sound/soc/generic/audio-graph-scu-card.c index a967aa143d51..095ef6426d42 100644 --- a/sound/soc/generic/audio-graph-scu-card.c +++ b/sound/soc/generic/audio-graph-scu-card.c @@ -348,8 +348,8 @@ static int asoc_graph_card_probe(struct platform_device *pdev) if (num == 0) return -EINVAL; - dai_props = devm_kzalloc(dev, sizeof(*dai_props) * num, GFP_KERNEL); - dai_link = devm_kzalloc(dev, sizeof(*dai_link) * num, GFP_KERNEL); + dai_props = devm_kcalloc(dev, num, sizeof(*dai_props), GFP_KERNEL); + dai_link = devm_kcalloc(dev, num, sizeof(*dai_link), GFP_KERNEL); if (!dai_props || !dai_link) return -ENOMEM; diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 6959a74a6f49..ca8dcda0906a 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -319,8 +319,8 @@ static int asoc_simple_card_parse_aux_devs(struct device_node *node, if (n <= 0) return -EINVAL; - card->aux_dev = devm_kzalloc(dev, - n * sizeof(*card->aux_dev), GFP_KERNEL); + card->aux_dev = devm_kcalloc(dev, + n, sizeof(*card->aux_dev), GFP_KERNEL); if (!card->aux_dev) return -ENOMEM; @@ -414,8 +414,8 @@ static int asoc_simple_card_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - dai_props = devm_kzalloc(dev, sizeof(*dai_props) * num, GFP_KERNEL); - dai_link = devm_kzalloc(dev, sizeof(*dai_link) * num, GFP_KERNEL); + dai_props = devm_kcalloc(dev, num, sizeof(*dai_props), GFP_KERNEL); + dai_link = devm_kcalloc(dev, num, sizeof(*dai_link), GFP_KERNEL); if (!dai_props || !dai_link) return -ENOMEM; diff --git a/sound/soc/generic/simple-scu-card.c b/sound/soc/generic/simple-scu-card.c index 48606c63562a..487716559deb 100644 --- a/sound/soc/generic/simple-scu-card.c +++ b/sound/soc/generic/simple-scu-card.c @@ -246,8 +246,8 @@ static int asoc_simple_card_probe(struct platform_device *pdev) num = of_get_child_count(np); - dai_props = devm_kzalloc(dev, sizeof(*dai_props) * num, GFP_KERNEL); - dai_link = devm_kzalloc(dev, sizeof(*dai_link) * num, GFP_KERNEL); + dai_props = devm_kcalloc(dev, num, sizeof(*dai_props), GFP_KERNEL); + dai_link = devm_kcalloc(dev, num, sizeof(*dai_link), GFP_KERNEL); if (!dai_props || !dai_link) return -ENOMEM; diff --git a/sound/soc/intel/common/sst-ipc.c b/sound/soc/intel/common/sst-ipc.c index fedce78675e8..771734fd7707 100644 --- a/sound/soc/intel/common/sst-ipc.c +++ b/sound/soc/intel/common/sst-ipc.c @@ -121,8 +121,8 @@ static int msg_empty_list_init(struct sst_generic_ipc *ipc) { int i; - ipc->msg = kzalloc(sizeof(struct ipc_message) * - IPC_EMPTY_LIST_SIZE, GFP_KERNEL); + ipc->msg = kcalloc(IPC_EMPTY_LIST_SIZE, sizeof(struct ipc_message), + GFP_KERNEL); if (ipc->msg == NULL) return -ENOMEM; diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index b45c1ae60f94..be189a34efdd 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -2334,8 +2334,10 @@ static int skl_tplg_get_token(struct device *dev, case SKL_TKN_U8_DYN_IN_PIN: if (!mconfig->m_in_pin) - mconfig->m_in_pin = devm_kzalloc(dev, MAX_IN_QUEUE * - sizeof(*mconfig->m_in_pin), GFP_KERNEL); + mconfig->m_in_pin = devm_kcalloc(dev, + MAX_IN_QUEUE, + sizeof(*mconfig->m_in_pin), + GFP_KERNEL); if (!mconfig->m_in_pin) return -ENOMEM; @@ -2345,8 +2347,10 @@ static int skl_tplg_get_token(struct device *dev, case SKL_TKN_U8_DYN_OUT_PIN: if (!mconfig->m_out_pin) - mconfig->m_out_pin = devm_kzalloc(dev, MAX_IN_QUEUE * - sizeof(*mconfig->m_in_pin), GFP_KERNEL); + mconfig->m_out_pin = devm_kcalloc(dev, + MAX_IN_QUEUE, + sizeof(*mconfig->m_in_pin), + GFP_KERNEL); if (!mconfig->m_out_pin) return -ENOMEM; diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c index 64b85e30c1f8..566080770889 100644 --- a/sound/soc/pxa/mmp-sspa.c +++ b/sound/soc/pxa/mmp-sspa.c @@ -426,8 +426,8 @@ static int asoc_mmp_sspa_probe(struct platform_device *pdev) if (priv->sspa == NULL) return -ENOMEM; - priv->dma_params = devm_kzalloc(&pdev->dev, - 2 * sizeof(struct snd_dmaengine_dai_dma_data), + priv->dma_params = devm_kcalloc(&pdev->dev, + 2, sizeof(struct snd_dmaengine_dai_dma_data), GFP_KERNEL); if (priv->dma_params == NULL) return -ENOMEM; diff --git a/sound/soc/sh/rcar/cmd.c b/sound/soc/sh/rcar/cmd.c index f1d4fb566892..6c65b6e295d1 100644 --- a/sound/soc/sh/rcar/cmd.c +++ b/sound/soc/sh/rcar/cmd.c @@ -156,7 +156,7 @@ int rsnd_cmd_probe(struct rsnd_priv *priv) if (!nr) return 0; - cmd = devm_kzalloc(dev, sizeof(*cmd) * nr, GFP_KERNEL); + cmd = devm_kcalloc(dev, nr, sizeof(*cmd), GFP_KERNEL); if (!cmd) return -ENOMEM; diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index f203c0878e69..6a4a49199b36 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1094,8 +1094,8 @@ static int rsnd_dai_probe(struct rsnd_priv *priv) if (!nr) return -EINVAL; - rdrv = devm_kzalloc(dev, sizeof(*rdrv) * nr, GFP_KERNEL); - rdai = devm_kzalloc(dev, sizeof(*rdai) * nr, GFP_KERNEL); + rdrv = devm_kcalloc(dev, nr, sizeof(*rdrv), GFP_KERNEL); + rdai = devm_kcalloc(dev, nr, sizeof(*rdai), GFP_KERNEL); if (!rdrv || !rdai) return -ENOMEM; diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c index e7f53f44165d..0fb32c49fc24 100644 --- a/sound/soc/sh/rcar/ctu.c +++ b/sound/soc/sh/rcar/ctu.c @@ -370,7 +370,7 @@ int rsnd_ctu_probe(struct rsnd_priv *priv) goto rsnd_ctu_probe_done; } - ctu = devm_kzalloc(dev, sizeof(*ctu) * nr, GFP_KERNEL); + ctu = devm_kcalloc(dev, nr, sizeof(*ctu), GFP_KERNEL); if (!ctu) { ret = -ENOMEM; goto rsnd_ctu_probe_done; diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 1743ade3cc55..edec2e245245 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -360,7 +360,7 @@ int rsnd_dvc_probe(struct rsnd_priv *priv) goto rsnd_dvc_probe_done; } - dvc = devm_kzalloc(dev, sizeof(*dvc) * nr, GFP_KERNEL); + dvc = devm_kcalloc(dev, nr, sizeof(*dvc), GFP_KERNEL); if (!dvc) { ret = -ENOMEM; goto rsnd_dvc_probe_done; diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c index 6c4826c189a4..b716207aab8e 100644 --- a/sound/soc/sh/rcar/mix.c +++ b/sound/soc/sh/rcar/mix.c @@ -148,7 +148,7 @@ int rsnd_mix_probe(struct rsnd_priv *priv) goto rsnd_mix_probe_done; } - mix = devm_kzalloc(dev, sizeof(*mix) * nr, GFP_KERNEL); + mix = devm_kcalloc(dev, nr, sizeof(*mix), GFP_KERNEL); if (!mix) { ret = -ENOMEM; goto rsnd_mix_probe_done; diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 510b68a483b4..0e71e8ed08f6 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -557,7 +557,7 @@ int rsnd_src_probe(struct rsnd_priv *priv) goto rsnd_src_probe_done; } - src = devm_kzalloc(dev, sizeof(*src) * nr, GFP_KERNEL); + src = devm_kcalloc(dev, nr, sizeof(*src), GFP_KERNEL); if (!src) { ret = -ENOMEM; goto rsnd_src_probe_done; diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index cae9ed6a0cdb..3eac3bc49e94 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -1112,7 +1112,7 @@ int rsnd_ssi_probe(struct rsnd_priv *priv) goto rsnd_ssi_probe_done; } - ssi = devm_kzalloc(dev, sizeof(*ssi) * nr, GFP_KERNEL); + ssi = devm_kcalloc(dev, nr, sizeof(*ssi), GFP_KERNEL); if (!ssi) { ret = -ENOMEM; goto rsnd_ssi_probe_done; diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index 5e5ed5475473..5f4469b67125 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c @@ -255,7 +255,7 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv) /* same number to SSI */ nr = priv->ssi_nr; - ssiu = devm_kzalloc(dev, sizeof(*ssiu) * nr, GFP_KERNEL); + ssiu = devm_kcalloc(dev, nr, sizeof(*ssiu), GFP_KERNEL); if (!ssiu) return -ENOMEM; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 123dcd1b9327..1c6858be01ce 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -626,8 +626,8 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( INIT_LIST_HEAD(&rtd->component_list); rtd->card = card; rtd->dai_link = dai_link; - rtd->codec_dais = kzalloc(sizeof(struct snd_soc_dai *) * - dai_link->num_codecs, + rtd->codec_dais = kcalloc(dai_link->num_codecs, + sizeof(struct snd_soc_dai *), GFP_KERNEL); if (!rtd->codec_dais) { kfree(rtd); @@ -4094,7 +4094,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, return -EINVAL; } - routes = devm_kzalloc(card->dev, num_routes * sizeof(*routes), + routes = devm_kcalloc(card->dev, num_routes, sizeof(*routes), GFP_KERNEL); if (!routes) { dev_err(card->dev, @@ -4446,8 +4446,8 @@ int snd_soc_of_get_dai_link_codecs(struct device *dev, dev_err(dev, "Bad phandle in 'sound-dai'\n"); return num_codecs; } - component = devm_kzalloc(dev, - sizeof *component * num_codecs, + component = devm_kcalloc(dev, + num_codecs, sizeof(*component), GFP_KERNEL); if (!component) return -ENOMEM; diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index ec1aa2bbc297..fcfc77793236 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -3091,7 +3091,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_card *card) continue; if (w->num_kcontrols) { - w->kcontrols = kzalloc(w->num_kcontrols * + w->kcontrols = kcalloc(w->num_kcontrols, sizeof(struct snd_kcontrol *), GFP_KERNEL); if (!w->kcontrols) { diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 50aa45525be5..fbadd6088c8e 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -936,7 +936,7 @@ static int soc_tplg_denum_create_texts(struct soc_enum *se, int i, ret; se->dobj.control.dtexts = - kzalloc(sizeof(char *) * ec->items, GFP_KERNEL); + kcalloc(ec->items, sizeof(char *), GFP_KERNEL); if (se->dobj.control.dtexts == NULL) return -ENOMEM; diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index 224a6a5d1c0e..2dd2518a71d3 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c @@ -591,12 +591,14 @@ static int usb6fire_pcm_buffers_init(struct pcm_runtime *rt) int i; for (i = 0; i < PCM_N_URBS; i++) { - rt->out_urbs[i].buffer = kzalloc(PCM_N_PACKETS_PER_URB - * PCM_MAX_PACKET_SIZE, GFP_KERNEL); + rt->out_urbs[i].buffer = kcalloc(PCM_MAX_PACKET_SIZE, + PCM_N_PACKETS_PER_URB, + GFP_KERNEL); if (!rt->out_urbs[i].buffer) return -ENOMEM; - rt->in_urbs[i].buffer = kzalloc(PCM_N_PACKETS_PER_URB - * PCM_MAX_PACKET_SIZE, GFP_KERNEL); + rt->in_urbs[i].buffer = kcalloc(PCM_MAX_PACKET_SIZE, + PCM_N_PACKETS_PER_URB, + GFP_KERNEL); if (!rt->in_urbs[i].buffer) return -ENOMEM; } diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c index fb1c1eac0b5e..f35d29f49ffe 100644 --- a/sound/usb/caiaq/audio.c +++ b/sound/usb/caiaq/audio.c @@ -728,7 +728,7 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *cdev, int dir, int *ret) usb_sndisocpipe(usb_dev, ENDPOINT_PLAYBACK) : usb_rcvisocpipe(usb_dev, ENDPOINT_CAPTURE); - urbs = kmalloc(N_URBS * sizeof(*urbs), GFP_KERNEL); + urbs = kmalloc_array(N_URBS, sizeof(*urbs), GFP_KERNEL); if (!urbs) { *ret = -ENOMEM; return NULL; @@ -742,7 +742,8 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *cdev, int dir, int *ret) } urbs[i]->transfer_buffer = - kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL); + kmalloc_array(BYTES_PER_FRAME, FRAMES_PER_URB, + GFP_KERNEL); if (!urbs[i]->transfer_buffer) { *ret = -ENOMEM; return urbs; @@ -857,7 +858,7 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *cdev) &snd_usb_caiaq_ops); cdev->data_cb_info = - kmalloc(sizeof(struct snd_usb_caiaq_cb_info) * N_URBS, + kmalloc_array(N_URBS, sizeof(struct snd_usb_caiaq_cb_info), GFP_KERNEL); if (!cdev->data_cb_info) diff --git a/sound/usb/format.c b/sound/usb/format.c index 2227b4cea338..79d6db652c60 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c @@ -204,7 +204,8 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof */ int r, idx; - fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); + fp->rate_table = kmalloc_array(nr_rates, sizeof(int), + GFP_KERNEL); if (fp->rate_table == NULL) return -ENOMEM; @@ -429,7 +430,7 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, goto err_free; } - fp->rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL); + fp->rate_table = kmalloc_array(fp->nr_rates, sizeof(int), GFP_KERNEL); if (!fp->rate_table) { ret = -ENOMEM; goto err_free; diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c index a65a82d5791d..bd0171cfec4c 100644 --- a/sound/usb/line6/capture.c +++ b/sound/usb/line6/capture.c @@ -264,8 +264,8 @@ int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm) struct usb_line6 *line6 = line6pcm->line6; int i; - line6pcm->in.urbs = kzalloc( - sizeof(struct urb *) * line6->iso_buffers, GFP_KERNEL); + line6pcm->in.urbs = kcalloc(line6->iso_buffers, sizeof(struct urb *), + GFP_KERNEL); if (line6pcm->in.urbs == NULL) return -ENOMEM; diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c index 896add5ffee3..868f38682103 100644 --- a/sound/usb/line6/pcm.c +++ b/sound/usb/line6/pcm.c @@ -158,8 +158,8 @@ static int line6_buffer_acquire(struct snd_line6_pcm *line6pcm, /* Invoked multiple times in a row so allocate once only */ if (!test_and_set_bit(type, &pstr->opened) && !pstr->buffer) { - pstr->buffer = kmalloc(line6pcm->line6->iso_buffers * - LINE6_ISO_PACKETS * pkt_size, GFP_KERNEL); + pstr->buffer = kmalloc(array3_size(line6pcm->line6->iso_buffers, LINE6_ISO_PACKETS, pkt_size), + GFP_KERNEL); if (!pstr->buffer) return -ENOMEM; } diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c index 1736eb3ee98e..6b8f2dd358a1 100644 --- a/sound/usb/line6/playback.c +++ b/sound/usb/line6/playback.c @@ -409,8 +409,8 @@ int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm) struct usb_line6 *line6 = line6pcm->line6; int i; - line6pcm->out.urbs = kzalloc( - sizeof(struct urb *) * line6->iso_buffers, GFP_KERNEL); + line6pcm->out.urbs = kcalloc(line6->iso_buffers, sizeof(struct urb *), + GFP_KERNEL); if (line6pcm->out.urbs == NULL) return -ENOMEM; diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 20f32c260fee..edb92a6941db 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -2443,7 +2443,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, cval->control = (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR) ? UAC2_CX_CLOCK_SELECTOR : UAC2_SU_SELECTOR; - namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL); + namelist = kmalloc_array(desc->bNrInPins, sizeof(char *), GFP_KERNEL); if (!namelist) { kfree(cval); return -ENOMEM; diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 816c7d5a41e3..ff4a89af9368 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -1261,7 +1261,7 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime, return 0; subs->rate_list.list = rate_list = - kmalloc(sizeof(int) * count, GFP_KERNEL); + kmalloc_array(count, sizeof(int), GFP_KERNEL); if (!subs->rate_list.list) return -ENOMEM; subs->rate_list.count = count; diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c index 4569c0efac0a..9f71a0b8b14f 100644 --- a/sound/usb/usx2y/usbusx2y.c +++ b/sound/usb/usx2y/usbusx2y.c @@ -266,7 +266,7 @@ int usX2Y_AsyncSeq04_init(struct usX2Ydev *usX2Y) int err = 0, i; - if (NULL == (usX2Y->AS04.buffer = kmalloc(URB_DataLen_AsyncSeq*URBS_AsyncSeq, GFP_KERNEL))) { + if (NULL == (usX2Y->AS04.buffer = kmalloc_array(URBS_AsyncSeq, URB_DataLen_AsyncSeq, GFP_KERNEL))) { err = -ENOMEM; } else for (i = 0; i < URBS_AsyncSeq; ++i) { diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index 2dfc0abf2e37..3c2898f82005 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c @@ -436,7 +436,9 @@ static int usX2Y_urbs_allocate(struct snd_usX2Y_substream *subs) } if (!is_playback && !(*purb)->transfer_buffer) { /* allocate a capture buffer per urb */ - (*purb)->transfer_buffer = kmalloc(subs->maxpacksize * nr_of_packs(), GFP_KERNEL); + (*purb)->transfer_buffer = kmalloc_array(subs->maxpacksize, + nr_of_packs(), + GFP_KERNEL); if (NULL == (*purb)->transfer_buffer) { usX2Y_urbs_release(subs); return -ENOMEM; @@ -662,7 +664,8 @@ static int usX2Y_rate_set(struct usX2Ydev *usX2Y, int rate) err = -ENOMEM; goto cleanup; } - usbdata = kmalloc(sizeof(int) * NOOF_SETRATE_URBS, GFP_KERNEL); + usbdata = kmalloc_array(NOOF_SETRATE_URBS, sizeof(int), + GFP_KERNEL); if (NULL == usbdata) { err = -ENOMEM; goto cleanup; diff --git a/techpack/audio/4.0/asoc/codecs/bolero/bolero-cdc.c b/techpack/audio/4.0/asoc/codecs/bolero/bolero-cdc.c index a09bbaec5f56..bfecc5651ee3 100644 --- a/techpack/audio/4.0/asoc/codecs/bolero/bolero-cdc.c +++ b/techpack/audio/4.0/asoc/codecs/bolero/bolero-cdc.c @@ -389,10 +389,9 @@ static int bolero_copy_dais_from_macro(struct bolero_priv *priv) /* memcpy into bolero_dais all macro dais */ if (!priv->bolero_dais) - priv->bolero_dais = devm_kzalloc(priv->dev, - priv->num_dais * - sizeof( - struct snd_soc_dai_driver), + priv->bolero_dais = devm_kcalloc(priv->dev, + priv->num_dais, + sizeof(struct snd_soc_dai_driver), GFP_KERNEL); if (!priv->bolero_dais) return -ENOMEM; diff --git a/techpack/audio/4.0/asoc/codecs/bolero/bolero-clk-rsc.c b/techpack/audio/4.0/asoc/codecs/bolero/bolero-clk-rsc.c index b134819e0c16..54f2ac6a6daf 100644 --- a/techpack/audio/4.0/asoc/codecs/bolero/bolero-clk-rsc.c +++ b/techpack/audio/4.0/asoc/codecs/bolero/bolero-clk-rsc.c @@ -640,7 +640,7 @@ static int bolero_clk_rsc_probe(struct platform_device *pdev) ret = -EINVAL; goto err; } - clk_name_array = devm_kzalloc(&pdev->dev, clk_cnt * sizeof(char *), + clk_name_array = devm_kcalloc(&pdev->dev, clk_cnt, sizeof(char *), GFP_KERNEL); if (!clk_name_array) { ret = -ENOMEM; diff --git a/techpack/audio/4.0/asoc/codecs/bolero/tx-macro.c b/techpack/audio/4.0/asoc/codecs/bolero/tx-macro.c index 9182601f6c28..70605c715f0a 100644 --- a/techpack/audio/4.0/asoc/codecs/bolero/tx-macro.c +++ b/techpack/audio/4.0/asoc/codecs/bolero/tx-macro.c @@ -175,6 +175,7 @@ struct tx_macro_priv { int dec_mode[NUM_DECIMATORS]; bool bcs_clk_en; bool hs_slow_insert_complete; + int amic_sample_rate; }; static bool tx_macro_get_data(struct snd_soc_codec *codec, @@ -494,6 +495,29 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) hpf_cut_off_freq << 5); snd_soc_update_bits(codec, hpf_gate_reg, 0x03, 0x02); + /* Add delay between toggle hpf gate based on sample rate */ + switch(tx_priv->amic_sample_rate) { + case 8000: + usleep_range(125, 130); + break; + case 16000: + usleep_range(62, 65); + break; + case 32000: + usleep_range(31, 32); + break; + case 48000: + usleep_range(20, 21); + break; + case 96000: + usleep_range(10, 11); + break; + case 192000: + usleep_range(5, 6); + break; + default: + usleep_range(125, 130); + } snd_soc_update_bits(codec, hpf_gate_reg, 0x03, 0x01); } else { @@ -829,6 +853,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, u16 dec_cfg_reg = 0; u16 hpf_gate_reg = 0; u16 tx_gain_ctl_reg = 0; + u16 tx_fs_reg = 0; u8 hpf_cut_off_freq = 0; int hpf_delay = TX_MACRO_DMIC_HPF_DELAY_MS; int unmute_delay = TX_MACRO_DMIC_UNMUTE_DELAY_MS; @@ -853,6 +878,10 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, TX_MACRO_TX_PATH_OFFSET * decimator; tx_gain_ctl_reg = BOLERO_CDC_TX0_TX_VOL_CTL + TX_MACRO_TX_PATH_OFFSET * decimator; + tx_fs_reg = BOLERO_CDC_TX0_TX_PATH_CTL + + TX_MACRO_TX_PATH_OFFSET * decimator; + + tx_priv->amic_sample_rate = (snd_soc_read(codec, tx_fs_reg) & 0x0F); switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -880,7 +909,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMU: snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x20, 0x20); - if (!(is_amic_enabled(codec, decimator) < BOLERO_ADC_MAX)) { + if (!is_amic_enabled(codec, decimator)) { snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x00); /* @@ -948,8 +977,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, hpf_cut_off_freq << 5); - if (is_amic_enabled(codec, decimator) < - BOLERO_ADC_MAX) + if (is_amic_enabled(codec, decimator)) snd_soc_update_bits(codec, hpf_gate_reg, 0x03, 0x02); @@ -2725,7 +2753,7 @@ undefined_rate: } static const struct tx_macro_reg_mask_val tx_macro_reg_init[] = { - {BOLERO_CDC_TX0_TX_PATH_SEC7, 0x3F, 0x02}, + {BOLERO_CDC_TX0_TX_PATH_SEC7, 0x3F, 0x0A}, }; static int tx_macro_init(struct snd_soc_codec *codec) { diff --git a/techpack/audio/4.0/asoc/codecs/wcd9xxx-core.c b/techpack/audio/4.0/asoc/codecs/wcd9xxx-core.c index 9736c43c365b..03e38e7954ed 100644 --- a/techpack/audio/4.0/asoc/codecs/wcd9xxx-core.c +++ b/techpack/audio/4.0/asoc/codecs/wcd9xxx-core.c @@ -179,7 +179,7 @@ static int wcd9xxx_slim_multi_reg_write(struct wcd9xxx *wcd9xxx, if (num_regs == 0) return -EINVAL; - bulk_reg = kzalloc(num_regs * (sizeof(struct wcd9xxx_reg_val)), + bulk_reg = kcalloc(num_regs, sizeof(struct wcd9xxx_reg_val), GFP_KERNEL); if (!bulk_reg) return -ENOMEM; @@ -484,7 +484,7 @@ int wcd9xxx_slim_bulk_write(struct wcd9xxx *wcd9xxx, return 0; } - msgs = kzalloc(size * (sizeof(struct slim_val_inf)), GFP_KERNEL); + msgs = kcalloc(size, sizeof(struct slim_val_inf), GFP_KERNEL); if (!msgs) { ret = -ENOMEM; goto mem_fail; diff --git a/techpack/audio/4.0/asoc/kona.c b/techpack/audio/4.0/asoc/kona.c index f9fad426847b..005a9becfa61 100644 --- a/techpack/audio/4.0/asoc/kona.c +++ b/techpack/audio/4.0/asoc/kona.c @@ -6224,6 +6224,33 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, }, + /* Proxy Tx BACK END DAI Link */ + { + .name = LPASS_BE_PROXY_TX, + .stream_name = "Proxy Capture", + .cpu_dai_name = "msm-dai-q6-dev.8195", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PROXY_TX, + .ignore_suspend = 1, + }, + /* Proxy Rx BACK END DAI Link */ + { + .name = LPASS_BE_PROXY_RX, + .stream_name = "Proxy Playback", + .cpu_dai_name = "msm-dai-q6-dev.8194", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PROXY_RX, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, { .name = LPASS_BE_USB_AUDIO_RX, .stream_name = "USB Audio Playback", diff --git a/techpack/audio/4.0/asoc/msm-dai-q6-v2.c b/techpack/audio/4.0/asoc/msm-dai-q6-v2.c index bf9c4c5b597b..d68f6ef49049 100644 --- a/techpack/audio/4.0/asoc/msm-dai-q6-v2.c +++ b/techpack/audio/4.0/asoc/msm-dai-q6-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -2621,6 +2621,8 @@ static int msm_dai_q6_hw_params(struct snd_pcm_substream *substream, case RT_PROXY_DAI_001_RX: case RT_PROXY_DAI_002_TX: case RT_PROXY_DAI_002_RX: + case RT_PROXY_PORT_002_TX: + case RT_PROXY_PORT_002_RX: rc = msm_dai_q6_afe_rtproxy_hw_params(params, dai); break; case VOICE_PLAYBACK_TX: @@ -4247,6 +4249,42 @@ static struct snd_soc_dai_driver msm_dai_q6_incall_record_dai[] = { }, }; +static struct snd_soc_dai_driver msm_dai_q6_proxy_tx_dai = { + .capture = { + .stream_name = "Proxy Capture", + .aif_name = "PROXY_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_ops, + .id = RT_PROXY_PORT_002_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, +}; + +static struct snd_soc_dai_driver msm_dai_q6_proxy_rx_dai = { + .playback = { + .stream_name = "Proxy Playback", + .aif_name = "PROXY_RX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_ops, + .id = RT_PROXY_PORT_002_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, +}; + static struct snd_soc_dai_driver msm_dai_q6_usb_rx_dai = { .playback = { .stream_name = "USB Audio Playback", @@ -4425,9 +4463,9 @@ static int msm_auxpcm_dev_probe(struct platform_device *pdev) } auxpcm_pdata->mode_8k.slot_mapping = - kzalloc(sizeof(uint16_t) * - auxpcm_pdata->mode_8k.num_slots, - GFP_KERNEL); + kcalloc(auxpcm_pdata->mode_8k.num_slots, + sizeof(uint16_t), + GFP_KERNEL); if (!auxpcm_pdata->mode_8k.slot_mapping) { dev_err(&pdev->dev, "%s No mem for mode_8k slot mapping\n", __func__); @@ -4440,9 +4478,9 @@ static int msm_auxpcm_dev_probe(struct platform_device *pdev) (u16)be32_to_cpu(slot_mapping_array[i]); auxpcm_pdata->mode_16k.slot_mapping = - kzalloc(sizeof(uint16_t) * - auxpcm_pdata->mode_16k.num_slots, - GFP_KERNEL); + kcalloc(auxpcm_pdata->mode_16k.num_slots, + sizeof(uint16_t), + GFP_KERNEL); if (!auxpcm_pdata->mode_16k.slot_mapping) { dev_err(&pdev->dev, "%s No mem for mode_16k slot mapping\n", @@ -7288,6 +7326,14 @@ register_uplink_capture: __func__, stream_name); break; + case RT_PROXY_PORT_002_RX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, &msm_dai_q6_proxy_rx_dai, 1); + break; + case RT_PROXY_PORT_002_TX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, &msm_dai_q6_proxy_tx_dai, 1); + break; default: rc = -ENODEV; break; diff --git a/techpack/audio/4.0/asoc/msm-dai-slim.c b/techpack/audio/4.0/asoc/msm-dai-slim.c index 545590fa3735..3bebf565c2f0 100644 --- a/techpack/audio/4.0/asoc/msm-dai-slim.c +++ b/techpack/audio/4.0/asoc/msm-dai-slim.c @@ -492,8 +492,8 @@ static int msm_dai_slim_populate_dai_data(struct device *dev, SET_DAI_STATE(dai_data_t->status, DAI_STATE_INITIALIZED); - dai_data_t->chan_h = devm_kzalloc(dev, - sizeof(u16) * num_ch, + dai_data_t->chan_h = devm_kcalloc(dev, + num_ch, sizeof(u16), GFP_KERNEL); if (!dai_data_t->chan_h) { dev_err(dev, @@ -503,8 +503,8 @@ static int msm_dai_slim_populate_dai_data(struct device *dev, goto err_mem_alloc; } - dai_data_t->sh_ch = devm_kzalloc(dev, - sizeof(u16) * num_ch, + dai_data_t->sh_ch = devm_kcalloc(dev, + num_ch, sizeof(u16), GFP_KERNEL); if (!dai_data_t->sh_ch) { dev_err(dev, diff --git a/techpack/audio/4.0/asoc/msm-lsm-client.c b/techpack/audio/4.0/asoc/msm-lsm-client.c index d6fd86cc97a2..9bcda9bf0fa5 100644 --- a/techpack/audio/4.0/asoc/msm-lsm-client.c +++ b/techpack/audio/4.0/asoc/msm-lsm-client.c @@ -2576,7 +2576,7 @@ static int msm_lsm_send_ch_mix_config(struct snd_pcm_substream *substream) return 0; } - ch_wght_coeff = kzalloc(in_params->num_chs * pp_ch_cnt * sizeof(int), + ch_wght_coeff = kcalloc(in_params->num_chs * pp_ch_cnt, sizeof(int), GFP_KERNEL); if (!ch_wght_coeff) return -ENOMEM; diff --git a/techpack/audio/4.0/asoc/msm-pcm-routing-v2.c b/techpack/audio/4.0/asoc/msm-pcm-routing-v2.c index d180f13b532b..856edb481ee5 100644 --- a/techpack/audio/4.0/asoc/msm-pcm-routing-v2.c +++ b/techpack/audio/4.0/asoc/msm-pcm-routing-v2.c @@ -699,6 +699,8 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { LPASS_BE_PRI_META_MI2S_RX}, { AFE_PORT_ID_SECONDARY_META_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_META_MI2S_RX}, + { RT_PROXY_PORT_002_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PROXY_RX}, + { RT_PROXY_PORT_002_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PROXY_TX}, }; /* Track ASM playback & capture sessions of DAI @@ -3530,7 +3532,7 @@ static const char *const be_name[] = { "RX_CDC_DMA_RX_6", "RX_CDC_DMA_RX_7", "PRI_SPDIF_TX", "SEC_SPDIF_RX", "SEC_SPDIF_TX", "SLIM_9_RX", "SLIM_9_TX", "AFE_LOOPBACK_TX", "PRI_META_MI2S_RX", -"SEC_META_MI2S_RX" +"SEC_META_MI2S_RX", "PROXY_RX", "PROXY_TX" }; static SOC_ENUM_SINGLE_DECL(mm1_channel_mux, @@ -20483,6 +20485,17 @@ static const struct snd_kcontrol_new slimbus_3_rx_mixer_controls[] = { msm_routing_put_voice_mixer), }; +static const struct snd_kcontrol_new proxy_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PROXY_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PROXY_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_I2S_TX, @@ -20584,6 +20597,9 @@ static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_TDM_TX_3_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PROXY_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PROXY_TX, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { @@ -20683,6 +20699,9 @@ static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_TDM_TX_3_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PROXY_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PROXY_TX, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { @@ -23900,6 +23919,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_IN("SLIMBUS_9_TX", "Slimbus9 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("USB_AUDIO_RX", "USB Audio Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("USB_AUDIO_TX", "USB Audio Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PROXY_RX", "Proxy Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PROXY_TX", "Proxy Capture", 0, 0, 0, 0), /* Switch Definitions */ SND_SOC_DAPM_SWITCH("SLIMBUS_DL_HL", SND_SOC_NOPM, 0, 0, @@ -24066,6 +24087,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_NOPM, 0, 0, wsa_cdc_dma_rx_0_voice_mixer_controls, ARRAY_SIZE(wsa_cdc_dma_rx_0_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("PROXY_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + proxy_rx_voice_mixer_controls, + ARRAY_SIZE(proxy_rx_voice_mixer_controls)), SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_0_Voice Mixer", SND_SOC_NOPM, 0, 0, rx_cdc_dma_rx_0_voice_mixer_controls, @@ -26337,6 +26362,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"WSA_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0_Voice Mixer"}, + {"PROXY_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PROXY_RX", NULL, "PROXY_RX_Voice Mixer"}, + + {"PROXY_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PROXY_RX", NULL, "PROXY_RX_Voice Mixer"}, + {"RX_CDC_DMA_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, {"RX_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"RX_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, @@ -26394,6 +26425,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_3_MMode1", "TX_CDC_DMA_TX_3"}, {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_4_MMode1", "TX_CDC_DMA_TX_4"}, {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_5_MMode1", "TX_CDC_DMA_TX_5"}, + {"VoiceMMode1_Tx Mixer", "PROXY_TX_MMode1", "PROXY_TX"}, {"VOICEMMODE1_UL", NULL, "VoiceMMode1_Tx Mixer"}, {"VoiceMMode2_Tx Mixer", "SLIM_0_TX_MMode2", "SLIMBUS_0_TX"}, @@ -26408,6 +26440,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_3_MMode2", "TX_CDC_DMA_TX_3"}, {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_4_MMode2", "TX_CDC_DMA_TX_4"}, {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_5_MMode2", "TX_CDC_DMA_TX_5"}, + {"VoiceMMode2_Tx Mixer", "PROXY_TX_MMode2", "PROXY_TX"}, {"VOICEMMODE2_UL", NULL, "VoiceMMode2_Tx Mixer"}, {"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"}, @@ -26714,6 +26747,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "RX_CDC_DMA_RX_5"}, {"BE_OUT", NULL, "RX_CDC_DMA_RX_6"}, {"BE_OUT", NULL, "RX_CDC_DMA_RX_7"}, + {"BE_OUT", NULL, "PROXY_RX"}, {"SLIMBUS_0_TX", NULL, "BE_IN" }, {"SLIMBUS_1_TX", NULL, "BE_IN" }, @@ -26756,6 +26790,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TX_CDC_DMA_TX_5", NULL, "BE_IN"}, {"PRI_SPDIF_TX", NULL, "BE_IN"}, {"SEC_SPDIF_TX", NULL, "BE_IN"}, + {"PROXY_TX", NULL, "BE_IN"}, }; #ifndef CONFIG_AUXPCM_DISABLE diff --git a/techpack/audio/4.0/asoc/msm-pcm-routing-v2.h b/techpack/audio/4.0/asoc/msm-pcm-routing-v2.h index 9c74c32ffbd5..ee9c63ad89c8 100644 --- a/techpack/audio/4.0/asoc/msm-pcm-routing-v2.h +++ b/techpack/audio/4.0/asoc/msm-pcm-routing-v2.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef _MSM_PCM_ROUTING_H #define _MSM_PCM_ROUTING_H @@ -42,6 +42,8 @@ #define LPASS_BE_VOICE2_PLAYBACK_TX "VOICE2_PLAYBACK_TX" #define LPASS_BE_INCALL_RECORD_RX "INCALL_RECORD_RX" #define LPASS_BE_INCALL_RECORD_TX "INCALL_RECORD_TX" +#define LPASS_BE_PROXY_RX "PROXY_RX" +#define LPASS_BE_PROXY_TX "PROXY_TX" #define LPASS_BE_SEC_I2S_RX "SECONDARY_I2S_RX" #define LPASS_BE_PRI_SPDIF_RX "PRI_SPDIF_RX" #define LPASS_BE_PRI_SPDIF_TX "PRI_SPDIF_TX" @@ -500,6 +502,8 @@ enum { MSM_BACKEND_DAI_AFE_LOOPBACK_TX, MSM_BACKEND_DAI_PRI_META_MI2S_RX, MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_BACKEND_DAI_PROXY_RX, + MSM_BACKEND_DAI_PROXY_TX, MSM_BACKEND_DAI_MAX, }; diff --git a/techpack/audio/4.0/dsp/adsp-loader.c b/techpack/audio/4.0/dsp/adsp-loader.c index c0dbe3f4f438..673fbff0eb14 100644 --- a/techpack/audio/4.0/dsp/adsp-loader.c +++ b/techpack/audio/4.0/dsp/adsp-loader.c @@ -371,8 +371,8 @@ static int adsp_loader_probe(struct platform_device *pdev) goto wqueue; } - adsp_fw_bit_values = devm_kzalloc(&pdev->dev, - adsp_fw_cnt * sizeof(u32), GFP_KERNEL); + adsp_fw_bit_values = devm_kcalloc(&pdev->dev, + adsp_fw_cnt, sizeof(u32), GFP_KERNEL); if (!adsp_fw_bit_values) goto wqueue; @@ -387,8 +387,8 @@ static int adsp_loader_probe(struct platform_device *pdev) goto wqueue; } - adsp_fw_name_array = devm_kzalloc(&pdev->dev, - adsp_fw_cnt * sizeof(char *), GFP_KERNEL); + adsp_fw_name_array = devm_kcalloc(&pdev->dev, + adsp_fw_cnt, sizeof(char *), GFP_KERNEL); if (!adsp_fw_name_array) goto wqueue; diff --git a/techpack/audio/4.0/dsp/q6afe.c b/techpack/audio/4.0/dsp/q6afe.c index 16d156783c53..e3d75ccc5727 100644 --- a/techpack/audio/4.0/dsp/q6afe.c +++ b/techpack/audio/4.0/dsp/q6afe.c @@ -988,6 +988,8 @@ int afe_sizeof_cfg_cmd(u16 port_id) break; case RT_PROXY_PORT_001_RX: case RT_PROXY_PORT_001_TX: + case RT_PROXY_PORT_002_RX: + case RT_PROXY_PORT_002_TX: ret_size = SIZEOF_CFG_CMD(afe_param_id_rt_proxy_port_cfg); break; case AFE_PORT_ID_USB_RX: @@ -4755,6 +4757,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, break; case RT_PROXY_PORT_001_RX: case RT_PROXY_PORT_001_TX: + case RT_PROXY_PORT_002_RX: + case RT_PROXY_PORT_002_TX: cfg_type = AFE_PARAM_ID_RT_PROXY_CONFIG; break; case INT_BT_SCO_RX: @@ -5302,6 +5306,10 @@ int afe_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_7; case AFE_LOOPBACK_TX: return IDX_AFE_LOOPBACK_TX; + case RT_PROXY_PORT_002_RX: + return IDX_RT_PROXY_PORT_002_RX; + case RT_PROXY_PORT_002_TX: + return IDX_RT_PROXY_PORT_002_TX; default: pr_err("%s: port 0x%x\n", __func__, port_id); return -EINVAL; @@ -7499,6 +7507,8 @@ int afe_validate_port(u16 port_id) case AFE_PORT_ID_TX_CODEC_DMA_TX_5: case AFE_PORT_ID_RX_CODEC_DMA_RX_6: case AFE_PORT_ID_RX_CODEC_DMA_RX_7: + case RT_PROXY_PORT_002_RX: + case RT_PROXY_PORT_002_TX: { ret = 0; break; diff --git a/techpack/audio/4.0/dsp/q6asm.c b/techpack/audio/4.0/dsp/q6asm.c index bb1df5b24432..8acd2330b84b 100644 --- a/techpack/audio/4.0/dsp/q6asm.c +++ b/techpack/audio/4.0/dsp/q6asm.c @@ -309,7 +309,7 @@ static ssize_t audio_output_latency_dbgfs_write(struct file *file, pr_err("%s: err count is more %zd\n", __func__, count); return -EINVAL; } - temp = kmalloc(2*sizeof(char), GFP_KERNEL); + temp = kmalloc(2, GFP_KERNEL); out_cold_index = 0; @@ -365,7 +365,7 @@ static ssize_t audio_input_latency_dbgfs_write(struct file *file, pr_err("%s: err count is more %zd\n", __func__, count); return -EINVAL; } - temp = kmalloc(2*sizeof(char), GFP_KERNEL); + temp = kmalloc(2, GFP_KERNEL); if (temp) { if (copy_from_user(temp, buf, 2*sizeof(char))) { @@ -8472,7 +8472,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir, return -EINVAL; } - buffer_node = kzalloc(sizeof(struct asm_buffer_node) * bufcnt, + buffer_node = kcalloc(bufcnt, sizeof(struct asm_buffer_node), GFP_KERNEL); if (!buffer_node) return -ENOMEM; diff --git a/techpack/audio/4.0/dsp/q6audio-v2.c b/techpack/audio/4.0/dsp/q6audio-v2.c index 68b373629a18..e3a2dc7805b7 100644 --- a/techpack/audio/4.0/dsp/q6audio-v2.c +++ b/techpack/audio/4.0/dsp/q6audio-v2.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -385,6 +385,10 @@ int q6audio_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_6; case AFE_PORT_ID_RX_CODEC_DMA_RX_7: return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_7; + case RT_PROXY_PORT_002_RX: + return IDX_RT_PROXY_PORT_002_RX; + case RT_PROXY_PORT_002_TX: + return IDX_RT_PROXY_PORT_002_TX; default: return -EINVAL; } } @@ -767,6 +771,10 @@ int q6audio_get_port_id(u16 port_id) return AFE_PORT_ID_RX_CODEC_DMA_RX_6; case AFE_PORT_ID_RX_CODEC_DMA_RX_7: return AFE_PORT_ID_RX_CODEC_DMA_RX_7; + case RT_PROXY_PORT_002_RX: + return RT_PROXY_PORT_002_RX; + case RT_PROXY_PORT_002_TX: + return RT_PROXY_PORT_002_TX; default: pr_warn("%s: Invalid port_id %d\n", __func__, port_id); return -EINVAL; @@ -1196,6 +1204,8 @@ int q6audio_validate_port(u16 port_id) case AFE_PORT_ID_TX_CODEC_DMA_TX_5: case AFE_PORT_ID_RX_CODEC_DMA_RX_6: case AFE_PORT_ID_RX_CODEC_DMA_RX_7: + case RT_PROXY_PORT_002_RX: + case RT_PROXY_PORT_002_TX: { ret = 0; break; diff --git a/techpack/audio/4.0/dsp/q6lsm.c b/techpack/audio/4.0/dsp/q6lsm.c index 8ad6ed624002..ca149618c8aa 100644 --- a/techpack/audio/4.0/dsp/q6lsm.c +++ b/techpack/audio/4.0/dsp/q6lsm.c @@ -2554,8 +2554,9 @@ int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc) out_params->buf_sz; allocate_size = PAGE_ALIGN(allocate_size); client->lab_buffer = - kzalloc(sizeof(struct lsm_lab_buffer) * - out_params->period_count, GFP_KERNEL); + kcalloc(out_params->period_count, + sizeof(struct lsm_lab_buffer), + GFP_KERNEL); if (!client->lab_buffer) { pr_err("%s: memory allocation for lab buffer failed count %d\n" , __func__, diff --git a/techpack/audio/4.0/dsp/q6usm.c b/techpack/audio/4.0/dsp/q6usm.c index cd024fce8139..94a88afe2aef 100644 --- a/techpack/audio/4.0/dsp/q6usm.c +++ b/techpack/audio/4.0/dsp/q6usm.c @@ -306,7 +306,7 @@ struct us_client *q6usm_us_client_alloc( if (usc == NULL) return NULL; - p_mem_handle = kzalloc(sizeof(uint32_t) * 4, GFP_KERNEL); + p_mem_handle = kcalloc(4, sizeof(uint32_t), GFP_KERNEL); if (p_mem_handle == NULL) { kfree(usc); return NULL; diff --git a/techpack/audio/4.0/include/dsp/apr_audio-v2.h b/techpack/audio/4.0/include/dsp/apr_audio-v2.h index cdc838ebb3a7..908ec649e462 100644 --- a/techpack/audio/4.0/include/dsp/apr_audio-v2.h +++ b/techpack/audio/4.0/include/dsp/apr_audio-v2.h @@ -1385,7 +1385,7 @@ struct adm_cmd_connect_afe_port_v5 { #define AFE_PORT_ID_SLIMBUS_RANGE_SIZE 0xA /* Size of the range of port IDs for real-time proxy ports. */ -#define AFE_PORT_ID_RT_PROXY_PORT_RANGE_SIZE 0x2 +#define AFE_PORT_ID_RT_PROXY_PORT_RANGE_SIZE 0x4 /* Size of the range of port IDs for pseudoports. */ #define AFE_PORT_ID_PSEUDOPORT_RANGE_SIZE 0x5 @@ -1664,6 +1664,16 @@ struct adm_cmd_connect_afe_port_v5 { #define AFE_PORT_ID_VOICE2_PLAYBACK_TX 0x8002 #define AFE_PORT_ID_VOICE_PLAYBACK_TX 0x8005 +/* + * Proxyport used for voice call data processing. + * In cases like call-screening feature, where user can communicate + * with caller with the help of "call screen" mode, and without + * connecting the call with any HW input/output devices in the phon, + * voice call can use Pseudo port to start voice data processing. + */ +#define RT_PROXY_PORT_002_TX 0x2003 +#define RT_PROXY_PORT_002_RX 0x2002 + #define AFE_PORT_ID_PRIMARY_TDM_RX \ (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x00) #define AFE_PORT_ID_PRIMARY_TDM_RX_1 \ diff --git a/techpack/audio/4.0/include/dsp/q6afe-v2.h b/techpack/audio/4.0/include/dsp/q6afe-v2.h index 9e1a0b2f44fb..73a7cf872a61 100644 --- a/techpack/audio/4.0/include/dsp/q6afe-v2.h +++ b/techpack/audio/4.0/include/dsp/q6afe-v2.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef __Q6AFE_V2_H__ #define __Q6AFE_V2_H__ @@ -284,6 +284,9 @@ enum { /* IDX 208-> 209 */ IDX_AFE_PORT_ID_PRIMARY_META_MI2S_RX, IDX_AFE_PORT_ID_SECONDARY_META_MI2S_RX, + /* IDX 210-> 211 */ + IDX_RT_PROXY_PORT_002_RX, + IDX_RT_PROXY_PORT_002_TX, AFE_MAX_PORTS }; diff --git a/techpack/audio/4.0/soc/pinctrl-wcd.c b/techpack/audio/4.0/soc/pinctrl-wcd.c index 437563f0a8a0..ff4c4718b8ab 100644 --- a/techpack/audio/4.0/soc/pinctrl-wcd.c +++ b/techpack/audio/4.0/soc/pinctrl-wcd.c @@ -331,7 +331,8 @@ static int wcd_pinctrl_probe(struct platform_device *pdev) goto err_name_alloc; } for (i = 0; i < npins; i++, pindesc++) { - name[i] = devm_kzalloc(dev, sizeof(char) * WCD_GPIO_STRING_LEN, + name[i] = devm_kzalloc(dev, + WCD_GPIO_STRING_LEN, GFP_KERNEL); if (!name[i]) { ret = -ENOMEM; diff --git a/techpack/audio/4.0/soc/swr-mstr-ctrl.c b/techpack/audio/4.0/soc/swr-mstr-ctrl.c index 847c90d71fb3..cfb6777cc30f 100644 --- a/techpack/audio/4.0/soc/swr-mstr-ctrl.c +++ b/techpack/audio/4.0/soc/swr-mstr-ctrl.c @@ -3204,8 +3204,8 @@ static int swrm_alloc_port_mem(struct device *dev, struct swr_mstr_ctrl *swrm, u32 uc, u32 size) { if (!swrm->port_param) { - swrm->port_param = devm_kzalloc(dev, - sizeof(swrm->port_param) * SWR_UC_MAX, + swrm->port_param = devm_kcalloc(dev, + SWR_UC_MAX, sizeof(swrm->port_param), GFP_KERNEL); if (!swrm->port_param) return -ENOMEM; diff --git a/techpack/audio/asoc/codecs/bolero/bolero-cdc.c b/techpack/audio/asoc/codecs/bolero/bolero-cdc.c index 02998fc4373a..7d5b1ccb0d58 100644 --- a/techpack/audio/asoc/codecs/bolero/bolero-cdc.c +++ b/techpack/audio/asoc/codecs/bolero/bolero-cdc.c @@ -288,10 +288,9 @@ static int bolero_copy_dais_from_macro(struct bolero_priv *priv) /* memcpy into bolero_dais all macro dais */ if (!priv->bolero_dais) - priv->bolero_dais = devm_kzalloc(priv->dev, - priv->num_dais * - sizeof( - struct snd_soc_dai_driver), + priv->bolero_dais = devm_kcalloc(priv->dev, + priv->num_dais, + sizeof(struct snd_soc_dai_driver), GFP_KERNEL); if (!priv->bolero_dais) return -ENOMEM; diff --git a/techpack/audio/asoc/codecs/sdm660_cdc/msm-analog-cdc.c b/techpack/audio/asoc/codecs/sdm660_cdc/msm-analog-cdc.c index abfa4b7e3f44..26827fb00075 100644 --- a/techpack/audio/asoc/codecs/sdm660_cdc/msm-analog-cdc.c +++ b/techpack/audio/asoc/codecs/sdm660_cdc/msm-analog-cdc.c @@ -4313,9 +4313,9 @@ static int msm_anlg_cdc_init_supplies(struct sdm660_cdc_priv *sdm660_cdc, int ret; int i; - sdm660_cdc->supplies = devm_kzalloc(sdm660_cdc->dev, - sizeof(struct regulator_bulk_data) * + sdm660_cdc->supplies = devm_kcalloc(sdm660_cdc->dev, ARRAY_SIZE(pdata->regulator), + sizeof(struct regulator_bulk_data), GFP_KERNEL); if (!sdm660_cdc->supplies) { ret = -ENOMEM; diff --git a/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c b/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c index 836ce927c2f4..ebd43dbaa9a5 100644 --- a/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c +++ b/techpack/audio/asoc/codecs/tfa98xx/src/tfa98xx.c @@ -2874,7 +2874,7 @@ enum Tfa98xx_Error tfa98xx_adsp_send_calib_values(void) if (tfa98xx_device_count == 1) { memcpy(&bytes[7], &bytes[4], sizeof(char)*3); } - pr_info("tfa98xx_device_count=%d bytes[0]=%d\n", tfa98xx_device_count, bytes[0]); + pr_debug("tfa98xx_device_count=%d bytes[0]=%d\n", tfa98xx_device_count, bytes[0]); /* we will send it to host DSP algorithm once calibraion value loaded from all device. */ if (tfa98xx_device_count == bytes[0]) { @@ -2902,7 +2902,7 @@ static int tfa98xx_send_mute_cmd(void) { uint8_t cmd[9] = {0x04, 0x81, 0x04, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff}; - pr_info("send mute command to host DSP.\n"); + pr_debug("send mute command to host DSP.\n"); return send_tfa_cal_in_band(&cmd[0], sizeof(cmd)); } #endif diff --git a/techpack/audio/asoc/codecs/wcd9xxx-core.c b/techpack/audio/asoc/codecs/wcd9xxx-core.c index f1b34b047251..312373339ad3 100644 --- a/techpack/audio/asoc/codecs/wcd9xxx-core.c +++ b/techpack/audio/asoc/codecs/wcd9xxx-core.c @@ -129,7 +129,7 @@ static int wcd9xxx_slim_multi_reg_write(struct wcd9xxx *wcd9xxx, if (num_regs == 0) return -EINVAL; - bulk_reg = kzalloc(num_regs * (sizeof(struct wcd9xxx_reg_val)), + bulk_reg = kcalloc(num_regs, sizeof(struct wcd9xxx_reg_val), GFP_KERNEL); if (!bulk_reg) return -ENOMEM; @@ -435,7 +435,7 @@ int wcd9xxx_slim_bulk_write(struct wcd9xxx *wcd9xxx, return 0; } - msgs = kzalloc(size * (sizeof(struct slim_val_inf)), GFP_KERNEL); + msgs = kcalloc(size, sizeof(struct slim_val_inf), GFP_KERNEL); if (!msgs) { ret = -ENOMEM; goto mem_fail; diff --git a/techpack/audio/asoc/msm-dai-q6-v2.c b/techpack/audio/asoc/msm-dai-q6-v2.c index 807b6332bd21..b79bdc23b740 100644 --- a/techpack/audio/asoc/msm-dai-q6-v2.c +++ b/techpack/audio/asoc/msm-dai-q6-v2.c @@ -2648,7 +2648,6 @@ static int msm_dai_q6_set_channel_map(struct snd_soc_dai *dai, return rc; } -/* all ports with excursion logging requirement can use this digital_mute api */ static int msm_dai_q6_spk_digital_mute(struct snd_soc_dai *dai, int mute) { @@ -4141,9 +4140,9 @@ static int msm_auxpcm_dev_probe(struct platform_device *pdev) } auxpcm_pdata->mode_8k.slot_mapping = - kzalloc(sizeof(uint16_t) * - auxpcm_pdata->mode_8k.num_slots, - GFP_KERNEL); + kcalloc(auxpcm_pdata->mode_8k.num_slots, + sizeof(uint16_t), + GFP_KERNEL); if (!auxpcm_pdata->mode_8k.slot_mapping) { dev_err(&pdev->dev, "%s No mem for mode_8k slot mapping\n", __func__); @@ -4156,9 +4155,9 @@ static int msm_auxpcm_dev_probe(struct platform_device *pdev) (u16)be32_to_cpu(slot_mapping_array[i]); auxpcm_pdata->mode_16k.slot_mapping = - kzalloc(sizeof(uint16_t) * - auxpcm_pdata->mode_16k.num_slots, - GFP_KERNEL); + kcalloc(auxpcm_pdata->mode_16k.num_slots, + sizeof(uint16_t), + GFP_KERNEL); if (!auxpcm_pdata->mode_16k.slot_mapping) { dev_err(&pdev->dev, "%s No mem for mode_16k slot mapping\n", @@ -10618,7 +10617,8 @@ static int msm_dai_q6_cdc_dma_prepare(struct snd_pcm_substream *substream, static void msm_dai_q6_cdc_dma_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); + struct msm_dai_q6_cdc_dma_dai_data *dai_data = + dev_get_drvdata(dai->dev); int rc = 0; if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { @@ -10637,6 +10637,19 @@ static void msm_dai_q6_cdc_dma_shutdown(struct snd_pcm_substream *substream, clear_bit(STATUS_PORT_STARTED, dai_data->hwfree_status); } +static int msm_dai_q6_cdc_dma_digital_mute(struct snd_soc_dai *dai, + int mute) +{ + int port_id = dai->id; + struct msm_dai_q6_cdc_dma_dai_data *dai_data = + dev_get_drvdata(dai->dev); + + if (mute && !dai_data->xt_logging_disable) + afe_get_sp_xt_logging_data(port_id); + + return 0; +} + static struct snd_soc_dai_ops msm_dai_q6_cdc_dma_ops = { .prepare = msm_dai_q6_cdc_dma_prepare, .hw_params = msm_dai_q6_cdc_dma_hw_params, @@ -10649,7 +10662,7 @@ static struct snd_soc_dai_ops msm_dai_q6_cdc_wsa_dma_ops = { .hw_params = msm_dai_q6_cdc_dma_hw_params, .shutdown = msm_dai_q6_cdc_dma_shutdown, .set_channel_map = msm_dai_q6_cdc_dma_set_channel_map, - .digital_mute = msm_dai_q6_spk_digital_mute, + .digital_mute = msm_dai_q6_cdc_dma_digital_mute, }; static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = { diff --git a/techpack/audio/asoc/msm-dai-slim.c b/techpack/audio/asoc/msm-dai-slim.c index e8bdf13fdc6c..906a86f6b007 100644 --- a/techpack/audio/asoc/msm-dai-slim.c +++ b/techpack/audio/asoc/msm-dai-slim.c @@ -500,8 +500,8 @@ static int msm_dai_slim_populate_dai_data(struct device *dev, SET_DAI_STATE(dai_data_t->status, DAI_STATE_INITIALIZED); - dai_data_t->chan_h = devm_kzalloc(dev, - sizeof(u16) * num_ch, + dai_data_t->chan_h = devm_kcalloc(dev, + num_ch, sizeof(u16), GFP_KERNEL); if (!dai_data_t->chan_h) { dev_err(dev, @@ -511,8 +511,8 @@ static int msm_dai_slim_populate_dai_data(struct device *dev, goto err_mem_alloc; } - dai_data_t->sh_ch = devm_kzalloc(dev, - sizeof(u16) * num_ch, + dai_data_t->sh_ch = devm_kcalloc(dev, + num_ch, sizeof(u16), GFP_KERNEL); if (!dai_data_t->sh_ch) { dev_err(dev, diff --git a/techpack/audio/asoc/msm-lsm-client.c b/techpack/audio/asoc/msm-lsm-client.c index 6cc8d43575c9..db355ec679f6 100644 --- a/techpack/audio/asoc/msm-lsm-client.c +++ b/techpack/audio/asoc/msm-lsm-client.c @@ -2535,7 +2535,7 @@ static int msm_lsm_send_ch_mix_config(struct snd_pcm_substream *substream) return 0; } - ch_wght_coeff = kzalloc(in_params->num_chs * pp_ch_cnt * sizeof(int), + ch_wght_coeff = kcalloc(in_params->num_chs * pp_ch_cnt, sizeof(int), GFP_KERNEL); if (!ch_wght_coeff) return -ENOMEM; diff --git a/techpack/audio/dsp/elliptic/elliptic.c b/techpack/audio/dsp/elliptic/elliptic.c index 4d018c1b8abc..8cb5f9d219c5 100755 --- a/techpack/audio/dsp/elliptic/elliptic.c +++ b/techpack/audio/dsp/elliptic/elliptic.c @@ -726,7 +726,7 @@ int __init elliptic_driver_init(void) goto fail; elliptic_devices = (struct elliptic_device *) - kzalloc(sizeof(struct elliptic_device) * ELLIPTIC_NUM_DEVICES, + kcalloc(ELLIPTIC_NUM_DEVICES, sizeof(struct elliptic_device), GFP_KERNEL); if (elliptic_devices == NULL) { diff --git a/techpack/audio/dsp/msm-cirrus-playback.c b/techpack/audio/dsp/msm-cirrus-playback.c index 8add0c570a5c..d074740c823e 100755 --- a/techpack/audio/dsp/msm-cirrus-playback.c +++ b/techpack/audio/dsp/msm-cirrus-playback.c @@ -1141,7 +1141,7 @@ int crus_afe_port_start(u16 port_id) { EXPORT_SYMBOL(crus_afe_port_start); int crus_afe_port_close(u16 port_id) { - pr_info("%s: 0x%x\n", __func__, port_id); + pr_debug("%s: 0x%x\n", __func__, port_id); //CSPL do not be involved in AFE #if 0 @@ -1161,7 +1161,7 @@ static long crus_sp_shared_ioctl(struct file *f, unsigned int cmd, uint32_t bufsize = 0, size; void *io_data = NULL; - pr_info("%s\n", __func__); + pr_debug("%s\n", __func__); if (copy_from_user(&size, arg, sizeof(size))) { pr_err("CRUS_SP: copy_from_user (size) failed\n"); @@ -1223,7 +1223,7 @@ static long crus_sp_shared_ioctl(struct file *f, unsigned int cmd, port = this_ctrl.ff_port; break; default: - pr_info("%s: Unrecognized port ID (%d)\n", __func__, + pr_debug("%s: Unrecognized port ID (%d)\n", __func__, crus_sp_hdr.module_id); port = this_ctrl.ff_port; } @@ -1252,7 +1252,7 @@ exit: static long crus_sp_ioctl(struct file *f, unsigned int cmd, unsigned long arg) { - pr_info("%s\n", __func__); + pr_debug("%s\n", __func__); return crus_sp_shared_ioctl(f, cmd, (void __user *)arg); } @@ -1262,7 +1262,7 @@ static long crus_sp_compat_ioctl(struct file *f, { unsigned int cmd64; - pr_info("%s\n", __func__); + pr_debug("%s\n", __func__); switch (cmd) { case CRUS_SP_IOCTL_GET32: diff --git a/techpack/audio/dsp/q6asm.c b/techpack/audio/dsp/q6asm.c index f89b01565870..34cf5768745e 100644 --- a/techpack/audio/dsp/q6asm.c +++ b/techpack/audio/dsp/q6asm.c @@ -311,7 +311,7 @@ static ssize_t audio_output_latency_dbgfs_write(struct file *file, pr_err("%s: err count is more %zd\n", __func__, count); return -EINVAL; } - temp = kmalloc(2*sizeof(char), GFP_KERNEL); + temp = kmalloc(2, GFP_KERNEL); out_cold_index = 0; @@ -367,7 +367,7 @@ static ssize_t audio_input_latency_dbgfs_write(struct file *file, pr_err("%s: err count is more %zd\n", __func__, count); return -EINVAL; } - temp = kmalloc(2*sizeof(char), GFP_KERNEL); + temp = kmalloc(2, GFP_KERNEL); if (temp) { if (copy_from_user(temp, buf, 2*sizeof(char))) { @@ -8328,7 +8328,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir, return -EINVAL; } - buffer_node = kzalloc(sizeof(struct asm_buffer_node) * bufcnt, + buffer_node = kcalloc(bufcnt, sizeof(struct asm_buffer_node), GFP_KERNEL); if (!buffer_node) return -ENOMEM; diff --git a/techpack/audio/dsp/q6lsm.c b/techpack/audio/dsp/q6lsm.c index aa864ddbee7b..dd6801af4e5e 100644 --- a/techpack/audio/dsp/q6lsm.c +++ b/techpack/audio/dsp/q6lsm.c @@ -2476,8 +2476,9 @@ int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc) out_params->buf_sz; allocate_size = PAGE_ALIGN(allocate_size); client->lab_buffer = - kzalloc(sizeof(struct lsm_lab_buffer) * - out_params->period_count, GFP_KERNEL); + kcalloc(out_params->period_count, + sizeof(struct lsm_lab_buffer), + GFP_KERNEL); if (!client->lab_buffer) { pr_err("%s: memory allocation for lab buffer failed count %d\n" , __func__, diff --git a/techpack/audio/dsp/q6usm.c b/techpack/audio/dsp/q6usm.c index 61e3bb96596b..e6d5a6779d80 100644 --- a/techpack/audio/dsp/q6usm.c +++ b/techpack/audio/dsp/q6usm.c @@ -314,7 +314,7 @@ struct us_client *q6usm_us_client_alloc( if (usc == NULL) return NULL; - p_mem_handle = kzalloc(sizeof(uint32_t) * 4, GFP_KERNEL); + p_mem_handle = kcalloc(4, sizeof(uint32_t), GFP_KERNEL); if (p_mem_handle == NULL) { kfree(usc); return NULL; diff --git a/techpack/audio/soc/pinctrl-wcd.c b/techpack/audio/soc/pinctrl-wcd.c index d7695dbe77b8..18881f09d566 100644 --- a/techpack/audio/soc/pinctrl-wcd.c +++ b/techpack/audio/soc/pinctrl-wcd.c @@ -339,7 +339,8 @@ static int wcd_pinctrl_probe(struct platform_device *pdev) goto err_name_alloc; } for (i = 0; i < npins; i++, pindesc++) { - name[i] = devm_kzalloc(dev, sizeof(char) * WCD_GPIO_STRING_LEN, + name[i] = devm_kzalloc(dev, + WCD_GPIO_STRING_LEN, GFP_KERNEL); if (!name[i]) { ret = -ENOMEM; diff --git a/techpack/data/drivers/emac-dwc-eqos/DWC_ETH_QOS_desc.c b/techpack/data/drivers/emac-dwc-eqos/DWC_ETH_QOS_desc.c index 3ee861820615..c9ae8247729e 100644 --- a/techpack/data/drivers/emac-dwc-eqos/DWC_ETH_QOS_desc.c +++ b/techpack/data/drivers/emac-dwc-eqos/DWC_ETH_QOS_desc.c @@ -127,8 +127,9 @@ static int DWC_ETH_QOS_alloc_rx_queue_struct(struct DWC_ETH_QOS_prv_data *pdata) DBGPR("rx_queue_cnt = %d\n", pdata->rx_queue_cnt); pdata->rx_queue = - kzalloc(sizeof(struct DWC_ETH_QOS_rx_queue) * pdata->rx_queue_cnt, - GFP_KERNEL); + kcalloc(pdata->rx_queue_cnt, + sizeof(struct DWC_ETH_QOS_rx_queue), + GFP_KERNEL); if (pdata->rx_queue == NULL) { IPCERR_RL("ERROR: Unable to allocate Rx queue structure\n"); ret = -ENOMEM; @@ -144,7 +145,8 @@ static int DWC_ETH_QOS_alloc_rx_queue_struct(struct DWC_ETH_QOS_prv_data *pdata) /* Alocate rx_desc_ptrs */ rx_desc_data->rx_desc_ptrs = - kzalloc(sizeof(struct s_RX_NORMAL_DESC *) * pdata->rx_queue[chInx].desc_cnt, + kcalloc(pdata->rx_queue[chInx].desc_cnt, + sizeof(struct s_RX_NORMAL_DESC *), GFP_KERNEL); if (rx_desc_data->rx_desc_ptrs == NULL) { IPCERR_RL("ERROR: Unable to allocate Rx Desc ptrs\n"); @@ -159,7 +161,8 @@ static int DWC_ETH_QOS_alloc_rx_queue_struct(struct DWC_ETH_QOS_prv_data *pdata) /* Alocate rx_desc_dma_addrs */ rx_desc_data->rx_desc_dma_addrs = - kzalloc(sizeof(dma_addr_t) *pdata->rx_queue[chInx].desc_cnt, + kcalloc(pdata->rx_queue[chInx].desc_cnt, + sizeof(dma_addr_t), GFP_KERNEL); if (rx_desc_data->rx_desc_dma_addrs == NULL) { IPCERR_RL("ERROR: Unable to allocate Rx Desc dma addr\n"); @@ -174,7 +177,8 @@ static int DWC_ETH_QOS_alloc_rx_queue_struct(struct DWC_ETH_QOS_prv_data *pdata) /* Alocate rx_buf_ptrs */ rx_desc_data->rx_buf_ptrs = - kzalloc(sizeof(struct DWC_ETH_QOS_rx_buffer *) * pdata->rx_queue[chInx].desc_cnt, + kcalloc(pdata->rx_queue[chInx].desc_cnt, + sizeof(struct DWC_ETH_QOS_rx_buffer *), GFP_KERNEL); if (rx_desc_data->rx_buf_ptrs == NULL) { IPCERR_RL("ERROR: Unable to allocate Rx Desc dma addr\n"); @@ -190,7 +194,9 @@ static int DWC_ETH_QOS_alloc_rx_queue_struct(struct DWC_ETH_QOS_prv_data *pdata) if (pdata->ipa_enabled) { /* Allocate ipa_rx_buff_pool_va_addrs_base */ rx_desc_data->ipa_rx_buff_pool_va_addrs_base = - kzalloc(sizeof(void *) * pdata->rx_queue[chInx].desc_cnt, GFP_KERNEL); + kcalloc(pdata->rx_queue[chInx].desc_cnt, + sizeof(void *), + GFP_KERNEL); if (rx_desc_data->ipa_rx_buff_pool_va_addrs_base == NULL) { IPCERR_RL("ERROR: Unable to allocate Rx ipa buff addrs\n"); ret = -ENOMEM; @@ -271,8 +277,9 @@ static int DWC_ETH_QOS_alloc_tx_queue_struct(struct DWC_ETH_QOS_prv_data *pdata) DBGPR("tx_queue_cnt = %d", pdata->tx_queue_cnt); pdata->tx_queue = - kzalloc(sizeof(struct DWC_ETH_QOS_tx_queue) * pdata->tx_queue_cnt, - GFP_KERNEL); + kcalloc(pdata->tx_queue_cnt, + sizeof(struct DWC_ETH_QOS_tx_queue), + GFP_KERNEL); if (pdata->tx_queue == NULL) { IPCERR_RL("ERROR: Unable to allocate Tx queue structure\n"); ret = -ENOMEM; @@ -288,7 +295,8 @@ static int DWC_ETH_QOS_alloc_tx_queue_struct(struct DWC_ETH_QOS_prv_data *pdata) /* Allocate tx_desc_ptrs */ tx_desc_data->tx_desc_ptrs = - kzalloc(sizeof(struct s_TX_NORMAL_DESC *) * pdata->tx_queue[chInx].desc_cnt, + kcalloc(pdata->tx_queue[chInx].desc_cnt, + sizeof(struct s_TX_NORMAL_DESC *), GFP_KERNEL); if (tx_desc_data->tx_desc_ptrs == NULL) { IPCERR_RL("ERROR: Unable to allocate Tx Desc ptrs\n"); @@ -302,7 +310,8 @@ static int DWC_ETH_QOS_alloc_tx_queue_struct(struct DWC_ETH_QOS_prv_data *pdata) /* Allocate tx_desc_dma_addrs */ tx_desc_data->tx_desc_dma_addrs = - kzalloc(sizeof(dma_addr_t) * pdata->tx_queue[chInx].desc_cnt, + kcalloc(pdata->tx_queue[chInx].desc_cnt, + sizeof(dma_addr_t), GFP_KERNEL); if (tx_desc_data->tx_desc_dma_addrs == NULL) { IPCERR_RL("ERROR: Unable to allocate Tx Desc dma addrs\n"); @@ -316,7 +325,8 @@ static int DWC_ETH_QOS_alloc_tx_queue_struct(struct DWC_ETH_QOS_prv_data *pdata) /* Allocate tx_buf_ptrs */ tx_desc_data->tx_buf_ptrs = - kzalloc(sizeof(struct DWC_ETH_QOS_tx_buffer *) * pdata->tx_queue[chInx].desc_cnt, + kcalloc(pdata->tx_queue[chInx].desc_cnt, + sizeof(struct DWC_ETH_QOS_tx_buffer *), GFP_KERNEL); if (tx_desc_data->tx_buf_ptrs == NULL) { IPCERR_RL("ERROR: Unable to allocate Tx buff ptrs\n"); @@ -331,7 +341,9 @@ static int DWC_ETH_QOS_alloc_tx_queue_struct(struct DWC_ETH_QOS_prv_data *pdata) if (pdata->ipa_enabled) { /* Allocate ipa_tx_buff_pool_va_addrs_base */ tx_desc_data->ipa_tx_buff_pool_va_addrs_base = - kzalloc(sizeof(void *) * pdata->tx_queue[chInx].desc_cnt,GFP_KERNEL); + kcalloc(pdata->tx_queue[chInx].desc_cnt, + sizeof(void *), + GFP_KERNEL); if (tx_desc_data->ipa_tx_buff_pool_va_addrs_base == NULL) { IPCERR_RL("ERROR: Unable to allocate Tx ipa buff addrs\n"); ret = -ENOMEM; diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index ce786f363476..ae63bdf9051b 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -641,7 +641,6 @@ static const struct { { "__GFP_ATOMIC", "_A" }, { "__GFP_IO", "I" }, { "__GFP_FS", "F" }, - { "__GFP_COLD", "CO" }, { "__GFP_NOWARN", "NWR" }, { "__GFP_RETRY_MAYFAIL", "R" }, { "__GFP_NOFAIL", "NF" }, diff --git a/tools/testing/selftests/networking/timestamping/rxtimestamp.c b/tools/testing/selftests/networking/timestamping/rxtimestamp.c index 7a573fb4c1c4..c6428f1ac22f 100644 --- a/tools/testing/selftests/networking/timestamping/rxtimestamp.c +++ b/tools/testing/selftests/networking/timestamping/rxtimestamp.c @@ -328,8 +328,7 @@ int main(int argc, char **argv) bool all_tests = true; int arg_index = 0; int failures = 0; - int s, t; - char opt; + int s, t, opt; while ((opt = getopt_long(argc, argv, "", long_options, &arg_index)) != -1) { diff --git a/update b/update new file mode 100644 index 000000000000..9f478d970f58 --- /dev/null +++ b/update @@ -0,0 +1,10 @@ +#!/bin/bash +OUT_DIR=out/ + +make ARCH=arm64 \ + O=${OUT_DIR} \ + raphael_defconfig \ + -j$(nproc --all) + +mv out/.config arch/arm64/configs/raphael_defconfig +git diff diff --git a/updatedefconfig b/updatedefconfig index 95b6ff52c022..b24306bf40ba 100644 --- a/updatedefconfig +++ b/updatedefconfig @@ -4,9 +4,10 @@ OUT_DIR=out/ make ARCH=arm64 \ O=${OUT_DIR} \ raphael_defconfig \ - -j4 + -j8 cp ${OUT_DIR}/.config arch/arm64/configs/raphael_defconfig -git add arch/ +git add arch/arm64/configs/raphael_defconfig + git commit -s -m "ARM64: configs: raphael: Update defconfig" diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 71f77ae6c2a6..60dad2a6cfbc 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -3167,7 +3167,7 @@ static long kvm_vm_ioctl(struct file *filp, goto out; if (routing.nr) { r = -ENOMEM; - entries = vmalloc(routing.nr * sizeof(*entries)); + entries = vmalloc(array_size(sizeof(*entries), routing.nr)); if (!entries) goto out; r = -EFAULT;