------------------ Note, this is the LAST release for the 6.3.y kernel series. After this is released, it will be end-of-life. Please move to the 6.4.y kernel series at this point in time, OR let us know what is preventing that from happening for you. ------------------
This is the start of the stable review cycle for the 6.3.13 release. There are 431 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue, 11 Jul 2023 11:14:03 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.3.13-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.3.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 6.3.13-rc1
Yu Kuai yukuai3@huawei.com md/raid1-10: fix casting from randomized structure in raid1_submit_write()
Thomas Gleixner tglx@linutronix.de x86/efi: Make efi_set_virtual_address_map IBT safe
Will Deacon will@kernel.org arm64: sme: Use STR P to clear FFR context field in streaming SVE mode
Arnd Bergmann arnd@arndb.de ksmbd: avoid field overflow warning
Paulo Alcantara pc@manguebit.com smb: client: fix shared DFS root mounts with different prefixes
Paulo Alcantara pc@manguebit.com smb: client: fix broken file attrs with nodfs mounts
Shyam Prasad N sprasad@microsoft.com cifs: do all necessary checks for credits within or before locking
Shyam Prasad N sprasad@microsoft.com cifs: prevent use-after-free by freeing the cfile later
Ard Biesheuvel ardb@kernel.org efi/libstub: Disable PCI DMA before grabbing the EFI memory map
Masahiro Yamada masahiroy@kernel.org kbuild: deb-pkg: remove the CONFIG_MODULES check in buildeb
Josh Triplett josh@joshtriplett.org kbuild: builddeb: always make modules_install, to install modules.builtin*
Dan Williams dan.j.williams@intel.com cxl/region: Fix state transitions after reset failure
Dan Williams dan.j.williams@intel.com cxl/region: Flag partially torn down regions as unusable
Dan Williams dan.j.williams@intel.com cxl/region: Move cache invalidation before region teardown, and before setup
Sami Tolvanen samitolvanen@google.com kbuild: Disable GCOV for *.mod.o
Sami Tolvanen samitolvanen@google.com kbuild: Fix CFI failures with GCOV
Martin Kaiser martin@kaiser.cx hwrng: st - keep clock enabled while hwrng is registered
Tarun Sahu tsahu@linux.ibm.com dax/kmem: Pass valid argument to memory_group_register_static
Dan Williams dan.j.williams@intel.com dax: Introduce alloc_dev_dax_id()
Dan Williams dan.j.williams@intel.com dax: Fix dax_mapping_release() use after free
Bharath SM bharathsm@microsoft.com SMB3: Do not send lease break acknowledgment if all file handles have been closed
Olga Kornievskaia kolga@netapp.com NFSv4.1: freeze the session table upon receiving NFS4ERR_BADSESSION
Qi Zheng zhengqi.arch@bytedance.com NFSv4.2: fix wrong shrinker_id
Hareshx Sankar Raj hareshx.sankar.raj@intel.com crypto: qat - unmap buffers before free for RSA
Hareshx Sankar Raj hareshx.sankar.raj@intel.com crypto: qat - unmap buffer before free for DH
Masahiro Yamada masahiroy@kernel.org ARC: define ASM_NL and __ALIGN(_STR) outside #ifdef __ASSEMBLY__ guard
Dan Carpenter dan.carpenter@linaro.org modpost: fix off by one in is_executable_section()
Stephan Müller smueller@chronox.de crypto: jitter - correct health test during initialization
Arnd Bergmann arnd@arndb.de crypto: marvell/cesa - Fix type mismatch warning
Masahiro Yamada masahiroy@kernel.org modpost: fix section mismatch message for R_ARM_{PC24,CALL,JUMP24}
Masahiro Yamada masahiroy@kernel.org modpost: fix section mismatch message for R_ARM_ABS32
Randy Dunlap rdunlap@infradead.org crypto: nx - fix build warnings when DEBUG_FS is not enabled
Masahiro Yamada masahiroy@kernel.org modpost: remove broken calculation of exception_table_entry size
Herbert Xu herbert@gondor.apana.org.au hwrng: virtio - Fix race on data_avail and actual data
Eric Farman farman@linux.ibm.com vfio/mdev: Move the compat_class initialization to module init
Xinghui Li korantli@tencent.com PCI: vmd: Fix uninitialized variable usage in vmd_enable_domain()
Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com PCI: endpoint: functions/pci-epf-test: Fix dma_chan direction
Shunsuke Mie mie@igel.co.jp PCI: endpoint: Fix a Kconfig prompt of vNTB driver
Namhyung Kim namhyung@kernel.org perf test: Set PERF_EXEC_PATH for script execution
Aneesh Kumar K.V aneesh.kumar@linux.ibm.com powerpc/mm/dax: Fix the condition when checking if altmap vmemap can cross-boundary
Aneesh Kumar K.V aneesh.kumar@linux.ibm.com powerpc/book3s64/mm: Fix DirectMap stats in /proc/meminfo
Tiezhu Yang yangtiezhu@loongson.cn riscv: uprobes: Restore thread.bad_cause
Xi Pardee xi.pardee@intel.com platform/x86:intel/pmc: Update maps for Meteor Lake P/M platforms
Aditya Gupta adityag@linux.ibm.com powerpc: update ppc_save_regs to save current r1 in pt_regs
Colin Ian King colin.i.king@gmail.com powerpc/powernv/sriov: perform null check on iov before dereferencing iov
Stanley Chu stanley.chu@mediatek.com scsi: ufs: core: mcq: Fix the incorrect OCS value for the device command
Bart Van Assche bvanassche@acm.org scsi: ufs: core: Remove a ufshcd_add_command_trace() call
Namhyung Kim namhyung@kernel.org perf stat: Reset aggr stats for each run
Claudiu Beznea claudiu.beznea@microchip.com pinctrl: at91-pio4: check return value of devm_kasprintf()
Claudiu Beznea claudiu.beznea@microchip.com pinctrl: microchip-sgpio: check return value of devm_kasprintf()
Xiaolei Wang xiaolei.wang@windriver.com pinctrl: freescale: Fix a memory out of bounds when num_configs is 1
Nicholas Piggin npiggin@gmail.com powerpc/64s: Fix VAS mm use after free
Ian Rogers irogers@google.com perf tool x86: Fix perf_env memory leak
Ravi Bangoria ravi.bangoria@amd.com perf tool x86: Consolidate is_amd check into single function
Michal Wilczynski michal.wilczynski@intel.com platform/x86/dell/dell-rbtn: Fix resources leaking on error path
Aditya Gupta adityag@linux.ibm.com perf tests task_analyzer: Skip tests if no libtraceevent support
Aditya Gupta adityag@linux.ibm.com perf tests task_analyzer: Fix bad substitution ${$1}
Namhyung Kim namhyung@kernel.org perf dwarf-aux: Fix off-by-one in die_get_varname()
Mark Pearson mpearson-lenovo@squebb.ca platform/x86: thinkpad_acpi: Fix lkp-tests warnings for platform profiles
Arnaldo Carvalho de Melo acme@redhat.com perf script: Fix allocation of evsel->priv related to per-event dump files
Christophe Leroy christophe.leroy@csgroup.eu powerpc/signal32: Force inlining of __unsafe_save_user_regs() and save_tm_user_regs_unsafe()
Christophe Leroy christophe.leroy@csgroup.eu powerpc/interrupt: Don't read MSR from interrupt_exit_kernel_prepare()
Christophe Leroy christophe.leroy@csgroup.eu kcsan: Don't expect 64 bits atomic builtins from 32 bits architectures
Jiasheng Jiang jiasheng@iscas.ac.cn pinctrl: npcm7xx: Add missing check for ioremap
Wells Lu wellslutw@gmail.com pinctrl:sunplus: Add check for kmalloc
Mark Pearson mpearson-lenovo@squebb.ca platform/x86: think-lmi: Correct NVME password handling
Mark Pearson mpearson-lenovo@squebb.ca platform/x86: think-lmi: Correct System password interface
Mark Pearson mpearson-lenovo@squebb.ca platform/x86: think-lmi: mutex protection around multiple WMI calls
Xi Pardee xi.pardee@intel.com platform/x86:intel/pmc: Remove Meteor Lake S platform support
Andy Shevchenko andriy.shevchenko@linux.intel.com pinctrl: cherryview: Return correct value if pin in push-pull mode
Arnaldo Carvalho de Melo acme@redhat.com perf bench: Add missing setlocale() call to allow usage of %'d style formatting
Thierry Reding treding@nvidia.com pinctrl: tegra: Duplicate pinmux functions table
Bart Van Assche bvanassche@acm.org scsi: ufs: core: Fix handling of lrbp->cmd
Bart Van Assche bvanassche@acm.org scsi: ufs: core: Increase the START STOP UNIT timeout from one to ten seconds
Justin Tee justin.tee@broadcom.com scsi: lpfc: Revise NPIV ELS unsol rcv cmpl logic to drop ndlp based on nlp_state
Sui Jingfeng suijingfeng@loongson.cn PCI: Add pci_clear_master() stub for non-CONFIG_PCI
Bart Van Assche bvanassche@acm.org scsi: ufs: Declare ufshcd_{hold,release}() once
Wells Lu wellslutw@gmail.com pinctrl: sunplus: Add check for kmalloc
Junyan Ye yejunyan@hust.edu.cn PCI: ftpci100: Release the clock resources
Ian Rogers irogers@google.com perf evsel: Don't let for_each_group() treat the head of the list as one of its nodes
Rongguang Wei weirongguang@kylinos.cn PCI: pciehp: Cancel bringup sequence if card is not present
Dan Carpenter dan.carpenter@linaro.org pinctrl: at91: fix a couple NULL vs IS_ERR() checks
Andy Shevchenko andriy.shevchenko@linux.intel.com pinctrl: at91: Use dev_err_probe() instead of custom messaging
Andy Shevchenko andriy.shevchenko@linux.intel.com pinctrl: at91: Don't mix non-devm calls with devm ones
Yuchen Yang u202114568@hust.edu.cn scsi: 3w-xxxx: Add error handling for initialization failure in tw_probe()
Ding Hui dinghui@sangfor.com.cn PCI/ASPM: Disable ASPM on MFD function removal to avoid use-after-free
Hans de Goede hdegoede@redhat.com platform/x86: lenovo-yogabook: Set default keyboard backligh brightness on probe()
Hans de Goede hdegoede@redhat.com platform/x86: lenovo-yogabook: Reprobe devices on remove()
Hans de Goede hdegoede@redhat.com platform/x86: lenovo-yogabook: Fix work race on remove()
Christophe JAILLET christophe.jaillet@wanadoo.fr pinctrl: bcm2835: Handle gpiochip_add_pin_range() errors
Jinhong Zhu jinhongzhu@hust.edu.cn scsi: qedf: Fix NULL dereference in error handling
Nirmal Patel nirmal.patel@linux.intel.com PCI: vmd: Reset VMD config register between soft reboots
Siddharth Vadapalli s-vadapalli@ti.com PCI: cadence: Fix Gen2 Link Retraining process
Jason Gunthorpe jgg@ziepe.ca iommufd: Call iopt_area_contig_done() under the lock
Jason Gunthorpe jgg@ziepe.ca iommufd: Do not access the area pointer after unlocking
Paul Cercueil paul@crapouillou.net MIPS: DTS: CI20: Raise VDDCORE voltage to 1.125 volts
Paul Cercueil paul@crapouillou.net MIPS: DTS: CI20: Add parent supplies to ACT8600 regulators
Syed Saba Kareem Syed.SabaKareem@amd.com ASoC: amd: acp: clear pdm dma interrupt mask
Michael Walle mwalle@kernel.org ARM: dts: lan966x: kontron-d10: fix SPI CS
Michael Walle mwalle@kernel.org ARM: dts: lan966x: kontron-d10: fix board reset
Fei Shao fshao@chromium.org clk: Fix memory leak in devm_clk_notifier_register()
Claudiu Beznea claudiu.beznea@microchip.com ASoC: imx-audmix: check return value of devm_kasprintf()
Amir Goldstein amir73il@gmail.com ovl: update of dentry revalidate flags after copy up
Alexey Romanov avromanov@sberdevices.ru drivers: meson: secure-pwrc: always enable DMA domain
Claudiu Beznea claudiu.beznea@microchip.com clk: ti: clkctrl: check return value of kasprintf()
Claudiu Beznea claudiu.beznea@microchip.com clk: keystone: sci-clk: check return value of kasprintf()
Claudiu Beznea claudiu.beznea@microchip.com clk: si5341: free unused memory on probe failure
Claudiu Beznea claudiu.beznea@microchip.com clk: si5341: check return value of {devm_}kasprintf()
Claudiu Beznea claudiu.beznea@microchip.com clk: si5341: return error if one synth clock registration fails
Claudiu Beznea claudiu.beznea@microchip.com clk: cdce925: check return value of kasprintf()
Claudiu Beznea claudiu.beznea@microchip.com clk: vc5: check memory returned by kasprintf()
AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com clk: mediatek: clk-mt8173-apmixedsys: Fix iomap not released issue
AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com clk: mediatek: clk-mt8173-apmixedsys: Fix return value for of_iomap() error
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/msm/dpu: correct MERGE_3D length
Luben Tuikov luben.tuikov@amd.com drm/amdgpu: Fix usage of UMC fill record in RAS
Srinivasan Shanmugam srinivasan.shanmugam@amd.com drm/amdgpu: Fix memcpy() in sienna_cichlid_append_powerplay_table function.
Daniel Golle daniel@makrotopia.org arm64: dts: mt7986: increase bl2 partition on NAND of Bananapi R3
Nícolas F. R. A. Prado nfraprado@collabora.com arm64: dts: mediatek: mt8192: Fix CPUs capacity-dmips-mhz
Allen-KH Cheng allen-kh.cheng@mediatek.com arm64: dts: mediatek: Add cpufreq nodes for MT8192
Bjorn Andersson quic_bjorande@quicinc.com drm/msm/dp: Free resources after unregistering them
Bjorn Andersson quic_bjorande@quicinc.com drm/msm/dp: Drop aux devices together with DP controller
Jessica Zhang quic_jesszhan@quicinc.com drm/msm/dsi: Remove incorrect references to slice_count
Jessica Zhang quic_jesszhan@quicinc.com drm/msm/dpu: Fix slice_last_group_size calculation
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/msm/dpu: do not enable color-management if DSPPs are not available
Su Hui suhui@nfschina.com ALSA: ac97: Fix possible NULL dereference in snd_ac97_mixer
Nishanth Menon nm@ti.com arm64: dts: ti: k3-am69-sk: Fix main_i2c0 alias
Thejasvi Konduru t-konduru@ti.com arm64: dts: ti: k3-j784s4: Fix wakeup pinmux range and pinctrl node offsets
Siddharth Vadapalli s-vadapalli@ti.com arm64: dts: ti: k3-j784s4-evm: Enable MCU CPSW2G
Nishanth Menon nm@ti.com arm64: dts: ti: k3-j784s4-evm: Fix main_i2c0 alias
Andrew Davis afd@ti.com arm64: dts: ti: k3-j721e-beagleboneai64: Fix mailbox node status
Yuan Can yuancan@huawei.com clk: tegra: tegra124-emc: Fix potential memory leak
Dan Carpenter dan.carpenter@linaro.org clk: clocking-wizard: Fix Oops in clk_wzrd_register_divider()
Dan Carpenter dan.carpenter@linaro.org clk: bcm: rpi: Fix off by one in raspberrypi_discover_clocks()
Abel Vesa abel.vesa@linaro.org arm64: dts: qcom: sm8550: Add missing interconnect path to USB HC
Marijn Suijten marijn.suijten@somainline.org arm64: dts: qcom: sm8250-edo: Panel framebuffer is 2.5k instead of 4k
Konrad Dybcio konrad.dybcio@linaro.org arm64: dts: qcom: sm8550: Flush RSC sleep & wake votes
Konrad Dybcio konrad.dybcio@linaro.org arm64: dts: qcom: sdm845: Flush RSC sleep & wake votes
Konrad Dybcio konrad.dybcio@linaro.org arm64: dts: qcom: sdm670: Flush RSC sleep & wake votes
Konrad Dybcio konrad.dybcio@linaro.org arm64: dts: qcom: qdu1000: Flush RSC sleep & wake votes
Bosi Zhang u201911157@hust.edu.cn clk: mediatek: fix of_iomap memory leak
Yuxing Liu lyx2022@hust.edu.cn clk: imx: clk-imx8mp: improve error handling in imx8mp_clocks_probe()
Zhanhao Hu zero12113@hust.edu.cn clk: imx93: fix memory leak and missing unwind goto in imx93_clocks_probe
Hao Luo m202171776@hust.edu.cn clk: imx: clk-imx8mn: fix memory leak in imx8mn_clocks_probe
Kai Ma kaima@hust.edu.cn clk: imx: clk-imxrt1050: fix memory leak in imxrt1050_clocks_probe
Kashyap Desai kashyap.desai@broadcom.com RDMA/bnxt_re: Avoid calling wake_up threads from spin_lock context
Kashyap Desai kashyap.desai@broadcom.com RDMA/bnxt_re: wraparound mbox producer index
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/msm/a5xx: really check for A510 in a5xx_gpu_init
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/msm/a6xx: don't set IO_PGTABLE_QUIRK_ARM_OUTER_WBWA with coherent SMMU
Chia-I Wu olvaffe@gmail.com amdgpu: validate offset_in_bo of drm_amdgpu_gem_va
Bob Pearson rpearsonhpe@gmail.com RDMA/rxe: Fix access checks in rxe_check_bind_mw
Geert Uytterhoeven geert+renesas@glider.be HID: uclogic: Modular KUnit tests should not depend on KUNIT=y
Nikita Zhandarovich n.zhandarovich@fintech.ru drm/radeon: fix possible division-by-zero errors
Aurabindo Pillai aurabindo.pillai@amd.com drm/amd/display: Fix artifacting on eDP panels when engaging freesync video mode
Chen-Yu Tsai wenst@chromium.org soc: mediatek: SVS: Fix MT8192 GPU node name
Daniil Dulov d.dulov@aladdin.ru drm/amdkfd: Fix potential deallocation of previously deallocated memory.
Christophe JAILLET christophe.jaillet@wanadoo.fr drm/amd/display: Fix a test dml32_rq_dlg_get_rq_reg()
Christophe JAILLET christophe.jaillet@wanadoo.fr drm/amd/display: Fix a test CalculatePrefetchSchedule()
Paul Cercueil paul@crapouillou.net MIPS: DTS: CI20: Fix ACT8600 regulator node names
Maxime Ripard maxime@cerno.tech clk: Export clk_hw_forward_rate_request()
Christian Lamparter chunkeey@gmail.com ARM: dts: BCM5301X: fix duplex-full => full-duplex
Guenter Roeck linux@roeck-us.net hwmon: (pmbus/adm1275) Fix problems with temperature monitoring on ADM1272
Tim Harvey tharvey@gateworks.com hwmon: (gsc-hwmon) fix fan pwm temperature scaling
Olivier Moysan olivier.moysan@foss.st.com ARM: dts: stm32: fix i2s endpoint format property for stm32mp15xx-dkx
Marek Vasut marex@denx.de ARM: dts: stm32: Fix audio routing on STM32MP15xx DHCOM PDK2
Caleb Connolly caleb.connolly@linaro.org Input: pm8941-powerkey - fix debounce on gen2+ PMICs
Keerthy j-keerthy@ti.com arm64: dts: ti: k3-j7200: Fix physical address of pin
Christophe JAILLET christophe.jaillet@wanadoo.fr fbdev: omapfb: lcd_mipid: Fix an error handling path in mipid_spi_probe()
Kuogee Hsieh quic_khsieh@quicinc.com drm/msm/dpu: always clear every individual pending flush mask
Kuogee Hsieh quic_khsieh@quicinc.com drm/msm/dpu: set DSC flush bit correctly at MDP CTL flush register
Wolfram Sang wsa+renesas@sang-engineering.com arm64: dts: renesas: ulcb-kf: Remove flow control for SCIF1
Geert Uytterhoeven geert+renesas@glider.be ARM: dts: iwg20d-q7-common: Fix backlight pwm specifier
Chengchang Tang tangchengchang@huawei.com RDMA/hns: Fix hns_roce_table_get return value
Brendan Cunningham bcunningham@cornelisnetworks.com IB/hfi1: Fix wrong mmu_node used for user SDMA packet after invalidate
Arnd Bergmann arnd@arndb.de RDMA/irdma: avoid fortify-string warning in irdma_clr_wqes
Randy Dunlap rdunlap@infradead.org soc/fsl/qe: fix usb.c build errors
Martin Blumenstingl martin.blumenstingl@googlemail.com ARM: dts: meson8: correct uart_B and uart_C clock references
Cristian Ciocaltea cristian.ciocaltea@collabora.com ASoC: es8316: Do not set rate constraints for unsupported MCLKs
Cristian Ciocaltea cristian.ciocaltea@collabora.com ASoC: es8316: Increment max value for ALC Capture Target Volume control
Dmitry Baryshkov dmitry.baryshkov@linaro.org ARM: dts: qcom: apq8074-dragonboard: Set DMA as remotely controlled
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org memory: brcmstb_dpfe: fix testing array offset after use
Marek Vasut marex@denx.de ARM: dts: stm32: Shorten the AV96 HDMI sound card name
Douglas Anderson dianders@chromium.org arm64: dts: mediatek: mt8183: Add mediatek,broken-save-restore-fw to kukui
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: apq8096: fix fixed regulator name property
Luca Weiss luca.weiss@fairphone.com arm64: dts: qcom: pm7250b: add missing spmi-vadc include
Arnd Bergmann arnd@arndb.de ARM: omap2: fix missing tick_broadcast() prototype
Arnd Bergmann arnd@arndb.de ARM: ep93xx: fix missing-prototype warnings
Dario Binacchi dario.binacchi@amarulasolutions.com drm/panel: simple: fix active size for Ampire AM-480272H3TMQW-T01H
Frieder Schrempf frieder.schrempf@kontron.de drm/bridge: ti-sn65dsi83: Fix enable/disable flow to meet spec
Stephan Gerhold stephan@gerhold.net arm64: dts: qcom: apq8016-sbc: Fix 1.8V power rail on LS expansion
Stephan Gerhold stephan@gerhold.net arm64: dts: qcom: apq8016-sbc: Fix regulator constraints
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: sdm845-polaris: add missing touchscreen child node reg
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: sm8550: correct pinctrl unit address
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: sm8550: correct crypto unit address
Vladimir Zapolskiy vladimir.zapolskiy@linaro.org arm64: dts: qcom: sm8550: add QCE IP family compatible values
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: sm8350: correct PCI phy unit address
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: sm8350: correct DMA controller unit address
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: sm6115: correct thermal-sensor unit address
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: sdm845: correct camss unit address
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: sdm630: correct camss unit address
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: msm8996: correct camss unit address
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: msm8994: correct SPMI unit address
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: msm8976: correct MMC unit address
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: msm8953: correct IOMMU unit address
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: msm8916: correct WCNSS unit address
Stephan Gerhold stephan.gerhold@kernkonzept.com arm64: dts: qcom: msm8916: Move WCN compatible to boards
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: msm8916: correct MMC unit address
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: msm8916: correct camss unit address
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: ipq6018: correct qrng unit address
Dmitry Baryshkov dmitry.baryshkov@linaro.org arm64: dts: qcom: pm8998: don't use GIC_SPI for SPMI interrupts
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ARM: dts: qcom: msm8974: do not use underscore in node name (again)
Linus Walleij linus.walleij@linaro.org ARM/musb: omap2: Remove global GPIO numbers from TUSB6010
Linus Walleij linus.walleij@linaro.org ARM: omap1: Exorcise the legacy GPIO header
Linus Walleij linus.walleij@linaro.org ARM/mmc: Convert old mmci-omap to GPIO descriptors
Linus Walleij linus.walleij@linaro.org ARM: omap1: Remove reliance on GPIO numbers from SX1
Linus Walleij linus.walleij@linaro.org ARM: omap1: Remove reliance on GPIO numbers from PalmTE
Linus Walleij linus.walleij@linaro.org ARM: omap1: Drop header on AMS Delta
Linus Walleij linus.walleij@linaro.org ARM/mfd/gpio: Fixup TPS65010 regression on OMAP1 OSK1
Nícolas F. R. A. Prado nfraprado@collabora.com drm/bridge: anx7625: Prevent endless probe loop
Tony Lindgren tony@atomide.com ARM: dts: gta04: Move model property out of pinctrl node
Biju Das biju.das.jz@bp.renesas.com clk: renesas: rzg2l: Fix CPG_SIPLL5_CLK1 register write
Jean-Philippe Brucker jean-philippe@linaro.org iommu/virtio: Return size mapped for a detached domain
Jean-Philippe Brucker jean-philippe@linaro.org iommu/virtio: Detach domain on endpoint release
Arnd Bergmann arnd@arndb.de drm/nouveau: dispnv50: fix missing-prototypes warning
Konrad Dybcio konrad.dybcio@linaro.org drm/msm/dpu: Set DPU_DATA_HCTL_EN for in INTF_SC7180_MASK
Vinod Polimera quic_vpolimer@quicinc.com drm/msm/disp/dpu: get timing engine status from intf status register
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/msm/dsi: don't allow enabling 14nm VCO with unprogrammed rate
Kalesh AP kalesh-anakkur.purayil@broadcom.com RDMA/bnxt_re: Fix to remove an unnecessary log
Kalesh AP kalesh-anakkur.purayil@broadcom.com RDMA/bnxt_re: Remove a redundant check inside bnxt_re_update_gid
Kalesh AP kalesh-anakkur.purayil@broadcom.com RDMA/bnxt_re: Use unique names while registering interrupts
Kalesh AP kalesh-anakkur.purayil@broadcom.com RDMA/bnxt_re: Fix to remove unnecessary return labels
Selvin Xavier selvin.xavier@broadcom.com RDMA/bnxt_re: Disable/kill tasklet only if it is enabled
Nikita Zhandarovich n.zhandarovich@fintech.ru hwmon: (f71882fg) prevent possible division by zero
Dan Carpenter dan.carpenter@linaro.org clk: imx: scu: use _safe list iterator to avoid a use after free
Alexander Stein alexander.stein@ew.tq-group.com drm/bridge: tc358767: Switch to devm MIPI-DSI helpers
Robert Marko robert.marko@sartura.hr arm64: dts: microchip: sparx5: do not use PSCI on reference boards
Tony Lindgren tony@atomide.com bus: ti-sysc: Fix dispc quirk masking bool variables
Marek Vasut marex@denx.de ARM: dts: stm32: Move ethernet MAC EEPROM from SoM to carrier boards
Maíra Canal mcanal@igalia.com drm/vkms: Fix RGB565 pixel conversion
Maíra Canal mcanal@igalia.com drm: Add fixed-point helper to get rounded integer values
Maíra Canal mcanal@igalia.com drm/vkms: isolate pixel conversion functionality
Bard Liao yung-chuan.liao@linux.intel.com ASoC: Intel: sof_sdw: remove SOF_SDW_TGL_HDMI for MeteorLake devices
Trevor Wu trevor.wu@mediatek.com ASoC: dt-bindings: mediatek,mt8188-afe: correct clock name
Dan Carpenter dan.carpenter@linaro.org driver: soc: xilinx: use _safe loop iterator to avoid a use after free
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/panel: sharp-ls043t1le01: adjust mode settings
XuDong Liu m202071377@hust.edu.cn drm: sun4i_tcon: use devm_clk_get_enabled in `sun4i_tcon_init_clocks`
Marek Vasut marex@denx.de Input: adxl34x - do not hardcode interrupt trigger type
Marek Vasut marek.vasut+renesas@mailbox.org clk: rs9: Fix .driver_data content in i2c_device_id
Alexander Stein alexander.stein@ew.tq-group.com clk: rs9: Add support for 9FGV0441
Alexander Stein alexander.stein@ew.tq-group.com clk: rs9: Support device specific dif bit calculation
Alexander Stein alexander.stein@ew.tq-group.com clk: rs9: Check for vendor/device ID
Marek Vasut marek.vasut+renesas@mailbox.org clk: vc7: Fix .driver_data content in i2c_device_id
Marek Vasut marek.vasut+renesas@mailbox.org clk: vc5: Fix .driver_data content in i2c_device_id
hfdevel@gmx.net hfdevel@gmx.net ARM: dts: meson8b: correct uart_B and uart_C clock references
Rafał Miłecki rafal@milecki.pl ARM: dts: BCM5301X: Drop "clock-names" from the SPI node
Luc Ma luc@sietium.com drm/vram-helper: fix function names in vram helper doc
Francesco Dolcini francesco.dolcini@toradex.com drm/bridge: tc358768: fix THS_TRAILCNT computation
Francesco Dolcini francesco.dolcini@toradex.com drm/bridge: tc358768: fix TXTAGOCNT computation
Francesco Dolcini francesco.dolcini@toradex.com drm/bridge: tc358768: fix THS_ZEROCNT computation
Francesco Dolcini francesco.dolcini@toradex.com drm/bridge: tc358768: fix TCLK_TRAILCNT computation
Francesco Dolcini francesco.dolcini@toradex.com drm/bridge: tc358768: Add atomic_get_input_bus_fmts() implementation
Francesco Dolcini francesco.dolcini@toradex.com drm/bridge: tc358768: fix TCLK_ZEROCNT computation
Francesco Dolcini francesco.dolcini@toradex.com drm/bridge: tc358768: fix PLL target frequency
Francesco Dolcini francesco.dolcini@toradex.com drm/bridge: tc358768: fix PLL parameters computation
Francesco Dolcini francesco.dolcini@toradex.com drm/bridge: tc358768: always enable HS video mode
Alexander Stein alexander.stein@ew.tq-group.com drm/bridge: ti-sn65dsi83: Fix enable error path
Duoming Zhou duoming@zju.edu.cn Input: cyttsp4_core - change del_timer_sync() to timer_shutdown_sync()
Luca Weiss luca@z3ntu.xyz Input: drv260x - sleep between polling GO bit
Markus Elfring elfring@users.sourceforge.net drm/bridge: it6505: Move a variable assignment behind a null pointer check in receive_timing_debugfs_show()
Vinay Belgaumkar vinay.belgaumkar@intel.com drm/i915/guc/slpc: Provide sysfs for efficient freq
John Harrison John.C.Harrison@Intel.com drm/i915/guc: More debug print updates - GuC SLPC
Liu Shixin liushixin2@huawei.com bootmem: remove the vmemmap pages from kmemleak in free_bootmem_page
Nicholas Kazlauskas nicholas.kazlauskas@amd.com drm/amd/display: Explicitly specify update type per plane info change
Nikita Zhandarovich n.zhandarovich@fintech.ru radeon: avoid double free in ci_dpm_init()
Arnd Bergmann arnd@arndb.de drm/amd/display: fix is_timing_changed() prototype
Wesley Chalmers Wesley.Chalmers@amd.com drm/amd/display: Add logging for display MALL refresh setting
Kuniyuki Iwashima kuniyu@amazon.com netlink: Add __sock_i_ino() for __netlink_diag_dump().
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: avoid suspicious RCU usage for synced VLAN-aware MAC addresses
Cambda Zhu cambda@linux.alibaba.com ipvlan: Fix return value of ipvlan_queue_xmit()
Ilia.Gavrilov Ilia.Gavrilov@infotecs.ru netfilter: nf_conntrack_sip: fix the ct_sip_parse_numerical_param() return value.
Florian Westphal fw@strlen.de netfilter: conntrack: dccp: copy entire header to stack buffer, not just basic one
Jeremy Sowden jeremy@azazel.net lib/ts_bm: reset initial match offset for every block of text
Lin Ma linma@zju.edu.cn net: nfc: Fix use-after-free caused by nfc_llcp_find_local
Edward Cree ecree.xilinx@gmail.com sfc: fix crash when reading stats while NIC is resetting
David Howells dhowells@redhat.com ocfs2: Fix use of slab data with sendpage
Maxim Kochetkov fido_max@inbox.ru net: axienet: Move reset before 64-bit DMA detection
Kuniyuki Iwashima kuniyu@amazon.com gtp: Fix use-after-free in __gtp_encap_destroy().
Sabrina Dubroca sd@queasysnail.net selftests: rtnetlink: remove netdevsim device after ipsec offload test
Eric Dumazet edumazet@google.com bonding: do not assume skb mac_header is set
Eric Dumazet edumazet@google.com netlink: do not hard code device address lenth in fdb dumps
Eric Dumazet edumazet@google.com netlink: fix potential deadlock in netlink_set_err()
Bartosz Golaszewski bartosz.golaszewski@linaro.org net: stmmac: fix double serdes powerdown
Jimmy Assarsson extja@kvaser.com can: kvaser_pciefd: Set hardware timestamp on transmitted packets
Jimmy Assarsson extja@kvaser.com can: kvaser_pciefd: Add function to set skb hwtstamps
Vincent Mailhol mailhol.vincent@wanadoo.fr can: length: fix bitstuffing count
Gilad Sever gilad9366@gmail.com bpf: Fix bpf socket lookup from tc/xdp to respect socket VRF bindings
Gilad Sever gilad9366@gmail.com bpf: Call __bpf_sk_lookup()/__bpf_skc_lookup() directly via TC hookpoint
Gilad Sever gilad9366@gmail.com bpf: Factor out socket lookup functions for the TC hookpoint.
Dmitry Antipov dmantipov@yandex.ru wifi: ath9k: convert msecs to jiffies where needed
Johannes Berg johannes.berg@intel.com wifi: iwlwifi: mvm: indicate HW decrypt for beacon protection
Marek Vasut marex@denx.de mmc: Add MMC_QUIRK_BROKEN_SD_CACHE for Kingston Canvas Go Plus from 11/2019
Ilan Peer ilan.peer@intel.com wifi: ieee80211: Fix the common size calculation for reconfiguration ML
Johannes Berg johannes.berg@intel.com wifi: cfg80211: fix regulatory disconnect with OCB/NAN
Benjamin Berg benjamin.berg@intel.com wifi: cfg80211: drop incorrect nontransmitted BSS update code
Benjamin Berg benjamin.berg@intel.com wifi: cfg80211: rewrite merging of inherited elements
Nicolas Cavallari nicolas.cavallari@green-communications.fr wifi: mac80211: Remove "Missing iftype sband data/EHT cap" spam
Anjaneyulu pagadala.yesu.anjaneyulu@intel.com wifi: iwlwifi: pcie: fix NULL pointer dereference in iwl_pcie_irq_rx_msix_handler()
Johannes Berg johannes.berg@intel.com wifi: iwlwifi: pull from TXQs with softirqs disabled
Ziyang Huang hzyitc@outlook.com wifi: ath11k: Add missing hw_ops->get_ring_selector() for IPQ5018
Ziyang Huang hzyitc@outlook.com wifi: ath11k: Restart firmware after cold boot calibration for IPQ5018
Ziyang Huang hzyitc@outlook.com wifi: ath11k: Add missing ops config for IPQ5018 in ath11k_ahb_probe()
Jiasheng Jiang jiasheng@iscas.ac.cn wifi: ath11k: Add missing check for ioremap
Edwin Peer edwin.peer@broadcom.com rtnetlink: extend RTEXT_FILTER_SKIP_STATS to IFLA_VF_INFO
Ilan Peer ilan.peer@intel.com wifi: mac80211: Fix permissions for valid_links debugfs entry
Remi Pommarel repk@triplefau.lt wifi: ath9k: Fix possible stall on ath9k_txq_list_has_key()
Eduard Zingerman eddyz87@gmail.com selftests/bpf: Fix invalid pointer check in get_xlated_program()
Arnd Bergmann arnd@arndb.de memstick r592: make memstick_debug_get_tpc_name() static
Douglas Anderson dianders@chromium.org mmc: mediatek: Avoid ugly error message when SDIO wakeup IRQ isn't used
Zhen Lei thunder.leizhen@huawei.com kexec: fix a memory leak in crash_shrink_memory()
Douglas Anderson dianders@chromium.org watchdog/perf: more properly prevent false positives with turbo modes
Douglas Anderson dianders@chromium.org watchdog/perf: define dummy watchdog_update_hrtimer_threshold() on correct config
Haifeng Xu haifeng.xu@shopee.com selftests: cgroup: fix unexpected failure on test_memcg_low
Karol Kolacinski karol.kolacinski@intel.com ice: handle extts in the miscellaneous interrupt thread
Marek Vasut marex@denx.de wifi: rsi: Do not set MMC_PM_KEEP_POWER in shutdown
Marek Vasut marex@denx.de wifi: rsi: Do not configure WoWlan in shutdown hook if not enabled
Jesper Dangaard Brouer brouer@redhat.com selftests/bpf: Fix check_mtu using wrong variable type
Johannes Berg johannes.berg@intel.com wifi: mac80211: recalc min chandef for new STA links
Viktor Malik vmalik@redhat.com tools/resolve_btfids: Fix setting HOSTCFLAGS
Youghandhar Chintala quic_youghand@quicinc.com wifi: ath10k: Trigger STA disconnect after reconfig complete on hardware restart
Jesper Dangaard Brouer brouer@redhat.com samples/bpf: xdp1 and xdp2 reduce XDPBUFSIZE to 60
Sascha Hauer s.hauer@pengutronix.de wifi: rtw88: usb: silence log flooding error message
Fedor Pchelkin pchelkin@ispras.ru wifi: ath9k: don't allow to overwrite ENDPOINT0 attributes
Christophe JAILLET christophe.jaillet@wanadoo.fr wifi: ray_cs: Fix an error handling path in ray_probe()
Christophe JAILLET christophe.jaillet@wanadoo.fr wifi: wl3501_cs: Fix an error handling path in wl3501_probe()
Christophe JAILLET christophe.jaillet@wanadoo.fr wifi: atmel: Fix an error handling path in atmel_probe()
Christophe JAILLET christophe.jaillet@wanadoo.fr wifi: orinoco: Fix an error handling path in orinoco_cs_probe()
Christophe JAILLET christophe.jaillet@wanadoo.fr wifi: orinoco: Fix an error handling path in spectrum_cs_probe()
Geert Uytterhoeven geert+renesas@glider.be regulator: core: Streamline debugfs operations
Geert Uytterhoeven geert+renesas@glider.be regulator: core: Fix more error checking for debugfs_create_dir()
Alexey Gladkov legion@kernel.org selftests/bpf: Do not use sign-file as testcase
Yafang Shao laoar.shao@gmail.com bpf: Fix memleak due to fentry attach failure
Yafang Shao laoar.shao@gmail.com bpf: Remove bpf trampoline selector
Alan Maguire alan.maguire@oracle.com bpftool: JIT limited misreported as negative value on aarch64
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org nfc: llcp: fix possible use of uninitialized variable in nfc_llcp_send_connect()
Joy Chakraborty joychakr@google.com spi: dw: Round of n_bytes to power of 2
Stanislav Fomichev sdf@google.com bpf: Don't EFAULT for {g,s}setsockopt with wrong optlen
Andrii Nakryiko andrii@kernel.org libbpf: fix offsetof() and container_of() to work with CO-RE
Alexander Mikhalitsyn alexander@mihalicyn.com sctp: add bpf_bypass_getsockopt proto callback
Christophe JAILLET christophe.jaillet@wanadoo.fr wifi: mwifiex: Fix the size of a memory allocation in mwifiex_ret_802_11_scan()
Amisha Patel amisha.patel@microchip.com wifi: wilc1000: fix for absent RSN capabilities WFA testcase
Vijaya Krishna Nivarthi quic_vnivarth@quicinc.com spi: spi-geni-qcom: Correct CS_TOGGLE bit in SPI_TRANS_CFG
Pengcheng Yang yangpc@wangsu.com samples/bpf: Fix buffer overflow in tcp_basertt
Martin KaFai Lau martin.lau@kernel.org libbpf: btf_dump_type_data_check_overflow needs to consider BTF_MEMBER_BITFIELD_SIZE
Fedor Pchelkin pchelkin@ispras.ru wifi: ath9k: avoid referencing uninit memory in ath9k_wmi_ctrl_rx
Peter Seiderer ps.report@gmx.net wifi: ath9k: fix AR9003 mac hardware hang check register offset calculation
Jesper Dangaard Brouer brouer@redhat.com igc: Enable and fix RX hash usage by netstack
Hao Jia jiahao.os@bytedance.com sched/core: Avoid multiple calling update_rq_clock() in __cfsb_csd_unthrottle()
Jiasheng Jiang jiasheng@iscas.ac.cn pstore/ram: Add check for kstrdup
Roberto Sassu roberto.sassu@huawei.com ima: Fix build warnings
Roberto Sassu roberto.sassu@huawei.com evm: Fix build warnings
Roberto Sassu roberto.sassu@huawei.com evm: Complete description of evm_inode_setattr()
Mark Rutland mark.rutland@arm.com locking/atomic: arm: fix sync ops
Juergen Gross jgross@suse.com x86/mm: Fix __swp_entry_to_pte() for Xen PV guests
Ravi Bangoria ravi.bangoria@amd.com perf/ibs: Fix interface via core pmu events
Colin Ian King colin.i.king@gmail.com kselftest: vDSO: Fix accumulation of uninitialized ret when CLOCK_REALTIME is undefined
Juergen Gross jgross@suse.com x86/xen: Set MTRR state when running as Xen PV initial domain
Juergen Gross jgross@suse.com x86/mtrr: Support setting MTRR state for software defined MTRRs
Juergen Gross jgross@suse.com x86/mtrr: Replace size_or_mask and size_and_mask with a much easier concept
Juergen Gross jgross@suse.com x86/mtrr: Remove physical address size calculation
Qiuxu Zhuo qiuxu.zhuo@intel.com rcu/rcuscale: Stop kfree_scale_thread thread(s) after unloading rcuscale
Qiuxu Zhuo qiuxu.zhuo@intel.com rcu/rcuscale: Move rcu_scale_*() after kfree_scale_cleanup()
Paul E. McKenney paulmck@kernel.org rcuscale: Move shutdown from wait_event() to wait_event_idle()
Paul E. McKenney paulmck@kernel.org rcutorture: Correct name of use_softirq module parameter
Paul E. McKenney paulmck@kernel.org rcu-tasks: Stop rcu_tasks_invoke_cbs() from using never-onlined CPUs
Paul E. McKenney paulmck@kernel.org rcu: Make rcu_cpu_starting() rely on interrupts being disabled
Peng Fan peng.fan@nxp.com thermal/drivers/qoriq: Only enable supported sensors
Daniel Lezcano daniel.lezcano@linaro.org thermal/hwmon: Use the right device for devm_thermal_add_hwmon_sysfs()
Christophe JAILLET christophe.jaillet@wanadoo.fr thermal/drivers/sun8i: Fix some error handling paths in sun8i_ths_probe()
Stephan Gerhold stephan.gerhold@kernkonzept.com thermal/drivers/qcom/tsens-v0_1: Add mdm9607 correction offsets
Stephan Gerhold stephan.gerhold@kernkonzept.com thermal/drivers/qcom/tsens-v0_1: Fix mdm9607 slope values
Matti Lehtimäki matti.lehtimaki@gmail.com thermal/drivers/qcom/tsens-v0_1: Add support for MSM8226
Tero Kristo tero.kristo@linux.intel.com cpufreq: intel_pstate: Fix energy_performance_preference for passive
Arnd Bergmann arnd@arndb.de ARM: 9303/1: kprobes: avoid missing-declaration warnings
Ulf Hansson ulf.hansson@linaro.org PM: domains: Move the verification of in-params from genpd_add_device()
Zhang Rui rui.zhang@intel.com powercap: RAPL: Fix CONFIG_IOSF_MBI dependency
Sumeet Pawnikar sumeet.r.pawnikar@intel.com powercap: RAPL: fix invalid initialization for pl4_supported field
Li Yang leoyang.li@nxp.com APEI: GHES: correctly return NULL for ghes_get_devices()
Robin Murphy robin.murphy@arm.com perf/arm_cspmu: Fix event attribute type
Ilkka Koskinen ilkka@os.amperecomputing.com perf: arm_cspmu: Set irq affinitiy only if overflow interrupt is used
Junhao He hejunhao3@huawei.com drivers/perf: hisi: Don't migrate perf to the CPU going to teardown
Kirill A. Shutemov kirill.shutemov@linux.intel.com x86/tdx: Fix race between set_memory_encrypted() and load_unaligned_zeropad()
Kirill A. Shutemov kirill.shutemov@linux.intel.com x86/mm: Allow guest.enc_status_change_prepare() to fail
Robin Murphy robin.murphy@arm.com perf/arm-cmn: Fix DTC reset
Nikita Zhandarovich n.zhandarovich@fintech.ru PM: domains: fix integer overflow issues in genpd_parse_state()
Feng Mingxi m202271825@hust.edu.cn clocksource/drivers/cadence-ttc: Fix memory leak in ttc_timer_probe
Christoph Hellwig hch@lst.de btrfs: fix file_offset for REQ_BTRFS_ONE_ORDERED bios that get split
Christoph Hellwig hch@lst.de btrfs: make btrfs_split_bio work on struct btrfs_bio
Sebastian Andrzej Siewior bigeasy@linutronix.de tracing/timer: Add missing hrtimer modes to decode_hrtimer_mode().
Wen Yang wenyang.linux@foxmail.com tick/rcu: Fix bogus ratelimit condition
Thomas Gleixner tglx@linutronix.de posix-timers: Prevent RT livelock in itimer_delete()
Gao Xiang xiang@kernel.org erofs: fix compact 4B support for 16k block size
Chuck Lever chuck.lever@oracle.com svcrdma: Prevent page release when nothing was received
John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de irqchip/jcore-aic: Fix missing allocation of IRQ descriptors
Antonio Borneo antonio.borneo@foss.st.com irqchip/stm32-exti: Fix warning on initialized field overwritten
Christoph Hellwig hch@lst.de splice: don't call file_accessed in copy_splice_read
Jianmin Lv lvjianmin@loongson.cn irqchip/loongson-eiointc: Fix irq affinity setting during resume
Yu Kuai yukuai3@huawei.com block: fix blktrace debugfs entries leakage
Yu Kuai yukuai3@huawei.com md/raid1-10: submit write io directly if bitmap is not enabled
Yu Kuai yukuai3@huawei.com md/raid1-10: factor out a helper to submit normal write
Yu Kuai yukuai3@huawei.com md/raid1-10: factor out a helper to add bio to plug
Li Nan linan122@huawei.com md/raid10: fix io loss while replacement replace rdev
Li Nan linan122@huawei.com md/raid10: fix null-ptr-deref of mreplace in raid10_sync_request
Li Nan linan122@huawei.com md/raid10: fix wrong setting of max_corr_read_errors
Li Nan linan122@huawei.com md/raid10: fix overflow of md/safe_mode_delay
Li Nan linan122@huawei.com md/raid10: check slab-out-of-bounds in md_bitmap_get_counter
Chaitanya Kulkarni kch@nvidia.com nvme-core: fix dev_pm_qos memleak
Chaitanya Kulkarni kch@nvidia.com nvme-core: add missing fault-injection cleanup
Chaitanya Kulkarni kch@nvidia.com nvme-core: fix memory leak in dhchap_ctrl_secret
Chaitanya Kulkarni kch@nvidia.com nvme-core: fix memory leak in dhchap_secret_store
NeilBrown neilb@suse.de lockd: drop inappropriate svc_get() from locked_get()
Yu Kuai yukuai3@huawei.com blk-mq: fix potential io hang by wrong 'wake_batch'
Arnd Bergmann arnd@arndb.de virt: sevguest: Add CONFIG_CRYPTO dependency
Waiman Long longman@redhat.com blk-cgroup: Reinit blkg_iostat_set after clearing in blkcg_reset_stats()
Tom Lendacky thomas.lendacky@amd.com x86/sev: Fix calculation of end address based on number of pages
Li Nan linan122@huawei.com blk-iocost: use spin_lock_irqsave in adjust_inuse_and_calc_cost
Shawn Wang shawnwang@linux.alibaba.com x86/resctrl: Only show tasks' pid in current pid namespace
Gao Xiang xiang@kernel.org erofs: kill hooked chains to avoid loops on deduplicated compressed images
David Howells dhowells@redhat.com splice: Fix filemap_splice_read() to use the correct inode
Bart Van Assche bvanassche@acm.org block: Fix the type of the second bdev_op_is_zoned_write() argument
Arnd Bergmann arnd@arndb.de fs: pipe: reveal missing function protoypes
Jeff Layton jlayton@kernel.org drm: use mgr->dev in drm_dbg_kms in drm_dp_add_payload_part2
Peter Collingbourne pcc@google.com mm: call arch_swap_restore() from do_swap_page()
-------------
Diffstat:
.../bindings/sound/mediatek,mt8188-afe.yaml | 36 +- Makefile | 4 +- arch/arc/include/asm/linkage.h | 8 +- arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 2 +- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 2 +- arch/arm/boot/dts/bcm5301x.dtsi | 1 - arch/arm/boot/dts/iwg20d-q7-common.dtsi | 2 +- .../boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi | 16 +- arch/arm/boot/dts/meson8.dtsi | 4 +- arch/arm/boot/dts/meson8b.dtsi | 4 +- arch/arm/boot/dts/omap3-gta04a5one.dts | 4 +- arch/arm/boot/dts/qcom-apq8074-dragonboard.dts | 4 + arch/arm/boot/dts/qcom-msm8974.dtsi | 2 +- arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi | 11 +- arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi | 8 +- .../boot/dts/stm32mp15xx-dhcor-drc-compact.dtsi | 6 + arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi | 6 - arch/arm/boot/dts/stm32mp15xx-dhcor-testbench.dtsi | 8 + arch/arm/boot/dts/stm32mp15xx-dkx.dtsi | 2 +- arch/arm/include/asm/assembler.h | 17 + arch/arm/include/asm/sync_bitops.h | 29 +- arch/arm/lib/bitops.h | 14 +- arch/arm/lib/testchangebit.S | 4 + arch/arm/lib/testclearbit.S | 4 + arch/arm/lib/testsetbit.S | 4 + arch/arm/mach-ep93xx/timer-ep93xx.c | 3 +- arch/arm/mach-omap1/board-ams-delta.c | 1 - arch/arm/mach-omap1/board-nokia770.c | 43 +- arch/arm/mach-omap1/board-osk.c | 139 +++++-- arch/arm/mach-omap1/board-palmte.c | 51 ++- arch/arm/mach-omap1/board-sx1-mmc.c | 1 - arch/arm/mach-omap1/board-sx1.c | 40 +- arch/arm/mach-omap1/devices.c | 1 - arch/arm/mach-omap1/gpio15xx.c | 1 - arch/arm/mach-omap1/gpio16xx.c | 1 - arch/arm/mach-omap1/irq.c | 1 - arch/arm/mach-omap2/board-generic.c | 1 + arch/arm/mach-omap2/board-n8x0.c | 156 ++----- arch/arm/mach-omap2/usb-tusb6010.c | 20 +- arch/arm/mach-omap2/usb-tusb6010.h | 12 + arch/arm/probes/kprobes/checkers-common.c | 2 +- arch/arm/probes/kprobes/core.c | 2 +- arch/arm/probes/kprobes/opt-arm.c | 2 - arch/arm/probes/kprobes/test-core.c | 2 +- arch/arm/probes/kprobes/test-core.h | 4 + .../dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso | 6 +- arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 4 + arch/arm64/boot/dts/mediatek/mt8192.dtsi | 22 +- arch/arm64/boot/dts/microchip/sparx5.dtsi | 2 +- .../boot/dts/microchip/sparx5_pcb_common.dtsi | 12 + arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 93 +++-- arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts | 4 +- arch/arm64/boot/dts/qcom/ipq6018.dtsi | 2 +- arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts | 12 +- .../boot/dts/qcom/msm8916-alcatel-idol347.dts | 12 +- arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts | 12 +- arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts | 12 +- arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts | 12 +- .../boot/dts/qcom/msm8916-longcheer-l8150.dts | 12 +- .../boot/dts/qcom/msm8916-longcheer-l8910.dts | 12 +- arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi | 22 +- .../dts/qcom/msm8916-samsung-a2015-common.dtsi | 4 - .../boot/dts/qcom/msm8916-samsung-a3u-eur.dts | 8 + .../boot/dts/qcom/msm8916-samsung-a5u-eur.dts | 14 +- .../dts/qcom/msm8916-samsung-e2015-common.dtsi | 8 + .../boot/dts/qcom/msm8916-samsung-gt5-common.dtsi | 16 +- .../boot/dts/qcom/msm8916-samsung-j5-common.dtsi | 12 +- .../boot/dts/qcom/msm8916-samsung-serranove.dts | 16 +- arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi | 12 +- .../boot/dts/qcom/msm8916-wingtech-wt88047.dts | 12 +- arch/arm64/boot/dts/qcom/msm8916.dtsi | 19 +- arch/arm64/boot/dts/qcom/msm8953.dtsi | 2 +- arch/arm64/boot/dts/qcom/msm8976.dtsi | 6 +- arch/arm64/boot/dts/qcom/msm8994.dtsi | 2 +- arch/arm64/boot/dts/qcom/msm8996.dtsi | 2 +- arch/arm64/boot/dts/qcom/pm7250b.dtsi | 1 + arch/arm64/boot/dts/qcom/pm8998.dtsi | 2 +- arch/arm64/boot/dts/qcom/qdu1000.dtsi | 1 + arch/arm64/boot/dts/qcom/sdm630.dtsi | 2 +- arch/arm64/boot/dts/qcom/sdm670.dtsi | 1 + arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts | 1 + arch/arm64/boot/dts/qcom/sdm845.dtsi | 3 +- arch/arm64/boot/dts/qcom/sm6115.dtsi | 2 +- .../boot/dts/qcom/sm8250-sony-xperia-edo.dtsi | 7 +- arch/arm64/boot/dts/qcom/sm8350.dtsi | 4 +- arch/arm64/boot/dts/qcom/sm8550.dtsi | 11 +- arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 3 +- arch/arm64/boot/dts/ti/k3-am69-sk.dts | 2 +- .../boot/dts/ti/k3-j7200-common-proc-board.dts | 28 +- arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts | 5 + arch/arm64/boot/dts/ti/k3-j784s4-evm.dts | 52 ++- arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi | 29 +- arch/arm64/include/asm/fpsimdmacros.h | 6 +- arch/mips/boot/dts/ingenic/ci20.dts | 38 +- arch/powerpc/kernel/interrupt.c | 3 +- arch/powerpc/kernel/ppc_save_regs.S | 6 +- arch/powerpc/kernel/signal_32.c | 15 +- arch/powerpc/mm/book3s64/radix_pgtable.c | 34 +- arch/powerpc/mm/init_64.c | 2 +- arch/powerpc/platforms/powernv/pci-sriov.c | 6 +- arch/powerpc/platforms/powernv/vas-window.c | 2 +- arch/powerpc/platforms/pseries/vas.c | 2 +- arch/riscv/kernel/probes/uprobes.c | 2 + arch/x86/coco/tdx/tdx.c | 51 ++- arch/x86/events/amd/core.c | 2 +- arch/x86/events/amd/ibs.c | 53 ++- arch/x86/include/asm/mtrr.h | 40 +- arch/x86/include/asm/perf_event.h | 2 + arch/x86/include/asm/pgtable_64.h | 4 +- arch/x86/include/asm/sev.h | 16 +- arch/x86/include/asm/x86_init.h | 2 +- arch/x86/include/uapi/asm/mtrr.h | 8 - arch/x86/kernel/cpu/mtrr/cleanup.c | 18 +- arch/x86/kernel/cpu/mtrr/generic.c | 124 ++++-- arch/x86/kernel/cpu/mtrr/mtrr.c | 73 +--- arch/x86/kernel/cpu/mtrr/mtrr.h | 4 +- arch/x86/kernel/cpu/resctrl/rdtgroup.c | 8 +- arch/x86/kernel/setup.c | 2 + arch/x86/kernel/sev.c | 14 +- arch/x86/kernel/x86_init.c | 2 +- arch/x86/mm/mem_encrypt_amd.c | 4 +- arch/x86/mm/pat/set_memory.c | 3 +- arch/x86/platform/efi/efi_64.c | 6 +- arch/x86/xen/enlighten_pv.c | 52 +++ block/blk-cgroup.c | 5 + block/blk-iocost.c | 7 +- block/blk-mq-debugfs.c | 2 +- block/blk-mq-tag.c | 15 +- block/blk-mq.h | 3 +- block/genhd.c | 5 +- crypto/jitterentropy.c | 9 +- drivers/acpi/apei/ghes.c | 2 + drivers/base/power/domain.c | 15 +- drivers/bus/ti-sysc.c | 4 +- drivers/char/hw_random/st-rng.c | 21 +- drivers/char/hw_random/virtio-rng.c | 10 +- drivers/clk/bcm/clk-raspberrypi.c | 4 +- drivers/clk/clk-cdce925.c | 12 + drivers/clk/clk-renesas-pcie.c | 72 +++- drivers/clk/clk-si5341.c | 38 +- drivers/clk/clk-versaclock5.c | 45 ++- drivers/clk/clk-versaclock7.c | 2 +- drivers/clk/clk.c | 2 + drivers/clk/imx/clk-imx8mn.c | 8 +- drivers/clk/imx/clk-imx8mp.c | 24 +- drivers/clk/imx/clk-imx93.c | 15 +- drivers/clk/imx/clk-imxrt1050.c | 22 +- drivers/clk/imx/clk-scu.c | 4 +- drivers/clk/keystone/sci-clk.c | 2 + drivers/clk/mediatek/clk-mt8173-apmixedsys.c | 7 +- drivers/clk/mediatek/clk-mtk.c | 7 +- drivers/clk/renesas/rzg2l-cpg.c | 6 +- drivers/clk/renesas/rzg2l-cpg.h | 3 - drivers/clk/tegra/clk-tegra124-emc.c | 2 + drivers/clk/ti/clkctrl.c | 7 + drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 2 +- drivers/clocksource/timer-cadence-ttc.c | 19 +- drivers/cpufreq/intel_pstate.c | 2 + drivers/crypto/marvell/cesa/cipher.c | 2 +- drivers/crypto/nx/Makefile | 2 +- drivers/crypto/nx/nx.h | 4 +- drivers/crypto/qat/qat_common/qat_asym_algs.c | 14 +- drivers/cxl/core/region.c | 102 +++-- drivers/cxl/cxl.h | 16 +- drivers/dax/bus.c | 61 +-- drivers/dax/dax-private.h | 4 +- drivers/dax/kmem.c | 2 +- drivers/firmware/efi/libstub/efi-stub-helper.c | 6 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 3 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 16 +- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c | 13 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 + .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 5 +- .../dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c | 3 + drivers/gpu/drm/amd/display/dc/core/dc.c | 3 - drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 6 +- drivers/gpu/drm/amd/display/dc/dc.h | 3 + .../amd/display/dc/dml/dcn21/display_mode_vba_21.c | 2 +- .../display/dc/dml/dcn32/display_rq_dlg_calc_32.c | 2 +- .../drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 18 +- drivers/gpu/drm/bridge/analogix/anx7625.c | 128 ++++-- drivers/gpu/drm/bridge/ite-it6505.c | 3 +- drivers/gpu/drm/bridge/tc358767.c | 4 +- drivers/gpu/drm/bridge/tc358768.c | 93 ++++- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 20 +- drivers/gpu/drm/display/drm_dp_mst_topology.c | 2 +- drivers/gpu/drm/drm_gem_vram_helper.c | 6 +- drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c | 35 ++ drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c | 8 +- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 95 +++-- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h | 1 + drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h | 1 + drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 3 +- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 10 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 12 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 5 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 5 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 8 +- drivers/gpu/drm/msm/dp/dp_display.c | 16 +- drivers/gpu/drm/msm/dsi/dsi_host.c | 26 +- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 3 + drivers/gpu/drm/nouveau/dispnv50/disp.c | 1 + drivers/gpu/drm/nouveau/nv50_display.h | 4 +- drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c | 11 +- drivers/gpu/drm/panel/panel-simple.c | 4 +- drivers/gpu/drm/radeon/ci_dpm.c | 28 +- drivers/gpu/drm/radeon/cypress_dpm.c | 8 +- drivers/gpu/drm/radeon/ni_dpm.c | 8 +- drivers/gpu/drm/radeon/rv740_dpm.c | 8 +- drivers/gpu/drm/sun4i/sun4i_tcon.c | 19 +- drivers/gpu/drm/vkms/vkms_composer.c | 4 +- drivers/gpu/drm/vkms/vkms_drv.h | 4 +- drivers/gpu/drm/vkms/vkms_formats.c | 131 +++--- drivers/gpu/drm/vkms/vkms_formats.h | 2 +- drivers/gpu/drm/vkms/vkms_plane.c | 2 +- drivers/hid/Kconfig | 2 +- drivers/hwmon/f71882fg.c | 7 +- drivers/hwmon/gsc-hwmon.c | 6 +- drivers/hwmon/pmbus/adm1275.c | 52 +-- drivers/infiniband/hw/bnxt_re/main.c | 20 +- drivers/infiniband/hw/bnxt_re/qplib_fp.c | 40 +- drivers/infiniband/hw/bnxt_re/qplib_fp.h | 2 +- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 46 ++- drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 1 + drivers/infiniband/hw/hfi1/ipoib_tx.c | 4 +- drivers/infiniband/hw/hfi1/mmu_rb.c | 101 +++-- drivers/infiniband/hw/hfi1/mmu_rb.h | 3 + drivers/infiniband/hw/hfi1/sdma.c | 23 +- drivers/infiniband/hw/hfi1/sdma.h | 47 ++- drivers/infiniband/hw/hfi1/sdma_txreq.h | 2 + drivers/infiniband/hw/hfi1/user_sdma.c | 137 +++---- drivers/infiniband/hw/hfi1/user_sdma.h | 1 - drivers/infiniband/hw/hfi1/vnic_sdma.c | 4 +- drivers/infiniband/hw/hns/hns_roce_hem.c | 7 +- drivers/infiniband/hw/irdma/uk.c | 10 +- drivers/infiniband/sw/rxe/rxe_mw.c | 17 +- drivers/input/misc/adxl34x.c | 3 +- drivers/input/misc/drv260x.c | 1 + drivers/input/misc/pm8941-pwrkey.c | 19 +- drivers/input/touchscreen/cyttsp4_core.c | 3 +- drivers/iommu/iommufd/device.c | 2 +- drivers/iommu/iommufd/io_pagetable.c | 14 +- drivers/iommu/virtio-iommu.c | 57 ++- drivers/irqchip/irq-jcore-aic.c | 7 + drivers/irqchip/irq-loongson-eiointc.c | 2 +- drivers/irqchip/irq-stm32-exti.c | 12 + drivers/md/md-bitmap.c | 21 +- drivers/md/md-bitmap.h | 7 + drivers/md/md.c | 9 +- drivers/md/raid1-10.c | 42 ++ drivers/md/raid1.c | 25 +- drivers/md/raid10.c | 73 ++-- drivers/memory/brcmstb_dpfe.c | 4 +- drivers/memstick/host/r592.c | 4 +- drivers/mfd/tps65010.c | 14 +- drivers/mmc/core/card.h | 30 +- drivers/mmc/core/quirks.h | 13 + drivers/mmc/core/sd.c | 2 +- drivers/mmc/host/mtk-sd.c | 2 +- drivers/mmc/host/omap.c | 46 ++- drivers/net/bonding/bond_main.c | 2 +- drivers/net/can/kvaser_pciefd.c | 39 +- drivers/net/ethernet/intel/ice/ice.h | 7 + drivers/net/ethernet/intel/ice/ice_main.c | 29 +- drivers/net/ethernet/intel/ice/ice_ptp.c | 12 +- drivers/net/ethernet/intel/ice/ice_ptp.h | 4 +- drivers/net/ethernet/intel/igc/igc.h | 28 ++ drivers/net/ethernet/intel/igc/igc_main.c | 31 +- drivers/net/ethernet/sfc/ef10.c | 13 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 - drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 10 +- drivers/net/gtp.c | 2 + drivers/net/ipvlan/ipvlan_core.c | 9 +- drivers/net/wireless/ath/ath10k/core.c | 9 - drivers/net/wireless/ath/ath10k/mac.c | 7 + drivers/net/wireless/ath/ath11k/ahb.c | 1 + drivers/net/wireless/ath/ath11k/core.c | 1 + drivers/net/wireless/ath/ath11k/hw.c | 2 +- drivers/net/wireless/ath/ath11k/qmi.c | 5 + drivers/net/wireless/ath/ath9k/ar9003_hw.c | 27 +- drivers/net/wireless/ath/ath9k/htc_hst.c | 8 +- drivers/net/wireless/ath/ath9k/main.c | 11 +- drivers/net/wireless/ath/ath9k/wmi.c | 4 + drivers/net/wireless/atmel/atmel_cs.c | 13 +- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 5 +- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 9 +- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 5 +- drivers/net/wireless/intersil/orinoco/orinoco_cs.c | 13 +- .../net/wireless/intersil/orinoco/spectrum_cs.c | 13 +- drivers/net/wireless/marvell/mwifiex/scan.c | 6 +- drivers/net/wireless/microchip/wilc1000/hif.c | 8 +- drivers/net/wireless/ray_cs.c | 16 +- drivers/net/wireless/realtek/rtw88/usb.c | 2 +- drivers/net/wireless/rsi/rsi_91x_sdio.c | 9 +- drivers/net/wireless/wl3501_cs.c | 16 +- drivers/nvme/host/core.c | 16 +- drivers/pci/controller/cadence/pcie-cadence-host.c | 27 ++ drivers/pci/controller/pci-ftpci100.c | 14 +- drivers/pci/controller/vmd.c | 11 +- drivers/pci/endpoint/functions/Kconfig | 2 +- drivers/pci/endpoint/functions/pci-epf-test.c | 2 +- drivers/pci/hotplug/pciehp_ctrl.c | 8 + drivers/pci/pcie/aspm.c | 21 +- drivers/perf/arm-cmn.c | 7 +- drivers/perf/arm_cspmu/arm_cspmu.c | 11 +- drivers/perf/hisilicon/hisi_pcie_pmu.c | 2 +- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 6 +- drivers/pinctrl/freescale/pinctrl-scu.c | 3 +- drivers/pinctrl/intel/pinctrl-cherryview.c | 15 +- drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 2 + drivers/pinctrl/pinctrl-at91-pio4.c | 2 + drivers/pinctrl/pinctrl-at91.c | 78 ++-- drivers/pinctrl/pinctrl-microchip-sgpio.c | 3 + drivers/pinctrl/sunplus/sppctl.c | 23 +- drivers/pinctrl/tegra/pinctrl-tegra.c | 15 +- drivers/pinctrl/tegra/pinctrl-tegra.h | 3 +- drivers/pinctrl/tegra/pinctrl-tegra114.c | 7 +- drivers/pinctrl/tegra/pinctrl-tegra124.c | 7 +- drivers/pinctrl/tegra/pinctrl-tegra194.c | 7 +- drivers/pinctrl/tegra/pinctrl-tegra20.c | 7 +- drivers/pinctrl/tegra/pinctrl-tegra210.c | 7 +- drivers/pinctrl/tegra/pinctrl-tegra30.c | 7 +- drivers/platform/x86/dell/dell-rbtn.c | 13 +- drivers/platform/x86/intel/pmc/core.c | 1 - drivers/platform/x86/intel/pmc/core.h | 28 +- drivers/platform/x86/intel/pmc/mtl.c | 448 ++++++++++++++++++++- drivers/platform/x86/lenovo-yogabook-wmi.c | 34 +- drivers/platform/x86/think-lmi.c | 20 +- drivers/platform/x86/thinkpad_acpi.c | 6 +- drivers/powercap/Kconfig | 4 +- drivers/powercap/intel_rapl_msr.c | 17 +- drivers/regulator/core.c | 30 +- drivers/scsi/3w-xxxx.c | 4 +- drivers/scsi/lpfc/lpfc_els.c | 14 +- drivers/scsi/qedf/qedf_main.c | 3 +- drivers/soc/amlogic/meson-secure-pwrc.c | 2 +- drivers/soc/fsl/qe/Kconfig | 1 + drivers/soc/mediatek/mtk-svs.c | 4 +- drivers/soc/xilinx/xlnx_event_manager.c | 6 +- drivers/spi/spi-dw-core.c | 5 +- drivers/spi/spi-geni-qcom.c | 2 +- drivers/thermal/amlogic_thermal.c | 2 +- drivers/thermal/imx8mm_thermal.c | 2 +- drivers/thermal/imx_sc_thermal.c | 2 +- drivers/thermal/k3_bandgap.c | 2 +- drivers/thermal/mediatek/auxadc_thermal.c | 2 +- drivers/thermal/qcom/qcom-spmi-adc-tm5.c | 2 +- drivers/thermal/qcom/qcom-spmi-temp-alarm.c | 2 +- drivers/thermal/qcom/tsens-v0_1.c | 56 ++- drivers/thermal/qcom/tsens.c | 21 +- drivers/thermal/qcom/tsens.h | 6 +- drivers/thermal/qoriq_thermal.c | 32 +- drivers/thermal/sun8i_thermal.c | 57 +-- drivers/thermal/tegra/tegra30-tsensor.c | 2 +- drivers/thermal/thermal_hwmon.c | 4 +- drivers/thermal/thermal_hwmon.h | 4 +- drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 2 +- drivers/ufs/core/ufshcd-priv.h | 3 - drivers/ufs/core/ufshcd.c | 21 +- drivers/usb/musb/musb_core.c | 1 - drivers/usb/musb/musb_core.h | 2 - drivers/usb/musb/tusb6010.c | 53 ++- drivers/vfio/mdev/mdev_core.c | 23 +- drivers/video/fbdev/omap/lcd_mipid.c | 6 +- drivers/virt/coco/sev-guest/Kconfig | 1 + fs/btrfs/bio.c | 28 +- fs/cifs/cifs_debug.c | 16 +- fs/cifs/cifsglob.h | 10 +- fs/cifs/cifsproto.h | 2 +- fs/cifs/connect.c | 70 ++-- fs/cifs/dfs.c | 55 +-- fs/cifs/dfs.h | 19 +- fs/cifs/dfs_cache.c | 8 +- fs/cifs/file.c | 25 +- fs/cifs/misc.c | 38 +- fs/cifs/smb2inode.c | 9 +- fs/cifs/smb2ops.c | 19 +- fs/cifs/transport.c | 20 +- fs/erofs/zdata.c | 72 +--- fs/erofs/zmap.c | 6 +- fs/ksmbd/smb_common.c | 2 +- fs/lockd/svc.c | 1 - fs/nfs/nfs42xattr.c | 79 ++-- fs/nfs/nfs4proc.c | 1 + fs/ocfs2/cluster/tcp.c | 23 +- fs/overlayfs/copy_up.c | 2 + fs/overlayfs/dir.c | 3 +- fs/overlayfs/export.c | 3 +- fs/overlayfs/namei.c | 3 +- fs/overlayfs/overlayfs.h | 6 +- fs/overlayfs/super.c | 2 +- fs/overlayfs/util.c | 24 +- fs/pstore/ram_core.c | 2 + fs/splice.c | 1 - include/drm/drm_fixed.h | 6 + include/linux/blk-mq.h | 3 +- include/linux/blkdev.h | 2 +- include/linux/bootmem_info.h | 2 + include/linux/bpf.h | 1 - include/linux/can/length.h | 14 +- include/linux/ieee80211.h | 5 +- include/linux/mfd/tps65010.h | 11 +- include/linux/mmc/card.h | 1 + include/linux/netdevice.h | 9 + include/linux/nmi.h | 2 +- include/linux/pci.h | 1 + include/linux/pipe_fs_i.h | 4 - include/linux/platform_data/mmc-omap.h | 2 - include/linux/usb/musb.h | 13 - include/net/dsa.h | 12 +- include/net/regulatory.h | 13 +- include/net/sock.h | 1 + include/trace/events/timer.h | 6 +- include/ufs/ufshcd.h | 1 - init/Makefile | 1 + kernel/bpf/cgroup.c | 15 + kernel/bpf/trampoline.c | 32 +- kernel/kcsan/core.c | 2 + kernel/kexec_core.c | 5 +- kernel/rcu/rcu.h | 6 + kernel/rcu/rcuscale.c | 204 +++++----- kernel/rcu/tasks.h | 7 +- kernel/rcu/tree.c | 23 +- kernel/sched/fair.c | 18 + kernel/sched/sched.h | 22 + kernel/time/posix-timers.c | 43 +- kernel/time/tick-sched.c | 2 +- kernel/watchdog_hld.c | 6 +- lib/ts_bm.c | 4 +- mm/filemap.c | 4 +- mm/memory.c | 7 + net/core/filter.c | 126 ++++-- net/core/rtnetlink.c | 104 ++--- net/core/sock.c | 17 +- net/dsa/dsa.c | 2 +- net/dsa/slave.c | 84 ++-- net/dsa/switch.c | 4 +- net/dsa/switch.h | 3 + net/mac80211/debugfs_netdev.c | 2 +- net/mac80211/sta_info.c | 2 + net/mac80211/util.c | 4 +- net/netfilter/nf_conntrack_proto_dccp.c | 52 ++- net/netfilter/nf_conntrack_sip.c | 2 +- net/netlink/af_netlink.c | 5 +- net/netlink/diag.c | 7 +- net/nfc/llcp.h | 1 - net/nfc/llcp_commands.c | 15 +- net/nfc/llcp_core.c | 49 ++- net/nfc/llcp_sock.c | 18 +- net/nfc/netlink.c | 20 +- net/nfc/nfc.h | 1 + net/sctp/socket.c | 18 + net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 12 +- net/wireless/core.c | 16 - net/wireless/reg.c | 14 +- net/wireless/scan.c | 367 +++++++---------- samples/bpf/tcp_basertt_kern.c | 2 +- samples/bpf/xdp1_kern.c | 2 +- samples/bpf/xdp2_kern.c | 2 +- scripts/Makefile.modfinal | 2 +- scripts/Makefile.vmlinux | 1 + scripts/mod/modpost.c | 86 ++-- scripts/package/builddeb | 14 +- security/integrity/evm/evm_crypto.c | 2 +- security/integrity/evm/evm_main.c | 4 +- security/integrity/ima/ima_modsig.c | 3 + security/integrity/ima/ima_policy.c | 3 +- sound/pci/ac97/ac97_codec.c | 4 +- sound/soc/amd/acp/acp-pdm.c | 2 +- sound/soc/codecs/es8316.c | 23 +- sound/soc/fsl/imx-audmix.c | 9 + sound/soc/intel/boards/sof_sdw.c | 2 +- tools/bpf/bpftool/feature.c | 24 +- tools/bpf/resolve_btfids/Makefile | 4 +- tools/lib/bpf/bpf_helpers.h | 15 +- tools/lib/bpf/btf_dump.c | 22 +- tools/perf/arch/x86/util/Build | 1 + tools/perf/arch/x86/util/env.c | 19 + tools/perf/arch/x86/util/env.h | 7 + tools/perf/arch/x86/util/evsel.c | 16 +- tools/perf/arch/x86/util/mem-events.c | 19 +- tools/perf/builtin-bench.c | 2 + tools/perf/builtin-script.c | 16 +- tools/perf/builtin-stat.c | 2 + tools/perf/tests/shell/test_task_analyzer.sh | 26 +- tools/perf/util/dwarf-aux.c | 2 +- tools/perf/util/evsel.h | 24 +- tools/perf/util/evsel_fprintf.c | 1 + tools/testing/selftests/bpf/Makefile | 3 +- tools/testing/selftests/bpf/prog_tests/check_mtu.c | 2 +- tools/testing/selftests/bpf/test_verifier.c | 24 +- tools/testing/selftests/cgroup/test_memcontrol.c | 4 +- tools/testing/selftests/net/rtnetlink.sh | 1 + .../rcutorture/configs/rcu/BUSTED-BOOST.boot | 2 +- .../selftests/rcutorture/configs/rcu/TREE03.boot | 2 +- .../selftests/vDSO/vdso_test_clock_getres.c | 4 +- 498 files changed, 5144 insertions(+), 3097 deletions(-)
From: Peter Collingbourne pcc@google.com
commit 6dca4ac6fc91fd41ea4d6c4511838d37f4e0eab2 upstream.
Commit c145e0b47c77 ("mm: streamline COW logic in do_swap_page()") moved the call to swap_free() before the call to set_pte_at(), which meant that the MTE tags could end up being freed before set_pte_at() had a chance to restore them. Fix it by adding a call to the arch_swap_restore() hook before the call to swap_free().
Link: https://lkml.kernel.org/r/20230523004312.1807357-2-pcc@google.com Link: https://linux-review.googlesource.com/id/I6470efa669e8bd2f841049b8c61020c510... Fixes: c145e0b47c77 ("mm: streamline COW logic in do_swap_page()") Signed-off-by: Peter Collingbourne pcc@google.com Reported-by: Qun-wei Lin Qun-wei.Lin@mediatek.com Closes: https://lore.kernel.org/all/5050805753ac469e8d727c797c2218a9d780d434.camel@m... Acked-by: David Hildenbrand david@redhat.com Acked-by: "Huang, Ying" ying.huang@intel.com Reviewed-by: Steven Price steven.price@arm.com Acked-by: Catalin Marinas catalin.marinas@arm.com Cc: stable@vger.kernel.org [6.1+] Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/memory.c | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/mm/memory.c +++ b/mm/memory.c @@ -3915,6 +3915,13 @@ vm_fault_t do_swap_page(struct vm_fault }
/* + * Some architectures may have to restore extra metadata to the page + * when reading from swap. This metadata may be indexed by swap entry + * so this must be called before swap_free(). + */ + arch_swap_restore(entry, folio); + + /* * Remove the swap entry and conditionally try to free up the swapcache. * We're already holding a reference on the page but haven't mapped it * yet.
From: Jeff Layton jlayton@kernel.org
commit 54d217406afe250d7a768783baaa79a035f21d38 upstream.
I've been experiencing some intermittent crashes down in the display driver code. The symptoms are ususally a line like this in dmesg:
amdgpu 0000:30:00.0: [drm] Failed to create MST payload for port 000000006d3a3885: -5
...followed by an Oops due to a NULL pointer dereference.
Switch to using mgr->dev instead of state->dev since "state" can be NULL in some cases.
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2184855 Suggested-by: Jani Nikula jani.nikula@linux.intel.com Signed-off-by: Jeff Layton jlayton@kernel.org Reviewed-by: Jani Nikula jani.nikula@intel.com Reviewed-by: Lyude Paul lyude@redhat.com Signed-off-by: Lyude Paul lyude@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20230419112447.18471-1-jlayton... Cc: "Limonciello, Mario" mario.limonciello@amd.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/display/drm_dp_mst_topology.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -3404,7 +3404,7 @@ int drm_dp_add_payload_part2(struct drm_
/* Skip failed payloads */ if (payload->vc_start_slot == -1) { - drm_dbg_kms(state->dev, "Part 1 of payload creation for %s failed, skipping part 2\n", + drm_dbg_kms(mgr->dev, "Part 1 of payload creation for %s failed, skipping part 2\n", payload->port->connector->name); return -EIO; }
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 247c8d2f9837a3e29e3b6b7a4aa9c36c37659dd4 ]
A couple of functions from fs/pipe.c are used both internally and for the watch queue code, but the declaration is only visible when the latter is enabled:
fs/pipe.c:1254:5: error: no previous prototype for 'pipe_resize_ring' fs/pipe.c:758:15: error: no previous prototype for 'account_pipe_buffers' fs/pipe.c:764:6: error: no previous prototype for 'too_many_pipe_buffers_soft' fs/pipe.c:771:6: error: no previous prototype for 'too_many_pipe_buffers_hard' fs/pipe.c:777:6: error: no previous prototype for 'pipe_is_unprivileged_user'
Make the visible unconditionally to avoid these warnings.
Fixes: c73be61cede5 ("pipe: Add general notification queue support") Signed-off-by: Arnd Bergmann arnd@arndb.de Message-Id: 20230516195629.551602-1-arnd@kernel.org Signed-off-by: Christian Brauner brauner@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/pipe_fs_i.h | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index d2c3f16cf6b18..02e0086b10f6f 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -261,18 +261,14 @@ void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *);
extern const struct pipe_buf_operations nosteal_pipe_buf_ops;
-#ifdef CONFIG_WATCH_QUEUE unsigned long account_pipe_buffers(struct user_struct *user, unsigned long old, unsigned long new); bool too_many_pipe_buffers_soft(unsigned long user_bufs); bool too_many_pipe_buffers_hard(unsigned long user_bufs); bool pipe_is_unprivileged_user(void); -#endif
/* for F_SETPIPE_SZ and F_GETPIPE_SZ */ -#ifdef CONFIG_WATCH_QUEUE int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots); -#endif long pipe_fcntl(struct file *, unsigned int, unsigned long arg); struct pipe_inode_info *get_pipe_info(struct file *file, bool for_splice);
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit 3ddbe2a7e0d4a155a805f69c906c9beed30d4cc4 ]
Change the type of the second argument of bdev_op_is_zoned_write() from blk_opf_t into enum req_op because this function expects an operation without flags as second argument.
Reviewed-by: Johannes Thumshirn johannes.thumshirn@wdc.com Reviewed-by: Pankaj Raghav p.raghav@samsung.com Reviewed-by: Christoph Hellwig hch@lst.de Reviewed-by: Damien Le Moal dlemoal@kernel.org Reviewed-by: Hannes Reinecke hare@suse.de Cc: Ming Lei ming.lei@redhat.com Fixes: 8cafdb5ab94c ("block: adapt blk_mq_plug() to not plug for writes that require a zone lock") Signed-off-by: Bart Van Assche bvanassche@acm.org Link: https://lore.kernel.org/r/20230517174230.897144-4-bvanassche@acm.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/blkdev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 941304f17492f..3d620f298aebd 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1297,7 +1297,7 @@ static inline unsigned int bdev_zone_no(struct block_device *bdev, sector_t sec) }
static inline bool bdev_op_is_zoned_write(struct block_device *bdev, - blk_opf_t op) + enum req_op op) { if (!bdev_is_zoned(bdev)) return false;
From: David Howells dhowells@redhat.com
[ Upstream commit c37222082f23c456664d1c3182a714670ab8f9a4 ]
Fix filemap_splice_read() to use file->f_mapping->host, not file->f_inode, as the source of the file size because in the case of a block device, file->f_inode points to the block-special file (which is typically 0 length) and not the backing store.
Fixes: 07073eb01c5f ("splice: Add a func to do a splice from a buffered file without ITER_PIPE") Signed-off-by: David Howells dhowells@redhat.com Reviewed-by: Christoph Hellwig hch@lst.de Reviewed-by: Christian Brauner brauner@kernel.org cc: Steve French stfrench@microsoft.com cc: Jens Axboe axboe@kernel.dk cc: Al Viro viro@zeniv.linux.org.uk cc: David Hildenbrand david@redhat.com cc: John Hubbard jhubbard@nvidia.com cc: linux-mm@kvack.org cc: linux-block@vger.kernel.org cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/20230522135018.2742245-2-dhowells@redhat.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- mm/filemap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mm/filemap.c b/mm/filemap.c index 2723104cc06a1..8f048e62279a2 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2903,7 +2903,7 @@ ssize_t filemap_splice_read(struct file *in, loff_t *ppos, do { cond_resched();
- if (*ppos >= i_size_read(file_inode(in))) + if (*ppos >= i_size_read(in->f_mapping->host)) break;
iocb.ki_pos = *ppos; @@ -2919,7 +2919,7 @@ ssize_t filemap_splice_read(struct file *in, loff_t *ppos, * part of the page is not copied back to userspace (unless * another truncate extends the file - this is desired though). */ - isize = i_size_read(file_inode(in)); + isize = i_size_read(in->f_mapping->host); if (unlikely(*ppos >= isize)) break; end_offset = min_t(loff_t, isize, *ppos + len);
From: Gao Xiang hsiangkao@linux.alibaba.com
[ Upstream commit 967c28b23f6c89bb8eef6a046ea88afe0d7c1029 ]
After heavily stressing EROFS with several images which include a hand-crafted image of repeated patterns for more than 46 days, I found two chains could be linked with each other almost simultaneously and form a loop so that the entire loop won't be submitted. As a consequence, the corresponding file pages will remain locked forever.
It can be _only_ observed on data-deduplicated compressed images. For example, consider two chains with five pclusters in total: Chain 1: 2->3->4->5 -- The tail pcluster is 5; Chain 2: 5->1->2 -- The tail pcluster is 2.
Chain 2 could link to Chain 1 with pcluster 5; and Chain 1 could link to Chain 2 at the same time with pcluster 2.
Since hooked chains are all linked locklessly now, I have no idea how to simply avoid the race. Instead, let's avoid hooked chains completely until I could work out a proper way to fix this and end users finally tell us that it's needed to add it back.
Actually, this optimization can be found with multi-threaded workloads (especially even more often on deduplicated compressed images), yet I'm not sure about the overall system impacts of not having this compared with implementation complexity.
Fixes: 267f2492c8f7 ("erofs: introduce multi-reference pclusters (fully-referenced)") Signed-off-by: Gao Xiang hsiangkao@linux.alibaba.com Reviewed-by: Yue Hu huyue2@coolpad.com Link: https://lore.kernel.org/r/20230526201459.128169-4-hsiangkao@linux.alibaba.co... Signed-off-by: Sasha Levin sashal@kernel.org --- fs/erofs/zdata.c | 72 ++++++++---------------------------------------- 1 file changed, 11 insertions(+), 61 deletions(-)
diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index d7add72a09437..72325d4b98f9d 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -94,11 +94,8 @@ struct z_erofs_pcluster {
/* let's avoid the valid 32-bit kernel addresses */
-/* the chained workgroup has't submitted io (still open) */ +/* the end of a chain of pclusters */ #define Z_EROFS_PCLUSTER_TAIL ((void *)0x5F0ECAFE) -/* the chained workgroup has already submitted io */ -#define Z_EROFS_PCLUSTER_TAIL_CLOSED ((void *)0x5F0EDEAD) - #define Z_EROFS_PCLUSTER_NIL (NULL)
struct z_erofs_decompressqueue { @@ -499,20 +496,6 @@ int __init z_erofs_init_zip_subsystem(void)
enum z_erofs_pclustermode { Z_EROFS_PCLUSTER_INFLIGHT, - /* - * The current pclusters was the tail of an exist chain, in addition - * that the previous processed chained pclusters are all decided to - * be hooked up to it. - * A new chain will be created for the remaining pclusters which are - * not processed yet, so different from Z_EROFS_PCLUSTER_FOLLOWED, - * the next pcluster cannot reuse the whole page safely for inplace I/O - * in the following scenario: - * ________________________________________________________________ - * | tail (partial) page | head (partial) page | - * | (belongs to the next pcl) | (belongs to the current pcl) | - * |_______PCLUSTER_FOLLOWED______|________PCLUSTER_HOOKED__________| - */ - Z_EROFS_PCLUSTER_HOOKED, /* * a weak form of Z_EROFS_PCLUSTER_FOLLOWED, the difference is that it * could be dispatched into bypass queue later due to uptodated managed @@ -530,8 +513,8 @@ enum z_erofs_pclustermode { * ________________________________________________________________ * | tail (partial) page | head (partial) page | * | (of the current cl) | (of the previous collection) | - * | PCLUSTER_FOLLOWED or | | - * |_____PCLUSTER_HOOKED__|___________PCLUSTER_FOLLOWED____________| + * | | | + * |__PCLUSTER_FOLLOWED___|___________PCLUSTER_FOLLOWED____________| * * [ (*) the above page can be used as inplace I/O. ] */ @@ -544,7 +527,7 @@ struct z_erofs_decompress_frontend { struct z_erofs_bvec_iter biter;
struct page *candidate_bvpage; - struct z_erofs_pcluster *pcl, *tailpcl; + struct z_erofs_pcluster *pcl; z_erofs_next_pcluster_t owned_head; enum z_erofs_pclustermode mode;
@@ -750,19 +733,7 @@ static void z_erofs_try_to_claim_pcluster(struct z_erofs_decompress_frontend *f) return; }
- /* - * type 2, link to the end of an existing open chain, be careful - * that its submission is controlled by the original attached chain. - */ - if (*owned_head != &pcl->next && pcl != f->tailpcl && - cmpxchg(&pcl->next, Z_EROFS_PCLUSTER_TAIL, - *owned_head) == Z_EROFS_PCLUSTER_TAIL) { - *owned_head = Z_EROFS_PCLUSTER_TAIL; - f->mode = Z_EROFS_PCLUSTER_HOOKED; - f->tailpcl = NULL; - return; - } - /* type 3, it belongs to a chain, but it isn't the end of the chain */ + /* type 2, it belongs to an ongoing chain */ f->mode = Z_EROFS_PCLUSTER_INFLIGHT; }
@@ -823,9 +794,6 @@ static int z_erofs_register_pcluster(struct z_erofs_decompress_frontend *fe) goto err_out; } } - /* used to check tail merging loop due to corrupted images */ - if (fe->owned_head == Z_EROFS_PCLUSTER_TAIL) - fe->tailpcl = pcl; fe->owned_head = &pcl->next; fe->pcl = pcl; return 0; @@ -846,7 +814,6 @@ static int z_erofs_collector_begin(struct z_erofs_decompress_frontend *fe)
/* must be Z_EROFS_PCLUSTER_TAIL or pointed to previous pcluster */ DBG_BUGON(fe->owned_head == Z_EROFS_PCLUSTER_NIL); - DBG_BUGON(fe->owned_head == Z_EROFS_PCLUSTER_TAIL_CLOSED);
if (!(map->m_flags & EROFS_MAP_META)) { grp = erofs_find_workgroup(fe->inode->i_sb, @@ -865,10 +832,6 @@ static int z_erofs_collector_begin(struct z_erofs_decompress_frontend *fe)
if (ret == -EEXIST) { mutex_lock(&fe->pcl->lock); - /* used to check tail merging loop due to corrupted images */ - if (fe->owned_head == Z_EROFS_PCLUSTER_TAIL) - fe->tailpcl = fe->pcl; - z_erofs_try_to_claim_pcluster(fe); } else if (ret) { return ret; @@ -1025,8 +988,7 @@ static int z_erofs_do_read_page(struct z_erofs_decompress_frontend *fe, * those chains are handled asynchronously thus the page cannot be used * for inplace I/O or bvpage (should be processed in a strict order.) */ - tight &= (fe->mode >= Z_EROFS_PCLUSTER_HOOKED && - fe->mode != Z_EROFS_PCLUSTER_FOLLOWED_NOINPLACE); + tight &= (fe->mode > Z_EROFS_PCLUSTER_FOLLOWED_NOINPLACE);
cur = end - min_t(unsigned int, offset + end - map->m_la, end); if (!(map->m_flags & EROFS_MAP_MAPPED)) { @@ -1407,10 +1369,7 @@ static void z_erofs_decompress_queue(const struct z_erofs_decompressqueue *io, }; z_erofs_next_pcluster_t owned = io->head;
- while (owned != Z_EROFS_PCLUSTER_TAIL_CLOSED) { - /* impossible that 'owned' equals Z_EROFS_WORK_TPTR_TAIL */ - DBG_BUGON(owned == Z_EROFS_PCLUSTER_TAIL); - /* impossible that 'owned' equals Z_EROFS_PCLUSTER_NIL */ + while (owned != Z_EROFS_PCLUSTER_TAIL) { DBG_BUGON(owned == Z_EROFS_PCLUSTER_NIL);
be.pcl = container_of(owned, struct z_erofs_pcluster, next); @@ -1427,7 +1386,7 @@ static void z_erofs_decompressqueue_work(struct work_struct *work) container_of(work, struct z_erofs_decompressqueue, u.work); struct page *pagepool = NULL;
- DBG_BUGON(bgq->head == Z_EROFS_PCLUSTER_TAIL_CLOSED); + DBG_BUGON(bgq->head == Z_EROFS_PCLUSTER_TAIL); z_erofs_decompress_queue(bgq, &pagepool); erofs_release_pages(&pagepool); kvfree(bgq); @@ -1615,7 +1574,7 @@ static struct z_erofs_decompressqueue *jobqueue_init(struct super_block *sb, q->sync = true; } q->sb = sb; - q->head = Z_EROFS_PCLUSTER_TAIL_CLOSED; + q->head = Z_EROFS_PCLUSTER_TAIL; return q; }
@@ -1633,11 +1592,7 @@ static void move_to_bypass_jobqueue(struct z_erofs_pcluster *pcl, z_erofs_next_pcluster_t *const submit_qtail = qtail[JQ_SUBMIT]; z_erofs_next_pcluster_t *const bypass_qtail = qtail[JQ_BYPASS];
- DBG_BUGON(owned_head == Z_EROFS_PCLUSTER_TAIL_CLOSED); - if (owned_head == Z_EROFS_PCLUSTER_TAIL) - owned_head = Z_EROFS_PCLUSTER_TAIL_CLOSED; - - WRITE_ONCE(pcl->next, Z_EROFS_PCLUSTER_TAIL_CLOSED); + WRITE_ONCE(pcl->next, Z_EROFS_PCLUSTER_TAIL);
WRITE_ONCE(*submit_qtail, owned_head); WRITE_ONCE(*bypass_qtail, &pcl->next); @@ -1708,15 +1663,10 @@ static void z_erofs_submit_queue(struct z_erofs_decompress_frontend *f, unsigned int i = 0; bool bypass = true;
- /* no possible 'owned_head' equals the following */ - DBG_BUGON(owned_head == Z_EROFS_PCLUSTER_TAIL_CLOSED); DBG_BUGON(owned_head == Z_EROFS_PCLUSTER_NIL); - pcl = container_of(owned_head, struct z_erofs_pcluster, next); + owned_head = READ_ONCE(pcl->next);
- /* close the main owned chain at first */ - owned_head = cmpxchg(&pcl->next, Z_EROFS_PCLUSTER_TAIL, - Z_EROFS_PCLUSTER_TAIL_CLOSED); if (z_erofs_is_inline_pcluster(pcl)) { move_to_bypass_jobqueue(pcl, qtail, owned_head); continue;
From: Shawn Wang shawnwang@linux.alibaba.com
[ Upstream commit 2997d94b5dd0e8b10076f5e0b6f18410c73e28bd ]
When writing a task id to the "tasks" file in an rdtgroup, rdtgroup_tasks_write() treats the pid as a number in the current pid namespace. But when reading the "tasks" file, rdtgroup_tasks_show() shows the list of global pids from the init namespace, which is confusing and incorrect.
To be more robust, let the "tasks" file only show pids in the current pid namespace.
Fixes: e02737d5b826 ("x86/intel_rdt: Add tasks files") Signed-off-by: Shawn Wang shawnwang@linux.alibaba.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Acked-by: Reinette Chatre reinette.chatre@intel.com Acked-by: Fenghua Yu fenghua.yu@intel.com Tested-by: Reinette Chatre reinette.chatre@intel.com Link: https://lore.kernel.org/all/20230116071246.97717-1-shawnwang@linux.alibaba.c... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/cpu/resctrl/rdtgroup.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c index 6ad33f355861f..61cdd9b1bb6d8 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -726,11 +726,15 @@ static ssize_t rdtgroup_tasks_write(struct kernfs_open_file *of, static void show_rdt_tasks(struct rdtgroup *r, struct seq_file *s) { struct task_struct *p, *t; + pid_t pid;
rcu_read_lock(); for_each_process_thread(p, t) { - if (is_closid_match(t, r) || is_rmid_match(t, r)) - seq_printf(s, "%d\n", t->pid); + if (is_closid_match(t, r) || is_rmid_match(t, r)) { + pid = task_pid_vnr(t); + if (pid) + seq_printf(s, "%d\n", pid); + } } rcu_read_unlock(); }
From: Li Nan linan122@huawei.com
[ Upstream commit 8d211554679d0b23702bd32ba04aeac0c1c4f660 ]
adjust_inuse_and_calc_cost() use spin_lock_irq() and IRQ will be enabled when unlock. DEADLOCK might happen if we have held other locks and disabled IRQ before invoking it.
Fix it by using spin_lock_irqsave() instead, which can keep IRQ state consistent with before when unlock.
================================ WARNING: inconsistent lock state 5.10.0-02758-g8e5f91fd772f #26 Not tainted -------------------------------- inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage. kworker/2:3/388 [HC0[0]:SC0[0]:HE0:SE1] takes: ffff888118c00c28 (&bfqd->lock){?.-.}-{2:2}, at: spin_lock_irq ffff888118c00c28 (&bfqd->lock){?.-.}-{2:2}, at: bfq_bio_merge+0x141/0x390 {IN-HARDIRQ-W} state was registered at: __lock_acquire+0x3d7/0x1070 lock_acquire+0x197/0x4a0 __raw_spin_lock_irqsave _raw_spin_lock_irqsave+0x3b/0x60 bfq_idle_slice_timer_body bfq_idle_slice_timer+0x53/0x1d0 __run_hrtimer+0x477/0xa70 __hrtimer_run_queues+0x1c6/0x2d0 hrtimer_interrupt+0x302/0x9e0 local_apic_timer_interrupt __sysvec_apic_timer_interrupt+0xfd/0x420 run_sysvec_on_irqstack_cond sysvec_apic_timer_interrupt+0x46/0xa0 asm_sysvec_apic_timer_interrupt+0x12/0x20 irq event stamp: 837522 hardirqs last enabled at (837521): [<ffffffff84b9419d>] __raw_spin_unlock_irqrestore hardirqs last enabled at (837521): [<ffffffff84b9419d>] _raw_spin_unlock_irqrestore+0x3d/0x40 hardirqs last disabled at (837522): [<ffffffff84b93fa3>] __raw_spin_lock_irq hardirqs last disabled at (837522): [<ffffffff84b93fa3>] _raw_spin_lock_irq+0x43/0x50 softirqs last enabled at (835852): [<ffffffff84e00558>] __do_softirq+0x558/0x8ec softirqs last disabled at (835845): [<ffffffff84c010ff>] asm_call_irq_on_stack+0xf/0x20
other info that might help us debug this: Possible unsafe locking scenario:
CPU0 ---- lock(&bfqd->lock); <Interrupt> lock(&bfqd->lock);
*** DEADLOCK ***
3 locks held by kworker/2:3/388: #0: ffff888107af0f38 ((wq_completion)kthrotld){+.+.}-{0:0}, at: process_one_work+0x742/0x13f0 #1: ffff8881176bfdd8 ((work_completion)(&td->dispatch_work)){+.+.}-{0:0}, at: process_one_work+0x777/0x13f0 #2: ffff888118c00c28 (&bfqd->lock){?.-.}-{2:2}, at: spin_lock_irq #2: ffff888118c00c28 (&bfqd->lock){?.-.}-{2:2}, at: bfq_bio_merge+0x141/0x390
stack backtrace: CPU: 2 PID: 388 Comm: kworker/2:3 Not tainted 5.10.0-02758-g8e5f91fd772f #26 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014 Workqueue: kthrotld blk_throtl_dispatch_work_fn Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x107/0x167 print_usage_bug valid_state mark_lock_irq.cold+0x32/0x3a mark_lock+0x693/0xbc0 mark_held_locks+0x9e/0xe0 __trace_hardirqs_on_caller lockdep_hardirqs_on_prepare.part.0+0x151/0x360 trace_hardirqs_on+0x5b/0x180 __raw_spin_unlock_irq _raw_spin_unlock_irq+0x24/0x40 spin_unlock_irq adjust_inuse_and_calc_cost+0x4fb/0x970 ioc_rqos_merge+0x277/0x740 __rq_qos_merge+0x62/0xb0 rq_qos_merge bio_attempt_back_merge+0x12c/0x4a0 blk_mq_sched_try_merge+0x1b6/0x4d0 bfq_bio_merge+0x24a/0x390 __blk_mq_sched_bio_merge+0xa6/0x460 blk_mq_sched_bio_merge blk_mq_submit_bio+0x2e7/0x1ee0 __submit_bio_noacct_mq+0x175/0x3b0 submit_bio_noacct+0x1fb/0x270 blk_throtl_dispatch_work_fn+0x1ef/0x2b0 process_one_work+0x83e/0x13f0 process_scheduled_works worker_thread+0x7e3/0xd80 kthread+0x353/0x470 ret_from_fork+0x1f/0x30
Fixes: b0853ab4a238 ("blk-iocost: revamp in-period donation snapbacks") Signed-off-by: Li Nan linan122@huawei.com Acked-by: Tejun Heo tj@kernel.org Reviewed-by: Yu Kuai yukuai3@huawei.com Link: https://lore.kernel.org/r/20230527091904.3001833-1-linan666@huaweicloud.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-iocost.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/block/blk-iocost.c b/block/blk-iocost.c index 285ced3467abb..6084a9519883e 100644 --- a/block/blk-iocost.c +++ b/block/blk-iocost.c @@ -2455,6 +2455,7 @@ static u64 adjust_inuse_and_calc_cost(struct ioc_gq *iocg, u64 vtime, u32 hwi, adj_step; s64 margin; u64 cost, new_inuse; + unsigned long flags;
current_hweight(iocg, NULL, &hwi); old_hwi = hwi; @@ -2473,11 +2474,11 @@ static u64 adjust_inuse_and_calc_cost(struct ioc_gq *iocg, u64 vtime, iocg->inuse == iocg->active) return cost;
- spin_lock_irq(&ioc->lock); + spin_lock_irqsave(&ioc->lock, flags);
/* we own inuse only when @iocg is in the normal active state */ if (iocg->abs_vdebt || list_empty(&iocg->active_list)) { - spin_unlock_irq(&ioc->lock); + spin_unlock_irqrestore(&ioc->lock, flags); return cost; }
@@ -2498,7 +2499,7 @@ static u64 adjust_inuse_and_calc_cost(struct ioc_gq *iocg, u64 vtime, } while (time_after64(vtime + cost, now->vnow) && iocg->inuse != iocg->active);
- spin_unlock_irq(&ioc->lock); + spin_unlock_irqrestore(&ioc->lock, flags);
TRACE_IOCG_PATH(inuse_adjust, iocg, now, old_inuse, iocg->inuse, old_hwi, hwi);
From: Tom Lendacky thomas.lendacky@amd.com
[ Upstream commit 5dee19b6b2b194216919b99a1f5af2949a754016 ]
When calculating an end address based on an unsigned int number of pages, any value greater than or equal to 0x100000 that is shift PAGE_SHIFT bits results in a 0 value, resulting in an invalid end address. Change the number of pages variable in various routines from an unsigned int to an unsigned long to calculate the end address correctly.
Fixes: 5e5ccff60a29 ("x86/sev: Add helper for validating pages in early enc attribute changes") Fixes: dc3f3d2474b8 ("x86/mm: Validate memory when changing the C-bit") Signed-off-by: Tom Lendacky thomas.lendacky@amd.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Link: https://lore.kernel.org/r/6a6e4eea0e1414402bac747744984fa4e9c01bb6.168606308... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/include/asm/sev.h | 16 ++++++++-------- arch/x86/kernel/sev.c | 14 +++++++------- 2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h index ebc271bb6d8ed..a0a58c4122ec3 100644 --- a/arch/x86/include/asm/sev.h +++ b/arch/x86/include/asm/sev.h @@ -187,12 +187,12 @@ static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate) } void setup_ghcb(void); void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, - unsigned int npages); + unsigned long npages); void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, - unsigned int npages); + unsigned long npages); void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op); -void snp_set_memory_shared(unsigned long vaddr, unsigned int npages); -void snp_set_memory_private(unsigned long vaddr, unsigned int npages); +void snp_set_memory_shared(unsigned long vaddr, unsigned long npages); +void snp_set_memory_private(unsigned long vaddr, unsigned long npages); void snp_set_wakeup_secondary_cpu(void); bool snp_init(struct boot_params *bp); void __init __noreturn snp_abort(void); @@ -207,12 +207,12 @@ static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate) static inline int rmpadjust(unsigned long vaddr, bool rmp_psize, unsigned long attrs) { return 0; } static inline void setup_ghcb(void) { } static inline void __init -early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, unsigned int npages) { } +early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, unsigned long npages) { } static inline void __init -early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, unsigned int npages) { } +early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, unsigned long npages) { } static inline void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op) { } -static inline void snp_set_memory_shared(unsigned long vaddr, unsigned int npages) { } -static inline void snp_set_memory_private(unsigned long vaddr, unsigned int npages) { } +static inline void snp_set_memory_shared(unsigned long vaddr, unsigned long npages) { } +static inline void snp_set_memory_private(unsigned long vaddr, unsigned long npages) { } static inline void snp_set_wakeup_secondary_cpu(void) { } static inline bool snp_init(struct boot_params *bp) { return false; } static inline void snp_abort(void) { } diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c index 3f664ab277c49..45ef3926381f8 100644 --- a/arch/x86/kernel/sev.c +++ b/arch/x86/kernel/sev.c @@ -643,7 +643,7 @@ static u64 __init get_jump_table_addr(void) return ret; }
-static void pvalidate_pages(unsigned long vaddr, unsigned int npages, bool validate) +static void pvalidate_pages(unsigned long vaddr, unsigned long npages, bool validate) { unsigned long vaddr_end; int rc; @@ -660,7 +660,7 @@ static void pvalidate_pages(unsigned long vaddr, unsigned int npages, bool valid } }
-static void __init early_set_pages_state(unsigned long paddr, unsigned int npages, enum psc_op op) +static void __init early_set_pages_state(unsigned long paddr, unsigned long npages, enum psc_op op) { unsigned long paddr_end; u64 val; @@ -699,7 +699,7 @@ static void __init early_set_pages_state(unsigned long paddr, unsigned int npage }
void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, - unsigned int npages) + unsigned long npages) { /* * This can be invoked in early boot while running identity mapped, so @@ -721,7 +721,7 @@ void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long padd }
void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, - unsigned int npages) + unsigned long npages) { /* * This can be invoked in early boot while running identity mapped, so @@ -877,7 +877,7 @@ static void __set_pages_state(struct snp_psc_desc *data, unsigned long vaddr, sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC); }
-static void set_pages_state(unsigned long vaddr, unsigned int npages, int op) +static void set_pages_state(unsigned long vaddr, unsigned long npages, int op) { unsigned long vaddr_end, next_vaddr; struct snp_psc_desc *desc; @@ -902,7 +902,7 @@ static void set_pages_state(unsigned long vaddr, unsigned int npages, int op) kfree(desc); }
-void snp_set_memory_shared(unsigned long vaddr, unsigned int npages) +void snp_set_memory_shared(unsigned long vaddr, unsigned long npages) { if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) return; @@ -912,7 +912,7 @@ void snp_set_memory_shared(unsigned long vaddr, unsigned int npages) set_pages_state(vaddr, npages, SNP_PAGE_STATE_SHARED); }
-void snp_set_memory_private(unsigned long vaddr, unsigned int npages) +void snp_set_memory_private(unsigned long vaddr, unsigned long npages) { if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) return;
From: Waiman Long longman@redhat.com
[ Upstream commit 3d2af77e31ade05ff7ccc3658c3635ec1bea0979 ]
When blkg_alloc() is called to allocate a blkcg_gq structure with the associated blkg_iostat_set's, there are 2 fields within blkg_iostat_set that requires proper initialization - blkg & sync. The former field was introduced by commit 3b8cc6298724 ("blk-cgroup: Optimize blkcg_rstat_flush()") while the later one was introduced by commit f73316482977 ("blk-cgroup: reimplement basic IO stats using cgroup rstat").
Unfortunately those fields in the blkg_iostat_set's are not properly re-initialized when they are cleared in v1's blkcg_reset_stats(). This can lead to a kernel panic due to NULL pointer access of the blkg pointer. The missing initialization of sync is less problematic and can be a problem in a debug kernel due to missing lockdep initialization.
Fix these problems by re-initializing them after memory clearing.
Fixes: 3b8cc6298724 ("blk-cgroup: Optimize blkcg_rstat_flush()") Fixes: f73316482977 ("blk-cgroup: reimplement basic IO stats using cgroup rstat") Signed-off-by: Waiman Long longman@redhat.com Reviewed-by: Ming Lei ming.lei@redhat.com Acked-by: Tejun Heo tj@kernel.org Link: https://lore.kernel.org/r/20230606180724.2455066-1-longman@redhat.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-cgroup.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index ad0cd992a6519..c50da8b3af029 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -585,8 +585,13 @@ static int blkcg_reset_stats(struct cgroup_subsys_state *css, struct blkg_iostat_set *bis = per_cpu_ptr(blkg->iostat_cpu, cpu); memset(bis, 0, sizeof(*bis)); + + /* Re-initialize the cleared blkg_iostat_set */ + u64_stats_init(&bis->sync); + bis->blkg = blkg; } memset(&blkg->iostat, 0, sizeof(blkg->iostat)); + u64_stats_init(&blkg->iostat.sync);
for (i = 0; i < BLKCG_MAX_POLS; i++) { struct blkcg_policy *pol = blkcg_policy[i];
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 84b9b44b99780d35fe72ac63c4724f158771e898 ]
This driver fails to link when CRYPTO is disabled, or in a loadable module:
WARNING: unmet direct dependencies detected for CRYPTO_GCM WARNING: unmet direct dependencies detected for CRYPTO_AEAD2 Depends on [m]: CRYPTO [=m] Selected by [y]: - SEV_GUEST [=y] && VIRT_DRIVERS [=y] && AMD_MEM_ENCRYPT [=y]
x86_64-linux-ld: crypto/aead.o: in function `crypto_register_aeads':
Fixes: fce96cf04430 ("virt: Add SEV-SNP guest driver") Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Link: https://lore.kernel.org/r/20230117171416.2715125-1-arnd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/virt/coco/sev-guest/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/virt/coco/sev-guest/Kconfig b/drivers/virt/coco/sev-guest/Kconfig index f9db0799ae67c..da2d7ca531f0f 100644 --- a/drivers/virt/coco/sev-guest/Kconfig +++ b/drivers/virt/coco/sev-guest/Kconfig @@ -2,6 +2,7 @@ config SEV_GUEST tristate "AMD SEV Guest driver" default m depends on AMD_MEM_ENCRYPT + select CRYPTO select CRYPTO_AEAD2 select CRYPTO_GCM help
From: Yu Kuai yukuai3@huawei.com
[ Upstream commit 4f1731df60f9033669f024d06ae26a6301260b55 ]
In __blk_mq_tag_busy/idle(), updating 'active_queues' and calculating 'wake_batch' is not atomic:
t1: t2: _blk_mq_tag_busy blk_mq_tag_busy inc active_queues // assume 1->2 inc active_queues // 2 -> 3 blk_mq_update_wake_batch // calculate based on 3 blk_mq_update_wake_batch /* calculate based on 2, while active_queues is actually 3. */
Fix this problem by protecting them wih 'tags->lock', this is not a hot path, so performance should not be concerned. And now that all writers are inside the lock, switch 'actives_queues' from atomic to unsigned int.
Fixes: 180dccb0dba4 ("blk-mq: fix tag_get wait task can't be awakened") Signed-off-by: Yu Kuai yukuai3@huawei.com Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20230610023043.2559121-1-yukuai1@huaweicloud.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-mq-debugfs.c | 2 +- block/blk-mq-tag.c | 15 ++++++++++----- block/blk-mq.h | 3 +-- include/linux/blk-mq.h | 3 +-- 4 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c index b01818f8e216e..c152276736832 100644 --- a/block/blk-mq-debugfs.c +++ b/block/blk-mq-debugfs.c @@ -427,7 +427,7 @@ static void blk_mq_debugfs_tags_show(struct seq_file *m, seq_printf(m, "nr_tags=%u\n", tags->nr_tags); seq_printf(m, "nr_reserved_tags=%u\n", tags->nr_reserved_tags); seq_printf(m, "active_queues=%d\n", - atomic_read(&tags->active_queues)); + READ_ONCE(tags->active_queues));
seq_puts(m, "\nbitmap_tags:\n"); sbitmap_queue_show(&tags->bitmap_tags, m); diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c index a80d7c62bdfe6..100889c276c3f 100644 --- a/block/blk-mq-tag.c +++ b/block/blk-mq-tag.c @@ -40,6 +40,7 @@ static void blk_mq_update_wake_batch(struct blk_mq_tags *tags, void __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx) { unsigned int users; + struct blk_mq_tags *tags = hctx->tags;
/* * calling test_bit() prior to test_and_set_bit() is intentional, @@ -57,9 +58,11 @@ void __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx) return; }
- users = atomic_inc_return(&hctx->tags->active_queues); - - blk_mq_update_wake_batch(hctx->tags, users); + spin_lock_irq(&tags->lock); + users = tags->active_queues + 1; + WRITE_ONCE(tags->active_queues, users); + blk_mq_update_wake_batch(tags, users); + spin_unlock_irq(&tags->lock); }
/* @@ -92,9 +95,11 @@ void __blk_mq_tag_idle(struct blk_mq_hw_ctx *hctx) return; }
- users = atomic_dec_return(&tags->active_queues); - + spin_lock_irq(&tags->lock); + users = tags->active_queues - 1; + WRITE_ONCE(tags->active_queues, users); blk_mq_update_wake_batch(tags, users); + spin_unlock_irq(&tags->lock);
blk_mq_tag_wakeup_all(tags, false); } diff --git a/block/blk-mq.h b/block/blk-mq.h index a7482d2cc82e7..4542308c8e62f 100644 --- a/block/blk-mq.h +++ b/block/blk-mq.h @@ -362,8 +362,7 @@ static inline bool hctx_may_queue(struct blk_mq_hw_ctx *hctx, return true; }
- users = atomic_read(&hctx->tags->active_queues); - + users = READ_ONCE(hctx->tags->active_queues); if (!users) return true;
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index de0b0c3e7395a..4110d6e99b2b9 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h @@ -748,8 +748,7 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q, struct blk_mq_tags { unsigned int nr_tags; unsigned int nr_reserved_tags; - - atomic_t active_queues; + unsigned int active_queues;
struct sbitmap_queue bitmap_tags; struct sbitmap_queue breserved_tags;
From: NeilBrown neilb@suse.de
[ Upstream commit 665e89ab7c5af1f2d260834c861a74b01a30f95f ]
The below-mentioned patch was intended to simplify refcounting on the svc_serv used by locked. The goal was to only ever have a single reference from the single thread. To that end we dropped a call to lockd_start_svc() (except when creating thread) which would take a reference, and dropped the svc_put(serv) that would drop that reference.
Unfortunately we didn't also remove the svc_get() from lockd_create_svc() in the case where the svc_serv already existed. So after the patch: - on the first call the svc_serv was allocated and the one reference was given to the thread, so there are no extra references - on subsequent calls svc_get() was called so there is now an extra reference. This is clearly not consistent.
The inconsistency is also clear in the current code in lockd_get() takes *two* references, one on nlmsvc_serv and one by incrementing nlmsvc_users. This clearly does not match lockd_put().
So: drop that svc_get() from lockd_get() (which used to be in lockd_create_svc().
Reported-by: Ido Schimmel idosch@idosch.org Closes: https://lore.kernel.org/linux-nfs/ZHsI%2FH16VX9kJQX1@shredder/T/#u Fixes: b73a2972041b ("lockd: move lockd_start_svc() call into lockd_create_svc()") Signed-off-by: NeilBrown neilb@suse.de Tested-by: Ido Schimmel idosch@nvidia.com Signed-off-by: Chuck Lever chuck.lever@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/lockd/svc.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 9a47303b2cba6..0c05668019c2b 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -355,7 +355,6 @@ static int lockd_get(void) int error;
if (nlmsvc_serv) { - svc_get(nlmsvc_serv); nlmsvc_users++; return 0; }
From: Chaitanya Kulkarni kch@nvidia.com
[ Upstream commit a836ca33c5b07d34dd5347af9f64d25651d12674 ]
Free dhchap_secret in nvme_ctrl_dhchap_secret_store() before we return fix following kmemleack:-
unreferenced object 0xffff8886376ea800 (size 64): comm "check", pid 22048, jiffies 4344316705 (age 92.199s) hex dump (first 32 bytes): 44 48 48 43 2d 31 3a 30 30 3a 6e 78 72 35 4b 67 DHHC-1:00:nxr5Kg 75 58 34 75 6f 41 78 73 4a 61 34 63 2f 68 75 4c uX4uoAxsJa4c/huL backtrace: [<0000000030ce5d4b>] __kmalloc+0x4b/0x130 [<000000009be1cdc1>] nvme_ctrl_dhchap_secret_store+0x8f/0x160 [nvme_core] [<00000000ac06c96a>] kernfs_fop_write_iter+0x12b/0x1c0 [<00000000437e7ced>] vfs_write+0x2ba/0x3c0 [<00000000f9491baf>] ksys_write+0x5f/0xe0 [<000000001c46513d>] do_syscall_64+0x3b/0x90 [<00000000ecf348fe>] entry_SYSCALL_64_after_hwframe+0x72/0xdc unreferenced object 0xffff8886376eaf00 (size 64): comm "check", pid 22048, jiffies 4344316736 (age 92.168s) hex dump (first 32 bytes): 44 48 48 43 2d 31 3a 30 30 3a 6e 78 72 35 4b 67 DHHC-1:00:nxr5Kg 75 58 34 75 6f 41 78 73 4a 61 34 63 2f 68 75 4c uX4uoAxsJa4c/huL backtrace: [<0000000030ce5d4b>] __kmalloc+0x4b/0x130 [<000000009be1cdc1>] nvme_ctrl_dhchap_secret_store+0x8f/0x160 [nvme_core] [<00000000ac06c96a>] kernfs_fop_write_iter+0x12b/0x1c0 [<00000000437e7ced>] vfs_write+0x2ba/0x3c0 [<00000000f9491baf>] ksys_write+0x5f/0xe0 [<000000001c46513d>] do_syscall_64+0x3b/0x90 [<00000000ecf348fe>] entry_SYSCALL_64_after_hwframe+0x72/0xdc
Fixes: f50fff73d620 ("nvme: implement In-Band authentication") Signed-off-by: Chaitanya Kulkarni kch@nvidia.com Tested-by: Yi Zhang yi.zhang@redhat.com Reviewed-by: Christoph Hellwig hch@lst.de Reviewed-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Keith Busch kbusch@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 8a632bf7f5a8f..8a706ca1b3e14 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -3872,8 +3872,10 @@ static ssize_t nvme_ctrl_dhchap_secret_store(struct device *dev, int ret;
ret = nvme_auth_generate_key(dhchap_secret, &key); - if (ret) + if (ret) { + kfree(dhchap_secret); return ret; + } kfree(opts->dhchap_secret); opts->dhchap_secret = dhchap_secret; host_key = ctrl->host_key; @@ -3881,7 +3883,8 @@ static ssize_t nvme_ctrl_dhchap_secret_store(struct device *dev, ctrl->host_key = key; mutex_unlock(&ctrl->dhchap_auth_mutex); nvme_auth_free_key(host_key); - } + } else + kfree(dhchap_secret); /* Start re-authentication */ dev_info(ctrl->device, "re-authenticating controller\n"); queue_work(nvme_wq, &ctrl->dhchap_auth_work);
From: Chaitanya Kulkarni kch@nvidia.com
[ Upstream commit 99c2dcc8ffc24e210a3aa05c204d92f3ef460b05 ]
Free dhchap_secret in nvme_ctrl_dhchap_ctrl_secret_store() before we return when nvme_auth_generate_key() returns error.
Fixes: f50fff73d620 ("nvme: implement In-Band authentication") Signed-off-by: Chaitanya Kulkarni kch@nvidia.com Reviewed-by: Christoph Hellwig hch@lst.de Reviewed-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Keith Busch kbusch@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 8a706ca1b3e14..b03f5a34b1ee0 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -3929,8 +3929,10 @@ static ssize_t nvme_ctrl_dhchap_ctrl_secret_store(struct device *dev, int ret;
ret = nvme_auth_generate_key(dhchap_secret, &key); - if (ret) + if (ret) { + kfree(dhchap_secret); return ret; + } kfree(opts->dhchap_ctrl_secret); opts->dhchap_ctrl_secret = dhchap_secret; ctrl_key = ctrl->ctrl_key; @@ -3938,7 +3940,8 @@ static ssize_t nvme_ctrl_dhchap_ctrl_secret_store(struct device *dev, ctrl->ctrl_key = key; mutex_unlock(&ctrl->dhchap_auth_mutex); nvme_auth_free_key(ctrl_key); - } + } else + kfree(dhchap_secret); /* Start re-authentication */ dev_info(ctrl->device, "re-authenticating controller\n"); queue_work(nvme_wq, &ctrl->dhchap_auth_work);
From: Chaitanya Kulkarni kch@nvidia.com
[ Upstream commit 3a12a0b868a512fcada564699d00f5e652c0998c ]
Add missing fault-injection cleanup in nvme_init_ctrl() in the error unwind path that also fixes following message for blktests:-
linux-block (for-next) # grep debugfs debugfs-err.log [ 147.853464] debugfs: Directory 'nvme1' with parent '/' already present! [ 147.853973] nvme1: failed to create debugfs attr [ 148.802490] debugfs: Directory 'nvme1' with parent '/' already present! [ 148.803244] nvme1: failed to create debugfs attr [ 148.877304] debugfs: Directory 'nvme1' with parent '/' already present! [ 148.877775] nvme1: failed to create debugfs attr [ 149.816652] debugfs: Directory 'nvme1' with parent '/' already present! [ 149.818011] nvme1: failed to create debugfs attr
Signed-off-by: Chaitanya Kulkarni kch@nvidia.com Tested-by: Yi Zhang yi.zhang@redhat.com Reviewed-by: Christoph Hellwig hch@lst.de Reviewed-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Keith Busch kbusch@kernel.org Stable-dep-of: 7ed5cf8e6d9b ("nvme-core: fix dev_pm_qos memleak") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index b03f5a34b1ee0..f07fd2fed3f9d 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -5249,6 +5249,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
return 0; out_free_cdev: + nvme_fault_inject_fini(&ctrl->fault_inject); cdev_device_del(&ctrl->cdev, ctrl->device); out_free_name: nvme_put_ctrl(ctrl);
From: Chaitanya Kulkarni kch@nvidia.com
[ Upstream commit 7ed5cf8e6d9bfb6a78d0471317edff14f0f2b4dd ]
Call dev_pm_qos_hide_latency_tolerance() in the error unwind patch to avoid following kmemleak:-
blktests (master) # kmemleak-clear; ./check nvme/044; blktests (master) # kmemleak-scan ; kmemleak-show nvme/044 (Test bi-directional authentication) [passed] runtime 2.111s ... 2.124s unreferenced object 0xffff888110c46240 (size 96): comm "nvme", pid 33461, jiffies 4345365353 (age 75.586s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<0000000069ac2cec>] kmalloc_trace+0x25/0x90 [<000000006acc66d5>] dev_pm_qos_update_user_latency_tolerance+0x6f/0x100 [<00000000cc376ea7>] nvme_init_ctrl+0x38e/0x410 [nvme_core] [<000000007df61b4b>] 0xffffffffc05e88b3 [<00000000d152b985>] 0xffffffffc05744cb [<00000000f04a4041>] vfs_write+0xc5/0x3c0 [<00000000f9491baf>] ksys_write+0x5f/0xe0 [<000000001c46513d>] do_syscall_64+0x3b/0x90 [<00000000ecf348fe>] entry_SYSCALL_64_after_hwframe+0x72/0xdc
Link: https://lore.kernel.org/linux-nvme/CAHj4cs-nDaKzMx2txO4dbE+Mz9ePwLtU0e3egz+S... Fixes: f50fff73d620 ("nvme: implement In-Band authentication") Signed-off-by: Chaitanya Kulkarni kch@nvidia.com Tested-by: Yi Zhang yi.zhang@redhat.com Reviewed-by: Christoph Hellwig hch@lst.de Reviewed-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Keith Busch kbusch@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index f07fd2fed3f9d..8d8403b65e1b3 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -5250,6 +5250,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev, return 0; out_free_cdev: nvme_fault_inject_fini(&ctrl->fault_inject); + dev_pm_qos_hide_latency_tolerance(ctrl->device); cdev_device_del(&ctrl->cdev, ctrl->device); out_free_name: nvme_put_ctrl(ctrl);
From: Li Nan linan122@huawei.com
[ Upstream commit 301867b1c16805aebbc306aafa6ecdc68b73c7e5 ]
If we write a large number to md/bitmap_set_bits, md_bitmap_checkpage() will return -EINVAL because 'page >= bitmap->pages', but the return value was not checked immediately in md_bitmap_get_counter() in order to set *blocks value and slab-out-of-bounds occurs.
Move check of 'page >= bitmap->pages' to md_bitmap_get_counter() and return directly if true.
Fixes: ef4256733506 ("md/bitmap: optimise scanning of empty bitmaps.") Signed-off-by: Li Nan linan122@huawei.com Reviewed-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230515134808.3936750-2-linan666@huaweicloud.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/md-bitmap.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index e7cc6ba1b657f..9640741e8d369 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -54,14 +54,7 @@ __acquires(bitmap->lock) { unsigned char *mappage;
- if (page >= bitmap->pages) { - /* This can happen if bitmap_start_sync goes beyond - * End-of-device while looking for a whole page. - * It is harmless. - */ - return -EINVAL; - } - + WARN_ON_ONCE(page >= bitmap->pages); if (bitmap->bp[page].hijacked) /* it's hijacked, don't try to alloc */ return 0;
@@ -1364,6 +1357,14 @@ __acquires(bitmap->lock) sector_t csize; int err;
+ if (page >= bitmap->pages) { + /* + * This can happen if bitmap_start_sync goes beyond + * End-of-device while looking for a whole page or + * user set a huge number to sysfs bitmap_set_bits. + */ + return NULL; + } err = md_bitmap_checkpage(bitmap, page, create, 0);
if (bitmap->bp[page].hijacked ||
From: Li Nan linan122@huawei.com
[ Upstream commit 6beb489b2eed25978523f379a605073f99240c50 ]
There is no input check when echo md/safe_mode_delay in safe_delay_store(). And msec might also overflow when HZ < 1000 in safe_delay_show(), Fix it by checking overflow in safe_delay_store() and use unsigned long conversion in safe_delay_show().
Fixes: 72e02075a33f ("md: factor out parsing of fixed-point numbers") Signed-off-by: Li Nan linan122@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230522072535.1523740-2-linan666@huaweicloud.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/md.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/md/md.c b/drivers/md/md.c index d479e1656ef33..61ad7dfe0e99a 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3814,8 +3814,9 @@ int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale) static ssize_t safe_delay_show(struct mddev *mddev, char *page) { - int msec = (mddev->safemode_delay*1000)/HZ; - return sprintf(page, "%d.%03d\n", msec/1000, msec%1000); + unsigned int msec = ((unsigned long)mddev->safemode_delay*1000)/HZ; + + return sprintf(page, "%u.%03u\n", msec/1000, msec%1000); } static ssize_t safe_delay_store(struct mddev *mddev, const char *cbuf, size_t len) @@ -3827,7 +3828,7 @@ safe_delay_store(struct mddev *mddev, const char *cbuf, size_t len) return -EINVAL; }
- if (strict_strtoul_scaled(cbuf, &msec, 3) < 0) + if (strict_strtoul_scaled(cbuf, &msec, 3) < 0 || msec > UINT_MAX / HZ) return -EINVAL; if (msec == 0) mddev->safemode_delay = 0;
From: Li Nan linan122@huawei.com
[ Upstream commit f8b20a405428803bd9881881d8242c9d72c6b2b2 ]
There is no input check when echo md/max_read_errors and overflow might occur. Add check of input number.
Fixes: 1e50915fe0bb ("raid: improve MD/raid10 handling of correctable read errors.") Signed-off-by: Li Nan linan122@huawei.com Reviewed-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230522072535.1523740-3-linan666@huaweicloud.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/md.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/md/md.c b/drivers/md/md.c index 61ad7dfe0e99a..2674cb1d699c0 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4498,6 +4498,8 @@ max_corrected_read_errors_store(struct mddev *mddev, const char *buf, size_t len rv = kstrtouint(buf, 10, &n); if (rv < 0) return rv; + if (n > INT_MAX) + return -EINVAL; atomic_set(&mddev->max_corr_read_errors, n); return len; }
From: Li Nan linan122@huawei.com
[ Upstream commit 34817a2441747b48e444cb0e05d84e14bc9443da ]
There are two check of 'mreplace' in raid10_sync_request(). In the first check, 'need_replace' will be set and 'mreplace' will be used later if no-Faulty 'mreplace' exists, In the second check, 'mreplace' will be set to NULL if it is Faulty, but 'need_replace' will not be changed accordingly. null-ptr-deref occurs if Faulty is set between two check.
Fix it by merging two checks into one. And replace 'need_replace' with 'mreplace' because their values are always the same.
Fixes: ee37d7314a32 ("md/raid10: Fix raid10 replace hang when new added disk faulty") Signed-off-by: Li Nan linan122@huawei.com Reviewed-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230527072218.2365857-2-linan666@huaweicloud.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/raid10.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index ea6967aeaa02a..7b5f26726b310 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -3436,7 +3436,6 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr, int must_sync; int any_working; int need_recover = 0; - int need_replace = 0; struct raid10_info *mirror = &conf->mirrors[i]; struct md_rdev *mrdev, *mreplace;
@@ -3448,11 +3447,10 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr, !test_bit(Faulty, &mrdev->flags) && !test_bit(In_sync, &mrdev->flags)) need_recover = 1; - if (mreplace != NULL && - !test_bit(Faulty, &mreplace->flags)) - need_replace = 1; + if (mreplace && test_bit(Faulty, &mreplace->flags)) + mreplace = NULL;
- if (!need_recover && !need_replace) { + if (!need_recover && !mreplace) { rcu_read_unlock(); continue; } @@ -3468,8 +3466,6 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr, rcu_read_unlock(); continue; } - if (mreplace && test_bit(Faulty, &mreplace->flags)) - mreplace = NULL; /* Unless we are doing a full sync, or a replacement * we only need to recover the block if it is set in * the bitmap @@ -3592,11 +3588,11 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr, bio = r10_bio->devs[1].repl_bio; if (bio) bio->bi_end_io = NULL; - /* Note: if need_replace, then bio + /* Note: if replace is not NULL, then bio * cannot be NULL as r10buf_pool_alloc will * have allocated it. */ - if (!need_replace) + if (!mreplace) break; bio->bi_next = biolist; biolist = bio;
From: Li Nan linan122@huawei.com
[ Upstream commit 2ae6aaf76912bae53c74b191569d2ab484f24bf3 ]
When removing a disk with replacement, the replacement will be used to replace rdev. During this process, there is a brief window in which both rdev and replacement are read as NULL in raid10_write_request(). This will result in io not being submitted but it should be.
//remove //write raid10_remove_disk raid10_write_request mirror->rdev = NULL read rdev -> NULL mirror->rdev = mirror->replacement mirror->replacement = NULL read replacement -> NULL
Fix it by reading replacement first and rdev later, meanwhile, use smp_mb() to prevent memory reordering.
Fixes: 475b0321a4df ("md/raid10: writes should get directed to replacement as well as original.") Signed-off-by: Li Nan linan122@huawei.com Reviewed-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230602091839.743798-3-linan666@huaweicloud.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/raid10.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 7b5f26726b310..5af4e8aa08e96 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -779,8 +779,16 @@ static struct md_rdev *read_balance(struct r10conf *conf, disk = r10_bio->devs[slot].devnum; rdev = rcu_dereference(conf->mirrors[disk].replacement); if (rdev == NULL || test_bit(Faulty, &rdev->flags) || - r10_bio->devs[slot].addr + sectors > rdev->recovery_offset) + r10_bio->devs[slot].addr + sectors > + rdev->recovery_offset) { + /* + * Read replacement first to prevent reading both rdev + * and replacement as NULL during replacement replace + * rdev. + */ + smp_mb(); rdev = rcu_dereference(conf->mirrors[disk].rdev); + } if (rdev == NULL || test_bit(Faulty, &rdev->flags)) continue; @@ -1477,9 +1485,15 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
for (i = 0; i < conf->copies; i++) { int d = r10_bio->devs[i].devnum; - struct md_rdev *rdev = rcu_dereference(conf->mirrors[d].rdev); - struct md_rdev *rrdev = rcu_dereference( - conf->mirrors[d].replacement); + struct md_rdev *rdev, *rrdev; + + rrdev = rcu_dereference(conf->mirrors[d].replacement); + /* + * Read replacement first to prevent reading both rdev and + * replacement as NULL during replacement replace rdev. + */ + smp_mb(); + rdev = rcu_dereference(conf->mirrors[d].rdev); if (rdev == rrdev) rrdev = NULL; if (rdev && (test_bit(Faulty, &rdev->flags)))
From: Yu Kuai yukuai3@huawei.com
[ Upstream commit 5ec6ca140a034682e421e2e808ef5ddfdfd65242 ]
The code in raid1 and raid10 is identical, prepare to limit the number of plugged bios.
Signed-off-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230529131106.2123367-3-yukuai1@huaweicloud.com Stable-dep-of: 7db922bae3ab ("md/raid1-10: submit write io directly if bitmap is not enabled") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/raid1-10.c | 16 ++++++++++++++++ drivers/md/raid1.c | 12 +----------- drivers/md/raid10.c | 11 +---------- 3 files changed, 18 insertions(+), 21 deletions(-)
diff --git a/drivers/md/raid1-10.c b/drivers/md/raid1-10.c index e61f6cad4e08e..9bf19a3409cef 100644 --- a/drivers/md/raid1-10.c +++ b/drivers/md/raid1-10.c @@ -109,3 +109,19 @@ static void md_bio_reset_resync_pages(struct bio *bio, struct resync_pages *rp, size -= len; } while (idx++ < RESYNC_PAGES && size > 0); } + +static inline bool raid1_add_bio_to_plug(struct mddev *mddev, struct bio *bio, + blk_plug_cb_fn unplug) +{ + struct raid1_plug_cb *plug = NULL; + struct blk_plug_cb *cb = blk_check_plugged(unplug, mddev, + sizeof(*plug)); + + if (!cb) + return false; + + plug = container_of(cb, struct raid1_plug_cb, cb); + bio_list_add(&plug->pending, bio); + + return true; +} diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 68a9e2d9985b2..131d8fd5ccaab 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1343,8 +1343,6 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, struct bitmap *bitmap = mddev->bitmap; unsigned long flags; struct md_rdev *blocked_rdev; - struct blk_plug_cb *cb; - struct raid1_plug_cb *plug = NULL; int first_clone; int max_sectors; bool write_behind = false; @@ -1573,15 +1571,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, r1_bio->sector); /* flush_pending_writes() needs access to the rdev so...*/ mbio->bi_bdev = (void *)rdev; - - cb = blk_check_plugged(raid1_unplug, mddev, sizeof(*plug)); - if (cb) - plug = container_of(cb, struct raid1_plug_cb, cb); - else - plug = NULL; - if (plug) { - bio_list_add(&plug->pending, mbio); - } else { + if (!raid1_add_bio_to_plug(mddev, mbio, raid1_unplug)) { spin_lock_irqsave(&conf->device_lock, flags); bio_list_add(&conf->pending_bio_list, mbio); spin_unlock_irqrestore(&conf->device_lock, flags); diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 5af4e8aa08e96..a6cc066a86f09 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1288,8 +1288,6 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio, const blk_opf_t do_sync = bio->bi_opf & REQ_SYNC; const blk_opf_t do_fua = bio->bi_opf & REQ_FUA; unsigned long flags; - struct blk_plug_cb *cb; - struct raid1_plug_cb *plug = NULL; struct r10conf *conf = mddev->private; struct md_rdev *rdev; int devnum = r10_bio->devs[n_copy].devnum; @@ -1329,14 +1327,7 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
atomic_inc(&r10_bio->remaining);
- cb = blk_check_plugged(raid10_unplug, mddev, sizeof(*plug)); - if (cb) - plug = container_of(cb, struct raid1_plug_cb, cb); - else - plug = NULL; - if (plug) { - bio_list_add(&plug->pending, mbio); - } else { + if (!raid1_add_bio_to_plug(mddev, mbio, raid10_unplug)) { spin_lock_irqsave(&conf->device_lock, flags); bio_list_add(&conf->pending_bio_list, mbio); spin_unlock_irqrestore(&conf->device_lock, flags);
From: Yu Kuai yukuai3@huawei.com
[ Upstream commit 8295efbe68c080047e98d9c0eb5cb933b238a8cb ]
There are multiple places to do the same thing, factor out a helper to prevent redundant code, and the helper will be used in following patch as well.
Signed-off-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230529131106.2123367-4-yukuai1@huaweicloud.com Stable-dep-of: 7db922bae3ab ("md/raid1-10: submit write io directly if bitmap is not enabled") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/raid1-10.c | 17 +++++++++++++++++ drivers/md/raid1.c | 13 ++----------- drivers/md/raid10.c | 26 ++++---------------------- 3 files changed, 23 insertions(+), 33 deletions(-)
diff --git a/drivers/md/raid1-10.c b/drivers/md/raid1-10.c index 9bf19a3409cef..506299bd55cb6 100644 --- a/drivers/md/raid1-10.c +++ b/drivers/md/raid1-10.c @@ -110,6 +110,23 @@ static void md_bio_reset_resync_pages(struct bio *bio, struct resync_pages *rp, } while (idx++ < RESYNC_PAGES && size > 0); }
+ +static inline void raid1_submit_write(struct bio *bio) +{ + struct md_rdev *rdev = (struct md_rdev *)bio->bi_bdev; + + bio->bi_next = NULL; + bio_set_dev(bio, rdev->bdev); + if (test_bit(Faulty, &rdev->flags)) + bio_io_error(bio); + else if (unlikely(bio_op(bio) == REQ_OP_DISCARD && + !bdev_max_discard_sectors(bio->bi_bdev))) + /* Just ignore it */ + bio_endio(bio); + else + submit_bio_noacct(bio); +} + static inline bool raid1_add_bio_to_plug(struct mddev *mddev, struct bio *bio, blk_plug_cb_fn unplug) { diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 131d8fd5ccaab..e51b77a3a8397 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -799,17 +799,8 @@ static void flush_bio_list(struct r1conf *conf, struct bio *bio)
while (bio) { /* submit pending writes */ struct bio *next = bio->bi_next; - struct md_rdev *rdev = (void *)bio->bi_bdev; - bio->bi_next = NULL; - bio_set_dev(bio, rdev->bdev); - if (test_bit(Faulty, &rdev->flags)) { - bio_io_error(bio); - } else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) && - !bdev_max_discard_sectors(bio->bi_bdev))) - /* Just ignore it */ - bio_endio(bio); - else - submit_bio_noacct(bio); + + raid1_submit_write(bio); bio = next; cond_resched(); } diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index a6cc066a86f09..f2f7538dd2a68 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -917,17 +917,8 @@ static void flush_pending_writes(struct r10conf *conf)
while (bio) { /* submit pending writes */ struct bio *next = bio->bi_next; - struct md_rdev *rdev = (void*)bio->bi_bdev; - bio->bi_next = NULL; - bio_set_dev(bio, rdev->bdev); - if (test_bit(Faulty, &rdev->flags)) { - bio_io_error(bio); - } else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) && - !bdev_max_discard_sectors(bio->bi_bdev))) - /* Just ignore it */ - bio_endio(bio); - else - submit_bio_noacct(bio); + + raid1_submit_write(bio); bio = next; } blk_finish_plug(&plug); @@ -1136,17 +1127,8 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
while (bio) { /* submit pending writes */ struct bio *next = bio->bi_next; - struct md_rdev *rdev = (void*)bio->bi_bdev; - bio->bi_next = NULL; - bio_set_dev(bio, rdev->bdev); - if (test_bit(Faulty, &rdev->flags)) { - bio_io_error(bio); - } else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) && - !bdev_max_discard_sectors(bio->bi_bdev))) - /* Just ignore it */ - bio_endio(bio); - else - submit_bio_noacct(bio); + + raid1_submit_write(bio); bio = next; } kfree(plug);
From: Yu Kuai yukuai3@huawei.com
[ Upstream commit 7db922bae3abdf0a1db81ef7228cc0b996a0c1e3 ]
Commit 6cce3b23f6f8 ("[PATCH] md: write intent bitmap support for raid10") add bitmap support, and it changed that write io is submitted through daemon thread because bitmap need to be updated before write io. And later, plug is used to fix performance regression because all the write io will go to demon thread, which means io can't be issued concurrently.
However, if bitmap is not enabled, the write io should not go to daemon thread in the first place, and plug is not needed as well.
Fixes: 6cce3b23f6f8 ("[PATCH] md: write intent bitmap support for raid10") Signed-off-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230529131106.2123367-5-yukuai1@huaweicloud.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/md-bitmap.c | 4 +--- drivers/md/md-bitmap.h | 7 +++++++ drivers/md/raid1-10.c | 13 +++++++++++-- 3 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 9640741e8d369..8bbeeec70905c 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -993,7 +993,6 @@ static int md_bitmap_file_test_bit(struct bitmap *bitmap, sector_t block) return set; }
- /* this gets called when the md device is ready to unplug its underlying * (slave) device queues -- before we let any writes go down, we need to * sync the dirty pages of the bitmap file to disk */ @@ -1003,8 +1002,7 @@ void md_bitmap_unplug(struct bitmap *bitmap) int dirty, need_write; int writing = 0;
- if (!bitmap || !bitmap->storage.filemap || - test_bit(BITMAP_STALE, &bitmap->flags)) + if (!md_bitmap_enabled(bitmap)) return;
/* look at each page to see if there are any set bits that need to be diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index cfd7395de8fd3..3a4750952b3a7 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -273,6 +273,13 @@ int md_bitmap_copy_from_slot(struct mddev *mddev, int slot, sector_t *lo, sector_t *hi, bool clear_bits); void md_bitmap_free(struct bitmap *bitmap); void md_bitmap_wait_behind_writes(struct mddev *mddev); + +static inline bool md_bitmap_enabled(struct bitmap *bitmap) +{ + return bitmap && bitmap->storage.filemap && + !test_bit(BITMAP_STALE, &bitmap->flags); +} + #endif
#endif diff --git a/drivers/md/raid1-10.c b/drivers/md/raid1-10.c index 506299bd55cb6..73cc3cb9154d8 100644 --- a/drivers/md/raid1-10.c +++ b/drivers/md/raid1-10.c @@ -131,9 +131,18 @@ static inline bool raid1_add_bio_to_plug(struct mddev *mddev, struct bio *bio, blk_plug_cb_fn unplug) { struct raid1_plug_cb *plug = NULL; - struct blk_plug_cb *cb = blk_check_plugged(unplug, mddev, - sizeof(*plug)); + struct blk_plug_cb *cb; + + /* + * If bitmap is not enabled, it's safe to submit the io directly, and + * this can get optimal performance. + */ + if (!md_bitmap_enabled(mddev->bitmap)) { + raid1_submit_write(bio); + return true; + }
+ cb = blk_check_plugged(unplug, mddev, sizeof(*plug)); if (!cb) return false;
From: Yu Kuai yukuai3@huawei.com
[ Upstream commit dd7de3704af9989b780693d51eaea49a665bd9c2 ]
Commit 99d055b4fd4b ("block: remove per-disk debugfs files in blk_unregister_queue") moves blk_trace_shutdown() from blk_release_queue() to blk_unregister_queue(), this is safe if blktrace is created through sysfs, however, there is a regression in corner case.
blktrace can still be enabled after del_gendisk() through ioctl if the disk is opened before del_gendisk(), and if blktrace is not shutdown through ioctl before closing the disk, debugfs entries will be leaked.
Fix this problem by shutdown blktrace in disk_release(), this is safe because blk_trace_remove() is reentrant.
Fixes: 99d055b4fd4b ("block: remove per-disk debugfs files in blk_unregister_queue") Signed-off-by: Yu Kuai yukuai3@huawei.com Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20230610022003.2557284-4-yukuai1@huaweicloud.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/genhd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/block/genhd.c b/block/genhd.c index 7f874737af682..c5a35e1b462fa 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -25,8 +25,9 @@ #include <linux/pm_runtime.h> #include <linux/badblocks.h> #include <linux/part_stat.h> -#include "blk-throttle.h" +#include <linux/blktrace_api.h>
+#include "blk-throttle.h" #include "blk.h" #include "blk-mq-sched.h" #include "blk-rq-qos.h" @@ -1183,6 +1184,8 @@ static void disk_release(struct device *dev) might_sleep(); WARN_ON_ONCE(disk_live(disk));
+ blk_trace_remove(disk->queue); + /* * To undo the all initialization from blk_mq_init_allocated_queue in * case of a probe failure where add_disk is never called we have to
From: Jianmin Lv lvjianmin@loongson.cn
[ Upstream commit fb07b8f83441febeb0daf199b5f18c6de9bbab03 ]
The hierarchy of PCH PIC, PCH PCI MSI and EIONTC is as following:
PCH PIC ------->| |---->EIOINTC PCH PCI MSI --->|
so the irq_data list of irq_desc for IRQs on PCH PIC and PCH PCI MSI is like this:
irq_desc->irq_data(domain: PCH PIC)->parent_data(domain: EIOINTC) irq_desc->irq_data(domain: PCH PCI MSI)->parent_data(domain: EIOINTC)
In eiointc_resume(), the irq_data passed into eiointc_set_irq_affinity() should be matched to EIOINTC domain instead of PCH PIC or PCH PCI MSI domain, so fix it.
Fixes: a90335c2dfb4 ("irqchip/loongson-eiointc: Add suspend/resume support")
Reported-by: yangqiming yangqiming@loongson.cn Signed-off-by: Jianmin Lv lvjianmin@loongson.cn Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20230614115936.5950-6-lvjianmin@loongson.cn Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/irqchip/irq-loongson-eiointc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c index 90181c42840b4..873a326ed6cbc 100644 --- a/drivers/irqchip/irq-loongson-eiointc.c +++ b/drivers/irqchip/irq-loongson-eiointc.c @@ -317,7 +317,7 @@ static void eiointc_resume(void) desc = irq_resolve_mapping(eiointc_priv[i]->eiointc_domain, j); if (desc && desc->handle_irq && desc->handle_irq != handle_bad_irq) { raw_spin_lock(&desc->lock); - irq_data = &desc->irq_data; + irq_data = irq_domain_get_irq_data(eiointc_priv[i]->eiointc_domain, irq_desc_get_irq(desc)); eiointc_set_irq_affinity(irq_data, irq_data->common->affinity, 0); raw_spin_unlock(&desc->lock); }
From: Christoph Hellwig hch@lst.de
[ Upstream commit 0b24be4691c9e6ea13ca70050d42a9f9032fa788 ]
copy_splice_read calls into ->read_iter to read the data, which already calls file_accessed.
Fixes: 33b3b041543e ("splice: Add a func to do a splice from an O_DIRECT file without ITER_PIPE") Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Johannes Thumshirn johannes.thumshirn@wdc.com Reviewed-by: Christian Brauner brauner@kernel.org Reviewed-by: David Howells dhowells@redhat.com Link: https://lore.kernel.org/r/20230614140341.521331-2-hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- fs/splice.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/fs/splice.c b/fs/splice.c index 2c3dec2b6dfaf..5eca589fe8479 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -338,7 +338,6 @@ ssize_t direct_splice_read(struct file *in, loff_t *ppos, reclaim -= ret; remain = ret; *ppos = kiocb.ki_pos; - file_accessed(in); } else if (ret < 0) { /* * callers of ->splice_read() expect -EAGAIN on
From: Antonio Borneo antonio.borneo@foss.st.com
[ Upstream commit 48f31e496488a25f443c0df52464da446fb1d10c ]
While compiling with W=1, both gcc and clang complain about a tricky way to initialize an array by filling it with a non-zero value and then overrride some of the array elements. In this case the override is intentional, so just disable the specific warning for only this part of the code.
Note: the flag "-Woverride-init" is recognized by both compilers, but the warning msg from clang reports "-Winitializer-overrides". The doc of clang clarifies that the two flags are synonyms, so use here only the flag name common on both compilers.
Signed-off-by: Antonio Borneo antonio.borneo@foss.st.com Fixes: c297493336b7 ("irqchip/stm32-exti: Simplify irq description table") Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20230601155614.34490-1-antonio.borneo@foss.st.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/irqchip/irq-stm32-exti.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c index 6a3f7498ea8ea..8bbb2b114636c 100644 --- a/drivers/irqchip/irq-stm32-exti.c +++ b/drivers/irqchip/irq-stm32-exti.c @@ -173,6 +173,16 @@ static struct irq_chip stm32_exti_h_chip_direct; #define EXTI_INVALID_IRQ U8_MAX #define STM32MP1_DESC_IRQ_SIZE (ARRAY_SIZE(stm32mp1_exti_banks) * IRQS_PER_BANK)
+/* + * Use some intentionally tricky logic here to initialize the whole array to + * EXTI_INVALID_IRQ, but then override certain fields, requiring us to indicate + * that we "know" that there are overrides in this structure, and we'll need to + * disable that warning from W=1 builds. + */ +__diag_push(); +__diag_ignore_all("-Woverride-init", + "logic to initialize all and then override some is OK"); + static const u8 stm32mp1_desc_irq[] = { /* default value */ [0 ... (STM32MP1_DESC_IRQ_SIZE - 1)] = EXTI_INVALID_IRQ, @@ -266,6 +276,8 @@ static const u8 stm32mp13_desc_irq[] = { [70] = 98, };
+__diag_pop(); + static const struct stm32_exti_drv_data stm32mp1_drv_data = { .exti_banks = stm32mp1_exti_banks, .bank_nr = ARRAY_SIZE(stm32mp1_exti_banks),
From: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de
[ Upstream commit 4848229494a323eeaab62eee5574ef9f7de80374 ]
The initialization function for the J-Core AIC aic_irq_of_init() is currently missing the call to irq_alloc_descs() which allocates and initializes all the IRQ descriptors. Add missing function call and return the error code from irq_alloc_descs() in case the allocation fails.
Fixes: 981b58f66cfc ("irqchip/jcore-aic: Add J-Core AIC driver") Signed-off-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Tested-by: Rob Landley rob@landley.net Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20230510163343.43090-1-glaubitz@physik.fu-berlin.d... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/irqchip/irq-jcore-aic.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/irqchip/irq-jcore-aic.c b/drivers/irqchip/irq-jcore-aic.c index 5f47d8ee4ae39..b9dcc8e78c750 100644 --- a/drivers/irqchip/irq-jcore-aic.c +++ b/drivers/irqchip/irq-jcore-aic.c @@ -68,6 +68,7 @@ static int __init aic_irq_of_init(struct device_node *node, unsigned min_irq = JCORE_AIC2_MIN_HWIRQ; unsigned dom_sz = JCORE_AIC_MAX_HWIRQ+1; struct irq_domain *domain; + int ret;
pr_info("Initializing J-Core AIC\n");
@@ -100,6 +101,12 @@ static int __init aic_irq_of_init(struct device_node *node, jcore_aic.irq_unmask = noop; jcore_aic.name = "AIC";
+ ret = irq_alloc_descs(-1, min_irq, dom_sz - min_irq, + of_node_to_nid(node)); + + if (ret < 0) + return ret; + domain = irq_domain_add_legacy(node, dom_sz - min_irq, min_irq, min_irq, &jcore_aic_irqdomain_ops, &jcore_aic);
From: Chuck Lever chuck.lever@oracle.com
[ Upstream commit baf6d18b116b7dc84ed5e212c3a89f17cdc3f28c ]
I noticed that svc_rqst_release_pages() was still unnecessarily releasing a page when svc_rdma_recvfrom() returns zero.
Fixes: a53d5cb0646a ("svcrdma: Avoid releasing a page in svc_xprt_release()") Reviewed-by: Jeff Layton jlayton@kernel.org Signed-off-by: Chuck Lever chuck.lever@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index a22fe7587fa6f..70207d8a318a4 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c @@ -796,6 +796,12 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp) struct svc_rdma_recv_ctxt *ctxt; int ret;
+ /* Prevent svc_xprt_release() from releasing pages in rq_pages + * when returning 0 or an error. + */ + rqstp->rq_respages = rqstp->rq_pages; + rqstp->rq_next_page = rqstp->rq_respages; + rqstp->rq_xprt_ctxt = NULL;
ctxt = NULL; @@ -819,12 +825,6 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp) DMA_FROM_DEVICE); svc_rdma_build_arg_xdr(rqstp, ctxt);
- /* Prevent svc_xprt_release from releasing pages in rq_pages - * if we return 0 or an error. - */ - rqstp->rq_respages = rqstp->rq_pages; - rqstp->rq_next_page = rqstp->rq_respages; - ret = svc_rdma_xdr_decode_req(&rqstp->rq_arg, ctxt); if (ret < 0) goto out_err;
From: Gao Xiang hsiangkao@linux.alibaba.com
[ Upstream commit 001b8ccd0650727e54ec16ef72bf1b8eeab7168e ]
In compact 4B, two adjacent lclusters are packed together as a unit to form on-disk indexes for effective random access, as below:
(amortized = 4, vcnt = 2) _____________________________________________ |___@_____ encoded bits __________|_ blkaddr _| 0 . amortized * vcnt = 8 . . . . amortized * vcnt - 4 = 4 . . .____________________________. |_type (2 bits)_|_clusterofs_|
Therefore, encoded bits for each pack are 32 bits (4 bytes). IOWs, since each lcluster can get 16 bits for its type and clusterofs, the maximum supported lclustersize for compact 4B format is 16k (14 bits).
Fix this to enable compact 4B format for 16k lclusters (blocks), which is tested on an arm64 server with 16k page size.
Fixes: 152a333a5895 ("staging: erofs: add compacted compression indexes support") Signed-off-by: Gao Xiang hsiangkao@linux.alibaba.com Link: https://lore.kernel.org/r/20230601112341.56960-1-hsiangkao@linux.alibaba.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/erofs/zmap.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c index b5f4086537548..322f110b3c8f4 100644 --- a/fs/erofs/zmap.c +++ b/fs/erofs/zmap.c @@ -148,7 +148,7 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m, u8 *in, type; bool big_pcluster;
- if (1 << amortizedshift == 4) + if (1 << amortizedshift == 4 && lclusterbits <= 14) vcnt = 2; else if (1 << amortizedshift == 2 && lclusterbits == 12) vcnt = 16; @@ -250,7 +250,6 @@ static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m, { struct inode *const inode = m->inode; struct erofs_inode *const vi = EROFS_I(inode); - const unsigned int lclusterbits = vi->z_logical_clusterbits; const erofs_off_t ebase = sizeof(struct z_erofs_map_header) + ALIGN(erofs_iloc(inode) + vi->inode_isize + vi->xattr_isize, 8); const unsigned int totalidx = DIV_ROUND_UP(inode->i_size, EROFS_BLKSIZ); @@ -258,9 +257,6 @@ static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m, unsigned int amortizedshift; erofs_off_t pos;
- if (lclusterbits != 12) - return -EOPNOTSUPP; - if (lcn >= totalidx) return -EINVAL;
From: Thomas Gleixner tglx@linutronix.de
[ Upstream commit 9d9e522010eb5685d8b53e8a24320653d9d4cbbf ]
itimer_delete() has a retry loop when the timer is concurrently expired. On non-RT kernels this just spin-waits until the timer callback has completed, except for posix CPU timers which have HAVE_POSIX_CPU_TIMERS_TASK_WORK enabled.
In that case and on RT kernels the existing task could live lock when preempting the task which does the timer delivery.
Replace spin_unlock() with an invocation of timer_wait_running() to handle it the same way as the other retry loops in the posix timer code.
Fixes: ec8f954a40da ("posix-timers: Use a callback for cancel synchronization on PREEMPT_RT") Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Frederic Weisbecker frederic@kernel.org Link: https://lore.kernel.org/r/87v8g7c50d.ffs@tglx Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/time/posix-timers.c | 43 +++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 8 deletions(-)
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 808a247205a9a..ed3c4a9543982 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -1037,27 +1037,52 @@ SYSCALL_DEFINE1(timer_delete, timer_t, timer_id) }
/* - * return timer owned by the process, used by exit_itimers + * Delete a timer if it is armed, remove it from the hash and schedule it + * for RCU freeing. */ static void itimer_delete(struct k_itimer *timer) { -retry_delete: - spin_lock_irq(&timer->it_lock); + unsigned long flags; + + /* + * irqsave is required to make timer_wait_running() work. + */ + spin_lock_irqsave(&timer->it_lock, flags);
+retry_delete: + /* + * Even if the timer is not longer accessible from other tasks + * it still might be armed and queued in the underlying timer + * mechanism. Worse, that timer mechanism might run the expiry + * function concurrently. + */ if (timer_delete_hook(timer) == TIMER_RETRY) { - spin_unlock_irq(&timer->it_lock); + /* + * Timer is expired concurrently, prevent livelocks + * and pointless spinning on RT. + * + * timer_wait_running() drops timer::it_lock, which opens + * the possibility for another task to delete the timer. + * + * That's not possible here because this is invoked from + * do_exit() only for the last thread of the thread group. + * So no other task can access and delete that timer. + */ + if (WARN_ON_ONCE(timer_wait_running(timer, &flags) != timer)) + return; + goto retry_delete; } list_del(&timer->list);
- spin_unlock_irq(&timer->it_lock); + spin_unlock_irqrestore(&timer->it_lock, flags); release_posix_timer(timer, IT_ID_SET); }
/* - * This is called by do_exit or de_thread, only when nobody else can - * modify the signal->posix_timers list. Yet we need sighand->siglock - * to prevent the race with /proc/pid/timers. + * Invoked from do_exit() when the last thread of a thread group exits. + * At that point no other task can access the timers of the dying + * task anymore. */ void exit_itimers(struct task_struct *tsk) { @@ -1067,10 +1092,12 @@ void exit_itimers(struct task_struct *tsk) if (list_empty(&tsk->signal->posix_timers)) return;
+ /* Protect against concurrent read via /proc/$PID/timers */ spin_lock_irq(&tsk->sighand->siglock); list_replace_init(&tsk->signal->posix_timers, &timers); spin_unlock_irq(&tsk->sighand->siglock);
+ /* The timers are not longer accessible via tsk::signal */ while (!list_empty(&timers)) { tmr = list_first_entry(&timers, struct k_itimer, list); itimer_delete(tmr);
From: Wen Yang wenyang.linux@foxmail.com
[ Upstream commit a7e282c77785c7eabf98836431b1f029481085ad ]
The ratelimit logic in report_idle_softirq() is broken because the exit condition is always true:
static int ratelimit;
if (ratelimit < 10) return false; ---> always returns here
ratelimit++; ---> no chance to run
Make it check for >= 10 instead.
Fixes: 0345691b24c0 ("tick/rcu: Stop allowing RCU_SOFTIRQ in idle") Signed-off-by: Wen Yang wenyang.linux@foxmail.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Link: https://lore.kernel.org/r/tencent_5AAA3EEAB42095C9B7740BE62FBF9A67E007@qq.co... Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/time/tick-sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index d6fb6a676bbbb..1ad89eec2a55f 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -1046,7 +1046,7 @@ static bool report_idle_softirq(void) return false; }
- if (ratelimit < 10) + if (ratelimit >= 10) return false;
/* On RT, softirqs handling may be waiting on some lock */
From: Sebastian Andrzej Siewior bigeasy@linutronix.de
[ Upstream commit 2951580ba6adb082bb6b7154a5ecb24e7c1f7569 ]
The trace output for the HRTIMER_MODE_.*_HARD modes is seen as a number since these modes are not decoded. The author was not aware of the fancy decoding function which makes the life easier.
Extend decode_hrtimer_mode() with the additional HRTIMER_MODE_.*_HARD modes.
Fixes: ae6683d815895 ("hrtimer: Introduce HARD expiry mode") Signed-off-by: Sebastian Andrzej Siewior bigeasy@linutronix.de Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Mukesh Ojha quic_mojha@quicinc.com Acked-by: Steven Rostedt (Google) rostedt@goodmis.org Link: https://lore.kernel.org/r/20230418143854.8vHWQKLM@linutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- include/trace/events/timer.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h index 3e8619c72f774..b4bc2828fa09f 100644 --- a/include/trace/events/timer.h +++ b/include/trace/events/timer.h @@ -158,7 +158,11 @@ DEFINE_EVENT(timer_class, timer_cancel, { HRTIMER_MODE_ABS_SOFT, "ABS|SOFT" }, \ { HRTIMER_MODE_REL_SOFT, "REL|SOFT" }, \ { HRTIMER_MODE_ABS_PINNED_SOFT, "ABS|PINNED|SOFT" }, \ - { HRTIMER_MODE_REL_PINNED_SOFT, "REL|PINNED|SOFT" }) + { HRTIMER_MODE_REL_PINNED_SOFT, "REL|PINNED|SOFT" }, \ + { HRTIMER_MODE_ABS_HARD, "ABS|HARD" }, \ + { HRTIMER_MODE_REL_HARD, "REL|HARD" }, \ + { HRTIMER_MODE_ABS_PINNED_HARD, "ABS|PINNED|HARD" }, \ + { HRTIMER_MODE_REL_PINNED_HARD, "REL|PINNED|HARD" })
/** * hrtimer_init - called when the hrtimer is initialized
From: Christoph Hellwig hch@lst.de
[ Upstream commit 2cef0c79bb81d8bae1dbc45195771a824ca45e76 ]
btrfs_split_bio expects a btrfs_bio as argument and always allocates one. Type both the orig_bio argument and the return value as struct btrfs_bio to improve type safety.
Reviewed-by: Anand Jain anand.jain@oracle.com Reviewed-by: Johannes Thumshirn johannes.thumshirn@wdc.com Reviewed-by: Qu Wenruo wqu@suse.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: David Sterba dsterba@suse.com Stable-dep-of: c731cd0b6d25 ("btrfs: fix file_offset for REQ_BTRFS_ONE_ORDERED bios that get split") Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/bio.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/fs/btrfs/bio.c b/fs/btrfs/bio.c index ada899613486a..67e5156f940d3 100644 --- a/fs/btrfs/bio.c +++ b/fs/btrfs/bio.c @@ -59,30 +59,31 @@ struct bio *btrfs_bio_alloc(unsigned int nr_vecs, blk_opf_t opf, return bio; }
-static struct bio *btrfs_split_bio(struct btrfs_fs_info *fs_info, - struct bio *orig, u64 map_length, - bool use_append) +static struct btrfs_bio *btrfs_split_bio(struct btrfs_fs_info *fs_info, + struct btrfs_bio *orig_bbio, + u64 map_length, bool use_append) { - struct btrfs_bio *orig_bbio = btrfs_bio(orig); + struct btrfs_bio *bbio; struct bio *bio;
if (use_append) { unsigned int nr_segs;
- bio = bio_split_rw(orig, &fs_info->limits, &nr_segs, + bio = bio_split_rw(&orig_bbio->bio, &fs_info->limits, &nr_segs, &btrfs_clone_bioset, map_length); } else { - bio = bio_split(orig, map_length >> SECTOR_SHIFT, GFP_NOFS, - &btrfs_clone_bioset); + bio = bio_split(&orig_bbio->bio, map_length >> SECTOR_SHIFT, + GFP_NOFS, &btrfs_clone_bioset); } - btrfs_bio_init(btrfs_bio(bio), orig_bbio->inode, NULL, orig_bbio); + bbio = btrfs_bio(bio); + btrfs_bio_init(bbio, orig_bbio->inode, NULL, orig_bbio);
- btrfs_bio(bio)->file_offset = orig_bbio->file_offset; - if (!(orig->bi_opf & REQ_BTRFS_ONE_ORDERED)) + bbio->file_offset = orig_bbio->file_offset; + if (!(orig_bbio->bio.bi_opf & REQ_BTRFS_ONE_ORDERED)) orig_bbio->file_offset += map_length;
atomic_inc(&orig_bbio->pending_ios); - return bio; + return bbio; }
static void btrfs_orig_write_end_io(struct bio *bio); @@ -631,8 +632,8 @@ static bool btrfs_submit_chunk(struct bio *bio, int mirror_num) map_length = min(map_length, fs_info->max_zone_append_size);
if (map_length < length) { - bio = btrfs_split_bio(fs_info, bio, map_length, use_append); - bbio = btrfs_bio(bio); + bbio = btrfs_split_bio(fs_info, bbio, map_length, use_append); + bio = &bbio->bio; }
/*
From: Christoph Hellwig hch@lst.de
[ Upstream commit c731cd0b6d255e4855a7cac9f276864032ab2387 ]
If a bio gets split, it needs to have a proper file_offset for checksum validation and repair to work properly.
Based on feedback from Josef, commit 852eee62d31a ("btrfs: allow btrfs_submit_bio to split bios") skipped this adjustment for ONE_ORDERED bios. But if we actually ever need to split a ONE_ORDERED read bio, this will lead to a wrong file offset in the repair code. Right now the only user of the file_offset is logging of an error message so this is mostly harmless, but the wrong offset might be more problematic for additional users in the future.
Fixes: 852eee62d31a ("btrfs: allow btrfs_submit_bio to split bios") Reviewed-by: Johannes Thumshirn johannes.thumshirn@wdc.com Reviewed-by: Josef Bacik josef@toxicpanda.com Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/bio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/fs/btrfs/bio.c b/fs/btrfs/bio.c index 67e5156f940d3..4bb2c6f4ad0e7 100644 --- a/fs/btrfs/bio.c +++ b/fs/btrfs/bio.c @@ -79,8 +79,7 @@ static struct btrfs_bio *btrfs_split_bio(struct btrfs_fs_info *fs_info, btrfs_bio_init(bbio, orig_bbio->inode, NULL, orig_bbio);
bbio->file_offset = orig_bbio->file_offset; - if (!(orig_bbio->bio.bi_opf & REQ_BTRFS_ONE_ORDERED)) - orig_bbio->file_offset += map_length; + orig_bbio->file_offset += map_length;
atomic_inc(&orig_bbio->pending_ios); return bbio;
From: Feng Mingxi m202271825@hust.edu.cn
[ Upstream commit 8b5bf64c89c7100c921bd807ba39b2eb003061ab ]
Smatch reports: drivers/clocksource/timer-cadence-ttc.c:529 ttc_timer_probe() warn: 'timer_baseaddr' from of_iomap() not released on lines: 498,508,516.
timer_baseaddr may have the problem of not being released after use, I replaced it with the devm_of_iomap() function and added the clk_put() function to cleanup the "clk_ce" and "clk_cs".
Fixes: e932900a3279 ("arm: zynq: Use standard timer binding") Fixes: 70504f311d4b ("clocksource/drivers/cadence_ttc: Convert init function to return error") Signed-off-by: Feng Mingxi m202271825@hust.edu.cn Reviewed-by: Dongliang Mu dzm91@hust.edu.cn Acked-by: Michal Simek michal.simek@amd.com Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Link: https://lore.kernel.org/r/20230425065611.702917-1-m202271825@hust.edu.cn Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clocksource/timer-cadence-ttc.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/clocksource/timer-cadence-ttc.c b/drivers/clocksource/timer-cadence-ttc.c index 4efd0cf3b602d..0d52e28fea4de 100644 --- a/drivers/clocksource/timer-cadence-ttc.c +++ b/drivers/clocksource/timer-cadence-ttc.c @@ -486,10 +486,10 @@ static int __init ttc_timer_probe(struct platform_device *pdev) * and use it. Note that the event timer uses the interrupt and it's the * 2nd TTC hence the irq_of_parse_and_map(,1) */ - timer_baseaddr = of_iomap(timer, 0); - if (!timer_baseaddr) { + timer_baseaddr = devm_of_iomap(&pdev->dev, timer, 0, NULL); + if (IS_ERR(timer_baseaddr)) { pr_err("ERROR: invalid timer base address\n"); - return -ENXIO; + return PTR_ERR(timer_baseaddr); }
irq = irq_of_parse_and_map(timer, 1); @@ -513,20 +513,27 @@ static int __init ttc_timer_probe(struct platform_device *pdev) clk_ce = of_clk_get(timer, clksel); if (IS_ERR(clk_ce)) { pr_err("ERROR: timer input clock not found\n"); - return PTR_ERR(clk_ce); + ret = PTR_ERR(clk_ce); + goto put_clk_cs; }
ret = ttc_setup_clocksource(clk_cs, timer_baseaddr, timer_width); if (ret) - return ret; + goto put_clk_ce;
ret = ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq); if (ret) - return ret; + goto put_clk_ce;
pr_info("%pOFn #0 at %p, irq=%d\n", timer, timer_baseaddr, irq);
return 0; + +put_clk_ce: + clk_put(clk_ce); +put_clk_cs: + clk_put(clk_cs); + return ret; }
static const struct of_device_id ttc_timer_of_match[] = {
From: Nikita Zhandarovich n.zhandarovich@fintech.ru
[ Upstream commit e5d1c8722083f0332dcd3c85fa1273d85fb6bed8 ]
Currently, while calculating residency and latency values, right operands may overflow if resulting values are big enough.
To prevent this, albeit unlikely case, play it safe and convert right operands to left ones' type s64.
Found by Linux Verification Center (linuxtesting.org) with static analysis tool SVACE.
Fixes: 30f604283e05 ("PM / Domains: Allow domain power states to be read from DT") Signed-off-by: Nikita Zhandarovich n.zhandarovich@fintech.ru Acked-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/base/power/domain.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 32084e38b73d0..51b9d4eaab5ea 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -2939,10 +2939,10 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state,
err = of_property_read_u32(state_node, "min-residency-us", &residency); if (!err) - genpd_state->residency_ns = 1000 * residency; + genpd_state->residency_ns = 1000LL * residency;
- genpd_state->power_on_latency_ns = 1000 * exit_latency; - genpd_state->power_off_latency_ns = 1000 * entry_latency; + genpd_state->power_on_latency_ns = 1000LL * exit_latency; + genpd_state->power_off_latency_ns = 1000LL * entry_latency; genpd_state->fwnode = &state_node->fwnode;
return 0;
From: Robin Murphy robin.murphy@arm.com
[ Upstream commit 71746c995cac92fcf6a65661b51211cf2009d7f0 ]
It turns out that my naive DTC reset logic fails to work as intended, since, after checking with the hardware designers, the PMU actually needs to be fully enabled in order to correctly clear any pending overflows. Therefore, invert the sequence to start with turning on both enables so that we can reliably get the DTCs into a known state, then moving to our normal counters-stopped state from there. Since all the DTM counters have already been unpaired during the initial discovery pass, we just need to additionally reset the cycle counters to ensure that no other unexpected overflows occur during this period.
Fixes: 0ba64770a2f2 ("perf: Add Arm CMN-600 PMU driver") Reported-by: Geoff Blake blakgeof@amazon.com Signed-off-by: Robin Murphy robin.murphy@arm.com Link: https://lore.kernel.org/r/0ea4559261ea394f827c9aee5168c77a60aaee03.168494638... Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/perf/arm-cmn.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c index 44b719f39c3b3..4f86b7fd9823f 100644 --- a/drivers/perf/arm-cmn.c +++ b/drivers/perf/arm-cmn.c @@ -1899,9 +1899,10 @@ static int arm_cmn_init_dtc(struct arm_cmn *cmn, struct arm_cmn_node *dn, int id if (dtc->irq < 0) return dtc->irq;
- writel_relaxed(0, dtc->base + CMN_DT_PMCR); + writel_relaxed(CMN_DT_DTC_CTL_DT_EN, dtc->base + CMN_DT_DTC_CTL); + writel_relaxed(CMN_DT_PMCR_PMU_EN | CMN_DT_PMCR_OVFL_INTR_EN, dtc->base + CMN_DT_PMCR); + writeq_relaxed(0, dtc->base + CMN_DT_PMCCNTR); writel_relaxed(0x1ff, dtc->base + CMN_DT_PMOVSR_CLR); - writel_relaxed(CMN_DT_PMCR_OVFL_INTR_EN, dtc->base + CMN_DT_PMCR);
return 0; } @@ -1961,7 +1962,7 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn) dn->type = CMN_TYPE_CCLA; }
- writel_relaxed(CMN_DT_DTC_CTL_DT_EN, cmn->dtc[0].base + CMN_DT_DTC_CTL); + arm_cmn_set_state(cmn, CMN_STATE_DISABLED);
return 0; }
From: Kirill A. Shutemov kirill.shutemov@linux.intel.com
[ Upstream commit 3f6819dd192ef4f0c568ec3e9d6d408b3fa1ad3d ]
TDX code is going to provide guest.enc_status_change_prepare() that is able to fail. TDX will use the call to convert the GPA range from shared to private. This operation can fail.
Add a way to return an error from the callback.
Signed-off-by: Kirill A. Shutemov kirill.shutemov@linux.intel.com Signed-off-by: Dave Hansen dave.hansen@linux.intel.com Reviewed-by: Kuppuswamy Sathyanarayanan sathyanarayanan.kuppuswamy@linux.intel.com Link: https://lore.kernel.org/all/20230606095622.1939-2-kirill.shutemov%40linux.in... Stable-dep-of: 195edce08b63 ("x86/tdx: Fix race between set_memory_encrypted() and load_unaligned_zeropad()") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/include/asm/x86_init.h | 2 +- arch/x86/kernel/x86_init.c | 2 +- arch/x86/mm/mem_encrypt_amd.c | 4 +++- arch/x86/mm/pat/set_memory.c | 3 ++- 4 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index c1c8c581759d6..034e62838b284 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h @@ -150,7 +150,7 @@ struct x86_init_acpi { * @enc_cache_flush_required Returns true if a cache flush is needed before changing page encryption status */ struct x86_guest { - void (*enc_status_change_prepare)(unsigned long vaddr, int npages, bool enc); + bool (*enc_status_change_prepare)(unsigned long vaddr, int npages, bool enc); bool (*enc_status_change_finish)(unsigned long vaddr, int npages, bool enc); bool (*enc_tlb_flush_required)(bool enc); bool (*enc_cache_flush_required)(void); diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c index 10622cf2b30f4..41e5b4cb898c3 100644 --- a/arch/x86/kernel/x86_init.c +++ b/arch/x86/kernel/x86_init.c @@ -130,7 +130,7 @@ struct x86_cpuinit_ops x86_cpuinit = {
static void default_nmi_init(void) { };
-static void enc_status_change_prepare_noop(unsigned long vaddr, int npages, bool enc) { } +static bool enc_status_change_prepare_noop(unsigned long vaddr, int npages, bool enc) { return true; } static bool enc_status_change_finish_noop(unsigned long vaddr, int npages, bool enc) { return false; } static bool enc_tlb_flush_required_noop(bool enc) { return false; } static bool enc_cache_flush_required_noop(void) { return false; } diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c index 9c4d8dbcb1296..ff6c0462beee7 100644 --- a/arch/x86/mm/mem_encrypt_amd.c +++ b/arch/x86/mm/mem_encrypt_amd.c @@ -319,7 +319,7 @@ static void enc_dec_hypercall(unsigned long vaddr, int npages, bool enc) #endif }
-static void amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool enc) +static bool amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool enc) { /* * To maintain the security guarantees of SEV-SNP guests, make sure @@ -327,6 +327,8 @@ static void amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool */ if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP) && !enc) snp_set_memory_shared(vaddr, npages); + + return true; }
/* Return true unconditionally: return value doesn't matter for the SEV side */ diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c index 356758b7d4b47..6a167290a1fd1 100644 --- a/arch/x86/mm/pat/set_memory.c +++ b/arch/x86/mm/pat/set_memory.c @@ -2151,7 +2151,8 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc) cpa_flush(&cpa, x86_platform.guest.enc_cache_flush_required());
/* Notify hypervisor that we are about to set/clr encryption attribute. */ - x86_platform.guest.enc_status_change_prepare(addr, numpages, enc); + if (!x86_platform.guest.enc_status_change_prepare(addr, numpages, enc)) + return -EIO;
ret = __change_page_attr_set_clr(&cpa, 1);
From: Kirill A. Shutemov kirill.shutemov@linux.intel.com
[ Upstream commit 195edce08b63d293377f615f4f7f086715d2d212 ]
tl;dr: There is a race in the TDX private<=>shared conversion code which could kill the TDX guest. Fix it by changing conversion ordering to eliminate the window.
TDX hardware maintains metadata to track which pages are private and shared. Additionally, TDX guests use the guest x86 page tables to specify whether a given mapping is intended to be private or shared. Bad things happen when the intent and metadata do not match.
So there are two thing in play: 1. "the page" -- the physical TDX page metadata 2. "the mapping" -- the guest-controlled x86 page table intent
For instance, an unrecoverable exit to VMM occurs if a guest touches a private mapping that points to a shared physical page.
In summary: * Private mapping => Private Page == OK (obviously) * Shared mapping => Shared Page == OK (obviously) * Private mapping => Shared Page == BIG BOOM! * Shared mapping => Private Page == OK-ish (It will read generate a recoverable #VE via handle_mmio())
Enter load_unaligned_zeropad(). It can touch memory that is adjacent but otherwise unrelated to the memory it needs to touch. It will cause one of those unrecoverable exits (aka. BIG BOOM) if it blunders into a shared mapping pointing to a private page.
This is a problem when __set_memory_enc_pgtable() converts pages from shared to private. It first changes the mapping and second modifies the TDX page metadata. It's moving from:
* Shared mapping => Shared Page == OK to: * Private mapping => Shared Page == BIG BOOM!
This means that there is a window with a shared mapping pointing to a private page where load_unaligned_zeropad() can strike.
Add a TDX handler for guest.enc_status_change_prepare(). This converts the page from shared to private *before* the page becomes private. This ensures that there is never a private mapping to a shared page.
Leave a guest.enc_status_change_finish() in place but only use it for private=>shared conversions. This will delay updating the TDX metadata marking the page private until *after* the mapping matches the metadata. This also ensures that there is never a private mapping to a shared page.
[ dhansen: rewrite changelog ]
Fixes: 7dbde7631629 ("x86/mm/cpa: Add support for TDX shared memory") Signed-off-by: Kirill A. Shutemov kirill.shutemov@linux.intel.com Signed-off-by: Dave Hansen dave.hansen@linux.intel.com Reviewed-by: Kuppuswamy Sathyanarayanan sathyanarayanan.kuppuswamy@linux.intel.com Link: https://lore.kernel.org/all/20230606095622.1939-3-kirill.shutemov%40linux.in... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/coco/tdx/tdx.c | 51 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-)
diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c index 055300e08fb38..3d191ec036fb7 100644 --- a/arch/x86/coco/tdx/tdx.c +++ b/arch/x86/coco/tdx/tdx.c @@ -840,6 +840,30 @@ static bool tdx_enc_status_changed(unsigned long vaddr, int numpages, bool enc) return true; }
+static bool tdx_enc_status_change_prepare(unsigned long vaddr, int numpages, + bool enc) +{ + /* + * Only handle shared->private conversion here. + * See the comment in tdx_early_init(). + */ + if (enc) + return tdx_enc_status_changed(vaddr, numpages, enc); + return true; +} + +static bool tdx_enc_status_change_finish(unsigned long vaddr, int numpages, + bool enc) +{ + /* + * Only handle private->shared conversion here. + * See the comment in tdx_early_init(). + */ + if (!enc) + return tdx_enc_status_changed(vaddr, numpages, enc); + return true; +} + void __init tdx_early_init(void) { u64 cc_mask; @@ -867,9 +891,30 @@ void __init tdx_early_init(void) */ physical_mask &= cc_mask - 1;
- x86_platform.guest.enc_cache_flush_required = tdx_cache_flush_required; - x86_platform.guest.enc_tlb_flush_required = tdx_tlb_flush_required; - x86_platform.guest.enc_status_change_finish = tdx_enc_status_changed; + /* + * The kernel mapping should match the TDX metadata for the page. + * load_unaligned_zeropad() can touch memory *adjacent* to that which is + * owned by the caller and can catch even _momentary_ mismatches. Bad + * things happen on mismatch: + * + * - Private mapping => Shared Page == Guest shutdown + * - Shared mapping => Private Page == Recoverable #VE + * + * guest.enc_status_change_prepare() converts the page from + * shared=>private before the mapping becomes private. + * + * guest.enc_status_change_finish() converts the page from + * private=>shared after the mapping becomes private. + * + * In both cases there is a temporary shared mapping to a private page, + * which can result in a #VE. But, there is never a private mapping to + * a shared page. + */ + x86_platform.guest.enc_status_change_prepare = tdx_enc_status_change_prepare; + x86_platform.guest.enc_status_change_finish = tdx_enc_status_change_finish; + + x86_platform.guest.enc_cache_flush_required = tdx_cache_flush_required; + x86_platform.guest.enc_tlb_flush_required = tdx_tlb_flush_required;
pr_info("Guest detected\n"); }
From: Junhao He hejunhao3@huawei.com
[ Upstream commit 7a6a9f1c5a0a875a421db798d4b2ee022dc1ee1a ]
The driver needs to migrate the perf context if the current using CPU going to teardown. By the time calling the cpuhp::teardown() callback the cpu_online_mask() hasn't updated yet and still includes the CPU going to teardown. In current driver's implementation we may migrate the context to the teardown CPU and leads to the below calltrace:
... [ 368.104662][ T932] task:cpuhp/0 state:D stack: 0 pid: 15 ppid: 2 flags:0x00000008 [ 368.113699][ T932] Call trace: [ 368.116834][ T932] __switch_to+0x7c/0xbc [ 368.120924][ T932] __schedule+0x338/0x6f0 [ 368.125098][ T932] schedule+0x50/0xe0 [ 368.128926][ T932] schedule_preempt_disabled+0x18/0x24 [ 368.134229][ T932] __mutex_lock.constprop.0+0x1d4/0x5dc [ 368.139617][ T932] __mutex_lock_slowpath+0x1c/0x30 [ 368.144573][ T932] mutex_lock+0x50/0x60 [ 368.148579][ T932] perf_pmu_migrate_context+0x84/0x2b0 [ 368.153884][ T932] hisi_pcie_pmu_offline_cpu+0x90/0xe0 [hisi_pcie_pmu] [ 368.160579][ T932] cpuhp_invoke_callback+0x2a0/0x650 [ 368.165707][ T932] cpuhp_thread_fun+0xe4/0x190 [ 368.170316][ T932] smpboot_thread_fn+0x15c/0x1a0 [ 368.175099][ T932] kthread+0x108/0x13c [ 368.179012][ T932] ret_from_fork+0x10/0x18 ...
Use function cpumask_any_but() to find one correct active cpu to fixes this issue.
Fixes: 8404b0fbc7fb ("drivers/perf: hisi: Add driver for HiSilicon PCIe PMU") Signed-off-by: Junhao He hejunhao3@huawei.com Reviewed-by: Jonathan Cameron Jonathan.Cameron@huawei.com Reviewed-by: Yicong Yang yangyicong@hisilicon.com Acked-by: Mark Rutland mark.rutland@arm.com Link: https://lore.kernel.org/r/20230608114326.27649-1-hejunhao3@huawei.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/perf/hisilicon/hisi_pcie_pmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c index 6fee0b6e163bb..e10fc7cb9493a 100644 --- a/drivers/perf/hisilicon/hisi_pcie_pmu.c +++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c @@ -683,7 +683,7 @@ static int hisi_pcie_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
pcie_pmu->on_cpu = -1; /* Choose a new CPU from all online cpus. */ - target = cpumask_first(cpu_online_mask); + target = cpumask_any_but(cpu_online_mask, cpu); if (target >= nr_cpu_ids) { pci_err(pcie_pmu->pdev, "There is no CPU to set\n"); return 0;
From: Ilkka Koskinen ilkka@os.amperecomputing.com
[ Upstream commit 225d757012e0afa673d8c862e6fb39ed2f429b4d ]
Don't try to set irq affinity if PMU doesn't have an overflow interrupt.
Fixes: e37dfd65731d ("perf: arm_cspmu: Add support for ARM CoreSight PMU driver") Signed-off-by: Ilkka Koskinen ilkka@os.amperecomputing.com Link: https://lore.kernel.org/r/20230608203742.3503486-1-ilkka@os.amperecomputing.... Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/perf/arm_cspmu/arm_cspmu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c index e31302ab7e37c..c1b6f4bdb04af 100644 --- a/drivers/perf/arm_cspmu/arm_cspmu.c +++ b/drivers/perf/arm_cspmu/arm_cspmu.c @@ -1230,7 +1230,8 @@ static struct platform_driver arm_cspmu_driver = { static void arm_cspmu_set_active_cpu(int cpu, struct arm_cspmu *cspmu) { cpumask_set_cpu(cpu, &cspmu->active_cpu); - WARN_ON(irq_set_affinity(cspmu->irq, &cspmu->active_cpu)); + if (cspmu->irq) + WARN_ON(irq_set_affinity(cspmu->irq, &cspmu->active_cpu)); }
static int arm_cspmu_cpu_online(unsigned int cpu, struct hlist_node *node)
From: Robin Murphy robin.murphy@arm.com
[ Upstream commit 71e0cb32d5fc61468e83ed962379af71bba8237e ]
ARM_CSPMU_EVENT_ATTR() defines a struct perf_pmu_events_attr, so arm_cspmu_sysfs_event_show() should not be interpreting it as struct dev_ext_attribute.
Fixes: e37dfd65731d ("perf: arm_cspmu: Add support for ARM CoreSight PMU driver") Reviewed-by: Suzuki K Poulose suzuki.poulose@arm.com Reviewed-and-tested-by: Ilkka Koskinen ilkka@os.amperecomputing.com Signed-off-by: Robin Murphy robin.murphy@arm.com Link: https://lore.kernel.org/r/27c0804af64007b2400abbc40278f642ee6a0a29.168598327... Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/perf/arm_cspmu/arm_cspmu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c index c1b6f4bdb04af..35d2fe33a7b6f 100644 --- a/drivers/perf/arm_cspmu/arm_cspmu.c +++ b/drivers/perf/arm_cspmu/arm_cspmu.c @@ -189,10 +189,10 @@ static inline bool use_64b_counter_reg(const struct arm_cspmu *cspmu) ssize_t arm_cspmu_sysfs_event_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct dev_ext_attribute *eattr = - container_of(attr, struct dev_ext_attribute, attr); - return sysfs_emit(buf, "event=0x%llx\n", - (unsigned long long)eattr->var); + struct perf_pmu_events_attr *pmu_attr; + + pmu_attr = container_of(attr, typeof(*pmu_attr), attr); + return sysfs_emit(buf, "event=0x%llx\n", pmu_attr->id); } EXPORT_SYMBOL_GPL(arm_cspmu_sysfs_event_show);
From: Li Yang leoyang.li@nxp.com
[ Upstream commit 9368aa1882ac7178adcd936cee5f0899dbf76dc4 ]
Since 315bada690e0 ("EDAC: Check for GHES preference in the chipset-specific EDAC drivers"), vendor specific EDAC driver will not probe correctly when CONFIG_ACPI_APEI_GHES is enabled but no GHES device is present. Make ghes_get_devices() return NULL when the GHES device list is empty to fix the problem.
Fixes: 9057a3f7ac36 ("EDAC/ghes: Prepare to make ghes_edac a proper module") Signed-off-by: Li Yang leoyang.li@nxp.com Reviewed-by: Tony Luck tony.luck@intel.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/apei/ghes.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 34ad071a64e96..4382fe13ee3e4 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -1544,6 +1544,8 @@ struct list_head *ghes_get_devices(void)
pr_warn_once("Force-loading ghes_edac on an unsupported platform. You're on your own!\n"); } + } else if (list_empty(&ghes_devs)) { + return NULL; }
return &ghes_devs;
From: Sumeet Pawnikar sumeet.r.pawnikar@intel.com
[ Upstream commit d05b5e0baf424c8c4b4709ac11f66ab726c8deaf ]
The current initialization of the struct x86_cpu_id via pl4_support_ids[] is partial and wrong. It is initializing "stepping" field with "X86_FEATURE_ANY" instead of "feature" field.
Use X86_MATCH_INTEL_FAM6_MODEL macro instead of initializing each field of the struct x86_cpu_id for pl4_supported list of CPUs. This X86_MATCH_INTEL_FAM6_MODEL macro internally uses another macro X86_MATCH_VENDOR_FAM_MODEL_FEATURE for X86 based CPU matching with appropriate initialized values.
Reported-by: Dave Hansen dave.hansen@intel.com Link: https://lore.kernel.org/lkml/28ead36b-2d9e-1a36-6f4e-04684e420260@intel.com Fixes: eb52bc2ae5b8 ("powercap: RAPL: Add Power Limit4 support for Meteor Lake SoC") Fixes: b08b95cf30f5 ("powercap: RAPL: Add Power Limit4 support for Alder Lake-N and Raptor Lake-P") Fixes: 515755906921 ("powercap: RAPL: Add Power Limit4 support for RaptorLake") Fixes: 1cc5b9a411e4 ("powercap: Add Power Limit4 support for Alder Lake SoC") Fixes: 8365a898fe53 ("powercap: Add Power Limit4 support") Signed-off-by: Sumeet Pawnikar sumeet.r.pawnikar@intel.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/powercap/intel_rapl_msr.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/powercap/intel_rapl_msr.c b/drivers/powercap/intel_rapl_msr.c index a27673706c3d6..7be7561f5ad64 100644 --- a/drivers/powercap/intel_rapl_msr.c +++ b/drivers/powercap/intel_rapl_msr.c @@ -137,14 +137,14 @@ static int rapl_msr_write_raw(int cpu, struct reg_action *ra)
/* List of verified CPUs. */ static const struct x86_cpu_id pl4_support_ids[] = { - { X86_VENDOR_INTEL, 6, INTEL_FAM6_TIGERLAKE_L, X86_FEATURE_ANY }, - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE, X86_FEATURE_ANY }, - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE_L, X86_FEATURE_ANY }, - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE_N, X86_FEATURE_ANY }, - { X86_VENDOR_INTEL, 6, INTEL_FAM6_RAPTORLAKE, X86_FEATURE_ANY }, - { X86_VENDOR_INTEL, 6, INTEL_FAM6_RAPTORLAKE_P, X86_FEATURE_ANY }, - { X86_VENDOR_INTEL, 6, INTEL_FAM6_METEORLAKE, X86_FEATURE_ANY }, - { X86_VENDOR_INTEL, 6, INTEL_FAM6_METEORLAKE_L, X86_FEATURE_ANY }, + X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, NULL), + X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, NULL), + X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, NULL), + X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, NULL), + X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, NULL), + X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, NULL), + X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE, NULL), + X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE_L, NULL), {} };
From: Zhang Rui rui.zhang@intel.com
[ Upstream commit 4658fe81b3f8afe8adf37734ec5fe595d90415c6 ]
After commit 3382388d7148 ("intel_rapl: abstract RAPL common code"), accessing to IOSF_MBI interface is done in the RAPL common code.
Thus it is the CONFIG_INTEL_RAPL_CORE that has dependency of CONFIG_IOSF_MBI, while CONFIG_INTEL_RAPL_MSR does not.
This problem was not exposed previously because all the previous RAPL common code users, aka, the RAPL MSR and MMIO I/F drivers, have CONFIG_IOSF_MBI selected.
Fix the CONFIG_IOSF_MBI dependency in RAPL code. This also fixes a build time failure when the RAPL TPMI I/F driver is introduced without selecting CONFIG_IOSF_MBI.
x86_64-linux-ld: vmlinux.o: in function `set_floor_freq_atom': intel_rapl_common.c:(.text+0x2dac9b8): undefined reference to `iosf_mbi_write' x86_64-linux-ld: intel_rapl_common.c:(.text+0x2daca66): undefined reference to `iosf_mbi_read'
Reference to iosf_mbi.h is also removed from the RAPL MSR I/F driver.
Fixes: 3382388d7148 ("intel_rapl: abstract RAPL common code") Reported-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/all/20230601213246.3271412-1-arnd@kernel.org Signed-off-by: Zhang Rui rui.zhang@intel.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/powercap/Kconfig | 4 +++- drivers/powercap/intel_rapl_msr.c | 1 - 2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/powercap/Kconfig b/drivers/powercap/Kconfig index 90d33cd1b670a..b063f75117738 100644 --- a/drivers/powercap/Kconfig +++ b/drivers/powercap/Kconfig @@ -18,10 +18,12 @@ if POWERCAP # Client driver configurations go here. config INTEL_RAPL_CORE tristate + depends on PCI + select IOSF_MBI
config INTEL_RAPL tristate "Intel RAPL Support via MSR Interface" - depends on X86 && IOSF_MBI + depends on X86 && PCI select INTEL_RAPL_CORE help This enables support for the Intel Running Average Power Limit (RAPL) diff --git a/drivers/powercap/intel_rapl_msr.c b/drivers/powercap/intel_rapl_msr.c index 7be7561f5ad64..9ea4797d70b44 100644 --- a/drivers/powercap/intel_rapl_msr.c +++ b/drivers/powercap/intel_rapl_msr.c @@ -22,7 +22,6 @@ #include <linux/processor.h> #include <linux/platform_device.h>
-#include <asm/iosf_mbi.h> #include <asm/cpu_device_id.h> #include <asm/intel-family.h>
From: Ulf Hansson ulf.hansson@linaro.org
[ Upstream commit 4384a70c8813e8573d1841fd94eee873f80a7e1a ]
Commit f38d1a6d0025 ("PM: domains: Allocate governor data dynamically based on a genpd governor") started to use the in-parameters in genpd_add_device(), without first doing a verification of them.
This isn't really a big problem, as most callers do a verification already.
Therefore, let's drop the verification from genpd_add_device() and make sure all the callers take care of it instead.
Reported-by: Dan Carpenter dan.carpenter@linaro.org Fixes: f38d1a6d0025 ("PM: domains: Allocate governor data dynamically based on a genpd governor") Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/base/power/domain.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 51b9d4eaab5ea..5cb2023581d4d 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1632,9 +1632,6 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
dev_dbg(dev, "%s()\n", __func__);
- if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev)) - return -EINVAL; - gpd_data = genpd_alloc_dev_data(dev, gd); if (IS_ERR(gpd_data)) return PTR_ERR(gpd_data); @@ -1676,6 +1673,9 @@ int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev) { int ret;
+ if (!genpd || !dev) + return -EINVAL; + mutex_lock(&gpd_list_lock); ret = genpd_add_device(genpd, dev, dev); mutex_unlock(&gpd_list_lock); @@ -2523,6 +2523,9 @@ int of_genpd_add_device(struct of_phandle_args *genpdspec, struct device *dev) struct generic_pm_domain *genpd; int ret;
+ if (!dev) + return -EINVAL; + mutex_lock(&gpd_list_lock);
genpd = genpd_get_from_provider(genpdspec);
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 1b9c3ddcec6a55e15d3e38e7405e2d078db02020 ]
checker_stack_use_t32strd() and kprobe_handler() can be made static since they are not used from other files, while coverage_start_registers() and __kprobes_test_case() are used from assembler code, and just need a declaration to avoid a warning with the global definition.
arch/arm/probes/kprobes/checkers-common.c:43:18: error: no previous prototype for 'checker_stack_use_t32strd' arch/arm/probes/kprobes/core.c:236:16: error: no previous prototype for 'kprobe_handler' arch/arm/probes/kprobes/test-core.c:723:10: error: no previous prototype for 'coverage_start_registers' arch/arm/probes/kprobes/test-core.c:918:14: error: no previous prototype for '__kprobes_test_case_start' arch/arm/probes/kprobes/test-core.c:952:14: error: no previous prototype for '__kprobes_test_case_end_16' arch/arm/probes/kprobes/test-core.c:967:14: error: no previous prototype for '__kprobes_test_case_end_32'
Fixes: 6624cf651f1a ("ARM: kprobes: collects stack consumption for store instructions") Fixes: 454f3e132d05 ("ARM/kprobes: Remove jprobe arm implementation") Acked-by: Masami Hiramatsu (Google) mhiramat@kernel.org Reviewed-by: Kees Cook keescook@chromium.org Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/probes/kprobes/checkers-common.c | 2 +- arch/arm/probes/kprobes/core.c | 2 +- arch/arm/probes/kprobes/opt-arm.c | 2 -- arch/arm/probes/kprobes/test-core.c | 2 +- arch/arm/probes/kprobes/test-core.h | 4 ++++ 5 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/arch/arm/probes/kprobes/checkers-common.c b/arch/arm/probes/kprobes/checkers-common.c index 4d720990cf2a3..eba7ac4725c02 100644 --- a/arch/arm/probes/kprobes/checkers-common.c +++ b/arch/arm/probes/kprobes/checkers-common.c @@ -40,7 +40,7 @@ enum probes_insn checker_stack_use_imm_0xx(probes_opcode_t insn, * Different from other insn uses imm8, the real addressing offset of * STRD in T32 encoding should be imm8 * 4. See ARMARM description. */ -enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn, +static enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn, struct arch_probes_insn *asi, const struct decode_header *h) { diff --git a/arch/arm/probes/kprobes/core.c b/arch/arm/probes/kprobes/core.c index 9090c3a74dcce..d8238da095df7 100644 --- a/arch/arm/probes/kprobes/core.c +++ b/arch/arm/probes/kprobes/core.c @@ -233,7 +233,7 @@ singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb) * kprobe, and that level is reserved for user kprobe handlers, so we can't * risk encountering a new kprobe in an interrupt handler. */ -void __kprobes kprobe_handler(struct pt_regs *regs) +static void __kprobes kprobe_handler(struct pt_regs *regs) { struct kprobe *p, *cur; struct kprobe_ctlblk *kcb; diff --git a/arch/arm/probes/kprobes/opt-arm.c b/arch/arm/probes/kprobes/opt-arm.c index dbef34ed933f2..7f65048380ca5 100644 --- a/arch/arm/probes/kprobes/opt-arm.c +++ b/arch/arm/probes/kprobes/opt-arm.c @@ -145,8 +145,6 @@ __arch_remove_optimized_kprobe(struct optimized_kprobe *op, int dirty) } }
-extern void kprobe_handler(struct pt_regs *regs); - static void optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs) { diff --git a/arch/arm/probes/kprobes/test-core.c b/arch/arm/probes/kprobes/test-core.c index c562832b86272..171c7076b89f4 100644 --- a/arch/arm/probes/kprobes/test-core.c +++ b/arch/arm/probes/kprobes/test-core.c @@ -720,7 +720,7 @@ static const char coverage_register_lookup[16] = { [REG_TYPE_NOSPPCX] = COVERAGE_ANY_REG | COVERAGE_SP, };
-unsigned coverage_start_registers(const struct decode_header *h) +static unsigned coverage_start_registers(const struct decode_header *h) { unsigned regs = 0; int i; diff --git a/arch/arm/probes/kprobes/test-core.h b/arch/arm/probes/kprobes/test-core.h index 56ad3c0aaeeac..c7297037c1623 100644 --- a/arch/arm/probes/kprobes/test-core.h +++ b/arch/arm/probes/kprobes/test-core.h @@ -454,3 +454,7 @@ void kprobe_thumb32_test_cases(void); #else void kprobe_arm_test_cases(void); #endif + +void __kprobes_test_case_start(void); +void __kprobes_test_case_end_16(void); +void __kprobes_test_case_end_32(void);
From: Tero Kristo tero.kristo@linux.intel.com
[ Upstream commit 03f44ffb3d5be2fceda375d92c70ab6de4df7081 ]
If the intel_pstate driver is set to passive mode, then writing the same value to the energy_performance_preference sysfs twice will fail. This is caused by the wrong return value used (index of the matched energy_perf_string), instead of the length of the passed in parameter. Fix by forcing the internal return value to zero when the same preference is passed in by user. This same issue is not present when active mode is used for the driver.
Fixes: f6ebbcf08f37 ("cpufreq: intel_pstate: Implement passive mode with HWP enabled") Reported-by: Niklas Neronin niklas.neronin@intel.com Signed-off-by: Tero Kristo tero.kristo@linux.intel.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/intel_pstate.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 48a4613cef1e1..ee9e96a1893c6 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -824,6 +824,8 @@ static ssize_t store_energy_performance_preference( err = cpufreq_start_governor(policy); if (!ret) ret = err; + } else { + ret = 0; } }
From: Matti Lehtimäki matti.lehtimaki@gmail.com
[ Upstream commit 598e1afca47fdbb302ce8d288b06bcc8728efc6c ]
The MSM8226 TSENS IP has 6 thermal sensors in a TSENS v0.1 block. The thermal sensors use non-standard slope values.
Signed-off-by: Matti Lehtimäki matti.lehtimaki@gmail.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Luca Weiss luca@z3ntu.xyz Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Link: https://lore.kernel.org/r/20230507201225.89694-4-matti.lehtimaki@gmail.com Stable-dep-of: 6812d1dfbca9 ("thermal/drivers/qcom/tsens-v0_1: Fix mdm9607 slope values") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thermal/qcom/tsens-v0_1.c | 27 ++++++++++++++++++++++++++- drivers/thermal/qcom/tsens.c | 3 +++ drivers/thermal/qcom/tsens.h | 2 +- 3 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c index e89c6f39a3aea..ad57ab94546b0 100644 --- a/drivers/thermal/qcom/tsens-v0_1.c +++ b/drivers/thermal/qcom/tsens-v0_1.c @@ -243,6 +243,18 @@ static int calibrate_8974(struct tsens_priv *priv) return 0; }
+static int __init init_8226(struct tsens_priv *priv) +{ + priv->sensor[0].slope = 2901; + priv->sensor[1].slope = 2846; + priv->sensor[2].slope = 3038; + priv->sensor[3].slope = 2955; + priv->sensor[4].slope = 2901; + priv->sensor[5].slope = 2846; + + return init_common(priv); +} + static int __init init_8939(struct tsens_priv *priv) { priv->sensor[0].slope = 2911; priv->sensor[1].slope = 2789; @@ -258,7 +270,7 @@ static int __init init_8939(struct tsens_priv *priv) { return init_common(priv); }
-/* v0.1: 8916, 8939, 8974, 9607 */ +/* v0.1: 8226, 8916, 8939, 8974, 9607 */
static struct tsens_features tsens_v0_1_feat = { .ver_major = VER_0_1, @@ -313,6 +325,19 @@ static const struct tsens_ops ops_v0_1 = { .get_temp = get_temp_common, };
+static const struct tsens_ops ops_8226 = { + .init = init_8226, + .calibrate = tsens_calibrate_common, + .get_temp = get_temp_common, +}; + +struct tsens_plat_data data_8226 = { + .num_sensors = 6, + .ops = &ops_8226, + .feat = &tsens_v0_1_feat, + .fields = tsens_v0_1_regfields, +}; + static const struct tsens_ops ops_8916 = { .init = init_common, .calibrate = calibrate_8916, diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index 8020ead2794e9..eb33a8bf0488d 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -1095,6 +1095,9 @@ static const struct of_device_id tsens_table[] = { }, { .compatible = "qcom,mdm9607-tsens", .data = &data_9607, + }, { + .compatible = "qcom,msm8226-tsens", + .data = &data_8226, }, { .compatible = "qcom,msm8916-tsens", .data = &data_8916, diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h index dba9cd38f637c..433eba370998c 100644 --- a/drivers/thermal/qcom/tsens.h +++ b/drivers/thermal/qcom/tsens.h @@ -635,7 +635,7 @@ int get_temp_common(const struct tsens_sensor *s, int *temp); extern struct tsens_plat_data data_8960;
/* TSENS v0.1 targets */ -extern struct tsens_plat_data data_8916, data_8939, data_8974, data_9607; +extern struct tsens_plat_data data_8226, data_8916, data_8939, data_8974, data_9607;
/* TSENS v1 targets */ extern struct tsens_plat_data data_tsens_v1, data_8976, data_8956;
From: Stephan Gerhold stephan.gerhold@kernkonzept.com
[ Upstream commit 6812d1dfbca99cd5032683354bf50e0002b2aa02 ]
According to the msm-3.18 vendor kernel from Qualcomm [1], mdm9607 uses a non-standard slope value of 3000 (instead of 3200) for all sensors. Fill it properly similar to the 8939 code added recently.
[1]: https://git.codelinaro.org/clo/la/kernel/msm-3.18/-/blob/LE.UM.4.3.2.r1-0420...
Fixes: a2149ab815fc ("thermal/drivers/qcom/tsens-v0_1: Add support for MDM9607") Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Stephan Gerhold stephan.gerhold@kernkonzept.com Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Link: https://lore.kernel.org/r/20230508-msm8909-tsens-v5-2-5eb632235ba7@kernkonze... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thermal/qcom/tsens-v0_1.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c index ad57ab94546b0..e89a0da4b4e14 100644 --- a/drivers/thermal/qcom/tsens-v0_1.c +++ b/drivers/thermal/qcom/tsens-v0_1.c @@ -270,6 +270,16 @@ static int __init init_8939(struct tsens_priv *priv) { return init_common(priv); }
+static int __init init_9607(struct tsens_priv *priv) +{ + int i; + + for (i = 0; i < priv->num_sensors; ++i) + priv->sensor[i].slope = 3000; + + return init_common(priv); +} + /* v0.1: 8226, 8916, 8939, 8974, 9607 */
static struct tsens_features tsens_v0_1_feat = { @@ -381,9 +391,15 @@ struct tsens_plat_data data_8974 = { .fields = tsens_v0_1_regfields, };
+static const struct tsens_ops ops_9607 = { + .init = init_9607, + .calibrate = tsens_calibrate_common, + .get_temp = get_temp_common, +}; + struct tsens_plat_data data_9607 = { .num_sensors = 5, - .ops = &ops_v0_1, + .ops = &ops_9607, .feat = &tsens_v0_1_feat, .fields = tsens_v0_1_regfields, };
From: Stephan Gerhold stephan.gerhold@kernkonzept.com
[ Upstream commit b6f739da0070c36655118618a173a59fa14c7adc ]
According to the msm-3.18 vendor kernel from Qualcomm, mdm9607 needs "correction factors" to adjust for additional offsets observed after the factory calibration values in the fuses [1, 2].
The fixed offsets should be applied unless there is a special calibration mode value that indicates that no offsets are needed [3].
Note that the new calibration mode values are called differently in this patch compared to the vendor kernel: - TSENS_TWO_POINT_CALIB_N_WA -> ONE_PT_CALIB2_NO_OFFSET - TSENS_TWO_POINT_CALIB_N_OFFSET_WA -> TWO_PT_CALIB_NO_OFFSET This is because close inspection of the calibration function [3] reveals that TSENS_TWO_POINT_CALIB_N_WA is actually a "one point" calibration because the if statements skip all "point2" related code for it.
[1]: https://git.codelinaro.org/clo/la/kernel/msm-3.18/-/commit/d9d2db1b82bf3f72f... [2]: https://git.codelinaro.org/clo/la/kernel/msm-3.18/-/commit/d75aef53a760e8ff7... [3]: https://git.codelinaro.org/clo/la/kernel/msm-3.18/-/blob/LE.UM.4.3.2.r1-0420...
Fixes: a2149ab815fc ("thermal/drivers/qcom/tsens-v0_1: Add support for MDM9607") Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Stephan Gerhold stephan.gerhold@kernkonzept.com Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Link: https://lore.kernel.org/r/20230508-msm8909-tsens-v5-3-5eb632235ba7@kernkonze... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thermal/qcom/tsens-v0_1.c | 11 +++++++++++ drivers/thermal/qcom/tsens.c | 16 +++++++++++++++- drivers/thermal/qcom/tsens.h | 4 ++++ 3 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c index e89a0da4b4e14..e9ce7b62b3818 100644 --- a/drivers/thermal/qcom/tsens-v0_1.c +++ b/drivers/thermal/qcom/tsens-v0_1.c @@ -277,6 +277,17 @@ static int __init init_9607(struct tsens_priv *priv) for (i = 0; i < priv->num_sensors; ++i) priv->sensor[i].slope = 3000;
+ priv->sensor[0].p1_calib_offset = 1; + priv->sensor[0].p2_calib_offset = 1; + priv->sensor[1].p1_calib_offset = -4; + priv->sensor[1].p2_calib_offset = -2; + priv->sensor[2].p1_calib_offset = 4; + priv->sensor[2].p2_calib_offset = 8; + priv->sensor[3].p1_calib_offset = -3; + priv->sensor[3].p2_calib_offset = -5; + priv->sensor[4].p1_calib_offset = -4; + priv->sensor[4].p2_calib_offset = -4; + return init_common(priv); }
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index eb33a8bf0488d..2c02c86db6527 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -134,10 +134,12 @@ int tsens_read_calibration(struct tsens_priv *priv, int shift, u32 *p1, u32 *p2, p1[i] = p1[i] + (base1 << shift); break; case TWO_PT_CALIB: + case TWO_PT_CALIB_NO_OFFSET: for (i = 0; i < priv->num_sensors; i++) p2[i] = (p2[i] + base2) << shift; fallthrough; case ONE_PT_CALIB2: + case ONE_PT_CALIB2_NO_OFFSET: for (i = 0; i < priv->num_sensors; i++) p1[i] = (p1[i] + base1) << shift; break; @@ -149,6 +151,18 @@ int tsens_read_calibration(struct tsens_priv *priv, int shift, u32 *p1, u32 *p2, } }
+ /* Apply calibration offset workaround except for _NO_OFFSET modes */ + switch (mode) { + case TWO_PT_CALIB: + for (i = 0; i < priv->num_sensors; i++) + p2[i] += priv->sensor[i].p2_calib_offset; + fallthrough; + case ONE_PT_CALIB2: + for (i = 0; i < priv->num_sensors; i++) + p1[i] += priv->sensor[i].p1_calib_offset; + break; + } + return mode; }
@@ -254,7 +268,7 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *p1,
if (!priv->sensor[i].slope) priv->sensor[i].slope = SLOPE_DEFAULT; - if (mode == TWO_PT_CALIB) { + if (mode == TWO_PT_CALIB || mode == TWO_PT_CALIB_NO_OFFSET) { /* * slope (m) = adc_code2 - adc_code1 (y2 - y1)/ * temp_120_degc - temp_30_degc (x2 - x1) diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h index 433eba370998c..1cd8f4fe0971f 100644 --- a/drivers/thermal/qcom/tsens.h +++ b/drivers/thermal/qcom/tsens.h @@ -10,6 +10,8 @@ #define ONE_PT_CALIB 0x1 #define ONE_PT_CALIB2 0x2 #define TWO_PT_CALIB 0x3 +#define ONE_PT_CALIB2_NO_OFFSET 0x6 +#define TWO_PT_CALIB_NO_OFFSET 0x7 #define CAL_DEGC_PT1 30 #define CAL_DEGC_PT2 120 #define SLOPE_FACTOR 1000 @@ -57,6 +59,8 @@ struct tsens_sensor { unsigned int hw_id; int slope; u32 status; + int p1_calib_offset; + int p2_calib_offset; };
/**
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 89382022b370dfd34eaae9c863baa123fcd4d132 ]
Should an error occur after calling sun8i_ths_resource_init() in the probe function, some resources need to be released, as already done in the .remove() function.
Switch to the devm_clk_get_enabled() helper and add a new devm_action to turn sun8i_ths_resource_init() into a fully managed function.
Move the place where reset_control_deassert() is called so that the recommended order of reset release/clock enable steps is kept. A64 manual states that:
3.3.6.4. Gating and reset
Make sure that the reset signal has been released before the release of module clock gating;
This fixes the issue and removes some LoC at the same time.
Fixes: dccc5c3b6f30 ("thermal/drivers/sun8i: Add thermal driver for H6/H5/H3/A64/A83T/R40") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Acked-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Link: https://lore.kernel.org/r/a8ae84bd2dc4b55fe428f8e20f31438bf8bb6762.168408993... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thermal/sun8i_thermal.c | 55 +++++++++++---------------------- 1 file changed, 18 insertions(+), 37 deletions(-)
diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c index 497beac63e5d9..31063e82afb69 100644 --- a/drivers/thermal/sun8i_thermal.c +++ b/drivers/thermal/sun8i_thermal.c @@ -319,6 +319,11 @@ static int sun8i_ths_calibrate(struct ths_device *tmdev) return ret; }
+static void sun8i_ths_reset_control_assert(void *data) +{ + reset_control_assert(data); +} + static int sun8i_ths_resource_init(struct ths_device *tmdev) { struct device *dev = tmdev->dev; @@ -339,47 +344,35 @@ static int sun8i_ths_resource_init(struct ths_device *tmdev) if (IS_ERR(tmdev->reset)) return PTR_ERR(tmdev->reset);
- tmdev->bus_clk = devm_clk_get(&pdev->dev, "bus"); + ret = reset_control_deassert(tmdev->reset); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev, sun8i_ths_reset_control_assert, + tmdev->reset); + if (ret) + return ret; + + tmdev->bus_clk = devm_clk_get_enabled(&pdev->dev, "bus"); if (IS_ERR(tmdev->bus_clk)) return PTR_ERR(tmdev->bus_clk); }
if (tmdev->chip->has_mod_clk) { - tmdev->mod_clk = devm_clk_get(&pdev->dev, "mod"); + tmdev->mod_clk = devm_clk_get_enabled(&pdev->dev, "mod"); if (IS_ERR(tmdev->mod_clk)) return PTR_ERR(tmdev->mod_clk); }
- ret = reset_control_deassert(tmdev->reset); - if (ret) - return ret; - - ret = clk_prepare_enable(tmdev->bus_clk); - if (ret) - goto assert_reset; - ret = clk_set_rate(tmdev->mod_clk, 24000000); if (ret) - goto bus_disable; - - ret = clk_prepare_enable(tmdev->mod_clk); - if (ret) - goto bus_disable; + return ret;
ret = sun8i_ths_calibrate(tmdev); if (ret) - goto mod_disable; + return ret;
return 0; - -mod_disable: - clk_disable_unprepare(tmdev->mod_clk); -bus_disable: - clk_disable_unprepare(tmdev->bus_clk); -assert_reset: - reset_control_assert(tmdev->reset); - - return ret; }
static int sun8i_h3_thermal_init(struct ths_device *tmdev) @@ -530,17 +523,6 @@ static int sun8i_ths_probe(struct platform_device *pdev) return 0; }
-static int sun8i_ths_remove(struct platform_device *pdev) -{ - struct ths_device *tmdev = platform_get_drvdata(pdev); - - clk_disable_unprepare(tmdev->mod_clk); - clk_disable_unprepare(tmdev->bus_clk); - reset_control_assert(tmdev->reset); - - return 0; -} - static const struct ths_thermal_chip sun8i_a83t_ths = { .sensor_num = 3, .scale = 705, @@ -642,7 +624,6 @@ MODULE_DEVICE_TABLE(of, of_ths_match);
static struct platform_driver ths_driver = { .probe = sun8i_ths_probe, - .remove = sun8i_ths_remove, .driver = { .name = "sun8i-thermal", .of_match_table = of_ths_match,
From: Daniel Lezcano daniel.lezcano@linaro.org
[ Upstream commit 4a16c190f761cb3a87dcbbf355f91c71ce1f8c0b ]
The devres variant of thermal_add_hwmon_sysfs() only takes the thermal zone structure pointer as parameter.
Actually, it uses the tz->device to add it in the devres list.
It is preferable to use the device registering the thermal zone instead of the thermal zone device itself. That prevents the driver accessing the thermal zone structure internals and it is from my POV more correct regarding how devm_ is used.
Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Acked-by: Martin Blumenstingl martin.blumenstingl@googlemail.com #amlogic_thermal Acked-by: Jernej Skrabec jernej.skrabec@gmail.com #sun8i_thermal Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com #MediaTek auxadc Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Stable-dep-of: 9301575df250 ("thermal/drivers/qoriq: Only enable supported sensors") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thermal/amlogic_thermal.c | 2 +- drivers/thermal/imx8mm_thermal.c | 2 +- drivers/thermal/imx_sc_thermal.c | 2 +- drivers/thermal/k3_bandgap.c | 2 +- drivers/thermal/mediatek/auxadc_thermal.c | 2 +- drivers/thermal/qcom/qcom-spmi-adc-tm5.c | 2 +- drivers/thermal/qcom/qcom-spmi-temp-alarm.c | 2 +- drivers/thermal/qcom/tsens.c | 2 +- drivers/thermal/qoriq_thermal.c | 2 +- drivers/thermal/sun8i_thermal.c | 2 +- drivers/thermal/tegra/tegra30-tsensor.c | 2 +- drivers/thermal/thermal_hwmon.c | 4 ++-- drivers/thermal/thermal_hwmon.h | 4 ++-- drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 2 +- 14 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/drivers/thermal/amlogic_thermal.c b/drivers/thermal/amlogic_thermal.c index 9235fda4ec1eb..337153042318f 100644 --- a/drivers/thermal/amlogic_thermal.c +++ b/drivers/thermal/amlogic_thermal.c @@ -285,7 +285,7 @@ static int amlogic_thermal_probe(struct platform_device *pdev) return ret; }
- if (devm_thermal_add_hwmon_sysfs(pdata->tzd)) + if (devm_thermal_add_hwmon_sysfs(&pdev->dev, pdata->tzd)) dev_warn(&pdev->dev, "Failed to add hwmon sysfs attributes\n");
ret = amlogic_thermal_initialize(pdata); diff --git a/drivers/thermal/imx8mm_thermal.c b/drivers/thermal/imx8mm_thermal.c index 72b5d6f319c1d..e1bec196c5350 100644 --- a/drivers/thermal/imx8mm_thermal.c +++ b/drivers/thermal/imx8mm_thermal.c @@ -343,7 +343,7 @@ static int imx8mm_tmu_probe(struct platform_device *pdev) } tmu->sensors[i].hw_id = i;
- if (devm_thermal_add_hwmon_sysfs(tmu->sensors[i].tzd)) + if (devm_thermal_add_hwmon_sysfs(&pdev->dev, tmu->sensors[i].tzd)) dev_warn(&pdev->dev, "failed to add hwmon sysfs attributes\n"); }
diff --git a/drivers/thermal/imx_sc_thermal.c b/drivers/thermal/imx_sc_thermal.c index f32e59e746231..e24572fc9e731 100644 --- a/drivers/thermal/imx_sc_thermal.c +++ b/drivers/thermal/imx_sc_thermal.c @@ -119,7 +119,7 @@ static int imx_sc_thermal_probe(struct platform_device *pdev) return ret; }
- if (devm_thermal_add_hwmon_sysfs(sensor->tzd)) + if (devm_thermal_add_hwmon_sysfs(&pdev->dev, sensor->tzd)) dev_warn(&pdev->dev, "failed to add hwmon sysfs attributes\n"); }
diff --git a/drivers/thermal/k3_bandgap.c b/drivers/thermal/k3_bandgap.c index 22c9bcb899c37..df184b837cdd0 100644 --- a/drivers/thermal/k3_bandgap.c +++ b/drivers/thermal/k3_bandgap.c @@ -222,7 +222,7 @@ static int k3_bandgap_probe(struct platform_device *pdev) goto err_alloc; }
- if (devm_thermal_add_hwmon_sysfs(data[id].tzd)) + if (devm_thermal_add_hwmon_sysfs(dev, data[id].tzd)) dev_warn(dev, "Failed to add hwmon sysfs attributes\n"); }
diff --git a/drivers/thermal/mediatek/auxadc_thermal.c b/drivers/thermal/mediatek/auxadc_thermal.c index ab730f9552d0e..585704d2df2be 100644 --- a/drivers/thermal/mediatek/auxadc_thermal.c +++ b/drivers/thermal/mediatek/auxadc_thermal.c @@ -1210,7 +1210,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) goto err_disable_clk_peri_therm; }
- ret = devm_thermal_add_hwmon_sysfs(tzdev); + ret = devm_thermal_add_hwmon_sysfs(&pdev->dev, tzdev); if (ret) dev_warn(&pdev->dev, "error in thermal_add_hwmon_sysfs");
diff --git a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c index 31164ade2dd11..dcb24a94f3fb4 100644 --- a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c +++ b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c @@ -689,7 +689,7 @@ static int adc_tm5_register_tzd(struct adc_tm5_chip *adc_tm) return PTR_ERR(tzd); } adc_tm->channels[i].tzd = tzd; - if (devm_thermal_add_hwmon_sysfs(tzd)) + if (devm_thermal_add_hwmon_sysfs(adc_tm->dev, tzd)) dev_warn(adc_tm->dev, "Failed to add hwmon sysfs attributes\n"); } diff --git a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c index 101c75d0e13f3..c0cfb255c14e2 100644 --- a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c +++ b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c @@ -459,7 +459,7 @@ static int qpnp_tm_probe(struct platform_device *pdev) return ret; }
- if (devm_thermal_add_hwmon_sysfs(chip->tz_dev)) + if (devm_thermal_add_hwmon_sysfs(&pdev->dev, chip->tz_dev)) dev_warn(&pdev->dev, "Failed to add hwmon sysfs attributes\n");
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index 2c02c86db6527..38f5c783fb297 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -1206,7 +1206,7 @@ static int tsens_register(struct tsens_priv *priv) if (priv->ops->enable) priv->ops->enable(priv, i);
- if (devm_thermal_add_hwmon_sysfs(tzd)) + if (devm_thermal_add_hwmon_sysfs(priv->dev, tzd)) dev_warn(priv->dev, "Failed to add hwmon sysfs attributes\n"); } diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c index 431c29c0898a7..5c9205fe30733 100644 --- a/drivers/thermal/qoriq_thermal.c +++ b/drivers/thermal/qoriq_thermal.c @@ -157,7 +157,7 @@ static int qoriq_tmu_register_tmu_zone(struct device *dev, return ret; }
- if (devm_thermal_add_hwmon_sysfs(tzd)) + if (devm_thermal_add_hwmon_sysfs(dev, tzd)) dev_warn(dev, "Failed to add hwmon sysfs attributes\n");
diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c index 31063e82afb69..7517067d6e817 100644 --- a/drivers/thermal/sun8i_thermal.c +++ b/drivers/thermal/sun8i_thermal.c @@ -468,7 +468,7 @@ static int sun8i_ths_register(struct ths_device *tmdev) if (IS_ERR(tmdev->sensor[i].tzd)) return PTR_ERR(tmdev->sensor[i].tzd);
- if (devm_thermal_add_hwmon_sysfs(tmdev->sensor[i].tzd)) + if (devm_thermal_add_hwmon_sysfs(tmdev->dev, tmdev->sensor[i].tzd)) dev_warn(tmdev->dev, "Failed to add hwmon sysfs attributes\n"); } diff --git a/drivers/thermal/tegra/tegra30-tsensor.c b/drivers/thermal/tegra/tegra30-tsensor.c index b3218b71b6d97..823560c82aaee 100644 --- a/drivers/thermal/tegra/tegra30-tsensor.c +++ b/drivers/thermal/tegra/tegra30-tsensor.c @@ -528,7 +528,7 @@ static int tegra_tsensor_register_channel(struct tegra_tsensor *ts, return 0; }
- if (devm_thermal_add_hwmon_sysfs(tsc->tzd)) + if (devm_thermal_add_hwmon_sysfs(ts->dev, tsc->tzd)) dev_warn(ts->dev, "failed to add hwmon sysfs attributes\n");
return 0; diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c index c594c42bea6da..964db7941e310 100644 --- a/drivers/thermal/thermal_hwmon.c +++ b/drivers/thermal/thermal_hwmon.c @@ -263,7 +263,7 @@ static void devm_thermal_hwmon_release(struct device *dev, void *res) thermal_remove_hwmon_sysfs(*(struct thermal_zone_device **)res); }
-int devm_thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) +int devm_thermal_add_hwmon_sysfs(struct device *dev, struct thermal_zone_device *tz) { struct thermal_zone_device **ptr; int ret; @@ -280,7 +280,7 @@ int devm_thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) }
*ptr = tz; - devres_add(&tz->device, ptr); + devres_add(dev, ptr);
return ret; } diff --git a/drivers/thermal/thermal_hwmon.h b/drivers/thermal/thermal_hwmon.h index 1a9d65f6a6a8b..b429f6e7abdb2 100644 --- a/drivers/thermal/thermal_hwmon.h +++ b/drivers/thermal/thermal_hwmon.h @@ -17,7 +17,7 @@
#ifdef CONFIG_THERMAL_HWMON int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz); -int devm_thermal_add_hwmon_sysfs(struct thermal_zone_device *tz); +int devm_thermal_add_hwmon_sysfs(struct device *dev, struct thermal_zone_device *tz); void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz); #else static inline int @@ -27,7 +27,7 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) }
static inline int -devm_thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) +devm_thermal_add_hwmon_sysfs(struct device *dev, struct thermal_zone_device *tz) { return 0; } diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c index 8a9055bd376ec..42d0ffd82514d 100644 --- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c +++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c @@ -182,7 +182,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id, ti_bandgap_set_sensor_data(bgp, id, data); ti_bandgap_write_update_interval(bgp, data->sensor_id, interval);
- if (devm_thermal_add_hwmon_sysfs(data->ti_thermal)) + if (devm_thermal_add_hwmon_sysfs(bgp->dev, data->ti_thermal)) dev_warn(bgp->dev, "failed to add hwmon sysfs attributes\n");
return 0;
From: Peng Fan peng.fan@nxp.com
[ Upstream commit 9301575df2509ecf8bd66f601046afaff606b1d5 ]
There are MAX 16 sensors, but not all of them supported. Such as i.MX8MQ, there are only 3 sensors. Enabling all 16 sensors will touch reserved bits from i.MX8MQ reference mannual, and TMU will stuck, temperature will not update anymore.
Fixes: 45038e03d633 ("thermal: qoriq: Enable all sensors before registering them") Signed-off-by: Peng Fan peng.fan@nxp.com Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Link: https://lore.kernel.org/r/20230516083746.63436-3-peng.fan@oss.nxp.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thermal/qoriq_thermal.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c index 5c9205fe30733..dec66cf3eba2c 100644 --- a/drivers/thermal/qoriq_thermal.c +++ b/drivers/thermal/qoriq_thermal.c @@ -31,7 +31,6 @@ #define TMR_DISABLE 0x0 #define TMR_ME 0x80000000 #define TMR_ALPF 0x0c000000 -#define TMR_MSITE_ALL GENMASK(15, 0)
#define REGS_TMTMIR 0x008 /* Temperature measurement interval Register */ #define TMTMIR_DEFAULT 0x0000000f @@ -105,6 +104,11 @@ static int tmu_get_temp(struct thermal_zone_device *tz, int *temp) * within sensor range. TEMP is an 9 bit value representing * temperature in KelVin. */ + + regmap_read(qdata->regmap, REGS_TMR, &val); + if (!(val & TMR_ME)) + return -EAGAIN; + if (regmap_read_poll_timeout(qdata->regmap, REGS_TRITSR(qsensor->id), val, @@ -128,15 +132,7 @@ static const struct thermal_zone_device_ops tmu_tz_ops = { static int qoriq_tmu_register_tmu_zone(struct device *dev, struct qoriq_tmu_data *qdata) { - int id; - - if (qdata->ver == TMU_VER1) { - regmap_write(qdata->regmap, REGS_TMR, - TMR_MSITE_ALL | TMR_ME | TMR_ALPF); - } else { - regmap_write(qdata->regmap, REGS_V2_TMSR, TMR_MSITE_ALL); - regmap_write(qdata->regmap, REGS_TMR, TMR_ME | TMR_ALPF_V2); - } + int id, sites = 0;
for (id = 0; id < SITES_MAX; id++) { struct thermal_zone_device *tzd; @@ -153,14 +149,26 @@ static int qoriq_tmu_register_tmu_zone(struct device *dev, if (ret == -ENODEV) continue;
- regmap_write(qdata->regmap, REGS_TMR, TMR_DISABLE); return ret; }
+ if (qdata->ver == TMU_VER1) + sites |= 0x1 << (15 - id); + else + sites |= 0x1 << id; + if (devm_thermal_add_hwmon_sysfs(dev, tzd)) dev_warn(dev, "Failed to add hwmon sysfs attributes\n"); + }
+ if (sites) { + if (qdata->ver == TMU_VER1) { + regmap_write(qdata->regmap, REGS_TMR, TMR_ME | TMR_ALPF | sites); + } else { + regmap_write(qdata->regmap, REGS_V2_TMSR, sites); + regmap_write(qdata->regmap, REGS_TMR, TMR_ME | TMR_ALPF_V2); + } }
return 0;
From: Paul E. McKenney paulmck@kernel.org
[ Upstream commit 15d44dfa40305da1648de4bf001e91cc63148725 ]
Currently, rcu_cpu_starting() is written so that it might be invoked with interrupts enabled. However, it is always called when interrupts are disabled, either by rcu_init(), notify_cpu_starting(), or from a call point prior to the call to notify_cpu_starting().
But why bother requiring that interrupts be disabled? The purpose is to allow the rcu_data structure's ->beenonline flag to be set after all early processing has completed for the incoming CPU, thus allowing this flag to be used to determine when workqueues have been set up for the incoming CPU, while still allowing this flag to be used as a diagnostic within rcu_core().
This commit therefore makes rcu_cpu_starting() rely on interrupts being disabled.
Signed-off-by: Paul E. McKenney paulmck@kernel.org Stable-dep-of: 401b0de3ae4f ("rcu-tasks: Stop rcu_tasks_invoke_cbs() from using never-onlined CPUs") Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/tree.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index a565dc5c54440..954a91fec912c 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -4364,15 +4364,16 @@ int rcutree_offline_cpu(unsigned int cpu) * Note that this function is special in that it is invoked directly * from the incoming CPU rather than from the cpuhp_step mechanism. * This is because this function must be invoked at a precise location. + * This incoming CPU must not have enabled interrupts yet. */ void rcu_cpu_starting(unsigned int cpu) { - unsigned long flags; unsigned long mask; struct rcu_data *rdp; struct rcu_node *rnp; bool newcpu;
+ lockdep_assert_irqs_disabled(); rdp = per_cpu_ptr(&rcu_data, cpu); if (rdp->cpu_started) return; @@ -4380,7 +4381,6 @@ void rcu_cpu_starting(unsigned int cpu)
rnp = rdp->mynode; mask = rdp->grpmask; - local_irq_save(flags); arch_spin_lock(&rcu_state.ofl_lock); rcu_dynticks_eqs_online(); raw_spin_lock(&rcu_state.barrier_lock); @@ -4399,17 +4399,16 @@ void rcu_cpu_starting(unsigned int cpu) /* An incoming CPU should never be blocking a grace period. */ if (WARN_ON_ONCE(rnp->qsmask & mask)) { /* RCU waiting on incoming CPU? */ /* rcu_report_qs_rnp() *really* wants some flags to restore */ - unsigned long flags2; + unsigned long flags;
- local_irq_save(flags2); + local_irq_save(flags); rcu_disable_urgency_upon_qs(rdp); /* Report QS -after- changing ->qsmaskinitnext! */ - rcu_report_qs_rnp(mask, rnp, rnp->gp_seq, flags2); + rcu_report_qs_rnp(mask, rnp, rnp->gp_seq, flags); } else { raw_spin_unlock_rcu_node(rnp); } arch_spin_unlock(&rcu_state.ofl_lock); - local_irq_restore(flags); smp_mb(); /* Ensure RCU read-side usage follows above initialization. */ }
From: Paul E. McKenney paulmck@kernel.org
[ Upstream commit 401b0de3ae4fa49d1014c8941e26d9a25f37e7cf ]
The rcu_tasks_invoke_cbs() function relies on queue_work_on() to silently fall back to WORK_CPU_UNBOUND when the specified CPU is offline. However, the queue_work_on() function's silent fallback mechanism relies on that CPU having been online at some time in the past. When queue_work_on() is passed a CPU that has never been online, workqueue lockups ensue, which can be bad for your kernel's general health and well-being.
This commit therefore checks whether a given CPU has ever been online, and, if not substitutes WORK_CPU_UNBOUND in the subsequent call to queue_work_on(). Why not simply omit the queue_work_on() call entirely? Because this function is flooding callback-invocation notifications to all CPUs, and must deal with possibilities that include a sparse cpu_possible_mask.
This commit also moves the setting of the rcu_data structure's ->beenonline field to rcu_cpu_starting(), which executes on the incoming CPU before that CPU has ever enabled interrupts. This ensures that the required workqueues are present. In addition, because the incoming CPU has not yet enabled its interrupts, there cannot yet have been any softirq handlers running on this CPU, which means that the WARN_ON_ONCE(!rdp->beenonline) within the RCU_SOFTIRQ handler cannot have triggered yet.
Fixes: d363f833c6d88 ("rcu-tasks: Use workqueues for multiple rcu_tasks_invoke_cbs() invocations") Reported-by: Tejun Heo tj@kernel.org Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/rcu.h | 6 ++++++ kernel/rcu/tasks.h | 7 +++++-- kernel/rcu/tree.c | 12 +++++++++++- 3 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h index 115616ac3bfa6..2d7e85dbf6734 100644 --- a/kernel/rcu/rcu.h +++ b/kernel/rcu/rcu.h @@ -603,4 +603,10 @@ void show_rcu_tasks_trace_gp_kthread(void); static inline void show_rcu_tasks_trace_gp_kthread(void) {} #endif
+#ifdef CONFIG_TINY_RCU +static inline bool rcu_cpu_beenfullyonline(int cpu) { return true; } +#else +bool rcu_cpu_beenfullyonline(int cpu); +#endif + #endif /* __LINUX_RCU_H */ diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h index bfb5e1549f2b2..dfa6ff2eb32f2 100644 --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@ -455,6 +455,7 @@ static void rcu_tasks_invoke_cbs(struct rcu_tasks *rtp, struct rcu_tasks_percpu { int cpu; int cpunext; + int cpuwq; unsigned long flags; int len; struct rcu_head *rhp; @@ -465,11 +466,13 @@ static void rcu_tasks_invoke_cbs(struct rcu_tasks *rtp, struct rcu_tasks_percpu cpunext = cpu * 2 + 1; if (cpunext < smp_load_acquire(&rtp->percpu_dequeue_lim)) { rtpcp_next = per_cpu_ptr(rtp->rtpcpu, cpunext); - queue_work_on(cpunext, system_wq, &rtpcp_next->rtp_work); + cpuwq = rcu_cpu_beenfullyonline(cpunext) ? cpunext : WORK_CPU_UNBOUND; + queue_work_on(cpuwq, system_wq, &rtpcp_next->rtp_work); cpunext++; if (cpunext < smp_load_acquire(&rtp->percpu_dequeue_lim)) { rtpcp_next = per_cpu_ptr(rtp->rtpcpu, cpunext); - queue_work_on(cpunext, system_wq, &rtpcp_next->rtp_work); + cpuwq = rcu_cpu_beenfullyonline(cpunext) ? cpunext : WORK_CPU_UNBOUND; + queue_work_on(cpuwq, system_wq, &rtpcp_next->rtp_work); } }
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 954a91fec912c..be490f55cb834 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -4279,7 +4279,6 @@ int rcutree_prepare_cpu(unsigned int cpu) */ rnp = rdp->mynode; raw_spin_lock_rcu_node(rnp); /* irqs already disabled. */ - rdp->beenonline = true; /* We have now been online. */ rdp->gp_seq = READ_ONCE(rnp->gp_seq); rdp->gp_seq_needed = rdp->gp_seq; rdp->cpu_no_qs.b.norm = true; @@ -4306,6 +4305,16 @@ static void rcutree_affinity_setting(unsigned int cpu, int outgoing) rcu_boost_kthread_setaffinity(rdp->mynode, outgoing); }
+/* + * Has the specified (known valid) CPU ever been fully online? + */ +bool rcu_cpu_beenfullyonline(int cpu) +{ + struct rcu_data *rdp = per_cpu_ptr(&rcu_data, cpu); + + return smp_load_acquire(&rdp->beenonline); +} + /* * Near the end of the CPU-online process. Pretty much all services * enabled, and the CPU is now very much alive. @@ -4409,6 +4418,7 @@ void rcu_cpu_starting(unsigned int cpu) raw_spin_unlock_rcu_node(rnp); } arch_spin_unlock(&rcu_state.ofl_lock); + smp_store_release(&rdp->beenonline, true); smp_mb(); /* Ensure RCU read-side usage follows above initialization. */ }
From: Paul E. McKenney paulmck@kernel.org
[ Upstream commit b409afe0268faeb77267f028ea85f2d93438fced ]
The BUSTED-BOOST and TREE03 scenarios specify a mythical tree.use_softirq module parameter, which means a failure to get full test coverage. This commit therefore corrects the name to rcutree.use_softirq.
Fixes: e2b949d54392 ("rcutorture: Make TREE03 use real-time tree.use_softirq setting") Signed-off-by: Paul E. McKenney paulmck@kernel.org Reviewed-by: Joel Fernandes (Google) joel@joelfernandes.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../testing/selftests/rcutorture/configs/rcu/BUSTED-BOOST.boot | 2 +- tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/BUSTED-BOOST.boot b/tools/testing/selftests/rcutorture/configs/rcu/BUSTED-BOOST.boot index f57720c52c0f9..84f6bb98ce993 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/BUSTED-BOOST.boot +++ b/tools/testing/selftests/rcutorture/configs/rcu/BUSTED-BOOST.boot @@ -5,4 +5,4 @@ rcutree.gp_init_delay=3 rcutree.gp_cleanup_delay=3 rcutree.kthread_prio=2 threadirqs -tree.use_softirq=0 +rcutree.use_softirq=0 diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot b/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot index 64f864f1f361f..8e50bfd4b710d 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot @@ -4,4 +4,4 @@ rcutree.gp_init_delay=3 rcutree.gp_cleanup_delay=3 rcutree.kthread_prio=2 threadirqs -tree.use_softirq=0 +rcutree.use_softirq=0
From: Paul E. McKenney paulmck@kernel.org
[ Upstream commit ef1ef3d47677dc191b88650a9f7f91413452cc1b ]
The rcu_scale_shutdown() and kfree_scale_shutdown() kthreads/functions use wait_event() to wait for the rcuscale test to complete. However, each updater thread in such a test waits for at least 100 grace periods. If each grace period takes more than 1.2 seconds, which is long, but not insanely so, this can trigger the hung-task timeout.
This commit therefore replaces those wait_event() calls with calls to wait_event_idle(), which do not trigger the hung-task timeout.
Reported-by: kernel test robot yujie.liu@intel.com Reported-by: Liam Howlett liam.howlett@oracle.com Signed-off-by: Paul E. McKenney paulmck@kernel.org Tested-by: Yujie Liu yujie.liu@intel.com Signed-off-by: Boqun Feng boqun.feng@gmail.com Stable-dep-of: 23fc8df26dea ("rcu/rcuscale: Stop kfree_scale_thread thread(s) after unloading rcuscale") Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/rcuscale.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c index 91fb5905a008f..4120f94030c3c 100644 --- a/kernel/rcu/rcuscale.c +++ b/kernel/rcu/rcuscale.c @@ -631,8 +631,7 @@ static int compute_real(int n) static int rcu_scale_shutdown(void *arg) { - wait_event(shutdown_wq, - atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters); + wait_event_idle(shutdown_wq, atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters); smp_mb(); /* Wake before output. */ rcu_scale_cleanup(); kernel_power_off(); @@ -771,8 +770,8 @@ kfree_scale_cleanup(void) static int kfree_scale_shutdown(void *arg) { - wait_event(shutdown_wq, - atomic_read(&n_kfree_scale_thread_ended) >= kfree_nrealthreads); + wait_event_idle(shutdown_wq, + atomic_read(&n_kfree_scale_thread_ended) >= kfree_nrealthreads);
smp_mb(); /* Wake before output. */
From: Qiuxu Zhuo qiuxu.zhuo@intel.com
[ Upstream commit bf5ddd736509a7d9077c0b6793e6f0852214dbea ]
This code-movement-only commit moves the rcu_scale_cleanup() and rcu_scale_shutdown() functions to follow kfree_scale_cleanup(). This is code movement is in preparation for a bug-fix patch that invokes kfree_scale_cleanup() from rcu_scale_cleanup().
Signed-off-by: Qiuxu Zhuo qiuxu.zhuo@intel.com Signed-off-by: Paul E. McKenney paulmck@kernel.org Reviewed-by: Joel Fernandes (Google) joel@joelfernandes.org Stable-dep-of: 23fc8df26dea ("rcu/rcuscale: Stop kfree_scale_thread thread(s) after unloading rcuscale") Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/rcuscale.c | 194 +++++++++++++++++++++--------------------- 1 file changed, 97 insertions(+), 97 deletions(-)
diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c index 4120f94030c3c..dd25d306559a5 100644 --- a/kernel/rcu/rcuscale.c +++ b/kernel/rcu/rcuscale.c @@ -522,89 +522,6 @@ rcu_scale_print_module_parms(struct rcu_scale_ops *cur_ops, const char *tag) scale_type, tag, nrealreaders, nrealwriters, verbose, shutdown); }
-static void -rcu_scale_cleanup(void) -{ - int i; - int j; - int ngps = 0; - u64 *wdp; - u64 *wdpp; - - /* - * Would like warning at start, but everything is expedited - * during the mid-boot phase, so have to wait till the end. - */ - if (rcu_gp_is_expedited() && !rcu_gp_is_normal() && !gp_exp) - SCALEOUT_ERRSTRING("All grace periods expedited, no normal ones to measure!"); - if (rcu_gp_is_normal() && gp_exp) - SCALEOUT_ERRSTRING("All grace periods normal, no expedited ones to measure!"); - if (gp_exp && gp_async) - SCALEOUT_ERRSTRING("No expedited async GPs, so went with async!"); - - if (torture_cleanup_begin()) - return; - if (!cur_ops) { - torture_cleanup_end(); - return; - } - - if (reader_tasks) { - for (i = 0; i < nrealreaders; i++) - torture_stop_kthread(rcu_scale_reader, - reader_tasks[i]); - kfree(reader_tasks); - } - - if (writer_tasks) { - for (i = 0; i < nrealwriters; i++) { - torture_stop_kthread(rcu_scale_writer, - writer_tasks[i]); - if (!writer_n_durations) - continue; - j = writer_n_durations[i]; - pr_alert("%s%s writer %d gps: %d\n", - scale_type, SCALE_FLAG, i, j); - ngps += j; - } - pr_alert("%s%s start: %llu end: %llu duration: %llu gps: %d batches: %ld\n", - scale_type, SCALE_FLAG, - t_rcu_scale_writer_started, t_rcu_scale_writer_finished, - t_rcu_scale_writer_finished - - t_rcu_scale_writer_started, - ngps, - rcuscale_seq_diff(b_rcu_gp_test_finished, - b_rcu_gp_test_started)); - for (i = 0; i < nrealwriters; i++) { - if (!writer_durations) - break; - if (!writer_n_durations) - continue; - wdpp = writer_durations[i]; - if (!wdpp) - continue; - for (j = 0; j < writer_n_durations[i]; j++) { - wdp = &wdpp[j]; - pr_alert("%s%s %4d writer-duration: %5d %llu\n", - scale_type, SCALE_FLAG, - i, j, *wdp); - if (j % 100 == 0) - schedule_timeout_uninterruptible(1); - } - kfree(writer_durations[i]); - } - kfree(writer_tasks); - kfree(writer_durations); - kfree(writer_n_durations); - } - - /* Do torture-type-specific cleanup operations. */ - if (cur_ops->cleanup != NULL) - cur_ops->cleanup(); - - torture_cleanup_end(); -} - /* * Return the number if non-negative. If -1, the number of CPUs. * If less than -1, that much less than the number of CPUs, but @@ -624,20 +541,6 @@ static int compute_real(int n) return nr; }
-/* - * RCU scalability shutdown kthread. Just waits to be awakened, then shuts - * down system. - */ -static int -rcu_scale_shutdown(void *arg) -{ - wait_event_idle(shutdown_wq, atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters); - smp_mb(); /* Wake before output. */ - rcu_scale_cleanup(); - kernel_power_off(); - return -EINVAL; -} - /* * kfree_rcu() scalability tests: Start a kfree_rcu() loop on all CPUs for number * of iterations and measure total time and number of GP for all iterations to complete. @@ -874,6 +777,103 @@ kfree_scale_init(void) return firsterr; }
+static void +rcu_scale_cleanup(void) +{ + int i; + int j; + int ngps = 0; + u64 *wdp; + u64 *wdpp; + + /* + * Would like warning at start, but everything is expedited + * during the mid-boot phase, so have to wait till the end. + */ + if (rcu_gp_is_expedited() && !rcu_gp_is_normal() && !gp_exp) + SCALEOUT_ERRSTRING("All grace periods expedited, no normal ones to measure!"); + if (rcu_gp_is_normal() && gp_exp) + SCALEOUT_ERRSTRING("All grace periods normal, no expedited ones to measure!"); + if (gp_exp && gp_async) + SCALEOUT_ERRSTRING("No expedited async GPs, so went with async!"); + + if (torture_cleanup_begin()) + return; + if (!cur_ops) { + torture_cleanup_end(); + return; + } + + if (reader_tasks) { + for (i = 0; i < nrealreaders; i++) + torture_stop_kthread(rcu_scale_reader, + reader_tasks[i]); + kfree(reader_tasks); + } + + if (writer_tasks) { + for (i = 0; i < nrealwriters; i++) { + torture_stop_kthread(rcu_scale_writer, + writer_tasks[i]); + if (!writer_n_durations) + continue; + j = writer_n_durations[i]; + pr_alert("%s%s writer %d gps: %d\n", + scale_type, SCALE_FLAG, i, j); + ngps += j; + } + pr_alert("%s%s start: %llu end: %llu duration: %llu gps: %d batches: %ld\n", + scale_type, SCALE_FLAG, + t_rcu_scale_writer_started, t_rcu_scale_writer_finished, + t_rcu_scale_writer_finished - + t_rcu_scale_writer_started, + ngps, + rcuscale_seq_diff(b_rcu_gp_test_finished, + b_rcu_gp_test_started)); + for (i = 0; i < nrealwriters; i++) { + if (!writer_durations) + break; + if (!writer_n_durations) + continue; + wdpp = writer_durations[i]; + if (!wdpp) + continue; + for (j = 0; j < writer_n_durations[i]; j++) { + wdp = &wdpp[j]; + pr_alert("%s%s %4d writer-duration: %5d %llu\n", + scale_type, SCALE_FLAG, + i, j, *wdp); + if (j % 100 == 0) + schedule_timeout_uninterruptible(1); + } + kfree(writer_durations[i]); + } + kfree(writer_tasks); + kfree(writer_durations); + kfree(writer_n_durations); + } + + /* Do torture-type-specific cleanup operations. */ + if (cur_ops->cleanup != NULL) + cur_ops->cleanup(); + + torture_cleanup_end(); +} + +/* + * RCU scalability shutdown kthread. Just waits to be awakened, then shuts + * down system. + */ +static int +rcu_scale_shutdown(void *arg) +{ + wait_event_idle(shutdown_wq, atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters); + smp_mb(); /* Wake before output. */ + rcu_scale_cleanup(); + kernel_power_off(); + return -EINVAL; +} + static int __init rcu_scale_init(void) {
From: Qiuxu Zhuo qiuxu.zhuo@intel.com
[ Upstream commit 23fc8df26dead16687ae6eb47b0561a4a832e2f6 ]
Running the 'kfree_rcu_test' test case [1] results in a splat [2]. The root cause is the kfree_scale_thread thread(s) continue running after unloading the rcuscale module. This commit fixes that isue by invoking kfree_scale_cleanup() from rcu_scale_cleanup() when removing the rcuscale module.
[1] modprobe rcuscale kfree_rcu_test=1 // After some time rmmod rcuscale rmmod torture
[2] BUG: unable to handle page fault for address: ffffffffc0601a87 #PF: supervisor instruction fetch in kernel mode #PF: error_code(0x0010) - not-present page PGD 11de4f067 P4D 11de4f067 PUD 11de51067 PMD 112f4d067 PTE 0 Oops: 0010 [#1] PREEMPT SMP NOPTI CPU: 1 PID: 1798 Comm: kfree_scale_thr Not tainted 6.3.0-rc1-rcu+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015 RIP: 0010:0xffffffffc0601a87 Code: Unable to access opcode bytes at 0xffffffffc0601a5d. RSP: 0018:ffffb25bc2e57e18 EFLAGS: 00010297 RAX: 0000000000000000 RBX: ffffffffc061f0b6 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffffffff962fd0de RDI: ffffffff962fd0de RBP: ffffb25bc2e57ea8 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000001 R12: 0000000000000000 R13: 0000000000000000 R14: 000000000000000a R15: 00000000001c1dbe FS: 0000000000000000(0000) GS:ffff921fa2200000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffc0601a5d CR3: 000000011de4c006 CR4: 0000000000370ee0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> ? kvfree_call_rcu+0xf0/0x3a0 ? kthread+0xf3/0x120 ? kthread_complete_and_exit+0x20/0x20 ? ret_from_fork+0x1f/0x30 </TASK> Modules linked in: rfkill sunrpc ... [last unloaded: torture] CR2: ffffffffc0601a87 ---[ end trace 0000000000000000 ]---
Fixes: e6e78b004fa7 ("rcuperf: Add kfree_rcu() performance Tests") Reviewed-by: Davidlohr Bueso dave@stgolabs.net Reviewed-by: Joel Fernandes (Google) joel@joelfernandes.org Signed-off-by: Qiuxu Zhuo qiuxu.zhuo@intel.com Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/rcuscale.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c index dd25d306559a5..602f0958e4362 100644 --- a/kernel/rcu/rcuscale.c +++ b/kernel/rcu/rcuscale.c @@ -797,6 +797,11 @@ rcu_scale_cleanup(void) if (gp_exp && gp_async) SCALEOUT_ERRSTRING("No expedited async GPs, so went with async!");
+ if (kfree_rcu_test) { + kfree_scale_cleanup(); + return; + } + if (torture_cleanup_begin()) return; if (!cur_ops) {
From: Juergen Gross jgross@suse.com
[ Upstream commit f6b980646b93a8c585b4ed991b8a34e8fc6ef847 ]
The physical address width calculation in mtrr_bp_init() can easily be replaced with using the already available value x86_phys_bits from struct cpuinfo_x86.
The same information source can be used in mtrr/cleanup.c, removing the need to pass that value on to mtrr_cleanup().
In print_mtrr_state() use x86_phys_bits instead of recalculating it from size_or_mask.
Move setting of size_or_mask and size_and_mask into a dedicated new function in mtrr/generic.c, enabling to make those 2 variables static, as they are used in generic.c only now.
Signed-off-by: Juergen Gross jgross@suse.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Tested-by: Michael Kelley mikelley@microsoft.com Link: https://lore.kernel.org/r/20230502120931.20719-2-jgross@suse.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Stable-dep-of: a153f254e5cd ("x86/xen: Set MTRR state when running as Xen PV initial domain") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/cpu/mtrr/cleanup.c | 16 ++++---- arch/x86/kernel/cpu/mtrr/generic.c | 12 +++++- arch/x86/kernel/cpu/mtrr/mtrr.c | 61 ++++-------------------------- arch/x86/kernel/cpu/mtrr/mtrr.h | 4 +- 4 files changed, 29 insertions(+), 64 deletions(-)
diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c index b5f43049fa5f7..70314093bb9b5 100644 --- a/arch/x86/kernel/cpu/mtrr/cleanup.c +++ b/arch/x86/kernel/cpu/mtrr/cleanup.c @@ -173,7 +173,7 @@ early_param("mtrr_cleanup_debug", mtrr_cleanup_debug_setup);
static void __init set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, - unsigned char type, unsigned int address_bits) + unsigned char type) { u32 base_lo, base_hi, mask_lo, mask_hi; u64 base, mask; @@ -183,7 +183,7 @@ set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, return; }
- mask = (1ULL << address_bits) - 1; + mask = (1ULL << boot_cpu_data.x86_phys_bits) - 1; mask &= ~((((u64)sizek) << 10) - 1);
base = ((u64)basek) << 10; @@ -209,7 +209,7 @@ save_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, range_state[reg].type = type; }
-static void __init set_var_mtrr_all(unsigned int address_bits) +static void __init set_var_mtrr_all(void) { unsigned long basek, sizek; unsigned char type; @@ -220,7 +220,7 @@ static void __init set_var_mtrr_all(unsigned int address_bits) sizek = range_state[reg].size_pfn << (PAGE_SHIFT - 10); type = range_state[reg].type;
- set_var_mtrr(reg, basek, sizek, type, address_bits); + set_var_mtrr(reg, basek, sizek, type); } }
@@ -680,7 +680,7 @@ static int __init mtrr_search_optimal_index(void) return index_good; }
-int __init mtrr_cleanup(unsigned address_bits) +int __init mtrr_cleanup(void) { unsigned long x_remove_base, x_remove_size; unsigned long base, size, def, dummy; @@ -742,7 +742,7 @@ int __init mtrr_cleanup(unsigned address_bits) mtrr_print_out_one_result(i);
if (!result[i].bad) { - set_var_mtrr_all(address_bits); + set_var_mtrr_all(); pr_debug("New variable MTRRs\n"); print_out_mtrr_range_state(); return 1; @@ -786,7 +786,7 @@ int __init mtrr_cleanup(unsigned address_bits) gran_size = result[i].gran_sizek; gran_size <<= 10; x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size); - set_var_mtrr_all(address_bits); + set_var_mtrr_all(); pr_debug("New variable MTRRs\n"); print_out_mtrr_range_state(); return 1; @@ -802,7 +802,7 @@ int __init mtrr_cleanup(unsigned address_bits) return 0; } #else -int __init mtrr_cleanup(unsigned address_bits) +int __init mtrr_cleanup(void) { return 0; } diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index ee09d359e08f0..3922552340b13 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -38,6 +38,16 @@ u64 mtrr_tom2; struct mtrr_state_type mtrr_state; EXPORT_SYMBOL_GPL(mtrr_state);
+static u64 size_or_mask, size_and_mask; + +void __init mtrr_set_mask(void) +{ + unsigned int phys_addr = boot_cpu_data.x86_phys_bits; + + size_or_mask = ~GENMASK_ULL(phys_addr - PAGE_SHIFT - 1, 0); + size_and_mask = ~size_or_mask & GENMASK_ULL(39, 20); +} + /* * BIOS is expected to clear MtrrFixDramModEn bit, see for example * "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD @@ -422,7 +432,7 @@ static void __init print_mtrr_state(void) } pr_debug("MTRR variable ranges %sabled:\n", mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED ? "en" : "dis"); - high_width = (__ffs64(size_or_mask) - (32 - PAGE_SHIFT) + 3) / 4; + high_width = (boot_cpu_data.x86_phys_bits - (32 - PAGE_SHIFT) + 3) / 4;
for (i = 0; i < num_var_ranges; ++i) { if (mtrr_state.var_ranges[i].mask_lo & (1 << 11)) diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtrr.c index 783f3210d5827..1bdab16f16bdc 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.c +++ b/arch/x86/kernel/cpu/mtrr/mtrr.c @@ -67,8 +67,6 @@ static bool mtrr_enabled(void) unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES]; static DEFINE_MUTEX(mtrr_mutex);
-u64 size_or_mask, size_and_mask; - const struct mtrr_ops *mtrr_if;
/* Returns non-zero if we have the write-combining memory type */ @@ -619,77 +617,34 @@ static struct syscore_ops mtrr_syscore_ops = {
int __initdata changed_by_mtrr_cleanup;
-#define SIZE_OR_MASK_BITS(n) (~((1ULL << ((n) - PAGE_SHIFT)) - 1)) /** - * mtrr_bp_init - initialize mtrrs on the boot CPU + * mtrr_bp_init - initialize MTRRs on the boot CPU * * This needs to be called early; before any of the other CPUs are * initialized (i.e. before smp_init()). - * */ void __init mtrr_bp_init(void) { const char *why = "(not available)"; - u32 phys_addr;
- phys_addr = 32; + mtrr_set_mask();
- if (boot_cpu_has(X86_FEATURE_MTRR)) { + if (cpu_feature_enabled(X86_FEATURE_MTRR)) { mtrr_if = &generic_mtrr_ops; - size_or_mask = SIZE_OR_MASK_BITS(36); - size_and_mask = 0x00f00000; - phys_addr = 36; - - /* - * This is an AMD specific MSR, but we assume(hope?) that - * Intel will implement it too when they extend the address - * bus of the Xeon. - */ - if (cpuid_eax(0x80000000) >= 0x80000008) { - phys_addr = cpuid_eax(0x80000008) & 0xff; - /* CPUID workaround for Intel 0F33/0F34 CPU */ - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && - boot_cpu_data.x86 == 0xF && - boot_cpu_data.x86_model == 0x3 && - (boot_cpu_data.x86_stepping == 0x3 || - boot_cpu_data.x86_stepping == 0x4)) - phys_addr = 36; - - size_or_mask = SIZE_OR_MASK_BITS(phys_addr); - size_and_mask = ~size_or_mask & 0xfffff00000ULL; - } else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR && - boot_cpu_data.x86 == 6) { - /* - * VIA C* family have Intel style MTRRs, - * but don't support PAE - */ - size_or_mask = SIZE_OR_MASK_BITS(32); - size_and_mask = 0; - phys_addr = 32; - } } else { switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_AMD: - if (cpu_feature_enabled(X86_FEATURE_K6_MTRR)) { - /* Pre-Athlon (K6) AMD CPU MTRRs */ + /* Pre-Athlon (K6) AMD CPU MTRRs */ + if (cpu_feature_enabled(X86_FEATURE_K6_MTRR)) mtrr_if = &amd_mtrr_ops; - size_or_mask = SIZE_OR_MASK_BITS(32); - size_and_mask = 0; - } break; case X86_VENDOR_CENTAUR: - if (cpu_feature_enabled(X86_FEATURE_CENTAUR_MCR)) { + if (cpu_feature_enabled(X86_FEATURE_CENTAUR_MCR)) mtrr_if = ¢aur_mtrr_ops; - size_or_mask = SIZE_OR_MASK_BITS(32); - size_and_mask = 0; - } break; case X86_VENDOR_CYRIX: - if (cpu_feature_enabled(X86_FEATURE_CYRIX_ARR)) { + if (cpu_feature_enabled(X86_FEATURE_CYRIX_ARR)) mtrr_if = &cyrix_mtrr_ops; - size_or_mask = SIZE_OR_MASK_BITS(32); - size_and_mask = 0; - } break; default: break; @@ -703,7 +658,7 @@ void __init mtrr_bp_init(void) /* BIOS may override */ if (get_mtrr_state()) { memory_caching_control |= CACHE_MTRR; - changed_by_mtrr_cleanup = mtrr_cleanup(phys_addr); + changed_by_mtrr_cleanup = mtrr_cleanup(); } else { mtrr_if = NULL; why = "by BIOS"; diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtrr.h index 02eb5871492d0..a00987e6cc1c1 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.h +++ b/arch/x86/kernel/cpu/mtrr/mtrr.h @@ -51,7 +51,6 @@ void fill_mtrr_var_range(unsigned int index, u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi); bool get_mtrr_state(void);
-extern u64 size_or_mask, size_and_mask; extern const struct mtrr_ops *mtrr_if;
#define is_cpu(vnd) (mtrr_if && mtrr_if->vendor == X86_VENDOR_##vnd) @@ -60,6 +59,7 @@ extern unsigned int num_var_ranges; extern u64 mtrr_tom2; extern struct mtrr_state_type mtrr_state;
+void mtrr_set_mask(void); void mtrr_state_warn(void); const char *mtrr_attrib_to_str(int x); void mtrr_wrmsr(unsigned, unsigned, unsigned); @@ -70,4 +70,4 @@ extern const struct mtrr_ops cyrix_mtrr_ops; extern const struct mtrr_ops centaur_mtrr_ops;
extern int changed_by_mtrr_cleanup; -extern int mtrr_cleanup(unsigned address_bits); +extern int mtrr_cleanup(void);
From: Juergen Gross jgross@suse.com
[ Upstream commit d053b481a5f16dbd4f020c6b3ebdf9173fdef0e2 ]
Replace size_or_mask and size_and_mask with the much easier concept of high reserved bits.
While at it, instead of using constants in the MTRR code, use some new
[ bp: - Drop mtrr_set_mask() - Unbreak long lines - Move struct mtrr_state_type out of the uapi header as it doesn't belong there. It also fixes a HDRTEST breakage "unknown type name ‘bool’" as Reported-by: kernel test robot lkp@intel.com - Massage. ]
Signed-off-by: Juergen Gross jgross@suse.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Link: https://lore.kernel.org/r/20230502120931.20719-3-jgross@suse.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Stable-dep-of: a153f254e5cd ("x86/xen: Set MTRR state when running as Xen PV initial domain") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/include/asm/mtrr.h | 32 +++++++++++++- arch/x86/include/uapi/asm/mtrr.h | 8 ---- arch/x86/kernel/cpu/mtrr/cleanup.c | 2 +- arch/x86/kernel/cpu/mtrr/generic.c | 70 +++++++++++++----------------- arch/x86/kernel/cpu/mtrr/mtrr.c | 4 +- arch/x86/kernel/cpu/mtrr/mtrr.h | 2 +- 6 files changed, 65 insertions(+), 53 deletions(-)
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h index f0eeaf6e5f5f7..1421fe811401e 100644 --- a/arch/x86/include/asm/mtrr.h +++ b/arch/x86/include/asm/mtrr.h @@ -23,8 +23,35 @@ #ifndef _ASM_X86_MTRR_H #define _ASM_X86_MTRR_H
+#include <linux/bits.h> #include <uapi/asm/mtrr.h>
+/* Defines for hardware MTRR registers. */ +#define MTRR_CAP_VCNT GENMASK(7, 0) +#define MTRR_CAP_FIX BIT_MASK(8) +#define MTRR_CAP_WC BIT_MASK(10) + +#define MTRR_DEF_TYPE_TYPE GENMASK(7, 0) +#define MTRR_DEF_TYPE_FE BIT_MASK(10) +#define MTRR_DEF_TYPE_E BIT_MASK(11) + +#define MTRR_DEF_TYPE_ENABLE (MTRR_DEF_TYPE_FE | MTRR_DEF_TYPE_E) +#define MTRR_DEF_TYPE_DISABLE ~(MTRR_DEF_TYPE_TYPE | MTRR_DEF_TYPE_ENABLE) + +#define MTRR_PHYSBASE_TYPE GENMASK(7, 0) +#define MTRR_PHYSBASE_RSVD GENMASK(11, 8) + +#define MTRR_PHYSMASK_RSVD GENMASK(10, 0) +#define MTRR_PHYSMASK_V BIT_MASK(11) + +struct mtrr_state_type { + struct mtrr_var_range var_ranges[MTRR_MAX_VAR_RANGES]; + mtrr_type fixed_ranges[MTRR_NUM_FIXED_RANGES]; + unsigned char enabled; + bool have_fixed; + mtrr_type def_type; +}; + /* * The following functions are for use by other drivers that cannot use * arch_phys_wc_add and arch_phys_wc_del. @@ -121,7 +148,8 @@ struct mtrr_gentry32 { #endif /* CONFIG_COMPAT */
/* Bit fields for enabled in struct mtrr_state_type */ -#define MTRR_STATE_MTRR_FIXED_ENABLED 0x01 -#define MTRR_STATE_MTRR_ENABLED 0x02 +#define MTRR_STATE_SHIFT 10 +#define MTRR_STATE_MTRR_FIXED_ENABLED (MTRR_DEF_TYPE_FE >> MTRR_STATE_SHIFT) +#define MTRR_STATE_MTRR_ENABLED (MTRR_DEF_TYPE_E >> MTRR_STATE_SHIFT)
#endif /* _ASM_X86_MTRR_H */ diff --git a/arch/x86/include/uapi/asm/mtrr.h b/arch/x86/include/uapi/asm/mtrr.h index 376563f2bac1f..ab194c8316259 100644 --- a/arch/x86/include/uapi/asm/mtrr.h +++ b/arch/x86/include/uapi/asm/mtrr.h @@ -81,14 +81,6 @@ typedef __u8 mtrr_type; #define MTRR_NUM_FIXED_RANGES 88 #define MTRR_MAX_VAR_RANGES 256
-struct mtrr_state_type { - struct mtrr_var_range var_ranges[MTRR_MAX_VAR_RANGES]; - mtrr_type fixed_ranges[MTRR_NUM_FIXED_RANGES]; - unsigned char enabled; - unsigned char have_fixed; - mtrr_type def_type; -}; - #define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg)) #define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c index 70314093bb9b5..ca2d567e729e2 100644 --- a/arch/x86/kernel/cpu/mtrr/cleanup.c +++ b/arch/x86/kernel/cpu/mtrr/cleanup.c @@ -890,7 +890,7 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn) return 0;
rdmsr(MSR_MTRRdefType, def, dummy); - def &= 0xff; + def &= MTRR_DEF_TYPE_TYPE; if (def != MTRR_TYPE_UNCACHABLE) return 0;
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 3922552340b13..08ba558321825 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -38,15 +38,8 @@ u64 mtrr_tom2; struct mtrr_state_type mtrr_state; EXPORT_SYMBOL_GPL(mtrr_state);
-static u64 size_or_mask, size_and_mask; - -void __init mtrr_set_mask(void) -{ - unsigned int phys_addr = boot_cpu_data.x86_phys_bits; - - size_or_mask = ~GENMASK_ULL(phys_addr - PAGE_SHIFT - 1, 0); - size_and_mask = ~size_or_mask & GENMASK_ULL(39, 20); -} +/* Reserved bits in the high portion of the MTRRphysBaseN MSR. */ +u32 phys_hi_rsvd;
/* * BIOS is expected to clear MtrrFixDramModEn bit, see for example @@ -79,10 +72,9 @@ static u64 get_mtrr_size(u64 mask) { u64 size;
- mask >>= PAGE_SHIFT; - mask |= size_or_mask; + mask |= (u64)phys_hi_rsvd << 32; size = -mask; - size <<= PAGE_SHIFT; + return size; }
@@ -181,7 +173,7 @@ static u8 mtrr_type_lookup_variable(u64 start, u64 end, u64 *partial_end, for (i = 0; i < num_var_ranges; ++i) { unsigned short start_state, end_state, inclusive;
- if (!(mtrr_state.var_ranges[i].mask_lo & (1 << 11))) + if (!(mtrr_state.var_ranges[i].mask_lo & MTRR_PHYSMASK_V)) continue;
base = (((u64)mtrr_state.var_ranges[i].base_hi) << 32) + @@ -233,7 +225,7 @@ static u8 mtrr_type_lookup_variable(u64 start, u64 end, u64 *partial_end, if ((start & mask) != (base & mask)) continue;
- curr_match = mtrr_state.var_ranges[i].base_lo & 0xff; + curr_match = mtrr_state.var_ranges[i].base_lo & MTRR_PHYSBASE_TYPE; if (prev_match == MTRR_TYPE_INVALID) { prev_match = curr_match; continue; @@ -435,7 +427,7 @@ static void __init print_mtrr_state(void) high_width = (boot_cpu_data.x86_phys_bits - (32 - PAGE_SHIFT) + 3) / 4;
for (i = 0; i < num_var_ranges; ++i) { - if (mtrr_state.var_ranges[i].mask_lo & (1 << 11)) + if (mtrr_state.var_ranges[i].mask_lo & MTRR_PHYSMASK_V) pr_debug(" %u base %0*X%05X000 mask %0*X%05X000 %s\n", i, high_width, @@ -444,7 +436,8 @@ static void __init print_mtrr_state(void) high_width, mtrr_state.var_ranges[i].mask_hi, mtrr_state.var_ranges[i].mask_lo >> 12, - mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & 0xff)); + mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & + MTRR_PHYSBASE_TYPE)); else pr_debug(" %u disabled\n", i); } @@ -462,7 +455,7 @@ bool __init get_mtrr_state(void) vrs = mtrr_state.var_ranges;
rdmsr(MSR_MTRRcap, lo, dummy); - mtrr_state.have_fixed = (lo >> 8) & 1; + mtrr_state.have_fixed = lo & MTRR_CAP_FIX;
for (i = 0; i < num_var_ranges; i++) get_mtrr_var_range(i, &vrs[i]); @@ -470,8 +463,8 @@ bool __init get_mtrr_state(void) get_fixed_ranges(mtrr_state.fixed_ranges);
rdmsr(MSR_MTRRdefType, lo, dummy); - mtrr_state.def_type = (lo & 0xff); - mtrr_state.enabled = (lo & 0xc00) >> 10; + mtrr_state.def_type = lo & MTRR_DEF_TYPE_TYPE; + mtrr_state.enabled = (lo & MTRR_DEF_TYPE_ENABLE) >> MTRR_STATE_SHIFT;
if (amd_special_default_mtrr()) { unsigned low, high; @@ -584,7 +577,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi);
- if ((mask_lo & 0x800) == 0) { + if (!(mask_lo & MTRR_PHYSMASK_V)) { /* Invalid (i.e. free) range */ *base = 0; *size = 0; @@ -595,8 +588,8 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, rdmsr(MTRRphysBase_MSR(reg), base_lo, base_hi);
/* Work out the shifted address mask: */ - tmp = (u64)mask_hi << (32 - PAGE_SHIFT) | mask_lo >> PAGE_SHIFT; - mask = size_or_mask | tmp; + tmp = (u64)mask_hi << 32 | (mask_lo & PAGE_MASK); + mask = (u64)phys_hi_rsvd << 32 | tmp;
/* Expand tmp with high bits to all 1s: */ hi = fls64(tmp); @@ -614,9 +607,9 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, * This works correctly if size is a power of two, i.e. a * contiguous range: */ - *size = -mask; + *size = -mask >> PAGE_SHIFT; *base = (u64)base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT; - *type = base_lo & 0xff; + *type = base_lo & MTRR_PHYSBASE_TYPE;
out_put_cpu: put_cpu(); @@ -654,9 +647,8 @@ static bool set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr) bool changed = false;
rdmsr(MTRRphysBase_MSR(index), lo, hi); - if ((vr->base_lo & 0xfffff0ffUL) != (lo & 0xfffff0ffUL) - || (vr->base_hi & (size_and_mask >> (32 - PAGE_SHIFT))) != - (hi & (size_and_mask >> (32 - PAGE_SHIFT)))) { + if ((vr->base_lo & ~MTRR_PHYSBASE_RSVD) != (lo & ~MTRR_PHYSBASE_RSVD) + || (vr->base_hi & ~phys_hi_rsvd) != (hi & ~phys_hi_rsvd)) {
mtrr_wrmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi); changed = true; @@ -664,9 +656,8 @@ static bool set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr)
rdmsr(MTRRphysMask_MSR(index), lo, hi);
- if ((vr->mask_lo & 0xfffff800UL) != (lo & 0xfffff800UL) - || (vr->mask_hi & (size_and_mask >> (32 - PAGE_SHIFT))) != - (hi & (size_and_mask >> (32 - PAGE_SHIFT)))) { + if ((vr->mask_lo & ~MTRR_PHYSMASK_RSVD) != (lo & ~MTRR_PHYSMASK_RSVD) + || (vr->mask_hi & ~phys_hi_rsvd) != (hi & ~phys_hi_rsvd)) { mtrr_wrmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi); changed = true; } @@ -701,11 +692,12 @@ static unsigned long set_mtrr_state(void) * Set_mtrr_restore restores the old value of MTRRdefType, * so to set it we fiddle with the saved value: */ - if ((deftype_lo & 0xff) != mtrr_state.def_type - || ((deftype_lo & 0xc00) >> 10) != mtrr_state.enabled) { + if ((deftype_lo & MTRR_DEF_TYPE_TYPE) != mtrr_state.def_type || + ((deftype_lo & MTRR_DEF_TYPE_ENABLE) >> MTRR_STATE_SHIFT) != mtrr_state.enabled) {
- deftype_lo = (deftype_lo & ~0xcff) | mtrr_state.def_type | - (mtrr_state.enabled << 10); + deftype_lo = (deftype_lo & MTRR_DEF_TYPE_DISABLE) | + mtrr_state.def_type | + (mtrr_state.enabled << MTRR_STATE_SHIFT); change_mask |= MTRR_CHANGE_MASK_DEFTYPE; }
@@ -718,7 +710,7 @@ void mtrr_disable(void) rdmsr(MSR_MTRRdefType, deftype_lo, deftype_hi);
/* Disable MTRRs, and set the default type to uncached */ - mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi); + mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & MTRR_DEF_TYPE_DISABLE, deftype_hi); }
void mtrr_enable(void) @@ -772,9 +764,9 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base, memset(vr, 0, sizeof(struct mtrr_var_range)); } else { vr->base_lo = base << PAGE_SHIFT | type; - vr->base_hi = (base & size_and_mask) >> (32 - PAGE_SHIFT); - vr->mask_lo = -size << PAGE_SHIFT | 0x800; - vr->mask_hi = (-size & size_and_mask) >> (32 - PAGE_SHIFT); + vr->base_hi = (base >> (32 - PAGE_SHIFT)) & ~phys_hi_rsvd; + vr->mask_lo = -size << PAGE_SHIFT | MTRR_PHYSMASK_V; + vr->mask_hi = (-size >> (32 - PAGE_SHIFT)) & ~phys_hi_rsvd;
mtrr_wrmsr(MTRRphysBase_MSR(reg), vr->base_lo, vr->base_hi); mtrr_wrmsr(MTRRphysMask_MSR(reg), vr->mask_lo, vr->mask_hi); @@ -827,7 +819,7 @@ static int generic_have_wrcomb(void) { unsigned long config, dummy; rdmsr(MSR_MTRRcap, config, dummy); - return config & (1 << 10); + return config & MTRR_CAP_WC; }
int positive_have_wrcomb(void) diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtrr.c index 1bdab16f16bdc..1067f128bded1 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.c +++ b/arch/x86/kernel/cpu/mtrr/mtrr.c @@ -115,7 +115,7 @@ static void __init set_num_var_ranges(bool use_generic) else if (is_cpu(CYRIX) || is_cpu(CENTAUR)) config = 8;
- num_var_ranges = config & 0xff; + num_var_ranges = config & MTRR_CAP_VCNT; }
static void __init init_table(void) @@ -627,7 +627,7 @@ void __init mtrr_bp_init(void) { const char *why = "(not available)";
- mtrr_set_mask(); + phys_hi_rsvd = GENMASK(31, boot_cpu_data.x86_phys_bits - 32);
if (cpu_feature_enabled(X86_FEATURE_MTRR)) { mtrr_if = &generic_mtrr_ops; diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtrr.h index a00987e6cc1c1..59e8fb26bf9dd 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.h +++ b/arch/x86/kernel/cpu/mtrr/mtrr.h @@ -58,8 +58,8 @@ extern const struct mtrr_ops *mtrr_if; extern unsigned int num_var_ranges; extern u64 mtrr_tom2; extern struct mtrr_state_type mtrr_state; +extern u32 phys_hi_rsvd;
-void mtrr_set_mask(void); void mtrr_state_warn(void); const char *mtrr_attrib_to_str(int x); void mtrr_wrmsr(unsigned, unsigned, unsigned);
From: Juergen Gross jgross@suse.com
[ Upstream commit 29055dc74287467bd7a053d60b4afe753832960d ]
When running virtualized, MTRR access can be reduced (e.g. in Xen PV guests or when running as a SEV-SNP guest under Hyper-V). Typically, the hypervisor will not advertize the MTRR feature in CPUID data, resulting in no MTRR memory type information being available for the kernel.
This has turned out to result in problems (Link tags below):
- Hyper-V SEV-SNP guests using uncached mappings where they shouldn't - Xen PV dom0 mapping memory as WB which should be UC- instead
Solve those problems by allowing an MTRR static state override, overwriting the empty state used today. In case such a state has been set, don't call get_mtrr_state() in mtrr_bp_init().
The set state will only be used by mtrr_type_lookup(), as in all other cases mtrr_enabled() is being checked, which will return false. Accept the overwrite call only for selected cases when running as a guest. Disable X86_FEATURE_MTRR in order to avoid any MTRR modifications by just refusing them.
[ bp: Massage. ]
Signed-off-by: Juergen Gross jgross@suse.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Tested-by: Michael Kelley mikelley@microsoft.com Link: https://lore.kernel.org/all/4fe9541e-4d4c-2b2a-f8c8-2d34a7284930@nerdbynatur... Link: https://lore.kernel.org/lkml/BYAPR21MB16883ABC186566BD4D2A1451D7FE9@BYAPR21M... Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Stable-dep-of: a153f254e5cd ("x86/xen: Set MTRR state when running as Xen PV initial domain") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/include/asm/mtrr.h | 8 ++++ arch/x86/kernel/cpu/mtrr/generic.c | 60 +++++++++++++++++++++++++++++- arch/x86/kernel/cpu/mtrr/mtrr.c | 14 ++++++- arch/x86/kernel/setup.c | 2 + 4 files changed, 82 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h index 1421fe811401e..1bae790a553a5 100644 --- a/arch/x86/include/asm/mtrr.h +++ b/arch/x86/include/asm/mtrr.h @@ -58,6 +58,8 @@ struct mtrr_state_type { */ # ifdef CONFIG_MTRR void mtrr_bp_init(void); +void mtrr_overwrite_state(struct mtrr_var_range *var, unsigned int num_var, + mtrr_type def_type); extern u8 mtrr_type_lookup(u64 addr, u64 end, u8 *uniform); extern void mtrr_save_fixed_ranges(void *); extern void mtrr_save_state(void); @@ -75,6 +77,12 @@ void mtrr_disable(void); void mtrr_enable(void); void mtrr_generic_set_state(void); # else +static inline void mtrr_overwrite_state(struct mtrr_var_range *var, + unsigned int num_var, + mtrr_type def_type) +{ +} + static inline u8 mtrr_type_lookup(u64 addr, u64 end, u8 *uniform) { /* diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 08ba558321825..e81d832475a1f 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -8,10 +8,12 @@ #include <linux/init.h> #include <linux/io.h> #include <linux/mm.h> - +#include <linux/cc_platform.h> #include <asm/processor-flags.h> #include <asm/cacheinfo.h> #include <asm/cpufeature.h> +#include <asm/hypervisor.h> +#include <asm/mshyperv.h> #include <asm/tlbflush.h> #include <asm/mtrr.h> #include <asm/msr.h> @@ -242,6 +244,62 @@ static u8 mtrr_type_lookup_variable(u64 start, u64 end, u64 *partial_end, return mtrr_state.def_type; }
+/** + * mtrr_overwrite_state - set static MTRR state + * + * Used to set MTRR state via different means (e.g. with data obtained from + * a hypervisor). + * Is allowed only for special cases when running virtualized. Must be called + * from the x86_init.hyper.init_platform() hook. It can be called only once. + * The MTRR state can't be changed afterwards. To ensure that, X86_FEATURE_MTRR + * is cleared. + */ +void mtrr_overwrite_state(struct mtrr_var_range *var, unsigned int num_var, + mtrr_type def_type) +{ + unsigned int i; + + /* Only allowed to be called once before mtrr_bp_init(). */ + if (WARN_ON_ONCE(mtrr_state_set)) + return; + + /* Only allowed when running virtualized. */ + if (!cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) + return; + + /* + * Only allowed for special virtualization cases: + * - when running as Hyper-V, SEV-SNP guest using vTOM + * - when running as Xen PV guest + * - when running as SEV-SNP or TDX guest to avoid unnecessary + * VMM communication/Virtualization exceptions (#VC, #VE) + */ + if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP) && + !hv_is_isolation_supported() && + !cpu_feature_enabled(X86_FEATURE_XENPV) && + !cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) + return; + + /* Disable MTRR in order to disable MTRR modifications. */ + setup_clear_cpu_cap(X86_FEATURE_MTRR); + + if (var) { + if (num_var > MTRR_MAX_VAR_RANGES) { + pr_warn("Trying to overwrite MTRR state with %u variable entries\n", + num_var); + num_var = MTRR_MAX_VAR_RANGES; + } + for (i = 0; i < num_var; i++) + mtrr_state.var_ranges[i] = var[i]; + num_var_ranges = num_var; + } + + mtrr_state.def_type = def_type; + mtrr_state.enabled |= MTRR_STATE_MTRR_ENABLED; + + mtrr_state_set = 1; +} + /** * mtrr_type_lookup - look up memory type in MTRR * diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtrr.c index 1067f128bded1..be35a0b09604d 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.c +++ b/arch/x86/kernel/cpu/mtrr/mtrr.c @@ -625,11 +625,23 @@ int __initdata changed_by_mtrr_cleanup; */ void __init mtrr_bp_init(void) { + bool generic_mtrrs = cpu_feature_enabled(X86_FEATURE_MTRR); const char *why = "(not available)";
phys_hi_rsvd = GENMASK(31, boot_cpu_data.x86_phys_bits - 32);
- if (cpu_feature_enabled(X86_FEATURE_MTRR)) { + if (!generic_mtrrs && mtrr_state.enabled) { + /* + * Software overwrite of MTRR state, only for generic case. + * Note that X86_FEATURE_MTRR has been reset in this case. + */ + init_table(); + pr_info("MTRRs set to read-only\n"); + + return; + } + + if (generic_mtrrs) { mtrr_if = &generic_mtrr_ops; } else { switch (boot_cpu_data.x86_vendor) { diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 16babff771bdf..0cccfeb67c3ad 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1037,6 +1037,8 @@ void __init setup_arch(char **cmdline_p) /* * VMware detection requires dmi to be available, so this * needs to be done after dmi_setup(), for the boot CPU. + * For some guest types (Xen PV, SEV-SNP, TDX) it is required to be + * called before cache_bp_init() for setting up MTRR state. */ init_hypervisor_platform();
From: Juergen Gross jgross@suse.com
[ Upstream commit a153f254e5cdf8fa3a1df90a6ffed3063fede154 ]
When running as Xen PV initial domain (aka dom0), MTRRs are disabled by the hypervisor, but the system should nevertheless use correct cache memory types. This has always kind of worked, as disabled MTRRs resulted in disabled PAT, too, so that the kernel avoided code paths resulting in inconsistencies. This bypassed all of the sanity checks the kernel is doing with enabled MTRRs in order to avoid memory mappings with conflicting memory types.
This has been changed recently, leading to PAT being accepted to be enabled, while MTRRs stayed disabled. The result is that mtrr_type_lookup() no longer is accepting all memory type requests, but started to return WB even if UC- was requested. This led to driver failures during initialization of some devices.
In reality MTRRs are still in effect, but they are under complete control of the Xen hypervisor. It is possible, however, to retrieve the MTRR settings from the hypervisor.
In order to fix those problems, overwrite the MTRR state via mtrr_overwrite_state() with the MTRR data from the hypervisor, if the system is running as a Xen dom0.
Fixes: 72cbc8f04fe2 ("x86/PAT: Have pat_enabled() properly reflect state when running on Xen") Signed-off-by: Juergen Gross jgross@suse.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Reviewed-by: Boris Ostrovsky boris.ostrovsky@oracle.com Tested-by: Michael Kelley mikelley@microsoft.com Link: https://lore.kernel.org/r/20230502120931.20719-6-jgross@suse.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/xen/enlighten_pv.c | 52 +++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+)
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 093b78c8bbec0..8732b85d56505 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -68,6 +68,7 @@ #include <asm/reboot.h> #include <asm/hypervisor.h> #include <asm/mach_traps.h> +#include <asm/mtrr.h> #include <asm/mwait.h> #include <asm/pci_x86.h> #include <asm/cpu.h> @@ -119,6 +120,54 @@ static int __init parse_xen_msr_safe(char *str) } early_param("xen_msr_safe", parse_xen_msr_safe);
+/* Get MTRR settings from Xen and put them into mtrr_state. */ +static void __init xen_set_mtrr_data(void) +{ +#ifdef CONFIG_MTRR + struct xen_platform_op op = { + .cmd = XENPF_read_memtype, + .interface_version = XENPF_INTERFACE_VERSION, + }; + unsigned int reg; + unsigned long mask; + uint32_t eax, width; + static struct mtrr_var_range var[MTRR_MAX_VAR_RANGES] __initdata; + + /* Get physical address width (only 64-bit cpus supported). */ + width = 36; + eax = cpuid_eax(0x80000000); + if ((eax >> 16) == 0x8000 && eax >= 0x80000008) { + eax = cpuid_eax(0x80000008); + width = eax & 0xff; + } + + for (reg = 0; reg < MTRR_MAX_VAR_RANGES; reg++) { + op.u.read_memtype.reg = reg; + if (HYPERVISOR_platform_op(&op)) + break; + + /* + * Only called in dom0, which has all RAM PFNs mapped at + * RAM MFNs, and all PCI space etc. is identity mapped. + * This means we can treat MFN == PFN regarding MTRR settings. + */ + var[reg].base_lo = op.u.read_memtype.type; + var[reg].base_lo |= op.u.read_memtype.mfn << PAGE_SHIFT; + var[reg].base_hi = op.u.read_memtype.mfn >> (32 - PAGE_SHIFT); + mask = ~((op.u.read_memtype.nr_mfns << PAGE_SHIFT) - 1); + mask &= (1UL << width) - 1; + if (mask) + mask |= MTRR_PHYSMASK_V; + var[reg].mask_lo = mask; + var[reg].mask_hi = mask >> 32; + } + + /* Only overwrite MTRR state if any MTRR could be got from Xen. */ + if (reg) + mtrr_overwrite_state(var, reg, MTRR_TYPE_UNCACHABLE); +#endif +} + static void __init xen_pv_init_platform(void) { /* PV guests can't operate virtio devices without grants. */ @@ -135,6 +184,9 @@ static void __init xen_pv_init_platform(void)
/* pvclock is in shared info area */ xen_init_time_ops(); + + if (xen_initial_domain()) + xen_set_mtrr_data(); }
static void __init xen_pv_guest_late_init(void)
From: Colin Ian King colin.i.king@gmail.com
[ Upstream commit 375b9ff53cb6f9c042817b75f2be0a650626dc4f ]
In the unlikely case that CLOCK_REALTIME is not defined, variable ret is not initialized and further accumulation of return values to ret can leave ret in an undefined state. Fix this by initialized ret to zero and changing the assignment of ret to an accumulation for the CLOCK_REALTIME case.
Fixes: 03f55c7952c9 ("kselftest: Extend vDSO selftest to clock_getres") Signed-off-by: Colin Ian King colin.i.king@gmail.com Reviewed-by: Vincenzo Frascino vincenzo.frascino@arm.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/vDSO/vdso_test_clock_getres.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/vDSO/vdso_test_clock_getres.c b/tools/testing/selftests/vDSO/vdso_test_clock_getres.c index 15dcee16ff726..38d46a8bf7cba 100644 --- a/tools/testing/selftests/vDSO/vdso_test_clock_getres.c +++ b/tools/testing/selftests/vDSO/vdso_test_clock_getres.c @@ -84,12 +84,12 @@ static inline int vdso_test_clock(unsigned int clock_id)
int main(int argc, char **argv) { - int ret; + int ret = 0;
#if _POSIX_TIMERS > 0
#ifdef CLOCK_REALTIME - ret = vdso_test_clock(CLOCK_REALTIME); + ret += vdso_test_clock(CLOCK_REALTIME); #endif
#ifdef CLOCK_BOOTTIME
From: Ravi Bangoria ravi.bangoria@amd.com
[ Upstream commit 2fad201fe38ff9a692acedb1990ece2c52a29f95 ]
Although, IBS pmus can be invoked via their own interface, indirect IBS invocation via core pmu events is also supported with fixed set of events: cpu-cycles:p, r076:p (same as cpu-cycles:p) and r0C1:p (micro-ops) for user convenience.
This indirect IBS invocation is broken since commit 66d258c5b048 ("perf/core: Optimize perf_init_event()"), which added RAW pmu under 'pmu_idr' list and thus if event_init() fails with RAW pmu, it started returning error instead of trying other pmus.
Forward precise events from core pmu to IBS by overwriting 'type' and 'config' in the kernel copy of perf_event_attr. Overwriting will cause perf_init_event() to retry with updated 'type' and 'config', which will automatically forward event to IBS pmu.
Without patch: $ sudo ./perf record -C 0 -e r076:p -- sleep 1 Error: The r076:p event is not supported.
With patch: $ sudo ./perf record -C 0 -e r076:p -- sleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.341 MB perf.data (37 samples) ]
Fixes: 66d258c5b048 ("perf/core: Optimize perf_init_event()") Reported-by: Stephane Eranian eranian@google.com Signed-off-by: Ravi Bangoria ravi.bangoria@amd.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20230504110003.2548-3-ravi.bangoria@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/events/amd/core.c | 2 +- arch/x86/events/amd/ibs.c | 53 +++++++++++++++---------------- arch/x86/include/asm/perf_event.h | 2 ++ 3 files changed, 29 insertions(+), 28 deletions(-)
diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index bccea57dee81e..abadd5f234254 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c @@ -374,7 +374,7 @@ static int amd_pmu_hw_config(struct perf_event *event)
/* pass precise event sampling to ibs: */ if (event->attr.precise_ip && get_ibs_caps()) - return -ENOENT; + return forward_event_to_ibs(event);
if (has_branch_stack(event) && !x86_pmu.lbr_nr) return -EOPNOTSUPP; diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c index 64582954b5f67..3710148021916 100644 --- a/arch/x86/events/amd/ibs.c +++ b/arch/x86/events/amd/ibs.c @@ -190,7 +190,7 @@ static struct perf_ibs *get_ibs_pmu(int type) }
/* - * Use IBS for precise event sampling: + * core pmu config -> IBS config * * perf record -a -e cpu-cycles:p ... # use ibs op counting cycle count * perf record -a -e r076:p ... # same as -e cpu-cycles:p @@ -199,25 +199,9 @@ static struct perf_ibs *get_ibs_pmu(int type) * IbsOpCntCtl (bit 19) of IBS Execution Control Register (IbsOpCtl, * MSRC001_1033) is used to select either cycle or micro-ops counting * mode. - * - * The rip of IBS samples has skid 0. Thus, IBS supports precise - * levels 1 and 2 and the PERF_EFLAGS_EXACT is set. In rare cases the - * rip is invalid when IBS was not able to record the rip correctly. - * We clear PERF_EFLAGS_EXACT and take the rip from pt_regs then. - * */ -static int perf_ibs_precise_event(struct perf_event *event, u64 *config) +static int core_pmu_ibs_config(struct perf_event *event, u64 *config) { - switch (event->attr.precise_ip) { - case 0: - return -ENOENT; - case 1: - case 2: - break; - default: - return -EOPNOTSUPP; - } - switch (event->attr.type) { case PERF_TYPE_HARDWARE: switch (event->attr.config) { @@ -243,22 +227,37 @@ static int perf_ibs_precise_event(struct perf_event *event, u64 *config) return -EOPNOTSUPP; }
+/* + * The rip of IBS samples has skid 0. Thus, IBS supports precise + * levels 1 and 2 and the PERF_EFLAGS_EXACT is set. In rare cases the + * rip is invalid when IBS was not able to record the rip correctly. + * We clear PERF_EFLAGS_EXACT and take the rip from pt_regs then. + */ +int forward_event_to_ibs(struct perf_event *event) +{ + u64 config = 0; + + if (!event->attr.precise_ip || event->attr.precise_ip > 2) + return -EOPNOTSUPP; + + if (!core_pmu_ibs_config(event, &config)) { + event->attr.type = perf_ibs_op.pmu.type; + event->attr.config = config; + } + return -ENOENT; +} + static int perf_ibs_init(struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; struct perf_ibs *perf_ibs; u64 max_cnt, config; - int ret;
perf_ibs = get_ibs_pmu(event->attr.type); - if (perf_ibs) { - config = event->attr.config; - } else { - perf_ibs = &perf_ibs_op; - ret = perf_ibs_precise_event(event, &config); - if (ret) - return ret; - } + if (!perf_ibs) + return -ENOENT; + + config = event->attr.config;
if (event->pmu != &perf_ibs->pmu) return -ENOENT; diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index abf09882f58b6..f1a46500a2753 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -478,8 +478,10 @@ struct pebs_xmm {
#ifdef CONFIG_X86_LOCAL_APIC extern u32 get_ibs_caps(void); +extern int forward_event_to_ibs(struct perf_event *event); #else static inline u32 get_ibs_caps(void) { return 0; } +static inline int forward_event_to_ibs(struct perf_event *event) { return -ENOENT; } #endif
#ifdef CONFIG_PERF_EVENTS
From: Juergen Gross jgross@suse.com
[ Upstream commit 0f88130e8a6fd185b0aeb5d8e286083735f2585a ]
Normally __swp_entry_to_pte() is never called with a value translating to a valid PTE. The only known exception is pte_swap_tests(), resulting in a WARN splat in Xen PV guests, as __pte_to_swp_entry() did translate the PFN of the valid PTE to a guest local PFN, while __swp_entry_to_pte() doesn't do the opposite translation.
Fix that by using __pte() in __swp_entry_to_pte() instead of open coding the native variant of it.
For correctness do the similar conversion for __swp_entry_to_pmd().
Fixes: 05289402d717 ("mm/debug_vm_pgtable: add tests validating arch helpers for core MM features") Signed-off-by: Juergen Gross jgross@suse.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Link: https://lore.kernel.org/r/20230306123259.12461-1-jgross@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/include/asm/pgtable_64.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index 7929327abe009..a629b1b9f65a6 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h @@ -237,8 +237,8 @@ static inline void native_pgd_clear(pgd_t *pgd)
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) }) #define __pmd_to_swp_entry(pmd) ((swp_entry_t) { pmd_val((pmd)) }) -#define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val }) -#define __swp_entry_to_pmd(x) ((pmd_t) { .pmd = (x).val }) +#define __swp_entry_to_pte(x) (__pte((x).val)) +#define __swp_entry_to_pmd(x) (__pmd((x).val))
extern void cleanup_highmap(void);
From: Mark Rutland mark.rutland@arm.com
[ Upstream commit dda5f312bb09e56e7a1c3e3851f2000eb2e9c879 ]
The sync_*() ops on arch/arm are defined in terms of the regular bitops with no special handling. This is not correct, as UP kernels elide barriers for the fully-ordered operations, and so the required ordering is lost when such UP kernels are run under a hypervsior on an SMP system.
Fix this by defining sync ops with the required barriers.
Note: On 32-bit arm, the sync_*() ops are currently only used by Xen, which requires ARMv7, but the semantics can be implemented for ARMv6+.
Fixes: e54d2f61528165bb ("xen/arm: sync_bitops") Signed-off-by: Mark Rutland mark.rutland@arm.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20230605070124.3741859-2-mark.rutland@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/include/asm/assembler.h | 17 +++++++++++++++++ arch/arm/include/asm/sync_bitops.h | 29 +++++++++++++++++++++++++---- arch/arm/lib/bitops.h | 14 +++++++++++--- arch/arm/lib/testchangebit.S | 4 ++++ arch/arm/lib/testclearbit.S | 4 ++++ arch/arm/lib/testsetbit.S | 4 ++++ 6 files changed, 65 insertions(+), 7 deletions(-)
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 505a306e0271a..aebe2c8f6a686 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -394,6 +394,23 @@ ALT_UP_B(.L0_@) #endif .endm
+/* + * Raw SMP data memory barrier + */ + .macro __smp_dmb mode +#if __LINUX_ARM_ARCH__ >= 7 + .ifeqs "\mode","arm" + dmb ish + .else + W(dmb) ish + .endif +#elif __LINUX_ARM_ARCH__ == 6 + mcr p15, 0, r0, c7, c10, 5 @ dmb +#else + .error "Incompatible SMP platform" +#endif + .endm + #if defined(CONFIG_CPU_V7M) /* * setmode is used to assert to be in svc mode during boot. For v7-M diff --git a/arch/arm/include/asm/sync_bitops.h b/arch/arm/include/asm/sync_bitops.h index 6f5d627c44a3c..f46b3c570f92e 100644 --- a/arch/arm/include/asm/sync_bitops.h +++ b/arch/arm/include/asm/sync_bitops.h @@ -14,14 +14,35 @@ * ops which are SMP safe even on a UP kernel. */
+/* + * Unordered + */ + #define sync_set_bit(nr, p) _set_bit(nr, p) #define sync_clear_bit(nr, p) _clear_bit(nr, p) #define sync_change_bit(nr, p) _change_bit(nr, p) -#define sync_test_and_set_bit(nr, p) _test_and_set_bit(nr, p) -#define sync_test_and_clear_bit(nr, p) _test_and_clear_bit(nr, p) -#define sync_test_and_change_bit(nr, p) _test_and_change_bit(nr, p) #define sync_test_bit(nr, addr) test_bit(nr, addr) -#define arch_sync_cmpxchg arch_cmpxchg
+/* + * Fully ordered + */ + +int _sync_test_and_set_bit(int nr, volatile unsigned long * p); +#define sync_test_and_set_bit(nr, p) _sync_test_and_set_bit(nr, p) + +int _sync_test_and_clear_bit(int nr, volatile unsigned long * p); +#define sync_test_and_clear_bit(nr, p) _sync_test_and_clear_bit(nr, p) + +int _sync_test_and_change_bit(int nr, volatile unsigned long * p); +#define sync_test_and_change_bit(nr, p) _sync_test_and_change_bit(nr, p) + +#define arch_sync_cmpxchg(ptr, old, new) \ +({ \ + __typeof__(*(ptr)) __ret; \ + __smp_mb__before_atomic(); \ + __ret = arch_cmpxchg_relaxed((ptr), (old), (new)); \ + __smp_mb__after_atomic(); \ + __ret; \ +})
#endif diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h index 95bd359912889..f069d1b2318e6 100644 --- a/arch/arm/lib/bitops.h +++ b/arch/arm/lib/bitops.h @@ -28,7 +28,7 @@ UNWIND( .fnend ) ENDPROC(\name ) .endm
- .macro testop, name, instr, store + .macro __testop, name, instr, store, barrier ENTRY( \name ) UNWIND( .fnstart ) ands ip, r1, #3 @@ -38,7 +38,7 @@ UNWIND( .fnstart ) mov r0, r0, lsr #5 add r1, r1, r0, lsl #2 @ Get word offset mov r3, r2, lsl r3 @ create mask - smp_dmb + \barrier #if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP) .arch_extension mp ALT_SMP(W(pldw) [r1]) @@ -50,13 +50,21 @@ UNWIND( .fnstart ) strex ip, r2, [r1] cmp ip, #0 bne 1b - smp_dmb + \barrier cmp r0, #0 movne r0, #1 2: bx lr UNWIND( .fnend ) ENDPROC(\name ) .endm + + .macro testop, name, instr, store + __testop \name, \instr, \store, smp_dmb + .endm + + .macro sync_testop, name, instr, store + __testop \name, \instr, \store, __smp_dmb + .endm #else .macro bitop, name, instr ENTRY( \name ) diff --git a/arch/arm/lib/testchangebit.S b/arch/arm/lib/testchangebit.S index 4ebecc67e6e04..f13fe9bc2399a 100644 --- a/arch/arm/lib/testchangebit.S +++ b/arch/arm/lib/testchangebit.S @@ -10,3 +10,7 @@ .text
testop _test_and_change_bit, eor, str + +#if __LINUX_ARM_ARCH__ >= 6 +sync_testop _sync_test_and_change_bit, eor, str +#endif diff --git a/arch/arm/lib/testclearbit.S b/arch/arm/lib/testclearbit.S index 009afa0f5b4a7..4d2c5ca620ebf 100644 --- a/arch/arm/lib/testclearbit.S +++ b/arch/arm/lib/testclearbit.S @@ -10,3 +10,7 @@ .text
testop _test_and_clear_bit, bicne, strne + +#if __LINUX_ARM_ARCH__ >= 6 +sync_testop _sync_test_and_clear_bit, bicne, strne +#endif diff --git a/arch/arm/lib/testsetbit.S b/arch/arm/lib/testsetbit.S index f3192e55acc87..649dbab65d8d0 100644 --- a/arch/arm/lib/testsetbit.S +++ b/arch/arm/lib/testsetbit.S @@ -10,3 +10,7 @@ .text
testop _test_and_set_bit, orreq, streq + +#if __LINUX_ARM_ARCH__ >= 6 +sync_testop _sync_test_and_set_bit, orreq, streq +#endif
From: Roberto Sassu roberto.sassu@huawei.com
[ Upstream commit b1de86d4248b273cb12c4cd7d20c08d459519f7d ]
Add the description for missing parameters of evm_inode_setattr() to avoid the warning arising with W=n compile option.
Fixes: 817b54aa45db ("evm: add evm_inode_setattr to prevent updating an invalid security.evm") # v3.2+ Fixes: c1632a0f1120 ("fs: port ->setattr() to pass mnt_idmap") # v6.3+ Signed-off-by: Roberto Sassu roberto.sassu@huawei.com Reviewed-by: Stefan Berger stefanb@linux.ibm.com Signed-off-by: Mimi Zohar zohar@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/integrity/evm/evm_main.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index cf24c5255583c..b1c2197473a21 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c @@ -795,7 +795,9 @@ static int evm_attr_change(struct mnt_idmap *idmap,
/** * evm_inode_setattr - prevent updating an invalid EVM extended attribute + * @idmap: idmap of the mount * @dentry: pointer to the affected dentry + * @attr: iattr structure containing the new file attributes * * Permit update of file attributes when files have a valid EVM signature, * except in the case of them having an immutable portable signature.
From: Roberto Sassu roberto.sassu@huawei.com
[ Upstream commit 996e0a97ebd7b11cb785794e2a83c20c1add9d92 ]
Fix build warnings (function parameters description) for evm_read_protected_xattrs(), evm_set_key() and evm_verifyxattr().
Fixes: 7626676320f3 ("evm: provide a function to set the EVM key from the kernel") # v4.5+ Fixes: 8314b6732ae4 ("ima: Define new template fields xattrnames, xattrlengths and xattrvalues") # v5.14+ Fixes: 2960e6cb5f7c ("evm: additional parameter to pass integrity cache entry 'iint'") # v3.2+ Signed-off-by: Roberto Sassu roberto.sassu@huawei.com Signed-off-by: Mimi Zohar zohar@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/integrity/evm/evm_crypto.c | 2 +- security/integrity/evm/evm_main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index 033804f5a5f20..0dae649f3740c 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c @@ -40,7 +40,7 @@ static const char evm_hmac[] = "hmac(sha1)"; /** * evm_set_key() - set EVM HMAC key from the kernel * @key: pointer to a buffer with the key data - * @size: length of the key data + * @keylen: length of the key data * * This function allows setting the EVM HMAC key from the kernel * without using the "encrypted" key subsystem keys. It can be used diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index b1c2197473a21..c9b6e2a43478a 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c @@ -318,7 +318,6 @@ int evm_protected_xattr_if_enabled(const char *req_xattr_name) /** * evm_read_protected_xattrs - read EVM protected xattr names, lengths, values * @dentry: dentry of the read xattrs - * @inode: inode of the read xattrs * @buffer: buffer xattr names, lengths or values are copied to * @buffer_size: size of buffer * @type: n: names, l: lengths, v: values @@ -390,6 +389,7 @@ int evm_read_protected_xattrs(struct dentry *dentry, u8 *buffer, * @xattr_name: requested xattr * @xattr_value: requested xattr value * @xattr_value_len: requested xattr value length + * @iint: inode integrity metadata * * Calculate the HMAC for the given dentry and verify it against the stored * security.evm xattr. For performance, use the xattr value and length
From: Roberto Sassu roberto.sassu@huawei.com
[ Upstream commit 95526d13038c2bbddd567a4d8e39fac42484e182 ]
Fix build warnings (function parameters description) for ima_collect_modsig(), ima_match_policy() and ima_parse_add_rule().
Fixes: 15588227e086 ("ima: Collect modsig") # v5.4+ Fixes: 2fe5d6def167 ("ima: integrity appraisal extension") # v5.14+ Fixes: 4af4662fa4a9 ("integrity: IMA policy") # v3.2+ Signed-off-by: Roberto Sassu roberto.sassu@huawei.com Signed-off-by: Mimi Zohar zohar@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/integrity/ima/ima_modsig.c | 3 +++ security/integrity/ima/ima_policy.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/security/integrity/ima/ima_modsig.c b/security/integrity/ima/ima_modsig.c index fb25723c65bc4..3e7bee30080f2 100644 --- a/security/integrity/ima/ima_modsig.c +++ b/security/integrity/ima/ima_modsig.c @@ -89,6 +89,9 @@ int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len,
/** * ima_collect_modsig - Calculate the file hash without the appended signature. + * @modsig: parsed module signature + * @buf: data to verify the signature on + * @size: data size * * Since the modsig is part of the file contents, the hash used in its signature * isn't the same one ordinarily calculated by IMA. Therefore PKCS7 code diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 3ca8b7348c2e4..c9b3bd8f1bb9c 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -721,6 +721,7 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func) * @secid: LSM secid of the task to be validated * @func: IMA hook identifier * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC) + * @flags: IMA actions to consider (e.g. IMA_MEASURE | IMA_APPRAISE) * @pcr: set the pcr to extend * @template_desc: the template that should be used for this rule * @func_data: func specific data, may be NULL @@ -1915,7 +1916,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
/** * ima_parse_add_rule - add a rule to ima_policy_rules - * @rule - ima measurement policy rule + * @rule: ima measurement policy rule * * Avoid locking by allowing just one writer at a time in ima_write_policy() * Returns the length of the rule parsed, an error code on failure
From: Jiasheng Jiang jiasheng@iscas.ac.cn
[ Upstream commit d97038d5ec2062733c1e016caf9baaf68cf64ea1 ]
Add check for the return value of kstrdup() and return the error if it fails in order to avoid NULL pointer dereference.
Fixes: e163fdb3f7f8 ("pstore/ram: Regularize prz label allocation lifetime") Signed-off-by: Jiasheng Jiang jiasheng@iscas.ac.cn Signed-off-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20230614093733.36048-1-jiasheng@iscas.ac.cn Signed-off-by: Sasha Levin sashal@kernel.org --- fs/pstore/ram_core.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 966191d3a5ba2..85aaf0fc6d7d1 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -599,6 +599,8 @@ struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size, raw_spin_lock_init(&prz->buffer_lock); prz->flags = flags; prz->label = kstrdup(label, GFP_KERNEL); + if (!prz->label) + goto err;
ret = persistent_ram_buffer_map(start, size, prz, memtype); if (ret)
From: Hao Jia jiahao.os@bytedance.com
[ Upstream commit ebb83d84e49b54369b0db67136a5fe1087124dcc ]
After commit 8ad075c2eb1f ("sched: Async unthrottling for cfs bandwidth"), we may update the rq clock multiple times in the loop of __cfsb_csd_unthrottle().
A prior (although less common) instance of this problem exists in unthrottle_offline_cfs_rqs().
Cure both by ensuring update_rq_clock() is called before the loop and setting RQCF_ACT_SKIP during the loop, to supress further updates. The alternative would be pulling update_rq_clock() out of unthrottle_cfs_rq(), but that gives an even bigger mess.
Fixes: 8ad075c2eb1f ("sched: Async unthrottling for cfs bandwidth") Reviewed-By: Ben Segall bsegall@google.com Suggested-by: Vincent Guittot vincent.guittot@linaro.org Signed-off-by: Hao Jia jiahao.os@bytedance.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Vincent Guittot vincent.guittot@linaro.org Link: https://lkml.kernel.org/r/20230613082012.49615-4-jiahao.os@bytedance.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/fair.c | 18 ++++++++++++++++++ kernel/sched/sched.h | 22 ++++++++++++++++++++++ 2 files changed, 40 insertions(+)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index ed89be0aa6503..853b7ef9dcafc 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -5519,6 +5519,14 @@ static void __cfsb_csd_unthrottle(void *arg)
rq_lock(rq, &rf);
+ /* + * Iterating over the list can trigger several call to + * update_rq_clock() in unthrottle_cfs_rq(). + * Do it once and skip the potential next ones. + */ + update_rq_clock(rq); + rq_clock_start_loop_update(rq); + /* * Since we hold rq lock we're safe from concurrent manipulation of * the CSD list. However, this RCU critical section annotates the @@ -5538,6 +5546,7 @@ static void __cfsb_csd_unthrottle(void *arg)
rcu_read_unlock();
+ rq_clock_stop_loop_update(rq); rq_unlock(rq, &rf); }
@@ -6054,6 +6063,13 @@ static void __maybe_unused unthrottle_offline_cfs_rqs(struct rq *rq)
lockdep_assert_rq_held(rq);
+ /* + * The rq clock has already been updated in the + * set_rq_offline(), so we should skip updating + * the rq clock again in unthrottle_cfs_rq(). + */ + rq_clock_start_loop_update(rq); + rcu_read_lock(); list_for_each_entry_rcu(tg, &task_groups, list) { struct cfs_rq *cfs_rq = tg->cfs_rq[cpu_of(rq)]; @@ -6076,6 +6092,8 @@ static void __maybe_unused unthrottle_offline_cfs_rqs(struct rq *rq) unthrottle_cfs_rq(cfs_rq); } rcu_read_unlock(); + + rq_clock_stop_loop_update(rq); }
#else /* CONFIG_CFS_BANDWIDTH */ diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 3e8df6d31c1e3..3adac73b17ca5 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1546,6 +1546,28 @@ static inline void rq_clock_cancel_skipupdate(struct rq *rq) rq->clock_update_flags &= ~RQCF_REQ_SKIP; }
+/* + * During cpu offlining and rq wide unthrottling, we can trigger + * an update_rq_clock() for several cfs and rt runqueues (Typically + * when using list_for_each_entry_*) + * rq_clock_start_loop_update() can be called after updating the clock + * once and before iterating over the list to prevent multiple update. + * After the iterative traversal, we need to call rq_clock_stop_loop_update() + * to clear RQCF_ACT_SKIP of rq->clock_update_flags. + */ +static inline void rq_clock_start_loop_update(struct rq *rq) +{ + lockdep_assert_rq_held(rq); + SCHED_WARN_ON(rq->clock_update_flags & RQCF_ACT_SKIP); + rq->clock_update_flags |= RQCF_ACT_SKIP; +} + +static inline void rq_clock_stop_loop_update(struct rq *rq) +{ + lockdep_assert_rq_held(rq); + rq->clock_update_flags &= ~RQCF_ACT_SKIP; +} + struct rq_flags { unsigned long flags; struct pin_cookie cookie;
From: Jesper Dangaard Brouer brouer@redhat.com
[ Upstream commit 84214ab4689f962b4bfc47fc9a5838d25ac4274d ]
When function igc_rx_hash() was introduced in v4.20 via commit 0507ef8a0372 ("igc: Add transmit and receive fastpath and interrupt handlers"), the hardware wasn't configured to provide RSS hash, thus it made sense to not enable net_device NETIF_F_RXHASH feature bit.
The NIC hardware was configured to enable RSS hash info in v5.2 via commit 2121c2712f82 ("igc: Add multiple receive queues control supporting"), but forgot to set the NETIF_F_RXHASH feature bit.
The original implementation of igc_rx_hash() didn't extract the associated pkt_hash_type, but statically set PKT_HASH_TYPE_L3. The largest portions of this patch are about extracting the RSS Type from the hardware and mapping this to enum pkt_hash_types. This was based on Foxville i225 software user manual rev-1.3.1 and tested on Intel Ethernet Controller I225-LM (rev 03).
For UDP it's worth noting that RSS (type) hashing have been disabled both for IPv4 and IPv6 (see IGC_MRQC_RSS_FIELD_IPV4_UDP + IGC_MRQC_RSS_FIELD_IPV6_UDP) because hardware RSS doesn't handle fragmented pkts well when enabled (can cause out-of-order). This results in PKT_HASH_TYPE_L3 for UDP packets, and hash value doesn't include UDP port numbers. Not being PKT_HASH_TYPE_L4, have the effect that netstack will do a software based hash calc calling into flow_dissect, but only when code calls skb_get_hash(), which doesn't necessary happen for local delivery.
For QA verification testing I wrote a small bpftrace prog: [0] https://github.com/xdp-project/xdp-project/blob/master/areas/hints/monitor_s...
Fixes: 2121c2712f82 ("igc: Add multiple receive queues control supporting") Signed-off-by: Jesper Dangaard Brouer brouer@redhat.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Song Yoong Siang yoong.siang.song@intel.com Link: https://lore.kernel.org/bpf/168182464270.616355.11391652654430626584.stgit@f... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/igc/igc.h | 28 ++++++++++++++++++++ drivers/net/ethernet/intel/igc/igc_main.c | 31 ++++++++++++++++++++--- 2 files changed, 55 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h index df3e26c0cf01a..f83cbc4a1afa8 100644 --- a/drivers/net/ethernet/intel/igc/igc.h +++ b/drivers/net/ethernet/intel/igc/igc.h @@ -13,6 +13,7 @@ #include <linux/ptp_clock_kernel.h> #include <linux/timecounter.h> #include <linux/net_tstamp.h> +#include <linux/bitfield.h>
#include "igc_hw.h"
@@ -311,6 +312,33 @@ extern char igc_driver_name[]; #define IGC_MRQC_RSS_FIELD_IPV4_UDP 0x00400000 #define IGC_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
+/* RX-desc Write-Back format RSS Type's */ +enum igc_rss_type_num { + IGC_RSS_TYPE_NO_HASH = 0, + IGC_RSS_TYPE_HASH_TCP_IPV4 = 1, + IGC_RSS_TYPE_HASH_IPV4 = 2, + IGC_RSS_TYPE_HASH_TCP_IPV6 = 3, + IGC_RSS_TYPE_HASH_IPV6_EX = 4, + IGC_RSS_TYPE_HASH_IPV6 = 5, + IGC_RSS_TYPE_HASH_TCP_IPV6_EX = 6, + IGC_RSS_TYPE_HASH_UDP_IPV4 = 7, + IGC_RSS_TYPE_HASH_UDP_IPV6 = 8, + IGC_RSS_TYPE_HASH_UDP_IPV6_EX = 9, + IGC_RSS_TYPE_MAX = 10, +}; +#define IGC_RSS_TYPE_MAX_TABLE 16 +#define IGC_RSS_TYPE_MASK GENMASK(3,0) /* 4-bits (3:0) = mask 0x0F */ + +/* igc_rss_type - Rx descriptor RSS type field */ +static inline u32 igc_rss_type(const union igc_adv_rx_desc *rx_desc) +{ + /* RSS Type 4-bits (3:0) number: 0-9 (above 9 is reserved) + * Accessing the same bits via u16 (wb.lower.lo_dword.hs_rss.pkt_info) + * is slightly slower than via u32 (wb.lower.lo_dword.data) + */ + return le32_get_bits(rx_desc->wb.lower.lo_dword.data, IGC_RSS_TYPE_MASK); +} + /* Interrupt defines */ #define IGC_START_ITR 648 /* ~6000 ints/sec */ #define IGC_4K_ITR 980 diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index b35f5ff3536e5..c85ceed443223 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -1687,14 +1687,36 @@ static void igc_rx_checksum(struct igc_ring *ring, le32_to_cpu(rx_desc->wb.upper.status_error)); }
+/* Mapping HW RSS Type to enum pkt_hash_types */ +static const enum pkt_hash_types igc_rss_type_table[IGC_RSS_TYPE_MAX_TABLE] = { + [IGC_RSS_TYPE_NO_HASH] = PKT_HASH_TYPE_L2, + [IGC_RSS_TYPE_HASH_TCP_IPV4] = PKT_HASH_TYPE_L4, + [IGC_RSS_TYPE_HASH_IPV4] = PKT_HASH_TYPE_L3, + [IGC_RSS_TYPE_HASH_TCP_IPV6] = PKT_HASH_TYPE_L4, + [IGC_RSS_TYPE_HASH_IPV6_EX] = PKT_HASH_TYPE_L3, + [IGC_RSS_TYPE_HASH_IPV6] = PKT_HASH_TYPE_L3, + [IGC_RSS_TYPE_HASH_TCP_IPV6_EX] = PKT_HASH_TYPE_L4, + [IGC_RSS_TYPE_HASH_UDP_IPV4] = PKT_HASH_TYPE_L4, + [IGC_RSS_TYPE_HASH_UDP_IPV6] = PKT_HASH_TYPE_L4, + [IGC_RSS_TYPE_HASH_UDP_IPV6_EX] = PKT_HASH_TYPE_L4, + [10] = PKT_HASH_TYPE_NONE, /* RSS Type above 9 "Reserved" by HW */ + [11] = PKT_HASH_TYPE_NONE, /* keep array sized for SW bit-mask */ + [12] = PKT_HASH_TYPE_NONE, /* to handle future HW revisons */ + [13] = PKT_HASH_TYPE_NONE, + [14] = PKT_HASH_TYPE_NONE, + [15] = PKT_HASH_TYPE_NONE, +}; + static inline void igc_rx_hash(struct igc_ring *ring, union igc_adv_rx_desc *rx_desc, struct sk_buff *skb) { - if (ring->netdev->features & NETIF_F_RXHASH) - skb_set_hash(skb, - le32_to_cpu(rx_desc->wb.lower.hi_dword.rss), - PKT_HASH_TYPE_L3); + if (ring->netdev->features & NETIF_F_RXHASH) { + u32 rss_hash = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss); + u32 rss_type = igc_rss_type(rx_desc); + + skb_set_hash(skb, rss_hash, igc_rss_type_table[rss_type]); + } }
static void igc_rx_vlan(struct igc_ring *rx_ring, @@ -6553,6 +6575,7 @@ static int igc_probe(struct pci_dev *pdev, netdev->features |= NETIF_F_TSO; netdev->features |= NETIF_F_TSO6; netdev->features |= NETIF_F_TSO_ECN; + netdev->features |= NETIF_F_RXHASH; netdev->features |= NETIF_F_RXCSUM; netdev->features |= NETIF_F_HW_CSUM; netdev->features |= NETIF_F_SCTP_CRC;
From: Peter Seiderer ps.report@gmx.net
[ Upstream commit 3e56c80931c7615250fe4bf83f93b57881969266 ]
Fix ath9k_hw_verify_hang()/ar9003_hw_detect_mac_hang() register offset calculation (do not overflow the shift for the second register/queues above five, use the register layout described in the comments above ath9k_hw_verify_hang() instead).
Fixes: 222e04830ff0 ("ath9k: Fix MAC HW hang check for AR9003")
Reported-by: Gregg Wonderly greggwonderly@seqtechllc.com Link: https://lore.kernel.org/linux-wireless/E3A9C354-0CB7-420C-ADEF-F0177FB722F4@... Signed-off-by: Peter Seiderer ps.report@gmx.net Acked-by: Toke Høiland-Jørgensen toke@toke.dk Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20230422212423.26065-1-ps.report@gmx.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 27 ++++++++++++++-------- 1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 4f27a9fb1482b..e9bd13eeee92f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -1099,17 +1099,22 @@ static bool ath9k_hw_verify_hang(struct ath_hw *ah, unsigned int queue) { u32 dma_dbg_chain, dma_dbg_complete; u8 dcu_chain_state, dcu_complete_state; + unsigned int dbg_reg, reg_offset; int i;
- for (i = 0; i < NUM_STATUS_READS; i++) { - if (queue < 6) - dma_dbg_chain = REG_READ(ah, AR_DMADBG_4); - else - dma_dbg_chain = REG_READ(ah, AR_DMADBG_5); + if (queue < 6) { + dbg_reg = AR_DMADBG_4; + reg_offset = queue * 5; + } else { + dbg_reg = AR_DMADBG_5; + reg_offset = (queue - 6) * 5; + }
+ for (i = 0; i < NUM_STATUS_READS; i++) { + dma_dbg_chain = REG_READ(ah, dbg_reg); dma_dbg_complete = REG_READ(ah, AR_DMADBG_6);
- dcu_chain_state = (dma_dbg_chain >> (5 * queue)) & 0x1f; + dcu_chain_state = (dma_dbg_chain >> reg_offset) & 0x1f; dcu_complete_state = dma_dbg_complete & 0x3;
if ((dcu_chain_state != 0x6) || (dcu_complete_state != 0x1)) @@ -1128,6 +1133,7 @@ static bool ar9003_hw_detect_mac_hang(struct ath_hw *ah) u8 dcu_chain_state, dcu_complete_state; bool dcu_wait_frdone = false; unsigned long chk_dcu = 0; + unsigned int reg_offset; unsigned int i = 0;
dma_dbg_4 = REG_READ(ah, AR_DMADBG_4); @@ -1139,12 +1145,15 @@ static bool ar9003_hw_detect_mac_hang(struct ath_hw *ah) goto exit;
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { - if (i < 6) + if (i < 6) { chk_dbg = dma_dbg_4; - else + reg_offset = i * 5; + } else { chk_dbg = dma_dbg_5; + reg_offset = (i - 6) * 5; + }
- dcu_chain_state = (chk_dbg >> (5 * i)) & 0x1f; + dcu_chain_state = (chk_dbg >> reg_offset) & 0x1f; if (dcu_chain_state == 0x6) { dcu_wait_frdone = true; chk_dcu |= BIT(i);
From: Fedor Pchelkin pchelkin@ispras.ru
[ Upstream commit f24292e827088bba8de7158501ac25a59b064953 ]
For the reasons also described in commit b383e8abed41 ("wifi: ath9k: avoid uninit memory read in ath9k_htc_rx_msg()"), ath9k_htc_rx_msg() should validate pkt_len before accessing the SKB.
For example, the obtained SKB may have been badly constructed with pkt_len = 8. In this case, the SKB can only contain a valid htc_frame_hdr but after being processed in ath9k_htc_rx_msg() and passed to ath9k_wmi_ctrl_rx() endpoint RX handler, it is expected to have a WMI command header which should be located inside its data payload.
Implement sanity checking inside ath9k_wmi_ctrl_rx(). Otherwise, uninit memory can be referenced.
Tested on Qualcomm Atheros Communications AR9271 802.11n .
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.") Reported-and-tested-by: syzbot+f2cb6e0ffdb961921e4d@syzkaller.appspotmail.com Signed-off-by: Fedor Pchelkin pchelkin@ispras.ru Acked-by: Toke Høiland-Jørgensen toke@toke.dk Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20230424183348.111355-1-pchelkin@ispras.ru Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/wmi.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 19345b8f7bfd5..d652c647d56b5 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -221,6 +221,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, if (unlikely(wmi->stopped)) goto free_skb;
+ /* Validate the obtained SKB. */ + if (unlikely(skb->len < sizeof(struct wmi_cmd_hdr))) + goto free_skb; + hdr = (struct wmi_cmd_hdr *) skb->data; cmd_id = be16_to_cpu(hdr->command_id);
From: Martin KaFai Lau martin.lau@kernel.org
[ Upstream commit c39028b333f3a3a765c5c0b9726b8e38aedf0ba1 ]
The btf_dump/struct_data selftest is failing with:
[...] test_btf_dump_struct_data:FAIL:unexpected return value dumping fs_context unexpected unexpected return value dumping fs_context: actual -7 != expected 264 [...]
The reason is in btf_dump_type_data_check_overflow(). It does not use BTF_MEMBER_BITFIELD_SIZE from the struct's member (btf_member). Instead, it is using the enum size which is 4. It had been working till the recent commit 4e04143c869c ("fs_context: drop the unused lsm_flags member") removed an integer member which also removed the 4 bytes padding at the end of the fs_context. Missing this 4 bytes padding exposed this bug. In particular, when btf_dump_type_data_check_overflow() reaches the member 'phase', -E2BIG is returned.
The fix is to pass bit_sz to btf_dump_type_data_check_overflow(). In btf_dump_type_data_check_overflow(), it does a different size check when bit_sz is not zero.
The current fs_context:
[3600] ENUM 'fs_context_purpose' encoding=UNSIGNED size=4 vlen=3 'FS_CONTEXT_FOR_MOUNT' val=0 'FS_CONTEXT_FOR_SUBMOUNT' val=1 'FS_CONTEXT_FOR_RECONFIGURE' val=2 [3601] ENUM 'fs_context_phase' encoding=UNSIGNED size=4 vlen=7 'FS_CONTEXT_CREATE_PARAMS' val=0 'FS_CONTEXT_CREATING' val=1 'FS_CONTEXT_AWAITING_MOUNT' val=2 'FS_CONTEXT_AWAITING_RECONF' val=3 'FS_CONTEXT_RECONF_PARAMS' val=4 'FS_CONTEXT_RECONFIGURING' val=5 'FS_CONTEXT_FAILED' val=6 [3602] STRUCT 'fs_context' size=264 vlen=21 'ops' type_id=3603 bits_offset=0 'uapi_mutex' type_id=235 bits_offset=64 'fs_type' type_id=872 bits_offset=1216 'fs_private' type_id=21 bits_offset=1280 'sget_key' type_id=21 bits_offset=1344 'root' type_id=781 bits_offset=1408 'user_ns' type_id=251 bits_offset=1472 'net_ns' type_id=984 bits_offset=1536 'cred' type_id=1785 bits_offset=1600 'log' type_id=3621 bits_offset=1664 'source' type_id=42 bits_offset=1792 'security' type_id=21 bits_offset=1856 's_fs_info' type_id=21 bits_offset=1920 'sb_flags' type_id=20 bits_offset=1984 'sb_flags_mask' type_id=20 bits_offset=2016 's_iflags' type_id=20 bits_offset=2048 'purpose' type_id=3600 bits_offset=2080 bitfield_size=8 'phase' type_id=3601 bits_offset=2088 bitfield_size=8 'need_free' type_id=67 bits_offset=2096 bitfield_size=1 'global' type_id=67 bits_offset=2097 bitfield_size=1 'oldapi' type_id=67 bits_offset=2098 bitfield_size=1
Fixes: 920d16af9b42 ("libbpf: BTF dumper support for typed data") Signed-off-by: Martin KaFai Lau martin.lau@kernel.org Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Yonghong Song yhs@fb.com Link: https://lore.kernel.org/bpf/20230428013638.1581263-1-martin.lau@linux.dev Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/btf_dump.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c index 580985ee55458..4d9f30bf7f014 100644 --- a/tools/lib/bpf/btf_dump.c +++ b/tools/lib/bpf/btf_dump.c @@ -2250,9 +2250,25 @@ static int btf_dump_type_data_check_overflow(struct btf_dump *d, const struct btf_type *t, __u32 id, const void *data, - __u8 bits_offset) + __u8 bits_offset, + __u8 bit_sz) { - __s64 size = btf__resolve_size(d->btf, id); + __s64 size; + + if (bit_sz) { + /* bits_offset is at most 7. bit_sz is at most 128. */ + __u8 nr_bytes = (bits_offset + bit_sz + 7) / 8; + + /* When bit_sz is non zero, it is called from + * btf_dump_struct_data() where it only cares about + * negative error value. + * Return nr_bytes in success case to make it + * consistent as the regular integer case below. + */ + return data + nr_bytes > d->typed_dump->data_end ? -E2BIG : nr_bytes; + } + + size = btf__resolve_size(d->btf, id);
if (size < 0 || size >= INT_MAX) { pr_warn("unexpected size [%zu] for id [%u]\n", @@ -2407,7 +2423,7 @@ static int btf_dump_dump_type_data(struct btf_dump *d, { int size, err = 0;
- size = btf_dump_type_data_check_overflow(d, t, id, data, bits_offset); + size = btf_dump_type_data_check_overflow(d, t, id, data, bits_offset, bit_sz); if (size < 0) return size; err = btf_dump_type_data_check_zero(d, t, id, data, bits_offset, bit_sz);
From: Pengcheng Yang yangpc@wangsu.com
[ Upstream commit f4dea9689c5fea3d07170c2cb0703e216f1a0922 ]
Using sizeof(nv) or strlen(nv)+1 is correct.
Fixes: c890063e4404 ("bpf: sample BPF_SOCKET_OPS_BASE_RTT program") Signed-off-by: Pengcheng Yang yangpc@wangsu.com Link: https://lore.kernel.org/r/1683276658-2860-1-git-send-email-yangpc@wangsu.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- samples/bpf/tcp_basertt_kern.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/samples/bpf/tcp_basertt_kern.c b/samples/bpf/tcp_basertt_kern.c index 8dfe09a92feca..822b0742b8154 100644 --- a/samples/bpf/tcp_basertt_kern.c +++ b/samples/bpf/tcp_basertt_kern.c @@ -47,7 +47,7 @@ int bpf_basertt(struct bpf_sock_ops *skops) case BPF_SOCK_OPS_BASE_RTT: n = bpf_getsockopt(skops, SOL_TCP, TCP_CONGESTION, cong, sizeof(cong)); - if (!n && !__builtin_memcmp(cong, nv, sizeof(nv)+1)) { + if (!n && !__builtin_memcmp(cong, nv, sizeof(nv))) { /* Set base_rtt to 80us */ rv = 80; } else if (n) {
From: Vijaya Krishna Nivarthi quic_vnivarth@quicinc.com
[ Upstream commit 5fd7c99ecf45c8ee8a9b1268f0ffc91cc6271da2 ]
The CS_TOGGLE bit when set is supposed to instruct FW to toggle CS line between words. The driver with intent of disabling this behaviour has been unsetting BIT(0). This has not caused any trouble so far because the original BIT(1) is untouched and BIT(0) likely wasn't being used.
Correct this to prevent a potential future bug.
Signed-off-by: Vijaya Krishna Nivarthi <quic_vnivarth@quicinc.com Acked-by: Konrad Dybcio <konrad.dybcio@linaro.org Fixes: 561de45f72bd ("spi: spi-geni-qcom: Add SPI driver support for GENI based QUP") Reviewed-by: Douglas Anderson <dianders@chromium.org Link: https://lore.kernel.org/r/1682412128-1913-1-git-send-email-quic_vnivarth@qui... Signed-off-by: Mark Brown <broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-geni-qcom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c index baf477383682d..d147519fe1089 100644 --- a/drivers/spi/spi-geni-qcom.c +++ b/drivers/spi/spi-geni-qcom.c @@ -35,7 +35,7 @@ #define CS_DEMUX_OUTPUT_SEL GENMASK(3, 0)
#define SE_SPI_TRANS_CFG 0x25c -#define CS_TOGGLE BIT(0) +#define CS_TOGGLE BIT(1)
#define SE_SPI_WORD_LEN 0x268 #define WORD_LEN_MSK GENMASK(9, 0)
From: Amisha Patel amisha.patel@microchip.com
[ Upstream commit 9ce4bb09123e9754996e358bd808d39f5d112899 ]
Mandatory WFA testcase CT_Security_WPA2Personal_STA_RSNEBoundsVerification-AbsentRSNCap, performs bounds verfication on Beacon and/or Probe response frames. It failed and observed the reason to be absence of cipher suite and AKM suite in RSN information. To fix this, enable the RSN flag before extracting RSN capabilities.
Fixes: cd21d99e595e ("wifi: wilc1000: validate pairwise and authentication suite offsets") Signed-off-by: Amisha Patel amisha.patel@microchip.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20230421181005.4865-1-amisha.patel@microchip.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/microchip/wilc1000/hif.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/microchip/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c index 5adc69d5bcae3..a28da59384813 100644 --- a/drivers/net/wireless/microchip/wilc1000/hif.c +++ b/drivers/net/wireless/microchip/wilc1000/hif.c @@ -485,6 +485,9 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss, int rsn_ie_len = sizeof(struct element) + rsn_ie[1]; int offset = 8;
+ param->mode_802_11i = 2; + param->rsn_found = true; + /* extract RSN capabilities */ if (offset < rsn_ie_len) { /* skip over pairwise suites */ @@ -494,11 +497,8 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss, /* skip over authentication suites */ offset += (rsn_ie[offset] * 4) + 2;
- if (offset + 1 < rsn_ie_len) { - param->mode_802_11i = 2; - param->rsn_found = true; + if (offset + 1 < rsn_ie_len) memcpy(param->rsn_cap, &rsn_ie[offset], 2); - } } } }
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit d9aef04fcfa81ee4fb2804a21a3712b7bbd936af ]
The type of "mwifiex_adapter->nd_info" is "struct cfg80211_wowlan_nd_info", not "struct cfg80211_wowlan_nd_match".
Use struct_size() to ease the computation of the needed size.
The current code over-allocates some memory, so is safe. But it wastes 32 bytes.
Fixes: 7d7f07d8c5d3 ("mwifiex: add wowlan net-detect support") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/7a6074fb056d2181e058a3cc6048d8155c20aec7.168337198... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/mwifiex/scan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c index ac8001c842935..644b1e134b01c 100644 --- a/drivers/net/wireless/marvell/mwifiex/scan.c +++ b/drivers/net/wireless/marvell/mwifiex/scan.c @@ -2187,9 +2187,9 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
if (nd_config) { adapter->nd_info = - kzalloc(sizeof(struct cfg80211_wowlan_nd_match) + - sizeof(struct cfg80211_wowlan_nd_match *) * - scan_rsp->number_of_sets, GFP_ATOMIC); + kzalloc(struct_size(adapter->nd_info, matches, + scan_rsp->number_of_sets), + GFP_ATOMIC);
if (adapter->nd_info) adapter->nd_info->n_matches = scan_rsp->number_of_sets;
From: Alexander Mikhalitsyn aleksandr.mikhalitsyn@canonical.com
[ Upstream commit 2598619e012cee5273a2821441b9a051ad931249 ]
Implement ->bpf_bypass_getsockopt proto callback and filter out SCTP_SOCKOPT_PEELOFF, SCTP_SOCKOPT_PEELOFF_FLAGS and SCTP_SOCKOPT_CONNECTX3 socket options from running eBPF hook on them.
SCTP_SOCKOPT_PEELOFF and SCTP_SOCKOPT_PEELOFF_FLAGS options do fd_install(), and if BPF_CGROUP_RUN_PROG_GETSOCKOPT hook returns an error after success of the original handler sctp_getsockopt(...), userspace will receive an error from getsockopt syscall and will be not aware that fd was successfully installed into a fdtable.
As pointed by Marcelo Ricardo Leitner it seems reasonable to skip bpf getsockopt hook for SCTP_SOCKOPT_CONNECTX3 sockopt too. Because internaly, it triggers connect() and if error is masked then userspace will be confused.
This patch was born as a result of discussion around a new SCM_PIDFD interface: https://lore.kernel.org/all/20230413133355.350571-3-aleksandr.mikhalitsyn@ca...
Fixes: 0d01da6afc54 ("bpf: implement getsockopt and setsockopt hooks") Cc: Daniel Borkmann daniel@iogearbox.net Cc: Christian Brauner brauner@kernel.org Cc: Stanislav Fomichev sdf@google.com Cc: Neil Horman nhorman@tuxdriver.com Cc: Marcelo Ricardo Leitner marcelo.leitner@gmail.com Cc: Xin Long lucien.xin@gmail.com Cc: linux-sctp@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: netdev@vger.kernel.org Suggested-by: Stanislav Fomichev sdf@google.com Acked-by: Stanislav Fomichev sdf@google.com Signed-off-by: Alexander Mikhalitsyn aleksandr.mikhalitsyn@canonical.com Acked-by: Xin Long lucien.xin@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/sctp/socket.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 218e0982c3707..0932cbf568ee9 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -8280,6 +8280,22 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname, return retval; }
+static bool sctp_bpf_bypass_getsockopt(int level, int optname) +{ + if (level == SOL_SCTP) { + switch (optname) { + case SCTP_SOCKOPT_PEELOFF: + case SCTP_SOCKOPT_PEELOFF_FLAGS: + case SCTP_SOCKOPT_CONNECTX3: + return true; + default: + return false; + } + } + + return false; +} + static int sctp_hash(struct sock *sk) { /* STUB */ @@ -9649,6 +9665,7 @@ struct proto sctp_prot = { .shutdown = sctp_shutdown, .setsockopt = sctp_setsockopt, .getsockopt = sctp_getsockopt, + .bpf_bypass_getsockopt = sctp_bpf_bypass_getsockopt, .sendmsg = sctp_sendmsg, .recvmsg = sctp_recvmsg, .bind = sctp_bind, @@ -9704,6 +9721,7 @@ struct proto sctpv6_prot = { .shutdown = sctp_shutdown, .setsockopt = sctp_setsockopt, .getsockopt = sctp_getsockopt, + .bpf_bypass_getsockopt = sctp_bpf_bypass_getsockopt, .sendmsg = sctp_sendmsg, .recvmsg = sctp_recvmsg, .bind = sctp_bind,
From: Andrii Nakryiko andrii@kernel.org
[ Upstream commit bdeeed3498c7871c17465bb4f11d1bc67f9098af ]
It seems like __builtin_offset() doesn't preserve CO-RE field relocations properly. So if offsetof() macro is defined through __builtin_offset(), CO-RE-enabled BPF code using container_of() will be subtly and silently broken.
To avoid this problem, redefine offsetof() and container_of() in the form that works with CO-RE relocations more reliably.
Fixes: 5fbc220862fc ("tools/libpf: Add offsetof/container_of macro in bpf_helpers.h") Reported-by: Lennart Poettering lennart@poettering.net Signed-off-by: Andrii Nakryiko andrii@kernel.org Acked-by: Yonghong Song yhs@fb.com Link: https://lore.kernel.org/r/20230509065502.2306180-1-andrii@kernel.org Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/bpf_helpers.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/tools/lib/bpf/bpf_helpers.h b/tools/lib/bpf/bpf_helpers.h index 5ec1871acb2fc..85a29cd69154e 100644 --- a/tools/lib/bpf/bpf_helpers.h +++ b/tools/lib/bpf/bpf_helpers.h @@ -77,16 +77,21 @@ /* * Helper macros to manipulate data structures */ -#ifndef offsetof -#define offsetof(TYPE, MEMBER) ((unsigned long)&((TYPE *)0)->MEMBER) -#endif -#ifndef container_of + +/* offsetof() definition that uses __builtin_offset() might not preserve field + * offset CO-RE relocation properly, so force-redefine offsetof() using + * old-school approach which works with CO-RE correctly + */ +#undef offsetof +#define offsetof(type, member) ((unsigned long)&((type *)0)->member) + +/* redefined container_of() to ensure we use the above offsetof() macro */ +#undef container_of #define container_of(ptr, type, member) \ ({ \ void *__mptr = (void *)(ptr); \ ((type *)(__mptr - offsetof(type, member))); \ }) -#endif
/* * Compiler (optimization) barrier.
From: Stanislav Fomichev sdf@google.com
[ Upstream commit 29ebbba7d46136cba324264e513a1e964ca16c0a ]
With the way the hooks implemented right now, we have a special condition: optval larger than PAGE_SIZE will expose only first 4k into BPF; any modifications to the optval are ignored. If the BPF program doesn't handle this condition by resetting optlen to 0, the userspace will get EFAULT.
The intention of the EFAULT was to make it apparent to the developers that the program is doing something wrong. However, this inadvertently might affect production workloads with the BPF programs that are not too careful (i.e., returning EFAULT for perfectly valid setsockopt/getsockopt calls).
Let's try to minimize the chance of BPF program screwing up userspace by ignoring the output of those BPF programs (instead of returning EFAULT to the userspace). pr_info_once those cases to the dmesg to help with figuring out what's going wrong.
Fixes: 0d01da6afc54 ("bpf: implement getsockopt and setsockopt hooks") Suggested-by: Martin KaFai Lau martin.lau@kernel.org Signed-off-by: Stanislav Fomichev sdf@google.com Link: https://lore.kernel.org/r/20230511170456.1759459-2-sdf@google.com Signed-off-by: Martin KaFai Lau martin.lau@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/cgroup.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index b86b907e566ca..bb70f400c25eb 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -1826,6 +1826,12 @@ int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level, ret = 1; } else if (ctx.optlen > max_optlen || ctx.optlen < -1) { /* optlen is out of bounds */ + if (*optlen > PAGE_SIZE && ctx.optlen >= 0) { + pr_info_once("bpf setsockopt: ignoring program buffer with optlen=%d (max_optlen=%d)\n", + ctx.optlen, max_optlen); + ret = 0; + goto out; + } ret = -EFAULT; } else { /* optlen within bounds, run kernel handler */ @@ -1881,8 +1887,10 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, .optname = optname, .current_task = current, }; + int orig_optlen; int ret;
+ orig_optlen = max_optlen; ctx.optlen = max_optlen; max_optlen = sockopt_alloc_buf(&ctx, max_optlen, &buf); if (max_optlen < 0) @@ -1905,6 +1913,7 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, ret = -EFAULT; goto out; } + orig_optlen = ctx.optlen;
if (copy_from_user(ctx.optval, optval, min(ctx.optlen, max_optlen)) != 0) { @@ -1922,6 +1931,12 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, goto out;
if (optval && (ctx.optlen > max_optlen || ctx.optlen < 0)) { + if (orig_optlen > PAGE_SIZE && ctx.optlen >= 0) { + pr_info_once("bpf getsockopt: ignoring program buffer with optlen=%d (max_optlen=%d)\n", + ctx.optlen, max_optlen); + ret = retval; + goto out; + } ret = -EFAULT; goto out; }
From: Joy Chakraborty joychakr@google.com
[ Upstream commit 9f34baf67e4d08908fd94ff29c825bb673295336 ]
n_bytes variable in the driver represents the number of bytes per word that needs to be sent/copied to fifo. Bits/word can be between 8 and 32 bits from the client but in memory they are a power of 2, same is mentioned in spi.h header: " * @bits_per_word: Data transfers involve one or more words; word sizes * like eight or 12 bits are common. In-memory wordsizes are * powers of two bytes (e.g. 20 bit samples use 32 bits). * This may be changed by the device's driver, or left at the * default (0) indicating protocol words are eight bit bytes. * The spi_transfer.bits_per_word can override this for each transfer. "
Hence, round of n_bytes to a power of 2 to avoid values like 3 which would generate unalligned/odd accesses to memory/fifo.
* tested on Baikal-T1 based system with DW SPI-looped back interface transferring a chunk of data with DFS:8,12,16.
Fixes: a51acc2400d4 ("spi: dw: Add support for 32-bits max xfer size") Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com Signed-off-by: Joy Chakraborty <joychakr@google.com Reviewed-by: Serge Semin <fancer.lancer@gmail.com Tested-by: Serge Semin <fancer.lancer@gmail.com Link: https://lore.kernel.org/r/20230512104746.1797865-4-joychakr@google.com Signed-off-by: Mark Brown <broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-dw-core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index c3bfb6c84cab2..4976e3b8923ee 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -426,7 +426,10 @@ static int dw_spi_transfer_one(struct spi_controller *master, int ret;
dws->dma_mapped = 0; - dws->n_bytes = DIV_ROUND_UP(transfer->bits_per_word, BITS_PER_BYTE); + dws->n_bytes = + roundup_pow_of_two(DIV_ROUND_UP(transfer->bits_per_word, + BITS_PER_BYTE)); + dws->tx = (void *)transfer->tx_buf; dws->tx_len = transfer->len / dws->n_bytes; dws->rx = transfer->rx_buf;
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 0d9b41daa5907756a31772d8af8ac5ff25cf17c1 ]
If sock->service_name is NULL, the local variable service_name_tlv_length will not be assigned by nfc_llcp_build_tlv(), later leading to using value frmo the stack. Smatch warning:
net/nfc/llcp_commands.c:442 nfc_llcp_send_connect() error: uninitialized symbol 'service_name_tlv_length'.
Fixes: de9e5aeb4f40 ("NFC: llcp: Fix usage of llcp_add_tlv()") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/nfc/llcp_commands.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c index 41e3a20c89355..cdb001de06928 100644 --- a/net/nfc/llcp_commands.c +++ b/net/nfc/llcp_commands.c @@ -390,7 +390,8 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) const u8 *service_name_tlv = NULL; const u8 *miux_tlv = NULL; const u8 *rw_tlv = NULL; - u8 service_name_tlv_length, miux_tlv_length, rw_tlv_length, rw; + u8 service_name_tlv_length = 0; + u8 miux_tlv_length, rw_tlv_length, rw; int err; u16 size = 0; __be16 miux;
From: Alan Maguire alan.maguire@oracle.com
[ Upstream commit 04cb8453a91c7c22f60ddadb6cef0d19abb33bb5 ]
On aarch64, "bpftool feature" reports an incorrect BPF JIT limit:
$ sudo /sbin/bpftool feature Scanning system configuration... bpf() syscall restricted to privileged users JIT compiler is enabled JIT compiler hardening is disabled JIT compiler kallsyms exports are enabled for root skipping kernel config, can't open file: No such file or directory Global memory limit for JIT compiler for unprivileged users is -201326592 bytes
This is because /proc/sys/net/core/bpf_jit_limit reports
$ sudo cat /proc/sys/net/core/bpf_jit_limit 68169519595520
...and an int is assumed in read_procfs(). Change read_procfs() to return a long to avoid negative value reporting.
Fixes: 7a4522bbef0c ("tools: bpftool: add probes for /proc/ eBPF parameters") Reported-by: Nicky Veitch nicky.veitch@oracle.com Signed-off-by: Alan Maguire alan.maguire@oracle.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Jiri Olsa jolsa@kernel.org Acked-by: Quentin Monnet quentin@isovalent.com Link: https://lore.kernel.org/bpf/20230512113134.58996-1-alan.maguire@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/bpf/bpftool/feature.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/tools/bpf/bpftool/feature.c b/tools/bpf/bpftool/feature.c index da16e6a27cccd..0675d6a464138 100644 --- a/tools/bpf/bpftool/feature.c +++ b/tools/bpf/bpftool/feature.c @@ -167,12 +167,12 @@ static int get_vendor_id(int ifindex) return strtol(buf, NULL, 0); }
-static int read_procfs(const char *path) +static long read_procfs(const char *path) { char *endptr, *line = NULL; size_t len = 0; FILE *fd; - int res; + long res;
fd = fopen(path, "r"); if (!fd) @@ -194,7 +194,7 @@ static int read_procfs(const char *path)
static void probe_unprivileged_disabled(void) { - int res; + long res;
/* No support for C-style ouptut */
@@ -216,14 +216,14 @@ static void probe_unprivileged_disabled(void) printf("Unable to retrieve required privileges for bpf() syscall\n"); break; default: - printf("bpf() syscall restriction has unknown value %d\n", res); + printf("bpf() syscall restriction has unknown value %ld\n", res); } } }
static void probe_jit_enable(void) { - int res; + long res;
/* No support for C-style ouptut */
@@ -245,7 +245,7 @@ static void probe_jit_enable(void) printf("Unable to retrieve JIT-compiler status\n"); break; default: - printf("JIT-compiler status has unknown value %d\n", + printf("JIT-compiler status has unknown value %ld\n", res); } } @@ -253,7 +253,7 @@ static void probe_jit_enable(void)
static void probe_jit_harden(void) { - int res; + long res;
/* No support for C-style ouptut */
@@ -275,7 +275,7 @@ static void probe_jit_harden(void) printf("Unable to retrieve JIT hardening status\n"); break; default: - printf("JIT hardening status has unknown value %d\n", + printf("JIT hardening status has unknown value %ld\n", res); } } @@ -283,7 +283,7 @@ static void probe_jit_harden(void)
static void probe_jit_kallsyms(void) { - int res; + long res;
/* No support for C-style ouptut */
@@ -302,14 +302,14 @@ static void probe_jit_kallsyms(void) printf("Unable to retrieve JIT kallsyms export status\n"); break; default: - printf("JIT kallsyms exports status has unknown value %d\n", res); + printf("JIT kallsyms exports status has unknown value %ld\n", res); } } }
static void probe_jit_limit(void) { - int res; + long res;
/* No support for C-style ouptut */
@@ -322,7 +322,7 @@ static void probe_jit_limit(void) printf("Unable to retrieve global memory limit for JIT compiler for unprivileged users\n"); break; default: - printf("Global memory limit for JIT compiler for unprivileged users is %d bytes\n", res); + printf("Global memory limit for JIT compiler for unprivileged users is %ld bytes\n", res); } } }
From: Yafang Shao laoar.shao@gmail.com
[ Upstream commit 47e79cbeea4b3891ad476047f4c68543eb51c8e0 ]
After commit e21aa341785c ("bpf: Fix fexit trampoline."), the selector is only used to indicate how many times the bpf trampoline image are updated and been displayed in the trampoline ksym name. After the trampoline is freed, the selector will start from 0 again. So the selector is a useless value to the user. We can remove it.
If the user want to check whether the bpf trampoline image has been updated or not, the user can compare the address. Each time the trampoline image is updated, the address will change consequently. Jiri also pointed out another issue that perf is still using the old name "bpf_trampoline_%lu", so this change can fix the issue in perf.
Fixes: e21aa341785c ("bpf: Fix fexit trampoline.") Signed-off-by: Yafang Shao laoar.shao@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Song Liu song@kernel.org Cc: Jiri Olsa olsajiri@gmail.com Link: https://lore.kernel.org/bpf/ZFvOOlrmHiY9AgXE@krava Link: https://lore.kernel.org/bpf/20230515130849.57502-3-laoar.shao@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/bpf.h | 1 - kernel/bpf/trampoline.c | 11 ++++------- 2 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 5bd6ac04773aa..18397e54bac18 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1082,7 +1082,6 @@ struct bpf_trampoline { int progs_cnt[BPF_TRAMP_MAX]; /* Executable image of trampoline */ struct bpf_tramp_image *cur_image; - u64 selector; struct module *mod; };
diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c index d0ed7d6f5eec5..213d9b3cb06ad 100644 --- a/kernel/bpf/trampoline.c +++ b/kernel/bpf/trampoline.c @@ -372,7 +372,7 @@ static void bpf_tramp_image_put(struct bpf_tramp_image *im) call_rcu_tasks_trace(&im->rcu, __bpf_tramp_image_put_rcu_tasks); }
-static struct bpf_tramp_image *bpf_tramp_image_alloc(u64 key, u32 idx) +static struct bpf_tramp_image *bpf_tramp_image_alloc(u64 key) { struct bpf_tramp_image *im; struct bpf_ksym *ksym; @@ -399,7 +399,7 @@ static struct bpf_tramp_image *bpf_tramp_image_alloc(u64 key, u32 idx)
ksym = &im->ksym; INIT_LIST_HEAD_RCU(&ksym->lnode); - snprintf(ksym->name, KSYM_NAME_LEN, "bpf_trampoline_%llu_%u", key, idx); + snprintf(ksym->name, KSYM_NAME_LEN, "bpf_trampoline_%llu", key); bpf_image_ksym_add(image, ksym); return im;
@@ -429,11 +429,10 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut err = unregister_fentry(tr, tr->cur_image->image); bpf_tramp_image_put(tr->cur_image); tr->cur_image = NULL; - tr->selector = 0; goto out; }
- im = bpf_tramp_image_alloc(tr->key, tr->selector); + im = bpf_tramp_image_alloc(tr->key); if (IS_ERR(im)) { err = PTR_ERR(im); goto out; @@ -470,8 +469,7 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut
set_memory_rox((long)im->image, 1);
- WARN_ON(tr->cur_image && tr->selector == 0); - WARN_ON(!tr->cur_image && tr->selector); + WARN_ON(tr->cur_image && total == 0); if (tr->cur_image) /* progs already running at this address */ err = modify_fentry(tr, tr->cur_image->image, im->image, lock_direct_mutex); @@ -501,7 +499,6 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut if (tr->cur_image) bpf_tramp_image_put(tr->cur_image); tr->cur_image = im; - tr->selector++; out: /* If any error happens, restore previous flags */ if (err)
From: Yafang Shao laoar.shao@gmail.com
[ Upstream commit 108598c39eefbedc9882273ac0df96127a629220 ]
If it fails to attach fentry, the allocated bpf trampoline image will be left in the system. That can be verified by checking /proc/kallsyms.
This meamleak can be verified by a simple bpf program as follows:
SEC("fentry/trap_init") int fentry_run() { return 0; }
It will fail to attach trap_init because this function is freed after kernel init, and then we can find the trampoline image is left in the system by checking /proc/kallsyms.
$ tail /proc/kallsyms ffffffffc0613000 t bpf_trampoline_6442453466_1 [bpf] ffffffffc06c3000 t bpf_trampoline_6442453466_1 [bpf]
$ bpftool btf dump file /sys/kernel/btf/vmlinux | grep "FUNC 'trap_init'" [2522] FUNC 'trap_init' type_id=119 linkage=static
$ echo $((6442453466 & 0x7fffffff)) 2522
Note that there are two left bpf trampoline images, that is because the libbpf will fallback to raw tracepoint if -EINVAL is returned.
Fixes: e21aa341785c ("bpf: Fix fexit trampoline.") Signed-off-by: Yafang Shao laoar.shao@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Song Liu song@kernel.org Cc: Jiri Olsa olsajiri@gmail.com Link: https://lore.kernel.org/bpf/20230515130849.57502-2-laoar.shao@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/trampoline.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c index 213d9b3cb06ad..fecb8d2d885a3 100644 --- a/kernel/bpf/trampoline.c +++ b/kernel/bpf/trampoline.c @@ -279,11 +279,8 @@ bpf_trampoline_get_progs(const struct bpf_trampoline *tr, int *total, bool *ip_a return tlinks; }
-static void __bpf_tramp_image_put_deferred(struct work_struct *work) +static void bpf_tramp_image_free(struct bpf_tramp_image *im) { - struct bpf_tramp_image *im; - - im = container_of(work, struct bpf_tramp_image, work); bpf_image_ksym_del(&im->ksym); bpf_jit_free_exec(im->image); bpf_jit_uncharge_modmem(PAGE_SIZE); @@ -291,6 +288,14 @@ static void __bpf_tramp_image_put_deferred(struct work_struct *work) kfree_rcu(im, rcu); }
+static void __bpf_tramp_image_put_deferred(struct work_struct *work) +{ + struct bpf_tramp_image *im; + + im = container_of(work, struct bpf_tramp_image, work); + bpf_tramp_image_free(im); +} + /* callback, fexit step 3 or fentry step 2 */ static void __bpf_tramp_image_put_rcu(struct rcu_head *rcu) { @@ -465,7 +470,7 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut &tr->func.model, tr->flags, tlinks, tr->func.addr); if (err < 0) - goto out; + goto out_free;
set_memory_rox((long)im->image, 1);
@@ -494,7 +499,7 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut } #endif if (err) - goto out; + goto out_free;
if (tr->cur_image) bpf_tramp_image_put(tr->cur_image); @@ -505,6 +510,10 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut tr->flags = orig_flags; kfree(tlinks); return err; + +out_free: + bpf_tramp_image_free(im); + goto out; }
static enum bpf_tramp_prog_type bpf_attach_type_to_tramp(struct bpf_prog *prog)
From: Alexey Gladkov legion@kernel.org
[ Upstream commit f04a32b2c5b539e3c097cb5c7c1df12a8f4a0cf0 ]
The sign-file utility (from scripts/) is used in prog_tests/verify_pkcs7_sig.c, but the utility should not be called as a test. Executing this utility produces the following error:
selftests: /linux/tools/testing/selftests/bpf: urandom_read ok 16 selftests: /linux/tools/testing/selftests/bpf: urandom_read
selftests: /linux/tools/testing/selftests/bpf: sign-file not ok 17 selftests: /linux/tools/testing/selftests/bpf: sign-file # exit=2
Also, urandom_read is mistakenly used as a test. It does not lead to an error, but should be moved over to TEST_GEN_FILES as well. The empty TEST_CUSTOM_PROGS can then be removed.
Fixes: fc97590668ae ("selftests/bpf: Add test for bpf_verify_pkcs7_signature() kfunc") Signed-off-by: Alexey Gladkov legion@kernel.org Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Roberto Sassu roberto.sassu@huawei.com Acked-by: Stanislav Fomichev sdf@google.com Link: https://lore.kernel.org/bpf/ZEuWFk3QyML9y5QQ@example.org Link: https://lore.kernel.org/bpf/88e3ab23029d726a2703adcf6af8356f7a2d3483.1684316... Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index ad01c9e1ff12b..625eedb84eecc 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -88,8 +88,7 @@ TEST_GEN_PROGS_EXTENDED = test_sock_addr test_skb_cgroup_id_user \ xskxceiver xdp_redirect_multi xdp_synproxy veristat xdp_hw_metadata \ xdp_features
-TEST_CUSTOM_PROGS = $(OUTPUT)/urandom_read $(OUTPUT)/sign-file -TEST_GEN_FILES += liburandom_read.so +TEST_GEN_FILES += liburandom_read.so urandom_read sign-file
# Emit succinct information message describing current building step # $1 - generic step name (e.g., CC, LINK, etc);
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 2715bb11cfff964aa33946847f9527cfbd4874f5 ]
In case of failure, debugfs_create_dir() does not return NULL, but an error pointer. Most incorrect error checks were fixed, but the one in create_regulator() was forgotten.
Fix the remaining error check.
Fixes: 2bf1c45be3b8f3a3 ("regulator: Fix error checking for debugfs_create_dir") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/ee980a108b5854dd8ce3630f8f673e784e057d17.168501305... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 323e8187a98ff..2997a26a9ce3b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1918,7 +1918,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
if (err != -EEXIST) regulator->debugfs = debugfs_create_dir(supply_name, rdev->debugfs); - if (!regulator->debugfs) { + if (IS_ERR(regulator->debugfs)) { rdev_dbg(rdev, "Failed to create debugfs directory\n"); } else { debugfs_create_u32("uA_load", 0444, regulator->debugfs,
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 08880713ceec023dd94d634f1e8902728c385939 ]
If CONFIG_DEBUG_FS is not set:
regulator: Failed to create debugfs directory ... regulator-dummy: Failed to create debugfs directory
As per the comments for debugfs_create_dir(), errors returned by this function should be expected, and ignored:
* If debugfs is not enabled in the kernel, the value -%ENODEV will be * returned. * * NOTE: it's expected that most callers should _ignore_ the errors returned * by this function. Other debugfs functions handle the fact that the "dentry" * passed to them could be an error and they don't crash in that case. * Drivers should generally work fine even if debugfs fails to init anyway.
Adhere to the debugfs spirit, and streamline all operations by: 1. Demoting the importance of the printed error messages to debug level, like is already done in create_regulator(), 2. Further ignoring any returned errors, as by design, all debugfs functions are no-ops when passed an error pointer.
Fixes: 2bf1c45be3b8f3a3 ("regulator: Fix error checking for debugfs_create_dir") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/2f8bb6e113359ddfab7b59e4d4274bd4c06d6d0a.168501305... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/core.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 2997a26a9ce3b..443be7b6e31df 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1918,19 +1918,17 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
if (err != -EEXIST) regulator->debugfs = debugfs_create_dir(supply_name, rdev->debugfs); - if (IS_ERR(regulator->debugfs)) { + if (IS_ERR(regulator->debugfs)) rdev_dbg(rdev, "Failed to create debugfs directory\n"); - } else { - debugfs_create_u32("uA_load", 0444, regulator->debugfs, - ®ulator->uA_load); - debugfs_create_u32("min_uV", 0444, regulator->debugfs, - ®ulator->voltage[PM_SUSPEND_ON].min_uV); - debugfs_create_u32("max_uV", 0444, regulator->debugfs, - ®ulator->voltage[PM_SUSPEND_ON].max_uV); - debugfs_create_file("constraint_flags", 0444, - regulator->debugfs, regulator, - &constraint_flags_fops); - } + + debugfs_create_u32("uA_load", 0444, regulator->debugfs, + ®ulator->uA_load); + debugfs_create_u32("min_uV", 0444, regulator->debugfs, + ®ulator->voltage[PM_SUSPEND_ON].min_uV); + debugfs_create_u32("max_uV", 0444, regulator->debugfs, + ®ulator->voltage[PM_SUSPEND_ON].max_uV); + debugfs_create_file("constraint_flags", 0444, regulator->debugfs, + regulator, &constraint_flags_fops);
/* * Check now if the regulator is an always on regulator - if @@ -5263,10 +5261,8 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) }
rdev->debugfs = debugfs_create_dir(rname, debugfs_root); - if (IS_ERR(rdev->debugfs)) { - rdev_warn(rdev, "Failed to create debugfs directory\n"); - return; - } + if (IS_ERR(rdev->debugfs)) + rdev_dbg(rdev, "Failed to create debugfs directory\n");
debugfs_create_u32("use_count", 0444, rdev->debugfs, &rdev->use_count); @@ -6186,7 +6182,7 @@ static int __init regulator_init(void)
debugfs_root = debugfs_create_dir("regulator", NULL); if (IS_ERR(debugfs_root)) - pr_warn("regulator: Failed to create debugfs directory\n"); + pr_debug("regulator: Failed to create debugfs directory\n");
#ifdef CONFIG_DEBUG_FS debugfs_create_file("supply_map", 0444, debugfs_root, NULL,
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 925244325159824385209e3e0e3f91fa6bf0646c ]
Should spectrum_cs_config() fail, some resources need to be released as already done in the remove function.
While at it, remove a useless and erroneous comment. The probe is spectrum_cs_probe(), not spectrum_cs_attach().
Fixes: 15b99ac17295 ("[PATCH] pcmcia: add return value to _config() functions") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/c0bc0c21c58ca477fc5521607615bafbf2aef8eb.168456773... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intersil/orinoco/spectrum_cs.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/intersil/orinoco/spectrum_cs.c b/drivers/net/wireless/intersil/orinoco/spectrum_cs.c index 291ef97ed45ec..841d623c621ac 100644 --- a/drivers/net/wireless/intersil/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/intersil/orinoco/spectrum_cs.c @@ -157,6 +157,7 @@ spectrum_cs_probe(struct pcmcia_device *link) { struct orinoco_private *priv; struct orinoco_pccard *card; + int ret;
priv = alloc_orinocodev(sizeof(*card), &link->dev, spectrum_cs_hard_reset, @@ -169,8 +170,16 @@ spectrum_cs_probe(struct pcmcia_device *link) card->p_dev = link; link->priv = priv;
- return spectrum_cs_config(link); -} /* spectrum_cs_attach */ + ret = spectrum_cs_config(link); + if (ret) + goto err_free_orinocodev; + + return 0; + +err_free_orinocodev: + free_orinocodev(priv); + return ret; +}
static void spectrum_cs_detach(struct pcmcia_device *link) {
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 67a81d911c01225f426cc6bee2373df044c1a9b7 ]
Should orinoco_cs_config() fail, some resources need to be released as already done in the remove function.
While at it, remove a useless and erroneous comment. The probe is orinoco_cs_probe(), not orinoco_cs_attach().
Fixes: 15b99ac17295 ("[PATCH] pcmcia: add return value to _config() functions") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/e24735ce4d82901d5f7ea08419eea53bfdde3d65.168456828... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intersil/orinoco/orinoco_cs.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_cs.c b/drivers/net/wireless/intersil/orinoco/orinoco_cs.c index a956f965a1e5e..03bfd2482656c 100644 --- a/drivers/net/wireless/intersil/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/intersil/orinoco/orinoco_cs.c @@ -96,6 +96,7 @@ orinoco_cs_probe(struct pcmcia_device *link) { struct orinoco_private *priv; struct orinoco_pccard *card; + int ret;
priv = alloc_orinocodev(sizeof(*card), &link->dev, orinoco_cs_hard_reset, NULL); @@ -107,8 +108,16 @@ orinoco_cs_probe(struct pcmcia_device *link) card->p_dev = link; link->priv = priv;
- return orinoco_cs_config(link); -} /* orinoco_cs_attach */ + ret = orinoco_cs_config(link); + if (ret) + goto err_free_orinocodev; + + return 0; + +err_free_orinocodev: + free_orinocodev(priv); + return ret; +}
static void orinoco_cs_detach(struct pcmcia_device *link) {
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 6b92e4351a29af52c285fe235e6e4d1a75de04b2 ]
Should atmel_config() fail, some resources need to be released as already done in the remove function.
While at it, remove a useless and erroneous comment. The probe is atmel_probe(), not atmel_attach().
Fixes: 15b99ac17295 ("[PATCH] pcmcia: add return value to _config() functions") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/1e65f174607a83348034197fa7d603bab10ba4a9.168456915... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/atmel/atmel_cs.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/atmel/atmel_cs.c b/drivers/net/wireless/atmel/atmel_cs.c index 453bb84cb3386..58bba9875d366 100644 --- a/drivers/net/wireless/atmel/atmel_cs.c +++ b/drivers/net/wireless/atmel/atmel_cs.c @@ -72,6 +72,7 @@ struct local_info { static int atmel_probe(struct pcmcia_device *p_dev) { struct local_info *local; + int ret;
dev_dbg(&p_dev->dev, "atmel_attach()\n");
@@ -82,8 +83,16 @@ static int atmel_probe(struct pcmcia_device *p_dev)
p_dev->priv = local;
- return atmel_config(p_dev); -} /* atmel_attach */ + ret = atmel_config(p_dev); + if (ret) + goto err_free_priv; + + return 0; + +err_free_priv: + kfree(p_dev->priv); + return ret; +}
static void atmel_detach(struct pcmcia_device *link) {
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 391af06a02e7642039ac5f6c4b2c034ab0992b5d ]
Should wl3501_config() fail, some resources need to be released as already done in the remove function.
Fixes: 15b99ac17295 ("[PATCH] pcmcia: add return value to _config() functions") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/7cc9c9316489b7d69b36aeb0edd3123538500b41.168456986... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/wl3501_cs.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 7fb2f95134760..c45c4b7cbbaf1 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -1862,6 +1862,7 @@ static int wl3501_probe(struct pcmcia_device *p_dev) { struct net_device *dev; struct wl3501_card *this; + int ret;
/* The io structure describes IO port mapping */ p_dev->resource[0]->end = 16; @@ -1873,8 +1874,7 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
dev = alloc_etherdev(sizeof(struct wl3501_card)); if (!dev) - goto out_link; - + return -ENOMEM;
dev->netdev_ops = &wl3501_netdev_ops; dev->watchdog_timeo = 5 * HZ; @@ -1887,9 +1887,15 @@ static int wl3501_probe(struct pcmcia_device *p_dev) netif_stop_queue(dev); p_dev->priv = dev;
- return wl3501_config(p_dev); -out_link: - return -ENOMEM; + ret = wl3501_config(p_dev); + if (ret) + goto out_free_etherdev; + + return 0; + +out_free_etherdev: + free_netdev(dev); + return ret; }
static int wl3501_config(struct pcmcia_device *link)
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 4f8d66a9fb2edcd05c1e563456a55a08910bfb37 ]
Should ray_config() fail, some resources need to be released as already done in the remove function.
While at it, remove a useless and erroneous comment. The probe is ray_probe(), not ray_attach().
Fixes: 15b99ac17295 ("[PATCH] pcmcia: add return value to _config() functions") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/8c544d18084f8b37dd108e844f7e79e85ff708ff.168457037... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ray_cs.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 1f57a0055bbd8..38782d4c4694a 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -270,13 +270,14 @@ static int ray_probe(struct pcmcia_device *p_dev) { ray_dev_t *local; struct net_device *dev; + int ret;
dev_dbg(&p_dev->dev, "ray_attach()\n");
/* Allocate space for private device-specific data */ dev = alloc_etherdev(sizeof(ray_dev_t)); if (!dev) - goto fail_alloc_dev; + return -ENOMEM;
local = netdev_priv(dev); local->finder = p_dev; @@ -313,11 +314,16 @@ static int ray_probe(struct pcmcia_device *p_dev) timer_setup(&local->timer, NULL, 0);
this_device = p_dev; - return ray_config(p_dev); + ret = ray_config(p_dev); + if (ret) + goto err_free_dev; + + return 0;
-fail_alloc_dev: - return -ENOMEM; -} /* ray_attach */ +err_free_dev: + free_netdev(dev); + return ret; +}
static void ray_detach(struct pcmcia_device *link) {
From: Fedor Pchelkin pchelkin@ispras.ru
[ Upstream commit 061b0cb9327b80d7a0f63a33e7c3e2a91a71f142 ]
A bad USB device is able to construct a service connection response message with target endpoint being ENDPOINT0 which is reserved for HTC_CTRL_RSVD_SVC and should not be modified to be used for any other services.
Reject such service connection responses.
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.") Reported-by: syzbot+b68fbebe56d8362907e8@syzkaller.appspotmail.com Signed-off-by: Fedor Pchelkin pchelkin@ispras.ru Acked-by: Toke Høiland-Jørgensen toke@toke.dk Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20230516150427.79469-1-pchelkin@ispras.ru Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/htc_hst.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index fe62ff668f757..99667aba289df 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -114,7 +114,13 @@ static void htc_process_conn_rsp(struct htc_target *target,
if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) { epid = svc_rspmsg->endpoint_id; - if (epid < 0 || epid >= ENDPOINT_MAX) + + /* Check that the received epid for the endpoint to attach + * a new service is valid. ENDPOINT0 can't be used here as it + * is already reserved for HTC_CTRL_RSVD_SVC service and thus + * should not be modified. + */ + if (epid <= ENDPOINT0 || epid >= ENDPOINT_MAX) return;
service_id = be16_to_cpu(svc_rspmsg->service_id);
From: Sascha Hauer s.hauer@pengutronix.de
[ Upstream commit 1f1784a59caf3eefd127908a1a3cf224017ff9c7 ]
When receiving more rx packets than the kernel can handle the driver drops the packets and issues an error message. This is bad for two reasons. The logs are flooded with myriads of messages, but then time consumed for printing messages in that critical code path brings down the device. After some time of excessive rx load the driver responds with:
rtw_8822cu 1-1:1.2: failed to get tx report from firmware rtw_8822cu 1-1:1.2: firmware failed to report density after scan rtw_8822cu 1-1:1.2: firmware failed to report density after scan
The device stops working until being replugged.
Fix this by lowering the priority to debug level and also by ratelimiting it.
Fixes: a82dfd33d1237 ("wifi: rtw88: Add common USB chip support") Signed-off-by: Sascha Hauer s.hauer@pengutronix.de Reviewed-by: Ping-Ke Shih pkshih@realtek.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20230524103934.1019096-1-s.hauer@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtw88/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c index 44a5fafb99055..976eafa739a2d 100644 --- a/drivers/net/wireless/realtek/rtw88/usb.c +++ b/drivers/net/wireless/realtek/rtw88/usb.c @@ -535,7 +535,7 @@ static void rtw_usb_rx_handler(struct work_struct *work) }
if (skb_queue_len(&rtwusb->rx_queue) >= RTW_USB_MAX_RXQ_LEN) { - rtw_err(rtwdev, "failed to get rx_queue, overflow\n"); + dev_dbg_ratelimited(rtwdev->dev, "failed to get rx_queue, overflow\n"); dev_kfree_skb_any(skb); continue; }
From: Jesper Dangaard Brouer brouer@redhat.com
[ Upstream commit 60548b825b082cedf89b275c21c28b1e1d030e50 ]
Default samples/pktgen scripts send 60 byte packets as hardware adds 4-bytes FCS checksum, which fulfils minimum Ethernet 64 bytes frame size.
XDP layer will not necessary have access to the 4-bytes FCS checksum.
This leads to bpf_xdp_load_bytes() failing as it tries to copy 64-bytes from an XDP packet that only have 60-bytes available.
Fixes: 772251742262 ("samples/bpf: fixup some tools to be able to support xdp multibuffer") Signed-off-by: Jesper Dangaard Brouer brouer@redhat.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Tariq Toukan tariqt@nvidia.com Link: https://lore.kernel.org/bpf/168545704139.2996228.2516528552939485216.stgit@f... Signed-off-by: Sasha Levin sashal@kernel.org --- samples/bpf/xdp1_kern.c | 2 +- samples/bpf/xdp2_kern.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/samples/bpf/xdp1_kern.c b/samples/bpf/xdp1_kern.c index 0a5c704badd00..d91f27cbcfa99 100644 --- a/samples/bpf/xdp1_kern.c +++ b/samples/bpf/xdp1_kern.c @@ -39,7 +39,7 @@ static int parse_ipv6(void *data, u64 nh_off, void *data_end) return ip6h->nexthdr; }
-#define XDPBUFSIZE 64 +#define XDPBUFSIZE 60 SEC("xdp.frags") int xdp_prog1(struct xdp_md *ctx) { diff --git a/samples/bpf/xdp2_kern.c b/samples/bpf/xdp2_kern.c index 67804ecf7ce37..8bca674451ed1 100644 --- a/samples/bpf/xdp2_kern.c +++ b/samples/bpf/xdp2_kern.c @@ -55,7 +55,7 @@ static int parse_ipv6(void *data, u64 nh_off, void *data_end) return ip6h->nexthdr; }
-#define XDPBUFSIZE 64 +#define XDPBUFSIZE 60 SEC("xdp.frags") int xdp_prog1(struct xdp_md *ctx) {
From: Youghandhar Chintala quic_youghand@quicinc.com
[ Upstream commit 75bd32f5ce94bc365ba0b9b68bcf9de84a391d37 ]
Currently, on WCN3990, the station disconnect after hardware recovery is not working as expected. This is because of setting the IEEE80211_SDATA_DISCONNECT_HW_RESTART flag very early in the hardware recovery process even before the driver invokes ieee80211_hw_restart(). On the contrary, mac80211 expects this flag to be set after ieee80211_hw_restart() is invoked for it to trigger station disconnect.
Set the IEEE80211_SDATA_DISCONNECT_HW_RESTART flag in ath10k_reconfig_complete() instead to fix this.
The other targets are not affected by this change, since the hardware params flag is not set.
Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.3.2.2.c10-00754-QCAHLSWMTPL-1
Fixes: 2c3fc50591ff ("ath10k: Trigger sta disconnect on hardware restart") Signed-off-by: Youghandhar Chintala quic_youghand@quicinc.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20230518101515.3820-1-quic_youghand@quicinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath10k/core.c | 9 --------- drivers/net/wireless/ath/ath10k/mac.c | 7 +++++++ 2 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 5eb131ab916fd..b6052dcc45ebf 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -2504,7 +2504,6 @@ EXPORT_SYMBOL(ath10k_core_napi_sync_disable); static void ath10k_core_restart(struct work_struct *work) { struct ath10k *ar = container_of(work, struct ath10k, restart_work); - struct ath10k_vif *arvif; int ret;
set_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags); @@ -2543,14 +2542,6 @@ static void ath10k_core_restart(struct work_struct *work) ar->state = ATH10K_STATE_RESTARTING; ath10k_halt(ar); ath10k_scan_finish(ar); - if (ar->hw_params.hw_restart_disconnect) { - list_for_each_entry(arvif, &ar->arvifs, list) { - if (arvif->is_up && - arvif->vdev_type == WMI_VDEV_TYPE_STA) - ieee80211_hw_restart_disconnect(arvif->vif); - } - } - ieee80211_restart_hw(ar->hw); break; case ATH10K_STATE_OFF: diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index ec8d5b29bc72c..f0729acdec50a 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -8108,6 +8108,7 @@ static void ath10k_reconfig_complete(struct ieee80211_hw *hw, enum ieee80211_reconfig_type reconfig_type) { struct ath10k *ar = hw->priv; + struct ath10k_vif *arvif;
if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART) return; @@ -8122,6 +8123,12 @@ static void ath10k_reconfig_complete(struct ieee80211_hw *hw, ar->state = ATH10K_STATE_ON; ieee80211_wake_queues(ar->hw); clear_bit(ATH10K_FLAG_RESTARTING, &ar->dev_flags); + if (ar->hw_params.hw_restart_disconnect) { + list_for_each_entry(arvif, &ar->arvifs, list) { + if (arvif->is_up && arvif->vdev_type == WMI_VDEV_TYPE_STA) + ieee80211_hw_restart_disconnect(arvif->vif); + } + } }
mutex_unlock(&ar->conf_mutex);
From: Viktor Malik vmalik@redhat.com
[ Upstream commit edd75c802855271c8610f58a2fc9e54aefc49ce5 ]
Building BPF selftests with custom HOSTCFLAGS yields an error:
# make HOSTCFLAGS="-O2" [...] HOSTCC ./tools/testing/selftests/bpf/tools/build/resolve_btfids/main.o main.c:73:10: fatal error: linux/rbtree.h: No such file or directory 73 | #include <linux/rbtree.h> | ^~~~~~~~~~~~~~~~
The reason is that tools/bpf/resolve_btfids/Makefile passes header include paths by extending HOSTCFLAGS which is overridden by setting HOSTCFLAGS in the make command (because of Makefile rules [1]).
This patch fixes the above problem by passing the include paths via `HOSTCFLAGS_resolve_btfids` which is used by tools/build/Build.include and can be combined with overridding HOSTCFLAGS.
[1] https://www.gnu.org/software/make/manual/html_node/Overriding.html
Fixes: 56a2df7615fa ("tools/resolve_btfids: Compile resolve_btfids as host program") Signed-off-by: Viktor Malik vmalik@redhat.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Acked-by: Jiri Olsa jolsa@kernel.org Link: https://lore.kernel.org/bpf/20230530123352.1308488-1-vmalik@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/bpf/resolve_btfids/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/bpf/resolve_btfids/Makefile b/tools/bpf/resolve_btfids/Makefile index ac548a7baa73e..4b8079f294f65 100644 --- a/tools/bpf/resolve_btfids/Makefile +++ b/tools/bpf/resolve_btfids/Makefile @@ -67,7 +67,7 @@ $(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(LIBBPF_OU LIBELF_FLAGS := $(shell $(HOSTPKG_CONFIG) libelf --cflags 2>/dev/null) LIBELF_LIBS := $(shell $(HOSTPKG_CONFIG) libelf --libs 2>/dev/null || echo -lelf)
-HOSTCFLAGS += -g \ +HOSTCFLAGS_resolve_btfids += -g \ -I$(srctree)/tools/include \ -I$(srctree)/tools/include/uapi \ -I$(LIBBPF_INCLUDE) \ @@ -76,7 +76,7 @@ HOSTCFLAGS += -g \
LIBS = $(LIBELF_LIBS) -lz
-export srctree OUTPUT HOSTCFLAGS Q HOSTCC HOSTLD HOSTAR +export srctree OUTPUT HOSTCFLAGS_resolve_btfids Q HOSTCC HOSTLD HOSTAR include $(srctree)/tools/build/Makefile.include
$(BINARY_IN): fixdep FORCE prepare | $(OUTPUT)
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit ba7af2654e3b7b810c750b3c6106f6f20b81cc88 ]
When adding a new link to a station, this needs to cause a recalculation of the minimum chandef since otherwise we can have a higher bandwidth station connected on that link than the link is operating at. Do the appropriate recalc.
Fixes: cb71f1d136a6 ("wifi: mac80211: add sta link addition/removal") Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20230604120651.377adf3c789a.I91bf28f399e16e6ac1f83... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/sta_info.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 941bda9141faa..2ec9e1ead127e 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -2901,6 +2901,8 @@ int ieee80211_sta_activate_link(struct sta_info *sta, unsigned int link_id) if (!test_sta_flag(sta, WLAN_STA_INSERTED)) goto hash;
+ ieee80211_recalc_min_chandef(sdata, link_id); + /* Ensure the values are updated for the driver, * redone by sta_remove_link on failure. */
From: Jesper Dangaard Brouer brouer@redhat.com
[ Upstream commit 095641817e1bf6aa2560e025e47575188ee3edaf ]
Dan Carpenter found via Smatch static checker, that unsigned 'mtu_lo' is never less than zero.
Variable mtu_lo should have been an 'int', because read_mtu_device_lo() uses minus as error indications.
Fixes: b62eba563229 ("selftests/bpf: Tests using bpf_check_mtu BPF-helper") Reported-by: Dan Carpenter dan.carpenter@linaro.org Signed-off-by: Jesper Dangaard Brouer brouer@redhat.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Simon Horman simon.horman@corigine.com Link: https://lore.kernel.org/bpf/168605104733.3636467.17945947801753092590.stgit@... Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/prog_tests/check_mtu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/check_mtu.c b/tools/testing/selftests/bpf/prog_tests/check_mtu.c index 5338d2ea04603..2a9a30650350e 100644 --- a/tools/testing/selftests/bpf/prog_tests/check_mtu.c +++ b/tools/testing/selftests/bpf/prog_tests/check_mtu.c @@ -183,7 +183,7 @@ static void test_check_mtu_tc(__u32 mtu, __u32 ifindex)
void serial_test_check_mtu(void) { - __u32 mtu_lo; + int mtu_lo;
if (test__start_subtest("bpf_check_mtu XDP-attach")) test_check_mtu_xdp_attach();
From: Marek Vasut marex@denx.de
[ Upstream commit b241e260820b68c09586e8a0ae0fc23c0e3215bd ]
In case WoWlan was never configured during the operation of the system, the hw->wiphy->wowlan_config will be NULL. rsi_config_wowlan() checks whether wowlan_config is non-NULL and if it is not, then WARNs about it. The warning is valid, as during normal operation the rsi_config_wowlan() should only ever be called with non-NULL wowlan_config. In shutdown this rsi_config_wowlan() should only ever be called if WoWlan was configured before by the user.
Add checks for non-NULL wowlan_config into the shutdown hook. While at it, check whether the wiphy is also non-NULL before accessing wowlan_config . Drop the single-use wowlan_config variable, just inline it into function call.
Fixes: 16bbc3eb8372 ("rsi: fix null pointer dereference during rsi_shutdown()") Signed-off-by: Marek Vasut marex@denx.de Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20230527222833.273741-1-marex@denx.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/rsi/rsi_91x_sdio.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c index d09998796ac08..6e33a2563fdbd 100644 --- a/drivers/net/wireless/rsi/rsi_91x_sdio.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c @@ -1463,10 +1463,8 @@ static void rsi_shutdown(struct device *dev)
rsi_dbg(ERR_ZONE, "SDIO Bus shutdown =====>\n");
- if (hw) { - struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config; - - if (rsi_config_wowlan(adapter, wowlan)) + if (hw && hw->wiphy && hw->wiphy->wowlan_config) { + if (rsi_config_wowlan(adapter, hw->wiphy->wowlan_config)) rsi_dbg(ERR_ZONE, "Failed to configure WoWLAN\n"); }
From: Marek Vasut marex@denx.de
[ Upstream commit e74f562328b03fbe9cf438f958464dff3a644dfc ]
It makes no sense to set MMC_PM_KEEP_POWER in shutdown. The flag indicates to the MMC subsystem to keep the slot powered on during suspend, but in shutdown the slot should actually be powered off. Drop this call.
Fixes: 063848c3e155 ("rsi: sdio: Add WOWLAN support for S5 shutdown state") Signed-off-by: Marek Vasut marex@denx.de Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20230527222859.273768-1-marex@denx.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/rsi/rsi_91x_sdio.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c index 6e33a2563fdbd..1911fef3bbad6 100644 --- a/drivers/net/wireless/rsi/rsi_91x_sdio.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c @@ -1479,9 +1479,6 @@ static void rsi_shutdown(struct device *dev) if (sdev->write_fail) rsi_dbg(INFO_ZONE, "###### Device is not ready #######\n");
- if (rsi_set_sdio_pm_caps(adapter)) - rsi_dbg(INFO_ZONE, "Setting power management caps failed\n"); - rsi_dbg(INFO_ZONE, "***** RSI module shut down *****\n"); }
From: Karol Kolacinski karol.kolacinski@intel.com
[ Upstream commit 6e8b2c88fc8cf95ed09de25946b20b7536c88cd5 ]
The ice_ptp_extts_work() and ice_ptp_periodic_work() functions are both scheduled on the same kthread worker, pf.ptp.kworker. The ice_ptp_periodic_work() function sends to the firmware to interact with the PHY, and must block to wait for responses.
This can cause delay in responding to the PFINT_OICR_TSYN_EVNT interrupt cause, ultimately resulting in disruption to processing an input signal of the frequency is high enough. In our testing, even 100 Hz signals get disrupted.
Fix this by instead processing the signal inside the miscellaneous interrupt thread prior to handling Tx timestamps.
Use atomic bits in a new pf->misc_thread bitmap in order to safely communicate which tasks require processing within the ice_misc_intr_thread_fn(). This ensures the communication of desired tasks from the ice_misc_intr() are correctly processed without racing even in the event that the interrupt triggers again before the thread function exits.
Fixes: 172db5f91d5f ("ice: add support for auxiliary input/output pins") Signed-off-by: Karol Kolacinski karol.kolacinski@intel.com Signed-off-by: Jacob Keller jacob.e.keller@intel.com Tested-by: Arpana Arland arpanax.arland@intel.com (A Contingent worker at Intel) Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/ice/ice.h | 7 ++++++ drivers/net/ethernet/intel/ice/ice_main.c | 29 ++++++++++++++++------- drivers/net/ethernet/intel/ice/ice_ptp.c | 12 +++------- drivers/net/ethernet/intel/ice/ice_ptp.h | 4 ++-- 4 files changed, 33 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h index e809249500e18..03c5aecd61402 100644 --- a/drivers/net/ethernet/intel/ice/ice.h +++ b/drivers/net/ethernet/intel/ice/ice.h @@ -515,6 +515,12 @@ enum ice_pf_flags { ICE_PF_FLAGS_NBITS /* must be last */ };
+enum ice_misc_thread_tasks { + ICE_MISC_THREAD_EXTTS_EVENT, + ICE_MISC_THREAD_TX_TSTAMP, + ICE_MISC_THREAD_NBITS /* must be last */ +}; + struct ice_switchdev_info { struct ice_vsi *control_vsi; struct ice_vsi *uplink_vsi; @@ -557,6 +563,7 @@ struct ice_pf { DECLARE_BITMAP(features, ICE_F_MAX); DECLARE_BITMAP(state, ICE_STATE_NBITS); DECLARE_BITMAP(flags, ICE_PF_FLAGS_NBITS); + DECLARE_BITMAP(misc_thread, ICE_MISC_THREAD_NBITS); unsigned long *avail_txqs; /* bitmap to track PF Tx queue usage */ unsigned long *avail_rxqs; /* bitmap to track PF Rx queue usage */ unsigned long serv_tmr_period; diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index 98e8ce743fb2e..65f77ab3fc806 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -3134,20 +3134,28 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
if (oicr & PFINT_OICR_TSYN_TX_M) { ena_mask &= ~PFINT_OICR_TSYN_TX_M; - if (!hw->reset_ongoing) + if (!hw->reset_ongoing) { + set_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread); ret = IRQ_WAKE_THREAD; + } }
if (oicr & PFINT_OICR_TSYN_EVNT_M) { u8 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; u32 gltsyn_stat = rd32(hw, GLTSYN_STAT(tmr_idx));
- /* Save EVENTs from GTSYN register */ - pf->ptp.ext_ts_irq |= gltsyn_stat & (GLTSYN_STAT_EVENT0_M | - GLTSYN_STAT_EVENT1_M | - GLTSYN_STAT_EVENT2_M); ena_mask &= ~PFINT_OICR_TSYN_EVNT_M; - kthread_queue_work(pf->ptp.kworker, &pf->ptp.extts_work); + + if (hw->func_caps.ts_func_info.src_tmr_owned) { + /* Save EVENTs from GLTSYN register */ + pf->ptp.ext_ts_irq |= gltsyn_stat & + (GLTSYN_STAT_EVENT0_M | + GLTSYN_STAT_EVENT1_M | + GLTSYN_STAT_EVENT2_M); + + set_bit(ICE_MISC_THREAD_EXTTS_EVENT, pf->misc_thread); + ret = IRQ_WAKE_THREAD; + } }
#define ICE_AUX_CRIT_ERR (PFINT_OICR_PE_CRITERR_M | PFINT_OICR_HMC_ERR_M | PFINT_OICR_PE_PUSH_M) @@ -3191,8 +3199,13 @@ static irqreturn_t ice_misc_intr_thread_fn(int __always_unused irq, void *data) if (ice_is_reset_in_progress(pf->state)) return IRQ_HANDLED;
- while (!ice_ptp_process_ts(pf)) - usleep_range(50, 100); + if (test_and_clear_bit(ICE_MISC_THREAD_EXTTS_EVENT, pf->misc_thread)) + ice_ptp_extts_event(pf); + + if (test_and_clear_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread)) { + while (!ice_ptp_process_ts(pf)) + usleep_range(50, 100); + }
return IRQ_HANDLED; } diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c index ac6f06f9a2ed0..e8507d09b8488 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c @@ -1458,15 +1458,11 @@ static int ice_ptp_adjfine(struct ptp_clock_info *info, long scaled_ppm) }
/** - * ice_ptp_extts_work - Workqueue task function - * @work: external timestamp work structure - * - * Service for PTP external clock event + * ice_ptp_extts_event - Process PTP external clock event + * @pf: Board private structure */ -static void ice_ptp_extts_work(struct kthread_work *work) +void ice_ptp_extts_event(struct ice_pf *pf) { - struct ice_ptp *ptp = container_of(work, struct ice_ptp, extts_work); - struct ice_pf *pf = container_of(ptp, struct ice_pf, ptp); struct ptp_clock_event event; struct ice_hw *hw = &pf->hw; u8 chan, tmr_idx; @@ -2558,7 +2554,6 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf) ice_ptp_cfg_timestamp(pf, false);
kthread_cancel_delayed_work_sync(&ptp->work); - kthread_cancel_work_sync(&ptp->extts_work);
if (test_bit(ICE_PFR_REQ, pf->state)) return; @@ -2656,7 +2651,6 @@ static int ice_ptp_init_work(struct ice_pf *pf, struct ice_ptp *ptp)
/* Initialize work functions */ kthread_init_delayed_work(&ptp->work, ice_ptp_periodic_work); - kthread_init_work(&ptp->extts_work, ice_ptp_extts_work);
/* Allocate a kworker for handling work required for the ports * connected to the PTP hardware clock. diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h index 9cda2f43e0e56..9f8902c1e743d 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.h +++ b/drivers/net/ethernet/intel/ice/ice_ptp.h @@ -169,7 +169,6 @@ struct ice_ptp_port { * struct ice_ptp - data used for integrating with CONFIG_PTP_1588_CLOCK * @port: data for the PHY port initialization procedure * @work: delayed work function for periodic tasks - * @extts_work: work function for handling external Tx timestamps * @cached_phc_time: a cached copy of the PHC time for timestamp extension * @cached_phc_jiffies: jiffies when cached_phc_time was last updated * @ext_ts_chan: the external timestamp channel in use @@ -190,7 +189,6 @@ struct ice_ptp_port { struct ice_ptp { struct ice_ptp_port port; struct kthread_delayed_work work; - struct kthread_work extts_work; u64 cached_phc_time; unsigned long cached_phc_jiffies; u8 ext_ts_chan; @@ -256,6 +254,7 @@ int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr); void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena); int ice_get_ptp_clock_index(struct ice_pf *pf);
+void ice_ptp_extts_event(struct ice_pf *pf); s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb); bool ice_ptp_process_ts(struct ice_pf *pf);
@@ -284,6 +283,7 @@ static inline int ice_get_ptp_clock_index(struct ice_pf *pf) return -1; }
+static inline void ice_ptp_extts_event(struct ice_pf *pf) { } static inline s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb) {
From: Haifeng Xu haifeng.xu@shopee.com
[ Upstream commit 19ab365762c6cc39dfdee9e13ab0d12fe4b5540d ]
Since commit f079a020ba95 ("selftests: memcg: factor out common parts of memory.{low,min} tests"), the value used in second alloc_anon has changed from 148M to 170M. Because memory.low allows reclaiming page cache in child cgroups, so the memory.current is close to 30M instead of 50M. Therefore, adjust the expected value of parent cgroup.
Link: https://lkml.kernel.org/r/20230522095233.4246-2-haifeng.xu@shopee.com Fixes: f079a020ba95 ("selftests: memcg: factor out common parts of memory.{low,min} tests") Signed-off-by: Haifeng Xu haifeng.xu@shopee.com Cc: Johannes Weiner hannes@cmpxchg.org Cc: Michal Hocko mhocko@kernel.org Cc: Roman Gushchin roman.gushchin@linux.dev Cc: Shakeel Butt shakeelb@google.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/cgroup/test_memcontrol.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testing/selftests/cgroup/test_memcontrol.c index f4f7c0aef702b..a2a90f4bfe9fe 100644 --- a/tools/testing/selftests/cgroup/test_memcontrol.c +++ b/tools/testing/selftests/cgroup/test_memcontrol.c @@ -292,6 +292,7 @@ static int test_memcg_protection(const char *root, bool min) char *children[4] = {NULL}; const char *attribute = min ? "memory.min" : "memory.low"; long c[4]; + long current; int i, attempts; int fd;
@@ -400,7 +401,8 @@ static int test_memcg_protection(const char *root, bool min) goto cleanup; }
- if (!values_close(cg_read_long(parent[1], "memory.current"), MB(50), 3)) + current = min ? MB(50) : MB(30); + if (!values_close(cg_read_long(parent[1], "memory.current"), current, 3)) goto cleanup;
if (!reclaim_until(children[0], MB(10)))
From: Douglas Anderson dianders@chromium.org
[ Upstream commit 5e008df11c55228a86a1bae692cc2002503572c9 ]
Patch series "watchdog/hardlockup: Add the buddy hardlockup detector", v5.
This patch series adds the "buddy" hardlockup detector. In brief, the buddy hardlockup detector can detect hardlockups without arch-level support by having CPUs checkup on a "buddy" CPU periodically.
Given the new design of this patch series, testing all combinations is fairly difficult. I've attempted to make sure that all combinations of CONFIG_ options are good, but it wouldn't surprise me if I missed something. I apologize in advance and I'll do my best to fix any problems that are found.
This patch (of 18):
The real watchdog_update_hrtimer_threshold() is defined in kernel/watchdog_hld.c. That file is included if CONFIG_HARDLOCKUP_DETECTOR_PERF and the function is defined in that file if CONFIG_HARDLOCKUP_CHECK_TIMESTAMP.
The dummy version of the function in "nmi.h" didn't get that quite right. While this doesn't appear to be a huge deal, it's nice to make it consistent.
It doesn't break builds because CHECK_TIMESTAMP is only defined by x86 so others don't get a double definition, and x86 uses perf lockup detector, so it gets the out of line version.
Link: https://lkml.kernel.org/r/20230519101840.v5.18.Ia44852044cdcb074f387e80df6b4... Link: https://lkml.kernel.org/r/20230519101840.v5.1.I8cbb2f4fa740528fcfade4f5439b6... Fixes: 7edaeb6841df ("kernel/watchdog: Prevent false positives with turbo modes") Signed-off-by: Douglas Anderson dianders@chromium.org Reviewed-by: Nicholas Piggin npiggin@gmail.com Reviewed-by: Petr Mladek pmladek@suse.com Cc: Andi Kleen ak@linux.intel.com Cc: Catalin Marinas catalin.marinas@arm.com Cc: Chen-Yu Tsai wens@csie.org Cc: Christophe Leroy christophe.leroy@csgroup.eu Cc: Daniel Thompson daniel.thompson@linaro.org Cc: "David S. Miller" davem@davemloft.net Cc: Guenter Roeck groeck@chromium.org Cc: Ian Rogers irogers@google.com Cc: Lecopzer Chen lecopzer.chen@mediatek.com Cc: Marc Zyngier maz@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Masayoshi Mizuma msys.mizuma@gmail.com Cc: Matthias Kaehlcke mka@chromium.org Cc: Michael Ellerman mpe@ellerman.id.au Cc: Pingfan Liu kernelfans@gmail.com Cc: Randy Dunlap rdunlap@infradead.org Cc: "Ravi V. Shankar" ravi.v.shankar@intel.com Cc: Ricardo Neri ricardo.neri@intel.com Cc: Stephane Eranian eranian@google.com Cc: Stephen Boyd swboyd@chromium.org Cc: Sumit Garg sumit.garg@linaro.org Cc: Tzung-Bi Shih tzungbi@chromium.org Cc: Will Deacon will@kernel.org Cc: Colin Cross ccross@android.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/nmi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/nmi.h b/include/linux/nmi.h index 048c0b9aa623d..771d77b62bc10 100644 --- a/include/linux/nmi.h +++ b/include/linux/nmi.h @@ -197,7 +197,7 @@ u64 hw_nmi_get_sample_period(int watchdog_thresh); #endif
#if defined(CONFIG_HARDLOCKUP_CHECK_TIMESTAMP) && \ - defined(CONFIG_HARDLOCKUP_DETECTOR) + defined(CONFIG_HARDLOCKUP_DETECTOR_PERF) void watchdog_update_hrtimer_threshold(u64 period); #else static inline void watchdog_update_hrtimer_threshold(u64 period) { }
From: Douglas Anderson dianders@chromium.org
[ Upstream commit 4379e59fe5665cfda737e45b8bf2f05321ef049c ]
Currently, in the watchdog_overflow_callback() we first check to see if the watchdog had been touched and _then_ we handle the workaround for turbo mode. This order should be reversed.
Specifically, "touching" the hardlockup detector's watchdog should avoid lockups being detected for one period that should be roughly the same regardless of whether we're running turbo or not. That means that we should do the extra accounting for turbo _before_ we look at (and clear) the global indicating that we've been touched.
NOTE: this fix is made based on code inspection. I am not aware of any reports where the old code would have generated false positives. That being said, this order seems more correct and also makes it easier down the line to share code with the "buddy" hardlockup detector.
Link: https://lkml.kernel.org/r/20230519101840.v5.2.I843b0d1de3e096ba111a179f3adb1... Fixes: 7edaeb6841df ("kernel/watchdog: Prevent false positives with turbo modes") Signed-off-by: Douglas Anderson dianders@chromium.org Cc: Andi Kleen ak@linux.intel.com Cc: Catalin Marinas catalin.marinas@arm.com Cc: Chen-Yu Tsai wens@csie.org Cc: Christophe Leroy christophe.leroy@csgroup.eu Cc: Colin Cross ccross@android.com Cc: Daniel Thompson daniel.thompson@linaro.org Cc: "David S. Miller" davem@davemloft.net Cc: Guenter Roeck groeck@chromium.org Cc: Ian Rogers irogers@google.com Cc: Lecopzer Chen lecopzer.chen@mediatek.com Cc: Marc Zyngier maz@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Masayoshi Mizuma msys.mizuma@gmail.com Cc: Matthias Kaehlcke mka@chromium.org Cc: Michael Ellerman mpe@ellerman.id.au Cc: Nicholas Piggin npiggin@gmail.com Cc: Petr Mladek pmladek@suse.com Cc: Pingfan Liu kernelfans@gmail.com Cc: Randy Dunlap rdunlap@infradead.org Cc: "Ravi V. Shankar" ravi.v.shankar@intel.com Cc: Ricardo Neri ricardo.neri@intel.com Cc: Stephane Eranian eranian@google.com Cc: Stephen Boyd swboyd@chromium.org Cc: Sumit Garg sumit.garg@linaro.org Cc: Tzung-Bi Shih tzungbi@chromium.org Cc: Will Deacon will@kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/watchdog_hld.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/kernel/watchdog_hld.c b/kernel/watchdog_hld.c index 247bf0b1582ca..1e8a49dc956e2 100644 --- a/kernel/watchdog_hld.c +++ b/kernel/watchdog_hld.c @@ -114,14 +114,14 @@ static void watchdog_overflow_callback(struct perf_event *event, /* Ensure the watchdog never gets throttled */ event->hw.interrupts = 0;
+ if (!watchdog_check_timestamp()) + return; + if (__this_cpu_read(watchdog_nmi_touch) == true) { __this_cpu_write(watchdog_nmi_touch, false); return; }
- if (!watchdog_check_timestamp()) - return; - /* check for a hardlockup * This is done by making sure our timer interrupt * is incrementing. The timer interrupt should have
From: Zhen Lei thunder.leizhen@huawei.com
[ Upstream commit 1cba6c4309f03de570202c46f03df3f73a0d4c82 ]
Patch series "kexec: enable kexec_crash_size to support two crash kernel regions".
When crashkernel=X fails to reserve region under 4G, it will fall back to reserve region above 4G and a region of the default size will also be reserved under 4G. Unfortunately, /sys/kernel/kexec_crash_size only supports one crash kernel region now, the user cannot sense the low memory reserved by reading /sys/kernel/kexec_crash_size. Also, low memory cannot be freed by writing this file.
For example: resource_size(crashk_res) = 512M resource_size(crashk_low_res) = 256M
The result of 'cat /sys/kernel/kexec_crash_size' is 512M, but it should be 768M. When we execute 'echo 0 > /sys/kernel/kexec_crash_size', the size of crashk_res becomes 0 and resource_size(crashk_low_res) is still 256 MB, which is incorrect.
Since crashk_res manages the memory with high address and crashk_low_res manages the memory with low address, crashk_low_res is shrunken only when all crashk_res is shrunken. And because when there is only one crash kernel region, crashk_res is always used. Therefore, if all crashk_res is shrunken and crashk_low_res still exists, swap them.
This patch (of 6):
If the value of parameter 'new_size' is in the semi-open and semi-closed interval (crashk_res.end - KEXEC_CRASH_MEM_ALIGN + 1, crashk_res.end], the calculation result of ram_res is:
ram_res->start = crashk_res.end + 1 ram_res->end = crashk_res.end
The operation of insert_resource() fails, and ram_res is not added to iomem_resource. As a result, the memory of the control block ram_res is leaked.
In fact, on all architectures, the start address and size of crashk_res are already aligned by KEXEC_CRASH_MEM_ALIGN. Therefore, we do not need to round up crashk_res.start again. Instead, we should round up 'new_size' in advance.
Link: https://lkml.kernel.org/r/20230527123439.772-1-thunder.leizhen@huawei.com Link: https://lkml.kernel.org/r/20230527123439.772-2-thunder.leizhen@huawei.com Fixes: 6480e5a09237 ("kdump: add missing RAM resource in crash_shrink_memory()") Fixes: 06a7f711246b ("kexec: premit reduction of the reserved memory size") Signed-off-by: Zhen Lei thunder.leizhen@huawei.com Acked-by: Baoquan He bhe@redhat.com Cc: Cong Wang amwang@redhat.com Cc: Eric W. Biederman ebiederm@xmission.com Cc: Michael Holzheu holzheu@linux.vnet.ibm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/kexec_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index 3d578c6fefee3..22acee18195a5 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -1122,6 +1122,7 @@ int crash_shrink_memory(unsigned long new_size) start = crashk_res.start; end = crashk_res.end; old_size = (end == 0) ? 0 : end - start + 1; + new_size = roundup(new_size, KEXEC_CRASH_MEM_ALIGN); if (new_size >= old_size) { ret = (new_size == old_size) ? 0 : -EINVAL; goto unlock; @@ -1133,9 +1134,7 @@ int crash_shrink_memory(unsigned long new_size) goto unlock; }
- start = roundup(start, KEXEC_CRASH_MEM_ALIGN); - end = roundup(start + new_size, KEXEC_CRASH_MEM_ALIGN); - + end = start + new_size; crash_free_reserved_phys_range(end, crashk_res.end);
if ((start == end) && (crashk_res.parent != NULL))
From: Douglas Anderson dianders@chromium.org
[ Upstream commit a3332b7aad346b14770797e03ddd02ebdb14db41 ]
When I boot a kukui-kodama board, I see an ugly warning in my kernel log: mtk-msdc 11240000.mmc: error -ENXIO: IRQ sdio_wakeup not found
It's pretty normal not to have an "sdio_wakeup" IRQ defined. In fact, no device trees in mainline seem to have it. Let's use the platform_get_irq_byname_optional() to avoid the error message.
Fixes: 527f36f5efa4 ("mmc: mediatek: add support for SDIO eint wakup IRQ") Signed-off-by: Douglas Anderson dianders@chromium.org Reviewed-by: Matthias Brugger matthias.bgg@gmail.com Link: https://lore.kernel.org/r/20230510064434.1.I935404c5396e6bf952e99bb7ffb744c6... Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/mtk-sd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index 9785ec91654f7..97c42aacaf346 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c @@ -2707,7 +2707,7 @@ static int msdc_drv_probe(struct platform_device *pdev)
/* Support for SDIO eint irq ? */ if ((mmc->pm_caps & MMC_PM_WAKE_SDIO_IRQ) && (mmc->pm_caps & MMC_PM_KEEP_POWER)) { - host->eint_irq = platform_get_irq_byname(pdev, "sdio_wakeup"); + host->eint_irq = platform_get_irq_byname_optional(pdev, "sdio_wakeup"); if (host->eint_irq > 0) { host->pins_eint = pinctrl_lookup_state(host->pinctrl, "state_eint"); if (IS_ERR(host->pins_eint)) {
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 434587df9f7fd68575f99a889cc5f2efc2eaee5e ]
There are no other files referencing this function, apparently it was left global to avoid an 'unused function' warning when the only caller is left out. With a 'W=1' build, it causes a 'missing prototype' warning though:
drivers/memstick/host/r592.c:47:13: error: no previous prototype for 'memstick_debug_get_tpc_name' [-Werror=missing-prototypes]
Annotate the function as 'static __maybe_unused' to avoid both problems.
Fixes: 926341250102 ("memstick: add driver for Ricoh R5C592 card reader") Signed-off-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/r/20230516202714.560929-1-arnd@kernel.org Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/memstick/host/r592.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c index 42bfc46842b82..461f5ffd02bc1 100644 --- a/drivers/memstick/host/r592.c +++ b/drivers/memstick/host/r592.c @@ -44,12 +44,10 @@ static const char *tpc_names[] = { * memstick_debug_get_tpc_name - debug helper that returns string for * a TPC number */ -const char *memstick_debug_get_tpc_name(int tpc) +static __maybe_unused const char *memstick_debug_get_tpc_name(int tpc) { return tpc_names[tpc-1]; } -EXPORT_SYMBOL(memstick_debug_get_tpc_name); -
/* Read a register*/ static inline u32 r592_read_reg(struct r592_device *dev, int address)
From: Eduard Zingerman eddyz87@gmail.com
[ Upstream commit b23ed4d74c4d583b5f621ee4c776699442833554 ]
Dan Carpenter reported invalid check for calloc() result in test_verifier.c:get_xlated_program():
./tools/testing/selftests/bpf/test_verifier.c:1365 get_xlated_program() warn: variable dereferenced before check 'buf' (see line 1364)
./tools/testing/selftests/bpf/test_verifier.c 1363 *cnt = xlated_prog_len / buf_element_size; 1364 *buf = calloc(*cnt, buf_element_size); 1365 if (!buf) {
This should be if (!*buf) {
1366 perror("can't allocate xlated program buffer"); 1367 return -ENOMEM;
This commit refactors the get_xlated_program() to avoid using double pointer type.
Fixes: 933ff53191eb ("selftests/bpf: specify expected instructions in test_verifier tests") Reported-by: Dan Carpenter dan.carpenter@linaro.org Signed-off-by: Eduard Zingerman eddyz87@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Closes: https://lore.kernel.org/bpf/ZH7u0hEGVB4MjGZq@moroto/ Link: https://lore.kernel.org/bpf/20230609221637.2631800-1-eddyz87@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/test_verifier.c | 24 +++++++++++---------- 1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index 8b9949bb833d7..2e9bdf2e91351 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c @@ -1232,45 +1232,46 @@ static bool cmp_str_seq(const char *log, const char *exp) return true; }
-static int get_xlated_program(int fd_prog, struct bpf_insn **buf, int *cnt) +static struct bpf_insn *get_xlated_program(int fd_prog, int *cnt) { + __u32 buf_element_size = sizeof(struct bpf_insn); struct bpf_prog_info info = {}; __u32 info_len = sizeof(info); __u32 xlated_prog_len; - __u32 buf_element_size = sizeof(struct bpf_insn); + struct bpf_insn *buf;
if (bpf_prog_get_info_by_fd(fd_prog, &info, &info_len)) { perror("bpf_prog_get_info_by_fd failed"); - return -1; + return NULL; }
xlated_prog_len = info.xlated_prog_len; if (xlated_prog_len % buf_element_size) { printf("Program length %d is not multiple of %d\n", xlated_prog_len, buf_element_size); - return -1; + return NULL; }
*cnt = xlated_prog_len / buf_element_size; - *buf = calloc(*cnt, buf_element_size); + buf = calloc(*cnt, buf_element_size); if (!buf) { perror("can't allocate xlated program buffer"); - return -ENOMEM; + return NULL; }
bzero(&info, sizeof(info)); info.xlated_prog_len = xlated_prog_len; - info.xlated_prog_insns = (__u64)(unsigned long)*buf; + info.xlated_prog_insns = (__u64)(unsigned long)buf; if (bpf_prog_get_info_by_fd(fd_prog, &info, &info_len)) { perror("second bpf_prog_get_info_by_fd failed"); goto out_free_buf; }
- return 0; + return buf;
out_free_buf: - free(*buf); - return -1; + free(buf); + return NULL; }
static bool is_null_insn(struct bpf_insn *insn) @@ -1403,7 +1404,8 @@ static bool check_xlated_program(struct bpf_test *test, int fd_prog) if (!check_expected && !check_unexpected) goto out;
- if (get_xlated_program(fd_prog, &buf, &cnt)) { + buf = get_xlated_program(fd_prog, &cnt); + if (!buf) { printf("FAIL: can't get xlated program\n"); result = false; goto out;
From: Remi Pommarel repk@triplefau.lt
[ Upstream commit 75086cc6dee046e3fbb3dba148b376d8802f83bc ]
On EDMA capable hardware, ath9k_txq_list_has_key() can enter infinite loop if it is called while all txq_fifos have packets that use different key that the one we are looking for. Fix it by exiting the loop if all txq_fifos have been checked already.
Because this loop is called under spin_lock_bh() (see ath_txq_lock) it causes the following rcu stall:
rcu: INFO: rcu_sched self-detected stall on CPU ath10k_pci 0000:01:00.0: failed to read temperature -11 rcu: 1-....: (5254 ticks this GP) idle=189/1/0x4000000000000002 softirq=8442983/8442984 fqs=2579 (t=5257 jiffies g=17983297 q=334) Task dump for CPU 1: task:hostapd state:R running task stack: 0 pid: 297 ppid: 289 flags:0x0000000a Call trace: dump_backtrace+0x0/0x170 show_stack+0x1c/0x24 sched_show_task+0x140/0x170 dump_cpu_task+0x48/0x54 rcu_dump_cpu_stacks+0xf0/0x134 rcu_sched_clock_irq+0x8d8/0x9fc update_process_times+0xa0/0xec tick_sched_timer+0x5c/0xd0 __hrtimer_run_queues+0x154/0x320 hrtimer_interrupt+0x120/0x2f0 arch_timer_handler_virt+0x38/0x44 handle_percpu_devid_irq+0x9c/0x1e0 handle_domain_irq+0x64/0x90 gic_handle_irq+0x78/0xb0 call_on_irq_stack+0x28/0x38 do_interrupt_handler+0x54/0x5c el1_interrupt+0x2c/0x4c el1h_64_irq_handler+0x14/0x1c el1h_64_irq+0x74/0x78 ath9k_txq_has_key+0x1bc/0x250 [ath9k] ath9k_set_key+0x1cc/0x3dc [ath9k] drv_set_key+0x78/0x170 ieee80211_key_replace+0x564/0x6cc ieee80211_key_link+0x174/0x220 ieee80211_add_key+0x11c/0x300 nl80211_new_key+0x12c/0x330 genl_family_rcv_msg_doit+0xbc/0x11c genl_rcv_msg+0xd8/0x1c4 netlink_rcv_skb+0x40/0x100 genl_rcv+0x3c/0x50 netlink_unicast+0x1ec/0x2c0 netlink_sendmsg+0x198/0x3c0 ____sys_sendmsg+0x210/0x250 ___sys_sendmsg+0x78/0xc4 __sys_sendmsg+0x4c/0x90 __arm64_sys_sendmsg+0x28/0x30 invoke_syscall.constprop.0+0x60/0x100 do_el0_svc+0x48/0xd0 el0_svc+0x14/0x50 el0t_64_sync_handler+0xa8/0xb0 el0t_64_sync+0x158/0x15c
This rcu stall is hard to reproduce as is, but changing ATH_TXFIFO_DEPTH from 8 to 2 makes it reasonably easy to reproduce.
Fixes: ca2848022c12 ("ath9k: Postpone key cache entry deletion for TXQ frames reference it") Signed-off-by: Remi Pommarel repk@triplefau.lt Tested-by: Nicolas Escande nico.escande@gmail.com Acked-by: Toke Høiland-Jørgensen toke@toke.dk Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20230609093744.1985-1-repk@triplefau.lt Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a4197c14f0a92..7f9f06ea8a05f 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -850,7 +850,7 @@ static bool ath9k_txq_list_has_key(struct list_head *txq_list, u32 keyix) static bool ath9k_txq_has_key(struct ath_softc *sc, u32 keyix) { struct ath_hw *ah = sc->sc_ah; - int i; + int i, j; struct ath_txq *txq; bool key_in_use = false;
@@ -868,8 +868,9 @@ static bool ath9k_txq_has_key(struct ath_softc *sc, u32 keyix) if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { int idx = txq->txq_tailidx;
- while (!key_in_use && - !list_empty(&txq->txq_fifo[idx])) { + for (j = 0; !key_in_use && + !list_empty(&txq->txq_fifo[idx]) && + j < ATH_TXFIFO_DEPTH; j++) { key_in_use = ath9k_txq_list_has_key( &txq->txq_fifo[idx], keyix); INCR(idx, ATH_TXFIFO_DEPTH);
From: Ilan Peer ilan.peer@intel.com
[ Upstream commit 4cacadc0dbd8013e6161aa8843d8e9d8ad435b47 ]
The entry should be a read only one and not a write only one. Fix it.
Fixes: 3d9011029227 ("wifi: mac80211: implement link switching") Signed-off-by: Ilan Peer ilan.peer@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20230611121219.c75316990411.I1565a7fcba8a37f83efff... [remove x16 change since it doesn't work yet] Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/debugfs_netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 0bac9af3ca966..371add9061f1f 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -691,7 +691,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata) DEBUGFS_ADD_MODE(uapsd_queues, 0600); DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600); DEBUGFS_ADD_MODE(tdls_wider_bw, 0600); - DEBUGFS_ADD_MODE(valid_links, 0200); + DEBUGFS_ADD_MODE(valid_links, 0400); DEBUGFS_ADD_MODE(active_links, 0600); }
From: Edwin Peer edwin.peer@broadcom.com
[ Upstream commit fa0e21fa44438a0e856d42224bfa24641d37b979 ]
This filter already exists for excluding IPv6 SNMP stats. Extend its definition to also exclude IFLA_VF_INFO stats in RTM_GETLINK.
This patch constitutes a partial fix for a netlink attribute nesting overflow bug in IFLA_VFINFO_LIST. By excluding the stats when the requester doesn't need them, the truncation of the VF list is avoided.
While it was technically only the stats added in commit c5a9f6f0ab40 ("net/core: Add drop counters to VF statistics") breaking the camel's back, the appreciable size of the stats data should never have been included without due consideration for the maximum number of VFs supported by PCI.
Fixes: 3b766cd83232 ("net/core: Add reading VF statistics through the PF netdevice") Fixes: c5a9f6f0ab40 ("net/core: Add drop counters to VF statistics") Signed-off-by: Edwin Peer edwin.peer@broadcom.com Cc: Edwin Peer espeer@gmail.com Signed-off-by: Gal Pressman gal@nvidia.com Link: https://lore.kernel.org/r/20230611105108.122586-1-gal@nvidia.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/rtnetlink.c | 96 +++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 45 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index f235cc6832767..bbecc31a2703f 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -958,24 +958,27 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev, nla_total_size(sizeof(struct ifla_vf_rate)) + nla_total_size(sizeof(struct ifla_vf_link_state)) + nla_total_size(sizeof(struct ifla_vf_rss_query_en)) + - nla_total_size(0) + /* nest IFLA_VF_STATS */ - /* IFLA_VF_STATS_RX_PACKETS */ - nla_total_size_64bit(sizeof(__u64)) + - /* IFLA_VF_STATS_TX_PACKETS */ - nla_total_size_64bit(sizeof(__u64)) + - /* IFLA_VF_STATS_RX_BYTES */ - nla_total_size_64bit(sizeof(__u64)) + - /* IFLA_VF_STATS_TX_BYTES */ - nla_total_size_64bit(sizeof(__u64)) + - /* IFLA_VF_STATS_BROADCAST */ - nla_total_size_64bit(sizeof(__u64)) + - /* IFLA_VF_STATS_MULTICAST */ - nla_total_size_64bit(sizeof(__u64)) + - /* IFLA_VF_STATS_RX_DROPPED */ - nla_total_size_64bit(sizeof(__u64)) + - /* IFLA_VF_STATS_TX_DROPPED */ - nla_total_size_64bit(sizeof(__u64)) + nla_total_size(sizeof(struct ifla_vf_trust))); + if (~ext_filter_mask & RTEXT_FILTER_SKIP_STATS) { + size += num_vfs * + (nla_total_size(0) + /* nest IFLA_VF_STATS */ + /* IFLA_VF_STATS_RX_PACKETS */ + nla_total_size_64bit(sizeof(__u64)) + + /* IFLA_VF_STATS_TX_PACKETS */ + nla_total_size_64bit(sizeof(__u64)) + + /* IFLA_VF_STATS_RX_BYTES */ + nla_total_size_64bit(sizeof(__u64)) + + /* IFLA_VF_STATS_TX_BYTES */ + nla_total_size_64bit(sizeof(__u64)) + + /* IFLA_VF_STATS_BROADCAST */ + nla_total_size_64bit(sizeof(__u64)) + + /* IFLA_VF_STATS_MULTICAST */ + nla_total_size_64bit(sizeof(__u64)) + + /* IFLA_VF_STATS_RX_DROPPED */ + nla_total_size_64bit(sizeof(__u64)) + + /* IFLA_VF_STATS_TX_DROPPED */ + nla_total_size_64bit(sizeof(__u64))); + } return size; } else return 0; @@ -1267,7 +1270,8 @@ static noinline_for_stack int rtnl_fill_stats(struct sk_buff *skb, static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb, struct net_device *dev, int vfs_num, - struct nlattr *vfinfo) + struct nlattr *vfinfo, + u32 ext_filter_mask) { struct ifla_vf_rss_query_en vf_rss_query_en; struct nlattr *vf, *vfstats, *vfvlanlist; @@ -1373,33 +1377,35 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb, goto nla_put_vf_failure; } nla_nest_end(skb, vfvlanlist); - memset(&vf_stats, 0, sizeof(vf_stats)); - if (dev->netdev_ops->ndo_get_vf_stats) - dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num, - &vf_stats); - vfstats = nla_nest_start_noflag(skb, IFLA_VF_STATS); - if (!vfstats) - goto nla_put_vf_failure; - if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS, - vf_stats.rx_packets, IFLA_VF_STATS_PAD) || - nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS, - vf_stats.tx_packets, IFLA_VF_STATS_PAD) || - nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES, - vf_stats.rx_bytes, IFLA_VF_STATS_PAD) || - nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES, - vf_stats.tx_bytes, IFLA_VF_STATS_PAD) || - nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST, - vf_stats.broadcast, IFLA_VF_STATS_PAD) || - nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST, - vf_stats.multicast, IFLA_VF_STATS_PAD) || - nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_DROPPED, - vf_stats.rx_dropped, IFLA_VF_STATS_PAD) || - nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_DROPPED, - vf_stats.tx_dropped, IFLA_VF_STATS_PAD)) { - nla_nest_cancel(skb, vfstats); - goto nla_put_vf_failure; + if (~ext_filter_mask & RTEXT_FILTER_SKIP_STATS) { + memset(&vf_stats, 0, sizeof(vf_stats)); + if (dev->netdev_ops->ndo_get_vf_stats) + dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num, + &vf_stats); + vfstats = nla_nest_start_noflag(skb, IFLA_VF_STATS); + if (!vfstats) + goto nla_put_vf_failure; + if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS, + vf_stats.rx_packets, IFLA_VF_STATS_PAD) || + nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS, + vf_stats.tx_packets, IFLA_VF_STATS_PAD) || + nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES, + vf_stats.rx_bytes, IFLA_VF_STATS_PAD) || + nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES, + vf_stats.tx_bytes, IFLA_VF_STATS_PAD) || + nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST, + vf_stats.broadcast, IFLA_VF_STATS_PAD) || + nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST, + vf_stats.multicast, IFLA_VF_STATS_PAD) || + nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_DROPPED, + vf_stats.rx_dropped, IFLA_VF_STATS_PAD) || + nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_DROPPED, + vf_stats.tx_dropped, IFLA_VF_STATS_PAD)) { + nla_nest_cancel(skb, vfstats); + goto nla_put_vf_failure; + } + nla_nest_end(skb, vfstats); } - nla_nest_end(skb, vfstats); nla_nest_end(skb, vf); return 0;
@@ -1432,7 +1438,7 @@ static noinline_for_stack int rtnl_fill_vf(struct sk_buff *skb, return -EMSGSIZE;
for (i = 0; i < num_vfs; i++) { - if (rtnl_fill_vfinfo(skb, dev, i, vfinfo)) + if (rtnl_fill_vfinfo(skb, dev, i, vfinfo, ext_filter_mask)) return -EMSGSIZE; }
From: Jiasheng Jiang jiasheng@iscas.ac.cn
[ Upstream commit 16e0077e14a73866e9b0f4a6bf4ad3d4a5cb0f2a ]
Add check for ioremap() and return the error if it fails in order to guarantee the success of ioremap(), same as in ath11k_qmi_load_file_target_mem().
Fixes: 6ac04bdc5edb ("ath11k: Use reserved host DDR addresses from DT for PCI devices") Signed-off-by: Jiasheng Jiang jiasheng@iscas.ac.cn Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20230608022858.27405-1-jiasheng@iscas.ac.cn Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/qmi.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index ab923e24b0a9c..2328b9447cf1b 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -2058,6 +2058,9 @@ static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab) ab->qmi.target_mem[idx].iaddr = ioremap(ab->qmi.target_mem[idx].paddr, ab->qmi.target_mem[i].size); + if (!ab->qmi.target_mem[idx].iaddr) + return -EIO; + ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size; host_ddr_sz = ab->qmi.target_mem[i].size; ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type; @@ -2083,6 +2086,8 @@ static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab) ab->qmi.target_mem[idx].iaddr = ioremap(ab->qmi.target_mem[idx].paddr, ab->qmi.target_mem[i].size); + if (!ab->qmi.target_mem[idx].iaddr) + return -EIO; } else { ab->qmi.target_mem[idx].paddr = ATH11K_QMI_CALDB_ADDRESS;
From: Ziyang Huang hzyitc@outlook.com
[ Upstream commit 469ddb20cae61cad9c4f208a4c8682305905a511 ]
Without this patch, the IPQ5018 WiFi will fail and print the following logs:
[ 11.033179] ath11k c000000.wifi: unsupported device type 7 [ 11.033223] ath11k: probe of c000000.wifi failed with error -95
Fixes: 25edca7bb18a ("wifi: ath11k: add ipq5018 device support") Signed-off-by: Ziyang Huang hzyitc@outlook.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/TYZPR01MB5556D7AA10ABEDDDD2D8F39EC953A@TYZPR01MB55... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/ahb.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c index 5cbba9a8b6ba9..396548e57022f 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.c +++ b/drivers/net/wireless/ath/ath11k/ahb.c @@ -1127,6 +1127,7 @@ static int ath11k_ahb_probe(struct platform_device *pdev) switch (hw_rev) { case ATH11K_HW_IPQ8074: case ATH11K_HW_IPQ6018_HW10: + case ATH11K_HW_IPQ5018_HW10: hif_ops = &ath11k_ahb_hif_ops_ipq8074; pci_ops = NULL; break;
From: Ziyang Huang hzyitc@outlook.com
[ Upstream commit 80c5390e1f5e5b16d820512265530ef26073d8e0 ]
Restart is required after cold boot calibration on IPQ5018. Otherwise, we get the following exception:
[ 14.412829] qcom-q6-mpd cd00000.remoteproc: fatal error received: err_smem_ver.2.1: [ 14.412829] QC Image Version : QC_IMAGE_VERSION_STRING=WLAN.HK.2.6.0.1-00974-QCAHKSWPL_SILICONZ-1 [ 14.412829] Image Variant : IMAGE_VARIANT_STRING=5018.wlanfw2.map_spr_spr_evalQ [ 14.412829] DALSysLogEvent.c:174 Assertion 0 failed param0 :zero,param1 :zero,param2 :zero [ 14.412829] Thread ID : 0x00000048 Thread name : WLAN RT0 Process ID : 0x00000001 Process name :wlan0 [ 14.412829] [ 14.412829] Registers: [ 14.412829] SP : 0x4c81c120 [ 14.412829] FP : 0x4c81c138 [ 14.412829] PC : 0xb022c590 [ 14.412829] SSR : 0x00000000 [ 14.412829] BADVA : 0x00000000 [ 14.412829] LR : 0xb0008490 [ 14.412829] [ 14.412829] StackDump [ 14.412829] from:0x4c81c120 [ 14.412829] to: 0x00000000: [ 14.412829] [ 14.463006] remoteproc remoteproc0: crash detected in cd00000.remoteproc: type fatal error
Fixes: 8dfe875aa24a ("wifi: ath11k: update hw params for IPQ5018") Signed-off-by: Ziyang Huang hzyitc@outlook.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/TYZPR01MB55566969818BD4B49E770445C953A@TYZPR01MB55... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 75fdbe4ef83a4..329f0957f9f09 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -671,6 +671,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hal_params = &ath11k_hw_hal_params_ipq8074, .single_pdev_only = false, .cold_boot_calib = true, + .cbcal_restart_fw = true, .fix_l1ss = true, .supports_dynamic_smps_6ghz = false, .alloc_cacheable_memory = true,
From: Ziyang Huang hzyitc@outlook.com
[ Upstream commit ce282d8de71f07f0056ea319541141152c65f552 ]
During sending data after clients connected, hw_ops->get_ring_selector() will be called. But for IPQ5018, this member isn't set, and the following NULL pointer exception will be occurred:
[ 38.840478] 8<--- cut here --- [ 38.840517] Unable to handle kernel NULL pointer dereference at virtual address 00000000 ... [ 38.923161] PC is at 0x0 [ 38.927930] LR is at ath11k_dp_tx+0x70/0x730 [ath11k] ... [ 39.063264] Process hostapd (pid: 1034, stack limit = 0x801ceb3d) [ 39.068994] Stack: (0x856a9a68 to 0x856aa000) ... [ 39.438467] [<7f323804>] (ath11k_dp_tx [ath11k]) from [<7f314e6c>] (ath11k_mac_op_tx+0x80/0x190 [ath11k]) [ 39.446607] [<7f314e6c>] (ath11k_mac_op_tx [ath11k]) from [<7f17dbe0>] (ieee80211_handle_wake_tx_queue+0x7c/0xc0 [mac80211]) [ 39.456162] [<7f17dbe0>] (ieee80211_handle_wake_tx_queue [mac80211]) from [<7f174450>] (ieee80211_probereq_get+0x584/0x704 [mac80211]) [ 39.467443] [<7f174450>] (ieee80211_probereq_get [mac80211]) from [<7f178c40>] (ieee80211_tx_prepare_skb+0x1f8/0x248 [mac80211]) [ 39.479334] [<7f178c40>] (ieee80211_tx_prepare_skb [mac80211]) from [<7f179e28>] (__ieee80211_subif_start_xmit+0x32c/0x3d4 [mac80211]) [ 39.491053] [<7f179e28>] (__ieee80211_subif_start_xmit [mac80211]) from [<7f17af08>] (ieee80211_tx_control_port+0x19c/0x288 [mac80211]) [ 39.502946] [<7f17af08>] (ieee80211_tx_control_port [mac80211]) from [<7f0fc704>] (nl80211_tx_control_port+0x174/0x1d4 [cfg80211]) [ 39.515017] [<7f0fc704>] (nl80211_tx_control_port [cfg80211]) from [<808ceac4>] (genl_rcv_msg+0x154/0x340) [ 39.526814] [<808ceac4>] (genl_rcv_msg) from [<808cdb74>] (netlink_rcv_skb+0xb8/0x11c) [ 39.536446] [<808cdb74>] (netlink_rcv_skb) from [<808ce1d0>] (genl_rcv+0x28/0x34) [ 39.544344] [<808ce1d0>] (genl_rcv) from [<808cd234>] (netlink_unicast+0x174/0x274) [ 39.551895] [<808cd234>] (netlink_unicast) from [<808cd510>] (netlink_sendmsg+0x1dc/0x440) [ 39.559362] [<808cd510>] (netlink_sendmsg) from [<808596e0>] (____sys_sendmsg+0x1a8/0x1fc) [ 39.567697] [<808596e0>] (____sys_sendmsg) from [<8085b1a8>] (___sys_sendmsg+0xa4/0xdc) [ 39.575941] [<8085b1a8>] (___sys_sendmsg) from [<8085b310>] (sys_sendmsg+0x44/0x74) [ 39.583841] [<8085b310>] (sys_sendmsg) from [<80300060>] (ret_fast_syscall+0x0/0x40) ... [ 39.620734] Code: bad PC value [ 39.625869] ---[ end trace 8aef983ad3cbc032 ]---
Fixes: ba60f2793d3a ("wifi: ath11k: initialize hw_ops for IPQ5018") Signed-off-by: Ziyang Huang hzyitc@outlook.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/TYZPR01MB5556D6E3F63EAB5129D11420C953A@TYZPR01MB55... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath11k/hw.c b/drivers/net/wireless/ath/ath11k/hw.c index ab8f0ccacc6be..727e6a785bb98 100644 --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c @@ -1165,7 +1165,7 @@ const struct ath11k_hw_ops ipq5018_ops = { .mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid, .rx_desc_mac_addr2_valid = ath11k_hw_ipq9074_rx_desc_mac_addr2_valid, .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2, - + .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, };
#define ATH11K_TX_RING_MASK_0 BIT(0)
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 96fb6f47db24a712d650b0a9b9074873f273fb0e ]
In mac80211, it's required that we pull from TXQs by calling ieee80211_tx_dequeue() only with softirqs disabled. However, in iwl_mvm_queue_state_change() we're often called with them enabled, e.g. from flush if anything was flushed, triggering a mac80211 warning.
Fix that by disabling the softirqs across the TX call.
Fixes: cfbc6c4c5b91 ("iwlwifi: mvm: support mac80211 TXQs model") Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20230614123446.0feef7fa81db.I4dd62542d955b40dd8f0a... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 9711841bb4564..3d91293cc250d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -1697,8 +1697,11 @@ static void iwl_mvm_queue_state_change(struct iwl_op_mode *op_mode, else set_bit(IWL_MVM_TXQ_STATE_STOP_FULL, &mvmtxq->state);
- if (start && mvmsta->sta_state != IEEE80211_STA_NOTEXIST) + if (start && mvmsta->sta_state != IEEE80211_STA_NOTEXIST) { + local_bh_disable(); iwl_mvm_mac_itxq_xmit(mvm->hw, txq); + local_bh_enable(); + } }
out:
From: Anjaneyulu pagadala.yesu.anjaneyulu@intel.com
[ Upstream commit 1902f1953b8ba100ee8705cb8a6f1a9795550eca ]
rxq can be NULL only when trans_pcie->rxq is NULL and entry->entry is zero. For the case when entry->entry is not equal to 0, rxq won't be NULL even if trans_pcie->rxq is NULL. Modify checker to check for trans_pcie->rxq.
Fixes: abc599efa67b ("iwlwifi: pcie: don't crash when rx queues aren't allocated in interrupt") Signed-off-by: Anjaneyulu pagadala.yesu.anjaneyulu@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20230614123446.5a5eb3889a4a.I375a1d58f16b48cd2044e... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 9c9f87fe83777..b455e981faa1f 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -1620,14 +1620,14 @@ irqreturn_t iwl_pcie_irq_rx_msix_handler(int irq, void *dev_id) struct msix_entry *entry = dev_id; struct iwl_trans_pcie *trans_pcie = iwl_pcie_get_trans_pcie(entry); struct iwl_trans *trans = trans_pcie->trans; - struct iwl_rxq *rxq = &trans_pcie->rxq[entry->entry]; + struct iwl_rxq *rxq;
trace_iwlwifi_dev_irq_msix(trans->dev, entry, false, 0, 0);
if (WARN_ON(entry->entry >= trans->num_rx_queues)) return IRQ_NONE;
- if (!rxq) { + if (!trans_pcie->rxq) { if (net_ratelimit()) IWL_ERR(trans, "[%d] Got MSI-X interrupt before we have Rx queues\n", @@ -1635,6 +1635,7 @@ irqreturn_t iwl_pcie_irq_rx_msix_handler(int irq, void *dev_id) return IRQ_NONE; }
+ rxq = &trans_pcie->rxq[entry->entry]; lock_map_acquire(&trans->sync_cmd_lockdep_map); IWL_DEBUG_ISR(trans, "[%d] Got interrupt\n", entry->entry);
From: Nicolas Cavallari nicolas.cavallari@green-communications.fr
[ Upstream commit 6e21e7b8cd897193cee3c2649640efceb3004ba5 ]
In mesh mode, ieee80211_chandef_he_6ghz_oper() is called by mesh_matches_local() for every received mesh beacon.
On a 6 GHz mesh of a HE-only phy, this spams that the hardware does not have EHT capabilities, even if the received mesh beacon does not have an EHT element.
Unlike HE, not supporting EHT in the 6 GHz band is not an error so do not print anything in this case.
Fixes: 5dca295dd767 ("mac80211: Add initial support for EHT and 320 MHz channels")
Signed-off-by: Nicolas Cavallari nicolas.cavallari@green-communications.fr Reviewed-by: Simon Horman simon.horman@corigine.com Link: https://lore.kernel.org/r/20230614132648.28995-1-nicolas.cavallari@green-com... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/util.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 1a0d38cd46337..ce25d14db4d28 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -3707,10 +3707,8 @@ bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata, }
eht_cap = ieee80211_get_eht_iftype_cap(sband, iftype); - if (!eht_cap) { - sdata_info(sdata, "Missing iftype sband data/EHT cap"); + if (!eht_cap) eht_oper = NULL; - }
he_6ghz_oper = ieee80211_he_6ghz_oper(he_oper);
From: Benjamin Berg benjamin.berg@intel.com
[ Upstream commit dfd9aa3e7a456d57b18021d66472ab7ff8373ab7 ]
The cfg80211_gen_new_ie function merges the IEs using inheritance rules. Rewrite this function to fix issues around inheritance rules. In particular, vendor elements do not require any special handling, as they are either all inherited or overridden by the subprofile. Also, add fragmentation handling as this may be needed in some cases.
This also changes the function to not require making a copy. The new version could be optimized a bit by explicitly tracking which IEs have been handled already rather than looking that up again every time.
Note that a small behavioural change is the removal of the SSID special handling. This should be fine for the MBSSID element, as the SSID must be included in the subelement.
Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") Signed-off-by: Benjamin Berg benjamin.berg@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20230616094949.bc6152e146db.I2b5f3bc45085e1901e5b5... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/wireless/scan.c | 213 ++++++++++++++++++++++++++------------------ 1 file changed, 124 insertions(+), 89 deletions(-)
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index b3829ed844f84..bb1b2cd73dd21 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -259,117 +259,152 @@ bool cfg80211_is_element_inherited(const struct element *elem, } EXPORT_SYMBOL(cfg80211_is_element_inherited);
-static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen, - const u8 *subelement, size_t subie_len, - u8 *new_ie, gfp_t gfp) +static size_t cfg80211_copy_elem_with_frags(const struct element *elem, + const u8 *ie, size_t ie_len, + u8 **pos, u8 *buf, size_t buf_len) { - u8 *pos, *tmp; - const u8 *tmp_old, *tmp_new; - const struct element *non_inherit_elem; - u8 *sub_copy; + if (WARN_ON((u8 *)elem < ie || elem->data > ie + ie_len || + elem->data + elem->datalen > ie + ie_len)) + return 0;
- /* copy subelement as we need to change its content to - * mark an ie after it is processed. - */ - sub_copy = kmemdup(subelement, subie_len, gfp); - if (!sub_copy) + if (elem->datalen + 2 > buf + buf_len - *pos) return 0;
- pos = &new_ie[0]; + memcpy(*pos, elem, elem->datalen + 2); + *pos += elem->datalen + 2;
- /* set new ssid */ - tmp_new = cfg80211_find_ie(WLAN_EID_SSID, sub_copy, subie_len); - if (tmp_new) { - memcpy(pos, tmp_new, tmp_new[1] + 2); - pos += (tmp_new[1] + 2); + /* Finish if it is not fragmented */ + if (elem->datalen != 255) + return *pos - buf; + + ie_len = ie + ie_len - elem->data - elem->datalen; + ie = (const u8 *)elem->data + elem->datalen; + + for_each_element(elem, ie, ie_len) { + if (elem->id != WLAN_EID_FRAGMENT) + break; + + if (elem->datalen + 2 > buf + buf_len - *pos) + return 0; + + memcpy(*pos, elem, elem->datalen + 2); + *pos += elem->datalen + 2; + + if (elem->datalen != 255) + break; }
- /* get non inheritance list if exists */ - non_inherit_elem = - cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE, - sub_copy, subie_len); + return *pos - buf; +}
- /* go through IEs in ie (skip SSID) and subelement, - * merge them into new_ie +static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen, + const u8 *subie, size_t subie_len, + u8 *new_ie, size_t new_ie_len) +{ + const struct element *non_inherit_elem, *parent, *sub; + u8 *pos = new_ie; + u8 id, ext_id; + unsigned int match_len; + + non_inherit_elem = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE, + subie, subie_len); + + /* We copy the elements one by one from the parent to the generated + * elements. + * If they are not inherited (included in subie or in the non + * inheritance element), then we copy all occurrences the first time + * we see this element type. */ - tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen); - tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie; - - while (tmp_old + 2 - ie <= ielen && - tmp_old + tmp_old[1] + 2 - ie <= ielen) { - if (tmp_old[0] == 0) { - tmp_old++; + for_each_element(parent, ie, ielen) { + if (parent->id == WLAN_EID_FRAGMENT) continue; + + if (parent->id == WLAN_EID_EXTENSION) { + if (parent->datalen < 1) + continue; + + id = WLAN_EID_EXTENSION; + ext_id = parent->data[0]; + match_len = 1; + } else { + id = parent->id; + match_len = 0; }
- if (tmp_old[0] == WLAN_EID_EXTENSION) - tmp = (u8 *)cfg80211_find_ext_ie(tmp_old[2], sub_copy, - subie_len); - else - tmp = (u8 *)cfg80211_find_ie(tmp_old[0], sub_copy, - subie_len); + /* Find first occurrence in subie */ + sub = cfg80211_find_elem_match(id, subie, subie_len, + &ext_id, match_len, 0);
- if (!tmp) { - const struct element *old_elem = (void *)tmp_old; + /* Copy from parent if not in subie and inherited */ + if (!sub && + cfg80211_is_element_inherited(parent, non_inherit_elem)) { + if (!cfg80211_copy_elem_with_frags(parent, + ie, ielen, + &pos, new_ie, + new_ie_len)) + return 0;
- /* ie in old ie but not in subelement */ - if (cfg80211_is_element_inherited(old_elem, - non_inherit_elem)) { - memcpy(pos, tmp_old, tmp_old[1] + 2); - pos += tmp_old[1] + 2; - } - } else { - /* ie in transmitting ie also in subelement, - * copy from subelement and flag the ie in subelement - * as copied (by setting eid field to WLAN_EID_SSID, - * which is skipped anyway). - * For vendor ie, compare OUI + type + subType to - * determine if they are the same ie. - */ - if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) { - if (tmp_old[1] >= 5 && tmp[1] >= 5 && - !memcmp(tmp_old + 2, tmp + 2, 5)) { - /* same vendor ie, copy from - * subelement - */ - memcpy(pos, tmp, tmp[1] + 2); - pos += tmp[1] + 2; - tmp[0] = WLAN_EID_SSID; - } else { - memcpy(pos, tmp_old, tmp_old[1] + 2); - pos += tmp_old[1] + 2; - } - } else { - /* copy ie from subelement into new ie */ - memcpy(pos, tmp, tmp[1] + 2); - pos += tmp[1] + 2; - tmp[0] = WLAN_EID_SSID; - } + continue; }
- if (tmp_old + tmp_old[1] + 2 - ie == ielen) - break; + /* Already copied if an earlier element had the same type */ + if (cfg80211_find_elem_match(id, ie, (u8 *)parent - ie, + &ext_id, match_len, 0)) + continue;
- tmp_old += tmp_old[1] + 2; + /* Not inheriting, copy all similar elements from subie */ + while (sub) { + if (!cfg80211_copy_elem_with_frags(sub, + subie, subie_len, + &pos, new_ie, + new_ie_len)) + return 0; + + sub = cfg80211_find_elem_match(id, + sub->data + sub->datalen, + subie_len + subie - + (sub->data + + sub->datalen), + &ext_id, match_len, 0); + } }
- /* go through subelement again to check if there is any ie not - * copied to new ie, skip ssid, capability, bssid-index ie + /* The above misses elements that are included in subie but not in the + * parent, so do a pass over subie and append those. + * Skip the non-tx BSSID caps and non-inheritance element. */ - tmp_new = sub_copy; - while (tmp_new + 2 - sub_copy <= subie_len && - tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) { - if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP || - tmp_new[0] == WLAN_EID_SSID)) { - memcpy(pos, tmp_new, tmp_new[1] + 2); - pos += tmp_new[1] + 2; + for_each_element(sub, subie, subie_len) { + if (sub->id == WLAN_EID_NON_TX_BSSID_CAP) + continue; + + if (sub->id == WLAN_EID_FRAGMENT) + continue; + + if (sub->id == WLAN_EID_EXTENSION) { + if (sub->datalen < 1) + continue; + + id = WLAN_EID_EXTENSION; + ext_id = sub->data[0]; + match_len = 1; + + if (ext_id == WLAN_EID_EXT_NON_INHERITANCE) + continue; + } else { + id = sub->id; + match_len = 0; } - if (tmp_new + tmp_new[1] + 2 - sub_copy == subie_len) - break; - tmp_new += tmp_new[1] + 2; + + /* Processed if one was included in the parent */ + if (cfg80211_find_elem_match(id, ie, ielen, + &ext_id, match_len, 0)) + continue; + + if (!cfg80211_copy_elem_with_frags(sub, subie, subie_len, + &pos, new_ie, new_ie_len)) + return 0; }
- kfree(sub_copy); return pos - new_ie; }
@@ -2217,7 +2252,7 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, new_ie_len = cfg80211_gen_new_ie(ie, ielen, profile, profile_len, new_ie, - gfp); + IEEE80211_MAX_DATA_LEN); if (!new_ie_len) continue;
From: Benjamin Berg benjamin.berg@intel.com
[ Upstream commit 39432f8a3752a87a53fd8d5e51824a43aaae5cab ]
The removed code ran for any BSS that was not included in the MBSSID element in order to update it. However, instead of using the correct inheritance rules, it would simply copy the elements from the transmitting AP. The result is that we would report incorrect elements in this case.
After some discussions, it seems that there are likely not even APs actually using this feature. Either way, removing the code decreases complexity and makes the cfg80211 behaviour more correct.
Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") Signed-off-by: Benjamin Berg benjamin.berg@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20230616094949.cfd6d8db1f26.Ia1044902b86cd7d366400... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/wireless/scan.c | 154 ++++---------------------------------------- 1 file changed, 11 insertions(+), 143 deletions(-)
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index bb1b2cd73dd21..68f9b6f7bf584 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -2301,118 +2301,6 @@ cfg80211_inform_bss_data(struct wiphy *wiphy, } EXPORT_SYMBOL(cfg80211_inform_bss_data);
-static void -cfg80211_parse_mbssid_frame_data(struct wiphy *wiphy, - struct cfg80211_inform_bss *data, - struct ieee80211_mgmt *mgmt, size_t len, - struct cfg80211_non_tx_bss *non_tx_data, - gfp_t gfp) -{ - enum cfg80211_bss_frame_type ftype; - const u8 *ie = mgmt->u.probe_resp.variable; - size_t ielen = len - offsetof(struct ieee80211_mgmt, - u.probe_resp.variable); - - ftype = ieee80211_is_beacon(mgmt->frame_control) ? - CFG80211_BSS_FTYPE_BEACON : CFG80211_BSS_FTYPE_PRESP; - - cfg80211_parse_mbssid_data(wiphy, data, ftype, mgmt->bssid, - le64_to_cpu(mgmt->u.probe_resp.timestamp), - le16_to_cpu(mgmt->u.probe_resp.beacon_int), - ie, ielen, non_tx_data, gfp); -} - -static void -cfg80211_update_notlisted_nontrans(struct wiphy *wiphy, - struct cfg80211_bss *nontrans_bss, - struct ieee80211_mgmt *mgmt, size_t len) -{ - u8 *ie, *new_ie, *pos; - const struct element *nontrans_ssid; - const u8 *trans_ssid, *mbssid; - size_t ielen = len - offsetof(struct ieee80211_mgmt, - u.probe_resp.variable); - size_t new_ie_len; - struct cfg80211_bss_ies *new_ies; - const struct cfg80211_bss_ies *old; - size_t cpy_len; - - lockdep_assert_held(&wiphy_to_rdev(wiphy)->bss_lock); - - ie = mgmt->u.probe_resp.variable; - - new_ie_len = ielen; - trans_ssid = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen); - if (!trans_ssid) - return; - new_ie_len -= trans_ssid[1]; - mbssid = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen); - /* - * It's not valid to have the MBSSID element before SSID - * ignore if that happens - the code below assumes it is - * after (while copying things inbetween). - */ - if (!mbssid || mbssid < trans_ssid) - return; - new_ie_len -= mbssid[1]; - - nontrans_ssid = ieee80211_bss_get_elem(nontrans_bss, WLAN_EID_SSID); - if (!nontrans_ssid) - return; - - new_ie_len += nontrans_ssid->datalen; - - /* generate new ie for nontrans BSS - * 1. replace SSID with nontrans BSS' SSID - * 2. skip MBSSID IE - */ - new_ie = kzalloc(new_ie_len, GFP_ATOMIC); - if (!new_ie) - return; - - new_ies = kzalloc(sizeof(*new_ies) + new_ie_len, GFP_ATOMIC); - if (!new_ies) - goto out_free; - - pos = new_ie; - - /* copy the nontransmitted SSID */ - cpy_len = nontrans_ssid->datalen + 2; - memcpy(pos, nontrans_ssid, cpy_len); - pos += cpy_len; - /* copy the IEs between SSID and MBSSID */ - cpy_len = trans_ssid[1] + 2; - memcpy(pos, (trans_ssid + cpy_len), (mbssid - (trans_ssid + cpy_len))); - pos += (mbssid - (trans_ssid + cpy_len)); - /* copy the IEs after MBSSID */ - cpy_len = mbssid[1] + 2; - memcpy(pos, mbssid + cpy_len, ((ie + ielen) - (mbssid + cpy_len))); - - /* update ie */ - new_ies->len = new_ie_len; - new_ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); - new_ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control); - memcpy(new_ies->data, new_ie, new_ie_len); - if (ieee80211_is_probe_resp(mgmt->frame_control)) { - old = rcu_access_pointer(nontrans_bss->proberesp_ies); - rcu_assign_pointer(nontrans_bss->proberesp_ies, new_ies); - rcu_assign_pointer(nontrans_bss->ies, new_ies); - if (old) - kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); - } else { - old = rcu_access_pointer(nontrans_bss->beacon_ies); - rcu_assign_pointer(nontrans_bss->beacon_ies, new_ies); - cfg80211_update_hidden_bsses(bss_from_pub(nontrans_bss), - new_ies, old); - rcu_assign_pointer(nontrans_bss->ies, new_ies); - if (old) - kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); - } - -out_free: - kfree(new_ie); -} - /* cfg80211_inform_bss_width_frame helper */ static struct cfg80211_bss * cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy, @@ -2554,51 +2442,31 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy, struct ieee80211_mgmt *mgmt, size_t len, gfp_t gfp) { - struct cfg80211_bss *res, *tmp_bss; + struct cfg80211_bss *res; const u8 *ie = mgmt->u.probe_resp.variable; - const struct cfg80211_bss_ies *ies1, *ies2; size_t ielen = len - offsetof(struct ieee80211_mgmt, u.probe_resp.variable); + enum cfg80211_bss_frame_type ftype; struct cfg80211_non_tx_bss non_tx_data = {};
res = cfg80211_inform_single_bss_frame_data(wiphy, data, mgmt, len, gfp); + if (!res) + return NULL;
/* don't do any further MBSSID handling for S1G */ if (ieee80211_is_s1g_beacon(mgmt->frame_control)) return res;
- if (!res || !wiphy->support_mbssid || - !cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID, ie, ielen)) - return res; - if (wiphy->support_only_he_mbssid && - !cfg80211_find_ext_elem(WLAN_EID_EXT_HE_CAPABILITY, ie, ielen)) - return res; - + ftype = ieee80211_is_beacon(mgmt->frame_control) ? + CFG80211_BSS_FTYPE_BEACON : CFG80211_BSS_FTYPE_PRESP; non_tx_data.tx_bss = res; - /* process each non-transmitting bss */ - cfg80211_parse_mbssid_frame_data(wiphy, data, mgmt, len, - &non_tx_data, gfp); - - spin_lock_bh(&wiphy_to_rdev(wiphy)->bss_lock);
- /* check if the res has other nontransmitting bss which is not - * in MBSSID IE - */ - ies1 = rcu_access_pointer(res->ies); - - /* go through nontrans_list, if the timestamp of the BSS is - * earlier than the timestamp of the transmitting BSS then - * update it - */ - list_for_each_entry(tmp_bss, &res->nontrans_list, - nontrans_list) { - ies2 = rcu_access_pointer(tmp_bss->ies); - if (ies2->tsf < ies1->tsf) - cfg80211_update_notlisted_nontrans(wiphy, tmp_bss, - mgmt, len); - } - spin_unlock_bh(&wiphy_to_rdev(wiphy)->bss_lock); + /* process each non-transmitting bss */ + cfg80211_parse_mbssid_data(wiphy, data, ftype, mgmt->bssid, + le64_to_cpu(mgmt->u.probe_resp.timestamp), + le16_to_cpu(mgmt->u.probe_resp.beacon_int), + ie, ielen, &non_tx_data, gfp);
return res; }
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit e8c2af660ba0790afd14d5cbc2fd05c6dc85e207 ]
Since regulatory disconnect was added, OCB and NAN interface types were added, which made it completely unusable for any driver that allowed OCB/NAN. Add OCB/NAN (though NAN doesn't do anything, we don't have any info) and also remove all the logic that opts out, so it won't be broken again if/when new interface types are added.
Fixes: 6e0bd6c35b02 ("cfg80211: 802.11p OCB mode handling") Fixes: cb3b7d87652a ("cfg80211: add start / stop NAN commands") Signed-off-by: Johannes Berg johannes.berg@intel.com Link: https://lore.kernel.org/r/20230616222844.2794d1625a26.I8e78a3789a29e6149447b... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/regulatory.h | 13 +------------ net/wireless/core.c | 16 ---------------- net/wireless/reg.c | 14 ++++++++++---- 3 files changed, 11 insertions(+), 32 deletions(-)
diff --git a/include/net/regulatory.h b/include/net/regulatory.h index 896191f420d50..b2cb4a9eb04dc 100644 --- a/include/net/regulatory.h +++ b/include/net/regulatory.h @@ -140,17 +140,6 @@ struct regulatory_request { * otherwise initiating radiation is not allowed. This will enable the * relaxations enabled under the CFG80211_REG_RELAX_NO_IR configuration * option - * @REGULATORY_IGNORE_STALE_KICKOFF: the regulatory core will _not_ make sure - * all interfaces on this wiphy reside on allowed channels. If this flag - * is not set, upon a regdomain change, the interfaces are given a grace - * period (currently 60 seconds) to disconnect or move to an allowed - * channel. Interfaces on forbidden channels are forcibly disconnected. - * Currently these types of interfaces are supported for enforcement: - * NL80211_IFTYPE_ADHOC, NL80211_IFTYPE_STATION, NL80211_IFTYPE_AP, - * NL80211_IFTYPE_AP_VLAN, NL80211_IFTYPE_MONITOR, - * NL80211_IFTYPE_P2P_CLIENT, NL80211_IFTYPE_P2P_GO, - * NL80211_IFTYPE_P2P_DEVICE. The flag will be set by default if a device - * includes any modes unsupported for enforcement checking. * @REGULATORY_WIPHY_SELF_MANAGED: for devices that employ wiphy-specific * regdom management. These devices will ignore all regdom changes not * originating from their own wiphy. @@ -177,7 +166,7 @@ enum ieee80211_regulatory_flags { REGULATORY_COUNTRY_IE_FOLLOW_POWER = BIT(3), REGULATORY_COUNTRY_IE_IGNORE = BIT(4), REGULATORY_ENABLE_RELAX_NO_IR = BIT(5), - REGULATORY_IGNORE_STALE_KICKOFF = BIT(6), + /* reuse bit 6 next time */ REGULATORY_WIPHY_SELF_MANAGED = BIT(7), };
diff --git a/net/wireless/core.c b/net/wireless/core.c index b3ec9eaec36b3..609b79fe4a748 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -721,22 +721,6 @@ int wiphy_register(struct wiphy *wiphy) return -EINVAL; }
- /* - * if a wiphy has unsupported modes for regulatory channel enforcement, - * opt-out of enforcement checking - */ - if (wiphy->interface_modes & ~(BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_P2P_CLIENT) | - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_MESH_POINT) | - BIT(NL80211_IFTYPE_P2P_GO) | - BIT(NL80211_IFTYPE_ADHOC) | - BIT(NL80211_IFTYPE_P2P_DEVICE) | - BIT(NL80211_IFTYPE_NAN) | - BIT(NL80211_IFTYPE_AP_VLAN) | - BIT(NL80211_IFTYPE_MONITOR))) - wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF; - if (WARN_ON((wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) && (wiphy->regulatory_flags & (REGULATORY_CUSTOM_REG | diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 26f11e4746c05..c8a1b925413b3 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -2391,9 +2391,17 @@ static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev) case NL80211_IFTYPE_P2P_DEVICE: /* no enforcement required */ break; + case NL80211_IFTYPE_OCB: + if (!wdev->u.ocb.chandef.chan) + continue; + chandef = wdev->u.ocb.chandef; + break; + case NL80211_IFTYPE_NAN: + /* we have no info, but NAN is also pretty universal */ + continue; default: /* others not implemented for now */ - WARN_ON(1); + WARN_ON_ONCE(1); break; }
@@ -2452,9 +2460,7 @@ static void reg_check_chans_work(struct work_struct *work) rtnl_lock();
list_for_each_entry(rdev, &cfg80211_rdev_list, list) - if (!(rdev->wiphy.regulatory_flags & - REGULATORY_IGNORE_STALE_KICKOFF)) - reg_leave_invalid_chans(&rdev->wiphy); + reg_leave_invalid_chans(&rdev->wiphy);
rtnl_unlock(); }
From: Ilan Peer ilan.peer@intel.com
[ Upstream commit ce6e1f600b0cfc563a7d607de702262a58cd835d ]
The common information length is found in the first octet of the common information.
Fixes: 0f48b8b88aa9 ("wifi: ieee80211: add definitions for multi-link element") Signed-off-by: Ilan Peer ilan.peer@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20230618214435.3c7ed4817338.I42ef706cb827b4dade6e4... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/ieee80211.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 2463bdd2a382d..1e25c9060225c 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -4592,15 +4592,12 @@ static inline u8 ieee80211_mle_common_size(const u8 *data) case IEEE80211_ML_CONTROL_TYPE_BASIC: case IEEE80211_ML_CONTROL_TYPE_PREQ: case IEEE80211_ML_CONTROL_TYPE_TDLS: + case IEEE80211_ML_CONTROL_TYPE_RECONF: /* * The length is the first octet pointed by mle->variable so no * need to add anything */ break; - case IEEE80211_ML_CONTROL_TYPE_RECONF: - if (control & IEEE80211_MLC_RECONF_PRES_MLD_MAC_ADDR) - common += ETH_ALEN; - return common; case IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS: if (control & IEEE80211_MLC_PRIO_ACCESS_PRES_AP_MLD_MAC_ADDR) common += ETH_ALEN;
From: Marek Vasut marex@denx.de
[ Upstream commit c467c8f081859d4f4ca4eee4fba54bb5d85d6c97 ]
This microSD card never clears Flush Cache bit after cache flush has been started in sd_flush_cache(). This leads e.g. to failure to mount file system. Add a quirk which disables the SD cache for this specific card from specific manufacturing date of 11/2019, since on newer dated cards from 05/2023 the cache flush works correctly.
Fixes: 08ebf903af57 ("mmc: core: Fixup support for writeback-cache for eMMC and SD") Signed-off-by: Marek Vasut marex@denx.de Link: https://lore.kernel.org/r/20230620102713.7701-1-marex@denx.de Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/core/card.h | 30 +++++++++++++++++++++++------- drivers/mmc/core/quirks.h | 13 +++++++++++++ drivers/mmc/core/sd.c | 2 +- include/linux/mmc/card.h | 1 + 4 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h index cfdd1ff40b865..4edf9057fa79d 100644 --- a/drivers/mmc/core/card.h +++ b/drivers/mmc/core/card.h @@ -53,6 +53,10 @@ struct mmc_fixup { unsigned int manfid; unsigned short oemid;
+ /* Manufacturing date */ + unsigned short year; + unsigned char month; + /* SDIO-specific fields. You can use SDIO_ANY_ID here of course */ u16 cis_vendor, cis_device;
@@ -68,6 +72,8 @@ struct mmc_fixup {
#define CID_MANFID_ANY (-1u) #define CID_OEMID_ANY ((unsigned short) -1) +#define CID_YEAR_ANY ((unsigned short) -1) +#define CID_MONTH_ANY ((unsigned char) -1) #define CID_NAME_ANY (NULL)
#define EXT_CSD_REV_ANY (-1u) @@ -81,17 +87,21 @@ struct mmc_fixup { #define CID_MANFID_APACER 0x27 #define CID_MANFID_KINGSTON 0x70 #define CID_MANFID_HYNIX 0x90 +#define CID_MANFID_KINGSTON_SD 0x9F #define CID_MANFID_NUMONYX 0xFE
#define END_FIXUP { NULL }
-#define _FIXUP_EXT(_name, _manfid, _oemid, _rev_start, _rev_end, \ - _cis_vendor, _cis_device, \ - _fixup, _data, _ext_csd_rev) \ +#define _FIXUP_EXT(_name, _manfid, _oemid, _year, _month, \ + _rev_start, _rev_end, \ + _cis_vendor, _cis_device, \ + _fixup, _data, _ext_csd_rev) \ { \ .name = (_name), \ .manfid = (_manfid), \ .oemid = (_oemid), \ + .year = (_year), \ + .month = (_month), \ .rev_start = (_rev_start), \ .rev_end = (_rev_end), \ .cis_vendor = (_cis_vendor), \ @@ -103,8 +113,8 @@ struct mmc_fixup {
#define MMC_FIXUP_REV(_name, _manfid, _oemid, _rev_start, _rev_end, \ _fixup, _data, _ext_csd_rev) \ - _FIXUP_EXT(_name, _manfid, \ - _oemid, _rev_start, _rev_end, \ + _FIXUP_EXT(_name, _manfid, _oemid, CID_YEAR_ANY, CID_MONTH_ANY, \ + _rev_start, _rev_end, \ SDIO_ANY_ID, SDIO_ANY_ID, \ _fixup, _data, _ext_csd_rev) \
@@ -118,8 +128,9 @@ struct mmc_fixup { _ext_csd_rev)
#define SDIO_FIXUP(_vendor, _device, _fixup, _data) \ - _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY, \ - CID_OEMID_ANY, 0, -1ull, \ + _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY, CID_OEMID_ANY, \ + CID_YEAR_ANY, CID_MONTH_ANY, \ + 0, -1ull, \ _vendor, _device, \ _fixup, _data, EXT_CSD_REV_ANY) \
@@ -264,4 +275,9 @@ static inline int mmc_card_broken_sd_discard(const struct mmc_card *c) return c->quirks & MMC_QUIRK_BROKEN_SD_DISCARD; }
+static inline int mmc_card_broken_sd_cache(const struct mmc_card *c) +{ + return c->quirks & MMC_QUIRK_BROKEN_SD_CACHE; +} + #endif diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h index 29b9497936df9..a7ffbc930ea9d 100644 --- a/drivers/mmc/core/quirks.h +++ b/drivers/mmc/core/quirks.h @@ -53,6 +53,15 @@ static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = { MMC_FIXUP("MMC32G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, MMC_QUIRK_BLK_NO_CMD23),
+ /* + * Kingston Canvas Go! Plus microSD cards never finish SD cache flush. + * This has so far only been observed on cards from 11/2019, while new + * cards from 2023/05 do not exhibit this behavior. + */ + _FIXUP_EXT("SD64G", CID_MANFID_KINGSTON_SD, 0x5449, 2019, 11, + 0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd, + MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY), + /* * Some SD cards lockup while using CMD23 multiblock transfers. */ @@ -209,6 +218,10 @@ static inline void mmc_fixup_device(struct mmc_card *card, if (f->of_compatible && !mmc_fixup_of_compatible_match(card, f->of_compatible)) continue; + if (f->year != CID_YEAR_ANY && f->year != card->cid.year) + continue; + if (f->month != CID_MONTH_ANY && f->month != card->cid.month) + continue;
dev_dbg(&card->dev, "calling %ps\n", f->vendor_fixup); f->vendor_fixup(card, f->data); diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 72b664ed90cf6..246ce027ae0aa 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1170,7 +1170,7 @@ static int sd_parse_ext_reg_perf(struct mmc_card *card, u8 fno, u8 page, card->ext_perf.feature_support |= SD_EXT_PERF_HOST_MAINT;
/* Cache support at bit 0. */ - if (reg_buf[4] & BIT(0)) + if ((reg_buf[4] & BIT(0)) && !mmc_card_broken_sd_cache(card)) card->ext_perf.feature_support |= SD_EXT_PERF_CACHE;
/* Command queue support indicated via queue depth bits (0 to 4). */ diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index c726ea7812552..daa2f40d9ce65 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -294,6 +294,7 @@ struct mmc_card { #define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */ #define MMC_QUIRK_BROKEN_HPI (1<<13) /* Disable broken HPI support */ #define MMC_QUIRK_BROKEN_SD_DISCARD (1<<14) /* Disable broken SD discard support */ +#define MMC_QUIRK_BROKEN_SD_CACHE (1<<15) /* Disable broken SD cache support */
bool reenable_cmdq; /* Re-enable Command Queue */
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 2db72b8a700943aa54dce0aabe6ff1b72b615162 ]
We've already done the 'decryption' here, so tell mac80211 it need not do it again.
Fixes: b1fdc2505abc ("iwlwifi: mvm: advertise BIGTK client support if available") Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20230620125813.a50cf68fbf2e.Ieceacbe3789d81ea02ae0... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index ad410b6efce73..7ebcf0ef29255 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -274,7 +274,8 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm, static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta, struct ieee80211_hdr *hdr, struct iwl_rx_mpdu_desc *desc, - u32 status) + u32 status, + struct ieee80211_rx_status *stats) { struct iwl_mvm_sta *mvmsta; struct iwl_mvm_vif *mvmvif; @@ -303,8 +304,10 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
/* good cases */ if (likely(status & IWL_RX_MPDU_STATUS_MIC_OK && - !(status & IWL_RX_MPDU_STATUS_REPLAY_ERROR))) + !(status & IWL_RX_MPDU_STATUS_REPLAY_ERROR))) { + stats->flag |= RX_FLAG_DECRYPTED; return 0; + }
if (!sta) return -1; @@ -373,7 +376,7 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
if (unlikely(ieee80211_is_mgmt(hdr->frame_control) && !ieee80211_has_protected(hdr->frame_control))) - return iwl_mvm_rx_mgmt_prot(sta, hdr, desc, status); + return iwl_mvm_rx_mgmt_prot(sta, hdr, desc, status, stats);
if (!ieee80211_has_protected(hdr->frame_control) || (status & IWL_RX_MPDU_STATUS_SEC_MASK) ==
From: Dmitry Antipov dmantipov@yandex.ru
[ Upstream commit 2aa083acea9f61be3280184384551178f510ff51 ]
Since 'ieee80211_queue_delayed_work()' expects timeout in jiffies and not milliseconds, 'msecs_to_jiffies()' should be used in 'ath_restart_work()' and '__ath9k_flush()'.
Fixes: d63ffc45c5d3 ("ath9k: rename tx_complete_work to hw_check_work") Signed-off-by: Dmitry Antipov dmantipov@yandex.ru Acked-by: Toke Høiland-Jørgensen toke@toke.dk Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20230613134655.248728-1-dmantipov@yandex.ru Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 7f9f06ea8a05f..6360d3356e256 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -203,7 +203,7 @@ void ath_cancel_work(struct ath_softc *sc) void ath_restart_work(struct ath_softc *sc) { ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work, - ATH_HW_CHECK_POLL_INT); + msecs_to_jiffies(ATH_HW_CHECK_POLL_INT));
if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9330(sc->sc_ah)) ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, @@ -2240,7 +2240,7 @@ void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop, }
ieee80211_queue_delayed_work(hw, &sc->hw_check_work, - ATH_HW_CHECK_POLL_INT); + msecs_to_jiffies(ATH_HW_CHECK_POLL_INT)); }
static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
From: Gilad Sever gilad9366@gmail.com
[ Upstream commit 6e98730bc0b44acaf86eccc75f823128aa9c9e79 ]
Change BPF helper socket lookup functions to use TC specific variants: bpf_tc_sk_lookup_tcp() / bpf_tc_sk_lookup_udp() / bpf_tc_skc_lookup_tcp() instead of sharing implementation with the cg / sk_skb hooking points. This allows introducing a separate logic for the TC flow.
The tc functions are identical to the original code.
Signed-off-by: Gilad Sever gilad9366@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Shmulik Ladkani shmulik.ladkani@gmail.com Reviewed-by: Eyal Birger eyal.birger@gmail.com Acked-by: Stanislav Fomichev sdf@google.com Link: https://lore.kernel.org/bpf/20230621104211.301902-2-gilad9366@gmail.com Stable-dep-of: 9a5cb79762e0 ("bpf: Fix bpf socket lookup from tc/xdp to respect socket VRF bindings") Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/filter.c | 63 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 3 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c index 1d6f165923bff..5910956f4e0db 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -6701,6 +6701,63 @@ static const struct bpf_func_proto bpf_sk_lookup_udp_proto = { .arg5_type = ARG_ANYTHING, };
+BPF_CALL_5(bpf_tc_skc_lookup_tcp, struct sk_buff *, skb, + struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) +{ + return (unsigned long)bpf_skc_lookup(skb, tuple, len, IPPROTO_TCP, + netns_id, flags); +} + +static const struct bpf_func_proto bpf_tc_skc_lookup_tcp_proto = { + .func = bpf_tc_skc_lookup_tcp, + .gpl_only = false, + .pkt_access = true, + .ret_type = RET_PTR_TO_SOCK_COMMON_OR_NULL, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, + .arg3_type = ARG_CONST_SIZE, + .arg4_type = ARG_ANYTHING, + .arg5_type = ARG_ANYTHING, +}; + +BPF_CALL_5(bpf_tc_sk_lookup_tcp, struct sk_buff *, skb, + struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) +{ + return (unsigned long)bpf_sk_lookup(skb, tuple, len, IPPROTO_TCP, + netns_id, flags); +} + +static const struct bpf_func_proto bpf_tc_sk_lookup_tcp_proto = { + .func = bpf_tc_sk_lookup_tcp, + .gpl_only = false, + .pkt_access = true, + .ret_type = RET_PTR_TO_SOCKET_OR_NULL, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, + .arg3_type = ARG_CONST_SIZE, + .arg4_type = ARG_ANYTHING, + .arg5_type = ARG_ANYTHING, +}; + +BPF_CALL_5(bpf_tc_sk_lookup_udp, struct sk_buff *, skb, + struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) +{ + return (unsigned long)bpf_sk_lookup(skb, tuple, len, IPPROTO_UDP, + netns_id, flags); +} + +static const struct bpf_func_proto bpf_tc_sk_lookup_udp_proto = { + .func = bpf_tc_sk_lookup_udp, + .gpl_only = false, + .pkt_access = true, + .ret_type = RET_PTR_TO_SOCKET_OR_NULL, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, + .arg3_type = ARG_CONST_SIZE, + .arg4_type = ARG_ANYTHING, + .arg5_type = ARG_ANYTHING, +}; + BPF_CALL_1(bpf_sk_release, struct sock *, sk) { if (sk && sk_is_refcounted(sk)) @@ -7954,9 +8011,9 @@ tc_cls_act_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) #endif #ifdef CONFIG_INET case BPF_FUNC_sk_lookup_tcp: - return &bpf_sk_lookup_tcp_proto; + return &bpf_tc_sk_lookup_tcp_proto; case BPF_FUNC_sk_lookup_udp: - return &bpf_sk_lookup_udp_proto; + return &bpf_tc_sk_lookup_udp_proto; case BPF_FUNC_sk_release: return &bpf_sk_release_proto; case BPF_FUNC_tcp_sock: @@ -7964,7 +8021,7 @@ tc_cls_act_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) case BPF_FUNC_get_listener_sock: return &bpf_get_listener_sock_proto; case BPF_FUNC_skc_lookup_tcp: - return &bpf_skc_lookup_tcp_proto; + return &bpf_tc_skc_lookup_tcp_proto; case BPF_FUNC_tcp_check_syncookie: return &bpf_tcp_check_syncookie_proto; case BPF_FUNC_skb_ecn_set_ce:
From: Gilad Sever gilad9366@gmail.com
[ Upstream commit 97fbfeb86917bdbe9c41d5143e335a929147f405 ]
skb->dev always exists in the tc flow. There is no need to use bpf_skc_lookup(), bpf_sk_lookup() from this code path.
This change facilitates fixing the tc flow to be VRF aware.
Signed-off-by: Gilad Sever gilad9366@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Shmulik Ladkani shmulik.ladkani@gmail.com Reviewed-by: Eyal Birger eyal.birger@gmail.com Acked-by: Stanislav Fomichev sdf@google.com Link: https://lore.kernel.org/bpf/20230621104211.301902-3-gilad9366@gmail.com Stable-dep-of: 9a5cb79762e0 ("bpf: Fix bpf socket lookup from tc/xdp to respect socket VRF bindings") Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/filter.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c index 5910956f4e0db..f43f86fc12356 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -6704,8 +6704,12 @@ static const struct bpf_func_proto bpf_sk_lookup_udp_proto = { BPF_CALL_5(bpf_tc_skc_lookup_tcp, struct sk_buff *, skb, struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) { - return (unsigned long)bpf_skc_lookup(skb, tuple, len, IPPROTO_TCP, - netns_id, flags); + struct net *caller_net = dev_net(skb->dev); + int ifindex = skb->dev->ifindex; + + return (unsigned long)__bpf_skc_lookup(skb, tuple, len, caller_net, + ifindex, IPPROTO_TCP, netns_id, + flags); }
static const struct bpf_func_proto bpf_tc_skc_lookup_tcp_proto = { @@ -6723,8 +6727,12 @@ static const struct bpf_func_proto bpf_tc_skc_lookup_tcp_proto = { BPF_CALL_5(bpf_tc_sk_lookup_tcp, struct sk_buff *, skb, struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) { - return (unsigned long)bpf_sk_lookup(skb, tuple, len, IPPROTO_TCP, - netns_id, flags); + struct net *caller_net = dev_net(skb->dev); + int ifindex = skb->dev->ifindex; + + return (unsigned long)__bpf_sk_lookup(skb, tuple, len, caller_net, + ifindex, IPPROTO_TCP, netns_id, + flags); }
static const struct bpf_func_proto bpf_tc_sk_lookup_tcp_proto = { @@ -6742,8 +6750,12 @@ static const struct bpf_func_proto bpf_tc_sk_lookup_tcp_proto = { BPF_CALL_5(bpf_tc_sk_lookup_udp, struct sk_buff *, skb, struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) { - return (unsigned long)bpf_sk_lookup(skb, tuple, len, IPPROTO_UDP, - netns_id, flags); + struct net *caller_net = dev_net(skb->dev); + int ifindex = skb->dev->ifindex; + + return (unsigned long)__bpf_sk_lookup(skb, tuple, len, caller_net, + ifindex, IPPROTO_UDP, netns_id, + flags); }
static const struct bpf_func_proto bpf_tc_sk_lookup_udp_proto = {
From: Gilad Sever gilad9366@gmail.com
[ Upstream commit 9a5cb79762e0eda17ca15c2a6eaca4622383c21c ]
When calling bpf_sk_lookup_tcp(), bpf_sk_lookup_udp() or bpf_skc_lookup_tcp() from tc/xdp ingress, VRF socket bindings aren't respoected, i.e. unbound sockets are returned, and bound sockets aren't found.
VRF binding is determined by the sdif argument to sk_lookup(), however when called from tc the IP SKB control block isn't initialized and thus inet{,6}_sdif() always returns 0.
Fix by calculating sdif for the tc/xdp flows by observing the device's l3 enslaved state.
The cg/sk_skb hooking points which are expected to support inet{,6}_sdif() pass sdif=-1 which makes __bpf_skc_lookup() use the existing logic.
Fixes: 6acc9b432e67 ("bpf: Add helper to retrieve socket in BPF") Signed-off-by: Gilad Sever gilad9366@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Shmulik Ladkani shmulik.ladkani@gmail.com Reviewed-by: Eyal Birger eyal.birger@gmail.com Acked-by: Stanislav Fomichev sdf@google.com Cc: David Ahern dsahern@kernel.org Link: https://lore.kernel.org/bpf/20230621104211.301902-4-gilad9366@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/netdevice.h | 9 +++++ net/core/filter.c | 69 ++++++++++++++++++++++----------------- 2 files changed, 48 insertions(+), 30 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 7ed63f5bbe056..02ac3a058c09f 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -5063,6 +5063,15 @@ static inline bool netif_is_l3_slave(const struct net_device *dev) return dev->priv_flags & IFF_L3MDEV_SLAVE; }
+static inline int dev_sdif(const struct net_device *dev) +{ +#ifdef CONFIG_NET_L3_MASTER_DEV + if (netif_is_l3_slave(dev)) + return dev->ifindex; +#endif + return 0; +} + static inline bool netif_is_bridge_master(const struct net_device *dev) { return dev->priv_flags & IFF_EBRIDGE; diff --git a/net/core/filter.c b/net/core/filter.c index f43f86fc12356..ebbab8c24beaf 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -6529,12 +6529,11 @@ static struct sock *sk_lookup(struct net *net, struct bpf_sock_tuple *tuple, static struct sock * __bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, struct net *caller_net, u32 ifindex, u8 proto, u64 netns_id, - u64 flags) + u64 flags, int sdif) { struct sock *sk = NULL; struct net *net; u8 family; - int sdif;
if (len == sizeof(tuple->ipv4)) family = AF_INET; @@ -6546,10 +6545,12 @@ __bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, if (unlikely(flags || !((s32)netns_id < 0 || netns_id <= S32_MAX))) goto out;
- if (family == AF_INET) - sdif = inet_sdif(skb); - else - sdif = inet6_sdif(skb); + if (sdif < 0) { + if (family == AF_INET) + sdif = inet_sdif(skb); + else + sdif = inet6_sdif(skb); + }
if ((s32)netns_id < 0) { net = caller_net; @@ -6569,10 +6570,11 @@ __bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, static struct sock * __bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, struct net *caller_net, u32 ifindex, u8 proto, u64 netns_id, - u64 flags) + u64 flags, int sdif) { struct sock *sk = __bpf_skc_lookup(skb, tuple, len, caller_net, - ifindex, proto, netns_id, flags); + ifindex, proto, netns_id, flags, + sdif);
if (sk) { struct sock *sk2 = sk_to_full_sk(sk); @@ -6612,7 +6614,7 @@ bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, }
return __bpf_skc_lookup(skb, tuple, len, caller_net, ifindex, proto, - netns_id, flags); + netns_id, flags, -1); }
static struct sock * @@ -6704,12 +6706,13 @@ static const struct bpf_func_proto bpf_sk_lookup_udp_proto = { BPF_CALL_5(bpf_tc_skc_lookup_tcp, struct sk_buff *, skb, struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) { - struct net *caller_net = dev_net(skb->dev); - int ifindex = skb->dev->ifindex; + struct net_device *dev = skb->dev; + int ifindex = dev->ifindex, sdif = dev_sdif(dev); + struct net *caller_net = dev_net(dev);
return (unsigned long)__bpf_skc_lookup(skb, tuple, len, caller_net, ifindex, IPPROTO_TCP, netns_id, - flags); + flags, sdif); }
static const struct bpf_func_proto bpf_tc_skc_lookup_tcp_proto = { @@ -6727,12 +6730,13 @@ static const struct bpf_func_proto bpf_tc_skc_lookup_tcp_proto = { BPF_CALL_5(bpf_tc_sk_lookup_tcp, struct sk_buff *, skb, struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) { - struct net *caller_net = dev_net(skb->dev); - int ifindex = skb->dev->ifindex; + struct net_device *dev = skb->dev; + int ifindex = dev->ifindex, sdif = dev_sdif(dev); + struct net *caller_net = dev_net(dev);
return (unsigned long)__bpf_sk_lookup(skb, tuple, len, caller_net, ifindex, IPPROTO_TCP, netns_id, - flags); + flags, sdif); }
static const struct bpf_func_proto bpf_tc_sk_lookup_tcp_proto = { @@ -6750,12 +6754,13 @@ static const struct bpf_func_proto bpf_tc_sk_lookup_tcp_proto = { BPF_CALL_5(bpf_tc_sk_lookup_udp, struct sk_buff *, skb, struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) { - struct net *caller_net = dev_net(skb->dev); - int ifindex = skb->dev->ifindex; + struct net_device *dev = skb->dev; + int ifindex = dev->ifindex, sdif = dev_sdif(dev); + struct net *caller_net = dev_net(dev);
return (unsigned long)__bpf_sk_lookup(skb, tuple, len, caller_net, ifindex, IPPROTO_UDP, netns_id, - flags); + flags, sdif); }
static const struct bpf_func_proto bpf_tc_sk_lookup_udp_proto = { @@ -6787,12 +6792,13 @@ static const struct bpf_func_proto bpf_sk_release_proto = { BPF_CALL_5(bpf_xdp_sk_lookup_udp, struct xdp_buff *, ctx, struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags) { - struct net *caller_net = dev_net(ctx->rxq->dev); - int ifindex = ctx->rxq->dev->ifindex; + struct net_device *dev = ctx->rxq->dev; + int ifindex = dev->ifindex, sdif = dev_sdif(dev); + struct net *caller_net = dev_net(dev);
return (unsigned long)__bpf_sk_lookup(NULL, tuple, len, caller_net, ifindex, IPPROTO_UDP, netns_id, - flags); + flags, sdif); }
static const struct bpf_func_proto bpf_xdp_sk_lookup_udp_proto = { @@ -6810,12 +6816,13 @@ static const struct bpf_func_proto bpf_xdp_sk_lookup_udp_proto = { BPF_CALL_5(bpf_xdp_skc_lookup_tcp, struct xdp_buff *, ctx, struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags) { - struct net *caller_net = dev_net(ctx->rxq->dev); - int ifindex = ctx->rxq->dev->ifindex; + struct net_device *dev = ctx->rxq->dev; + int ifindex = dev->ifindex, sdif = dev_sdif(dev); + struct net *caller_net = dev_net(dev);
return (unsigned long)__bpf_skc_lookup(NULL, tuple, len, caller_net, ifindex, IPPROTO_TCP, netns_id, - flags); + flags, sdif); }
static const struct bpf_func_proto bpf_xdp_skc_lookup_tcp_proto = { @@ -6833,12 +6840,13 @@ static const struct bpf_func_proto bpf_xdp_skc_lookup_tcp_proto = { BPF_CALL_5(bpf_xdp_sk_lookup_tcp, struct xdp_buff *, ctx, struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags) { - struct net *caller_net = dev_net(ctx->rxq->dev); - int ifindex = ctx->rxq->dev->ifindex; + struct net_device *dev = ctx->rxq->dev; + int ifindex = dev->ifindex, sdif = dev_sdif(dev); + struct net *caller_net = dev_net(dev);
return (unsigned long)__bpf_sk_lookup(NULL, tuple, len, caller_net, ifindex, IPPROTO_TCP, netns_id, - flags); + flags, sdif); }
static const struct bpf_func_proto bpf_xdp_sk_lookup_tcp_proto = { @@ -6858,7 +6866,8 @@ BPF_CALL_5(bpf_sock_addr_skc_lookup_tcp, struct bpf_sock_addr_kern *, ctx, { return (unsigned long)__bpf_skc_lookup(NULL, tuple, len, sock_net(ctx->sk), 0, - IPPROTO_TCP, netns_id, flags); + IPPROTO_TCP, netns_id, flags, + -1); }
static const struct bpf_func_proto bpf_sock_addr_skc_lookup_tcp_proto = { @@ -6877,7 +6886,7 @@ BPF_CALL_5(bpf_sock_addr_sk_lookup_tcp, struct bpf_sock_addr_kern *, ctx, { return (unsigned long)__bpf_sk_lookup(NULL, tuple, len, sock_net(ctx->sk), 0, IPPROTO_TCP, - netns_id, flags); + netns_id, flags, -1); }
static const struct bpf_func_proto bpf_sock_addr_sk_lookup_tcp_proto = { @@ -6896,7 +6905,7 @@ BPF_CALL_5(bpf_sock_addr_sk_lookup_udp, struct bpf_sock_addr_kern *, ctx, { return (unsigned long)__bpf_sk_lookup(NULL, tuple, len, sock_net(ctx->sk), 0, IPPROTO_UDP, - netns_id, flags); + netns_id, flags, -1); }
static const struct bpf_func_proto bpf_sock_addr_sk_lookup_udp_proto = {
From: Vincent Mailhol mailhol.vincent@wanadoo.fr
[ Upstream commit 9fde4c557f78ee2f3626e92b4089ce9d54a2573a ]
The Stuff Bit Count is always coded on 4 bits [1]. Update the Stuff Bit Count size accordingly.
In addition, the CRC fields of CAN FD Frames contain stuff bits at fixed positions called fixed stuff bits [2]. The CRC field starts with a fixed stuff bit and then has another fixed stuff bit after each fourth bit [2], which allows us to derive this formula:
FSB count = 1 + round_down(len(CRC field)/4)
The length of the CRC field is [1]:
len(CRC field) = len(Stuff Bit Count) + len(CRC) = 4 + len(CRC)
with len(CRC) either 17 or 21 bits depending of the payload length.
In conclusion, for CRC17:
FSB count = 1 + round_down((4 + 17)/4) = 6
and for CRC 21:
FSB count = 1 + round_down((4 + 21)/4) = 7
Add a Fixed Stuff bits (FSB) field with above values and update CANFD_FRAME_OVERHEAD_SFF and CANFD_FRAME_OVERHEAD_EFF accordingly.
[1] ISO 11898-1:2015 section 10.4.2.6 "CRC field":
The CRC field shall contain the CRC sequence followed by a recessive CRC delimiter. For FD Frames, the CRC field shall also contain the stuff count.
Stuff count
If FD Frames, the stuff count shall be at the beginning of the CRC field. It shall consist of the stuff bit count modulo 8 in a 3-bit gray code followed by a parity bit [...]
[2] ISO 11898-1:2015 paragraph 10.5 "Frame coding":
In the CRC field of FD Frames, the stuff bits shall be inserted at fixed positions; they are called fixed stuff bits. There shall be a fixed stuff bit before the first bit of the stuff count, even if the last bits of the preceding field are a sequence of five consecutive bits of identical value, there shall be only the fixed stuff bit, there shall not be two consecutive stuff bits. A further fixed stuff bit shall be inserted after each fourth bit of the CRC field [...]
Fixes: 85d99c3e2a13 ("can: length: can_skb_get_frame_len(): introduce function to get data length of frame in data link layer") Suggested-by: Thomas Kopp Thomas.Kopp@microchip.com Signed-off-by: Vincent Mailhol mailhol.vincent@wanadoo.fr Reviewed-by: Thomas Kopp Thomas.Kopp@microchip.com Link: https://lore.kernel.org/all/20230611025728.450837-2-mailhol.vincent@wanadoo.... Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/can/length.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/include/linux/can/length.h b/include/linux/can/length.h index 6995092b774ec..ef1fd32cef16b 100644 --- a/include/linux/can/length.h +++ b/include/linux/can/length.h @@ -69,17 +69,18 @@ * Error Status Indicator (ESI) 1 * Data length code (DLC) 4 * Data field 0...512 - * Stuff Bit Count (SBC) 0...16: 4 20...64:5 + * Stuff Bit Count (SBC) 4 * CRC 0...16: 17 20...64:21 * CRC delimiter (CD) 1 + * Fixed Stuff bits (FSB) 0...16: 6 20...64:7 * ACK slot (AS) 1 * ACK delimiter (AD) 1 * End-of-frame (EOF) 7 * Inter frame spacing 3 * - * assuming CRC21, rounded up and ignoring bitstuffing + * assuming CRC21, rounded up and ignoring dynamic bitstuffing */ -#define CANFD_FRAME_OVERHEAD_SFF DIV_ROUND_UP(61, 8) +#define CANFD_FRAME_OVERHEAD_SFF DIV_ROUND_UP(67, 8)
/* * Size of a CAN-FD Extended Frame @@ -98,17 +99,18 @@ * Error Status Indicator (ESI) 1 * Data length code (DLC) 4 * Data field 0...512 - * Stuff Bit Count (SBC) 0...16: 4 20...64:5 + * Stuff Bit Count (SBC) 4 * CRC 0...16: 17 20...64:21 * CRC delimiter (CD) 1 + * Fixed Stuff bits (FSB) 0...16: 6 20...64:7 * ACK slot (AS) 1 * ACK delimiter (AD) 1 * End-of-frame (EOF) 7 * Inter frame spacing 3 * - * assuming CRC21, rounded up and ignoring bitstuffing + * assuming CRC21, rounded up and ignoring dynamic bitstuffing */ -#define CANFD_FRAME_OVERHEAD_EFF DIV_ROUND_UP(80, 8) +#define CANFD_FRAME_OVERHEAD_EFF DIV_ROUND_UP(86, 8)
/* * Maximum size of a Classical CAN frame
From: Jimmy Assarsson extja@kvaser.com
[ Upstream commit 2d55e9f9b4427e1ad59b974f2267767aac3788d3 ]
Add new function, kvaser_pciefd_set_skb_timestamp(), to set skb hwtstamps.
Signed-off-by: Jimmy Assarsson extja@kvaser.com Reviewed-by: Vincent Mailhol mailhol.vincent@wanadoo.fr Link: https://lore.kernel.org/all/20230529134248.752036-4-extja@kvaser.com Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Stable-dep-of: ec681b91befa ("can: kvaser_pciefd: Set hardware timestamp on transmitted packets") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/kvaser_pciefd.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-)
diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c index 956a4a57396f9..0b537292c7b19 100644 --- a/drivers/net/can/kvaser_pciefd.c +++ b/drivers/net/can/kvaser_pciefd.c @@ -538,6 +538,13 @@ static int kvaser_pciefd_set_tx_irq(struct kvaser_pciefd_can *can) return 0; }
+static inline void kvaser_pciefd_set_skb_timestamp(const struct kvaser_pciefd *pcie, + struct sk_buff *skb, u64 timestamp) +{ + skb_hwtstamps(skb)->hwtstamp = + ns_to_ktime(div_u64(timestamp * 1000, pcie->freq_to_ticks_div)); +} + static void kvaser_pciefd_setup_controller(struct kvaser_pciefd_can *can) { u32 mode; @@ -1171,7 +1178,6 @@ static int kvaser_pciefd_handle_data_packet(struct kvaser_pciefd *pcie, struct canfd_frame *cf; struct can_priv *priv; struct net_device_stats *stats; - struct skb_shared_hwtstamps *shhwtstamps; u8 ch_id = (p->header[1] >> KVASER_PCIEFD_PACKET_CHID_SHIFT) & 0x7;
if (ch_id >= pcie->nr_channels) @@ -1214,12 +1220,7 @@ static int kvaser_pciefd_handle_data_packet(struct kvaser_pciefd *pcie, stats->rx_bytes += cf->len; } stats->rx_packets++; - - shhwtstamps = skb_hwtstamps(skb); - - shhwtstamps->hwtstamp = - ns_to_ktime(div_u64(p->timestamp * 1000, - pcie->freq_to_ticks_div)); + kvaser_pciefd_set_skb_timestamp(pcie, skb, p->timestamp);
return netif_rx(skb); } @@ -1282,7 +1283,6 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can, struct net_device *ndev = can->can.dev; struct sk_buff *skb; struct can_frame *cf = NULL; - struct skb_shared_hwtstamps *shhwtstamps; struct net_device_stats *stats = &ndev->stats;
old_state = can->can.state; @@ -1323,10 +1323,7 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can, return -ENOMEM; }
- shhwtstamps = skb_hwtstamps(skb); - shhwtstamps->hwtstamp = - ns_to_ktime(div_u64(p->timestamp * 1000, - can->kv_pcie->freq_to_ticks_div)); + kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp); cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_CNT;
cf->data[6] = bec.txerr; @@ -1374,7 +1371,6 @@ static int kvaser_pciefd_handle_status_resp(struct kvaser_pciefd_can *can, struct net_device *ndev = can->can.dev; struct sk_buff *skb; struct can_frame *cf; - struct skb_shared_hwtstamps *shhwtstamps;
skb = alloc_can_err_skb(ndev, &cf); if (!skb) { @@ -1394,10 +1390,7 @@ static int kvaser_pciefd_handle_status_resp(struct kvaser_pciefd_can *can, cf->can_id |= CAN_ERR_RESTARTED; }
- shhwtstamps = skb_hwtstamps(skb); - shhwtstamps->hwtstamp = - ns_to_ktime(div_u64(p->timestamp * 1000, - can->kv_pcie->freq_to_ticks_div)); + kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp);
cf->data[6] = bec.txerr; cf->data[7] = bec.rxerr;
From: Jimmy Assarsson extja@kvaser.com
[ Upstream commit ec681b91befa982477e24a150dd6452427fe6473 ]
Set hardware timestamp on transmitted packets.
Fixes: 26ad340e582d ("can: kvaser_pciefd: Add driver for Kvaser PCIEcan devices") Signed-off-by: Jimmy Assarsson extja@kvaser.com Reviewed-by: Vincent Mailhol mailhol.vincent@wanadoo.fr Link: https://lore.kernel.org/all/20230529134248.752036-5-extja@kvaser.com Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/kvaser_pciefd.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c index 0b537292c7b19..74a47244f1291 100644 --- a/drivers/net/can/kvaser_pciefd.c +++ b/drivers/net/can/kvaser_pciefd.c @@ -1519,6 +1519,7 @@ static void kvaser_pciefd_handle_nack_packet(struct kvaser_pciefd_can *can,
if (skb) { cf->can_id |= CAN_ERR_BUSERROR; + kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp); netif_rx(skb); } else { stats->rx_dropped++; @@ -1550,8 +1551,15 @@ static int kvaser_pciefd_handle_ack_packet(struct kvaser_pciefd *pcie, netdev_dbg(can->can.dev, "Packet was flushed\n"); } else { int echo_idx = p->header[0] & KVASER_PCIEFD_PACKET_SEQ_MSK; - int dlc = can_get_echo_skb(can->can.dev, echo_idx, NULL); - u8 count = ioread32(can->reg_base + + int dlc; + u8 count; + struct sk_buff *skb; + + skb = can->can.echo_skb[echo_idx]; + if (skb) + kvaser_pciefd_set_skb_timestamp(pcie, skb, p->timestamp); + dlc = can_get_echo_skb(can->can.dev, echo_idx, NULL); + count = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_TX_NPACKETS_REG) & 0xff;
if (count < KVASER_PCIEFD_CAN_TX_MAX_COUNT &&
From: Bartosz Golaszewski bartosz.golaszewski@linaro.org
[ Upstream commit c4fc88ad2a765224a648db8ab35f125e120fe41b ]
Commit 49725ffc15fc ("net: stmmac: power up/down serdes in stmmac_open/release") correctly added a call to the serdes_powerdown() callback to stmmac_release() but did not remove the one from stmmac_remove() which leads to a doubled call to serdes_powerdown().
This can lead to all kinds of problems: in the case of the qcom ethqos driver, it caused an unbalanced regulator disable splat.
Fixes: 49725ffc15fc ("net: stmmac: power up/down serdes in stmmac_open/release") Signed-off-by: Bartosz Golaszewski bartosz.golaszewski@linaro.org Reviewed-by: Jiri Pirko jiri@nvidia.com Acked-by: Junxiao Chang junxiao.chang@intel.com Reviewed-by: Andrew Halaney ahalaney@redhat.com Tested-by: Andrew Halaney ahalaney@redhat.com Link: https://lore.kernel.org/r/20230621135537.376649-1-brgl@bgdev.pl Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 ------ 1 file changed, 6 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 4e59f0e164ec0..29d70ecdac846 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -7394,12 +7394,6 @@ void stmmac_dvr_remove(struct device *dev) netif_carrier_off(ndev); unregister_netdev(ndev);
- /* Serdes power down needs to happen after VLAN filter - * is deleted that is triggered by unregister_netdev(). - */ - if (priv->plat->serdes_powerdown) - priv->plat->serdes_powerdown(ndev, priv->plat->bsp_priv); - #ifdef CONFIG_DEBUG_FS stmmac_exit_fs(ndev); #endif
From: Eric Dumazet edumazet@google.com
[ Upstream commit 8d61f926d42045961e6b65191c09e3678d86a9cf ]
syzbot reported a possible deadlock in netlink_set_err() [1]
A similar issue was fixed in commit 1d482e666b8e ("netlink: disable IRQs for netlink_lock_table()") in netlink_lock_table()
This patch adds IRQ safety to netlink_set_err() and __netlink_diag_dump() which were not covered by cited commit.
[1]
WARNING: possible irq lock inversion dependency detected 6.4.0-rc6-syzkaller-00240-g4e9f0ec38852 #0 Not tainted
syz-executor.2/23011 just changed the state of lock: ffffffff8e1a7a58 (nl_table_lock){.+.?}-{2:2}, at: netlink_set_err+0x2e/0x3a0 net/netlink/af_netlink.c:1612 but this lock was taken by another, SOFTIRQ-safe lock in the past: (&local->queue_stop_reason_lock){..-.}-{2:2}
and interrupts could create inverse lock ordering between them.
other info that might help us debug this: Possible interrupt unsafe locking scenario:
CPU0 CPU1 ---- ---- lock(nl_table_lock); local_irq_disable(); lock(&local->queue_stop_reason_lock); lock(nl_table_lock); <Interrupt> lock(&local->queue_stop_reason_lock);
*** DEADLOCK ***
Fixes: 1d482e666b8e ("netlink: disable IRQs for netlink_lock_table()") Reported-by: syzbot+a7d200a347f912723e5c@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=a7d200a347f912723e5c Link: https://lore.kernel.org/netdev/000000000000e38d1605fea5747e@google.com/T/#u Signed-off-by: Eric Dumazet edumazet@google.com Cc: Johannes Berg johannes.berg@intel.com Link: https://lore.kernel.org/r/20230621154337.1668594-1-edumazet@google.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/netlink/af_netlink.c | 5 +++-- net/netlink/diag.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 717e27a4b66a0..f4adccb8d49a2 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1600,6 +1600,7 @@ static int do_one_set_err(struct sock *sk, struct netlink_set_err_data *p) int netlink_set_err(struct sock *ssk, u32 portid, u32 group, int code) { struct netlink_set_err_data info; + unsigned long flags; struct sock *sk; int ret = 0;
@@ -1609,12 +1610,12 @@ int netlink_set_err(struct sock *ssk, u32 portid, u32 group, int code) /* sk->sk_err wants a positive error value */ info.code = -code;
- read_lock(&nl_table_lock); + read_lock_irqsave(&nl_table_lock, flags);
sk_for_each_bound(sk, &nl_table[ssk->sk_protocol].mc_list) ret += do_one_set_err(sk, &info);
- read_unlock(&nl_table_lock); + read_unlock_irqrestore(&nl_table_lock, flags); return ret; } EXPORT_SYMBOL(netlink_set_err); diff --git a/net/netlink/diag.c b/net/netlink/diag.c index c6255eac305c7..4143b2ea4195a 100644 --- a/net/netlink/diag.c +++ b/net/netlink/diag.c @@ -94,6 +94,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, struct net *net = sock_net(skb->sk); struct netlink_diag_req *req; struct netlink_sock *nlsk; + unsigned long flags; struct sock *sk; int num = 2; int ret = 0; @@ -152,7 +153,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, num++;
mc_list: - read_lock(&nl_table_lock); + read_lock_irqsave(&nl_table_lock, flags); sk_for_each_bound(sk, &tbl->mc_list) { if (sk_hashed(sk)) continue; @@ -173,7 +174,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, } num++; } - read_unlock(&nl_table_lock); + read_unlock_irqrestore(&nl_table_lock, flags);
done: cb->args[0] = num;
From: Eric Dumazet edumazet@google.com
[ Upstream commit aa5406950726e336c5c9585b09799a734b6e77bf ]
syzbot reports that some netdev devices do not have a six bytes address [1]
Replace ETH_ALEN by dev->addr_len.
[1] (Case of a device where dev->addr_len = 4)
BUG: KMSAN: kernel-infoleak in instrument_copy_to_user include/linux/instrumented.h:114 [inline] BUG: KMSAN: kernel-infoleak in copyout+0xb8/0x100 lib/iov_iter.c:169 instrument_copy_to_user include/linux/instrumented.h:114 [inline] copyout+0xb8/0x100 lib/iov_iter.c:169 _copy_to_iter+0x6d8/0x1d00 lib/iov_iter.c:536 copy_to_iter include/linux/uio.h:206 [inline] simple_copy_to_iter+0x68/0xa0 net/core/datagram.c:513 __skb_datagram_iter+0x123/0xdc0 net/core/datagram.c:419 skb_copy_datagram_iter+0x5c/0x200 net/core/datagram.c:527 skb_copy_datagram_msg include/linux/skbuff.h:3960 [inline] netlink_recvmsg+0x4ae/0x15a0 net/netlink/af_netlink.c:1970 sock_recvmsg_nosec net/socket.c:1019 [inline] sock_recvmsg net/socket.c:1040 [inline] ____sys_recvmsg+0x283/0x7f0 net/socket.c:2722 ___sys_recvmsg+0x223/0x840 net/socket.c:2764 do_recvmmsg+0x4f9/0xfd0 net/socket.c:2858 __sys_recvmmsg net/socket.c:2937 [inline] __do_sys_recvmmsg net/socket.c:2960 [inline] __se_sys_recvmmsg net/socket.c:2953 [inline] __x64_sys_recvmmsg+0x397/0x490 net/socket.c:2953 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
Uninit was stored to memory at: __nla_put lib/nlattr.c:1009 [inline] nla_put+0x1c6/0x230 lib/nlattr.c:1067 nlmsg_populate_fdb_fill+0x2b8/0x600 net/core/rtnetlink.c:4071 nlmsg_populate_fdb net/core/rtnetlink.c:4418 [inline] ndo_dflt_fdb_dump+0x616/0x840 net/core/rtnetlink.c:4456 rtnl_fdb_dump+0x14ff/0x1fc0 net/core/rtnetlink.c:4629 netlink_dump+0x9d1/0x1310 net/netlink/af_netlink.c:2268 netlink_recvmsg+0xc5c/0x15a0 net/netlink/af_netlink.c:1995 sock_recvmsg_nosec+0x7a/0x120 net/socket.c:1019 ____sys_recvmsg+0x664/0x7f0 net/socket.c:2720 ___sys_recvmsg+0x223/0x840 net/socket.c:2764 do_recvmmsg+0x4f9/0xfd0 net/socket.c:2858 __sys_recvmmsg net/socket.c:2937 [inline] __do_sys_recvmmsg net/socket.c:2960 [inline] __se_sys_recvmmsg net/socket.c:2953 [inline] __x64_sys_recvmmsg+0x397/0x490 net/socket.c:2953 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
Uninit was created at: slab_post_alloc_hook+0x12d/0xb60 mm/slab.h:716 slab_alloc_node mm/slub.c:3451 [inline] __kmem_cache_alloc_node+0x4ff/0x8b0 mm/slub.c:3490 kmalloc_trace+0x51/0x200 mm/slab_common.c:1057 kmalloc include/linux/slab.h:559 [inline] __hw_addr_create net/core/dev_addr_lists.c:60 [inline] __hw_addr_add_ex+0x2e5/0x9e0 net/core/dev_addr_lists.c:118 __dev_mc_add net/core/dev_addr_lists.c:867 [inline] dev_mc_add+0x9a/0x130 net/core/dev_addr_lists.c:885 igmp6_group_added+0x267/0xbc0 net/ipv6/mcast.c:680 ipv6_mc_up+0x296/0x3b0 net/ipv6/mcast.c:2754 ipv6_mc_remap+0x1e/0x30 net/ipv6/mcast.c:2708 addrconf_type_change net/ipv6/addrconf.c:3731 [inline] addrconf_notify+0x4d3/0x1d90 net/ipv6/addrconf.c:3699 notifier_call_chain kernel/notifier.c:93 [inline] raw_notifier_call_chain+0xe4/0x430 kernel/notifier.c:461 call_netdevice_notifiers_info net/core/dev.c:1935 [inline] call_netdevice_notifiers_extack net/core/dev.c:1973 [inline] call_netdevice_notifiers+0x1ee/0x2d0 net/core/dev.c:1987 bond_enslave+0xccd/0x53f0 drivers/net/bonding/bond_main.c:1906 do_set_master net/core/rtnetlink.c:2626 [inline] rtnl_newlink_create net/core/rtnetlink.c:3460 [inline] __rtnl_newlink net/core/rtnetlink.c:3660 [inline] rtnl_newlink+0x378c/0x40e0 net/core/rtnetlink.c:3673 rtnetlink_rcv_msg+0x16a6/0x1840 net/core/rtnetlink.c:6395 netlink_rcv_skb+0x371/0x650 net/netlink/af_netlink.c:2546 rtnetlink_rcv+0x34/0x40 net/core/rtnetlink.c:6413 netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline] netlink_unicast+0xf28/0x1230 net/netlink/af_netlink.c:1365 netlink_sendmsg+0x122f/0x13d0 net/netlink/af_netlink.c:1913 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg net/socket.c:747 [inline] ____sys_sendmsg+0x999/0xd50 net/socket.c:2503 ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2557 __sys_sendmsg net/socket.c:2586 [inline] __do_sys_sendmsg net/socket.c:2595 [inline] __se_sys_sendmsg net/socket.c:2593 [inline] __x64_sys_sendmsg+0x304/0x490 net/socket.c:2593 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
Bytes 2856-2857 of 3500 are uninitialized Memory access of size 3500 starts at ffff888018d99104 Data copied to user address 0000000020000480
Fixes: d83b06036048 ("net: add fdb generic dump routine") Reported-by: syzbot syzkaller@googlegroups.com Signed-off-by: Eric Dumazet edumazet@google.com Reviewed-by: Jiri Pirko jiri@nvidia.com Link: https://lore.kernel.org/r/20230621174720.1845040-1-edumazet@google.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/rtnetlink.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index bbecc31a2703f..f21254a9cd373 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -4093,7 +4093,7 @@ static int nlmsg_populate_fdb_fill(struct sk_buff *skb, ndm->ndm_ifindex = dev->ifindex; ndm->ndm_state = ndm_state;
- if (nla_put(skb, NDA_LLADDR, ETH_ALEN, addr)) + if (nla_put(skb, NDA_LLADDR, dev->addr_len, addr)) goto nla_put_failure; if (vid) if (nla_put(skb, NDA_VLAN, sizeof(u16), &vid)) @@ -4107,10 +4107,10 @@ static int nlmsg_populate_fdb_fill(struct sk_buff *skb, return -EMSGSIZE; }
-static inline size_t rtnl_fdb_nlmsg_size(void) +static inline size_t rtnl_fdb_nlmsg_size(const struct net_device *dev) { return NLMSG_ALIGN(sizeof(struct ndmsg)) + - nla_total_size(ETH_ALEN) + /* NDA_LLADDR */ + nla_total_size(dev->addr_len) + /* NDA_LLADDR */ nla_total_size(sizeof(u16)) + /* NDA_VLAN */ 0; } @@ -4122,7 +4122,7 @@ static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, u16 vid, int type, struct sk_buff *skb; int err = -ENOBUFS;
- skb = nlmsg_new(rtnl_fdb_nlmsg_size(), GFP_ATOMIC); + skb = nlmsg_new(rtnl_fdb_nlmsg_size(dev), GFP_ATOMIC); if (!skb) goto errout;
From: Eric Dumazet edumazet@google.com
[ Upstream commit 6a940abdef3162e5723f1495b8a49859d1708f79 ]
Drivers must not assume in their ndo_start_xmit() that skbs have their mac_header set. skb->data is all what is needed.
bonding seems to be one of the last offender as caught by syzbot:
WARNING: CPU: 1 PID: 12155 at include/linux/skbuff.h:2907 skb_mac_offset include/linux/skbuff.h:2913 [inline] WARNING: CPU: 1 PID: 12155 at include/linux/skbuff.h:2907 bond_xmit_hash drivers/net/bonding/bond_main.c:4170 [inline] WARNING: CPU: 1 PID: 12155 at include/linux/skbuff.h:2907 bond_xmit_3ad_xor_slave_get drivers/net/bonding/bond_main.c:5149 [inline] WARNING: CPU: 1 PID: 12155 at include/linux/skbuff.h:2907 bond_3ad_xor_xmit drivers/net/bonding/bond_main.c:5186 [inline] WARNING: CPU: 1 PID: 12155 at include/linux/skbuff.h:2907 __bond_start_xmit drivers/net/bonding/bond_main.c:5442 [inline] WARNING: CPU: 1 PID: 12155 at include/linux/skbuff.h:2907 bond_start_xmit+0x14ab/0x19d0 drivers/net/bonding/bond_main.c:5470 Modules linked in: CPU: 1 PID: 12155 Comm: syz-executor.3 Not tainted 6.1.30-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/25/2023 RIP: 0010:skb_mac_header include/linux/skbuff.h:2907 [inline] RIP: 0010:skb_mac_offset include/linux/skbuff.h:2913 [inline] RIP: 0010:bond_xmit_hash drivers/net/bonding/bond_main.c:4170 [inline] RIP: 0010:bond_xmit_3ad_xor_slave_get drivers/net/bonding/bond_main.c:5149 [inline] RIP: 0010:bond_3ad_xor_xmit drivers/net/bonding/bond_main.c:5186 [inline] RIP: 0010:__bond_start_xmit drivers/net/bonding/bond_main.c:5442 [inline] RIP: 0010:bond_start_xmit+0x14ab/0x19d0 drivers/net/bonding/bond_main.c:5470 Code: 8b 7c 24 30 e8 76 dd 1a 01 48 85 c0 74 0d 48 89 c3 e8 29 67 2e fe e9 15 ef ff ff e8 1f 67 2e fe e9 10 ef ff ff e8 15 67 2e fe <0f> 0b e9 45 f8 ff ff e8 09 67 2e fe e9 dc fa ff ff e8 ff 66 2e fe RSP: 0018:ffffc90002fff6e0 EFLAGS: 00010283 RAX: ffffffff835874db RBX: 000000000000ffff RCX: 0000000000040000 RDX: ffffc90004dcf000 RSI: 00000000000000b5 RDI: 00000000000000b6 RBP: ffffc90002fff8b8 R08: ffffffff83586d16 R09: ffffffff83586584 R10: 0000000000000007 R11: ffff8881599fc780 R12: ffff88811b6a7b7e R13: 1ffff110236d4f6f R14: ffff88811b6a7ac0 R15: 1ffff110236d4f76 FS: 00007f2e9eb47700(0000) GS:ffff8881f6b00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000001b2e421000 CR3: 000000010e6d4000 CR4: 00000000003526e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> [<ffffffff8471a49f>] netdev_start_xmit include/linux/netdevice.h:4925 [inline] [<ffffffff8471a49f>] __dev_direct_xmit+0x4ef/0x850 net/core/dev.c:4380 [<ffffffff851d845b>] dev_direct_xmit include/linux/netdevice.h:3043 [inline] [<ffffffff851d845b>] packet_direct_xmit+0x18b/0x300 net/packet/af_packet.c:284 [<ffffffff851c7472>] packet_snd net/packet/af_packet.c:3112 [inline] [<ffffffff851c7472>] packet_sendmsg+0x4a22/0x64d0 net/packet/af_packet.c:3143 [<ffffffff8467a4b2>] sock_sendmsg_nosec net/socket.c:716 [inline] [<ffffffff8467a4b2>] sock_sendmsg net/socket.c:736 [inline] [<ffffffff8467a4b2>] __sys_sendto+0x472/0x5f0 net/socket.c:2139 [<ffffffff8467a715>] __do_sys_sendto net/socket.c:2151 [inline] [<ffffffff8467a715>] __se_sys_sendto net/socket.c:2147 [inline] [<ffffffff8467a715>] __x64_sys_sendto+0xe5/0x100 net/socket.c:2147 [<ffffffff8553071f>] do_syscall_x64 arch/x86/entry/common.c:50 [inline] [<ffffffff8553071f>] do_syscall_64+0x2f/0x50 arch/x86/entry/common.c:80 [<ffffffff85600087>] entry_SYSCALL_64_after_hwframe+0x63/0xcd
Fixes: 7b8fc0103bb5 ("bonding: add a vlan+srcmac tx hashing option") Reported-by: syzbot syzkaller@googlegroups.com Signed-off-by: Eric Dumazet edumazet@google.com Cc: Jarod Wilson jarod@redhat.com Cc: Moshe Tal moshet@nvidia.com Cc: Jussi Maki joamaki@gmail.com Cc: Jay Vosburgh j.vosburgh@gmail.com Cc: Andy Gospodarek andy@greyhouse.net Cc: Vladimir Oltean vladimir.oltean@nxp.com Link: https://lore.kernel.org/r/20230622152304.2137482-1-edumazet@google.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/bonding/bond_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 806d33d9f7124..172939e275a3b 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4171,7 +4171,7 @@ u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb) return skb->hash;
return __bond_xmit_hash(bond, skb, skb->data, skb->protocol, - skb_mac_offset(skb), skb_network_offset(skb), + 0, skb_network_offset(skb), skb_headlen(skb)); }
From: Sabrina Dubroca sd@queasysnail.net
[ Upstream commit 5f789f103671fec3733ebe756e56adf15c90c21d ]
On systems where netdevsim is built-in or loaded before the test starts, kci_test_ipsec_offload doesn't remove the netdevsim device it created during the test.
Fixes: e05b2d141fef ("netdevsim: move netdev creation/destruction to dev probe") Signed-off-by: Sabrina Dubroca sd@queasysnail.net Reviewed-by: Simon Horman simon.horman@corigine.com Reviewed-by: Jiri Pirko jiri@nvidia.com Link: https://lore.kernel.org/r/e1cb94f4f82f4eca4a444feec4488a1323396357.168746690... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/net/rtnetlink.sh | 1 + 1 file changed, 1 insertion(+)
diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh index 275491be3da2f..cafd14b1ed2ab 100755 --- a/tools/testing/selftests/net/rtnetlink.sh +++ b/tools/testing/selftests/net/rtnetlink.sh @@ -835,6 +835,7 @@ EOF fi
# clean up any leftovers + echo 0 > /sys/bus/netdevsim/del_device $probed && rmmod netdevsim
if [ $ret -ne 0 ]; then
From: Kuniyuki Iwashima kuniyu@amazon.com
[ Upstream commit ce3aee7114c575fab32a5e9e939d4bbb3dcca79f ]
syzkaller reported use-after-free in __gtp_encap_destroy(). [0]
It shows the same process freed sk and touched it illegally.
Commit e198987e7dd7 ("gtp: fix suspicious RCU usage") added lock_sock() and release_sock() in __gtp_encap_destroy() to protect sk->sk_user_data, but release_sock() is called after sock_put() releases the last refcnt.
[0]: BUG: KASAN: slab-use-after-free in instrument_atomic_read_write include/linux/instrumented.h:96 [inline] BUG: KASAN: slab-use-after-free in atomic_try_cmpxchg_acquire include/linux/atomic/atomic-instrumented.h:541 [inline] BUG: KASAN: slab-use-after-free in queued_spin_lock include/asm-generic/qspinlock.h:111 [inline] BUG: KASAN: slab-use-after-free in do_raw_spin_lock include/linux/spinlock.h:186 [inline] BUG: KASAN: slab-use-after-free in __raw_spin_lock_bh include/linux/spinlock_api_smp.h:127 [inline] BUG: KASAN: slab-use-after-free in _raw_spin_lock_bh+0x75/0xe0 kernel/locking/spinlock.c:178 Write of size 4 at addr ffff88800dbef398 by task syz-executor.2/2401
CPU: 1 PID: 2401 Comm: syz-executor.2 Not tainted 6.4.0-rc5-01219-gfa0e21fa4443 #2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x72/0xa0 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:351 [inline] print_report+0xcc/0x620 mm/kasan/report.c:462 kasan_report+0xb2/0xe0 mm/kasan/report.c:572 check_region_inline mm/kasan/generic.c:181 [inline] kasan_check_range+0x39/0x1c0 mm/kasan/generic.c:187 instrument_atomic_read_write include/linux/instrumented.h:96 [inline] atomic_try_cmpxchg_acquire include/linux/atomic/atomic-instrumented.h:541 [inline] queued_spin_lock include/asm-generic/qspinlock.h:111 [inline] do_raw_spin_lock include/linux/spinlock.h:186 [inline] __raw_spin_lock_bh include/linux/spinlock_api_smp.h:127 [inline] _raw_spin_lock_bh+0x75/0xe0 kernel/locking/spinlock.c:178 spin_lock_bh include/linux/spinlock.h:355 [inline] release_sock+0x1f/0x1a0 net/core/sock.c:3526 gtp_encap_disable_sock drivers/net/gtp.c:651 [inline] gtp_encap_disable+0xb9/0x220 drivers/net/gtp.c:664 gtp_dev_uninit+0x19/0x50 drivers/net/gtp.c:728 unregister_netdevice_many_notify+0x97e/0x1520 net/core/dev.c:10841 rtnl_delete_link net/core/rtnetlink.c:3216 [inline] rtnl_dellink+0x3c0/0xb30 net/core/rtnetlink.c:3268 rtnetlink_rcv_msg+0x450/0xb10 net/core/rtnetlink.c:6423 netlink_rcv_skb+0x15d/0x450 net/netlink/af_netlink.c:2548 netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline] netlink_unicast+0x700/0x930 net/netlink/af_netlink.c:1365 netlink_sendmsg+0x91c/0xe30 net/netlink/af_netlink.c:1913 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg+0x1b7/0x200 net/socket.c:747 ____sys_sendmsg+0x75a/0x990 net/socket.c:2493 ___sys_sendmsg+0x11d/0x1c0 net/socket.c:2547 __sys_sendmsg+0xfe/0x1d0 net/socket.c:2576 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc RIP: 0033:0x7f1168b1fe5d Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 73 9f 1b 00 f7 d8 64 89 01 48 RSP: 002b:00007f1167edccc8 EFLAGS: 00000246 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 00000000004bbf80 RCX: 00007f1168b1fe5d RDX: 0000000000000000 RSI: 00000000200002c0 RDI: 0000000000000003 RBP: 00000000004bbf80 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 000000000000000b R14: 00007f1168b80530 R15: 0000000000000000 </TASK>
Allocated by task 1483: kasan_save_stack+0x22/0x50 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 __kasan_slab_alloc+0x59/0x70 mm/kasan/common.c:328 kasan_slab_alloc include/linux/kasan.h:186 [inline] slab_post_alloc_hook mm/slab.h:711 [inline] slab_alloc_node mm/slub.c:3451 [inline] slab_alloc mm/slub.c:3459 [inline] __kmem_cache_alloc_lru mm/slub.c:3466 [inline] kmem_cache_alloc+0x16d/0x340 mm/slub.c:3475 sk_prot_alloc+0x5f/0x280 net/core/sock.c:2073 sk_alloc+0x34/0x6c0 net/core/sock.c:2132 inet6_create net/ipv6/af_inet6.c:192 [inline] inet6_create+0x2c7/0xf20 net/ipv6/af_inet6.c:119 __sock_create+0x2a1/0x530 net/socket.c:1535 sock_create net/socket.c:1586 [inline] __sys_socket_create net/socket.c:1623 [inline] __sys_socket_create net/socket.c:1608 [inline] __sys_socket+0x137/0x250 net/socket.c:1651 __do_sys_socket net/socket.c:1664 [inline] __se_sys_socket net/socket.c:1662 [inline] __x64_sys_socket+0x72/0xb0 net/socket.c:1662 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc
Freed by task 2401: kasan_save_stack+0x22/0x50 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 kasan_save_free_info+0x2e/0x50 mm/kasan/generic.c:521 ____kasan_slab_free mm/kasan/common.c:236 [inline] ____kasan_slab_free mm/kasan/common.c:200 [inline] __kasan_slab_free+0x10c/0x1b0 mm/kasan/common.c:244 kasan_slab_free include/linux/kasan.h:162 [inline] slab_free_hook mm/slub.c:1781 [inline] slab_free_freelist_hook mm/slub.c:1807 [inline] slab_free mm/slub.c:3786 [inline] kmem_cache_free+0xb4/0x490 mm/slub.c:3808 sk_prot_free net/core/sock.c:2113 [inline] __sk_destruct+0x500/0x720 net/core/sock.c:2207 sk_destruct+0xc1/0xe0 net/core/sock.c:2222 __sk_free+0xed/0x3d0 net/core/sock.c:2233 sk_free+0x7c/0xa0 net/core/sock.c:2244 sock_put include/net/sock.h:1981 [inline] __gtp_encap_destroy+0x165/0x1b0 drivers/net/gtp.c:634 gtp_encap_disable_sock drivers/net/gtp.c:651 [inline] gtp_encap_disable+0xb9/0x220 drivers/net/gtp.c:664 gtp_dev_uninit+0x19/0x50 drivers/net/gtp.c:728 unregister_netdevice_many_notify+0x97e/0x1520 net/core/dev.c:10841 rtnl_delete_link net/core/rtnetlink.c:3216 [inline] rtnl_dellink+0x3c0/0xb30 net/core/rtnetlink.c:3268 rtnetlink_rcv_msg+0x450/0xb10 net/core/rtnetlink.c:6423 netlink_rcv_skb+0x15d/0x450 net/netlink/af_netlink.c:2548 netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline] netlink_unicast+0x700/0x930 net/netlink/af_netlink.c:1365 netlink_sendmsg+0x91c/0xe30 net/netlink/af_netlink.c:1913 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg+0x1b7/0x200 net/socket.c:747 ____sys_sendmsg+0x75a/0x990 net/socket.c:2493 ___sys_sendmsg+0x11d/0x1c0 net/socket.c:2547 __sys_sendmsg+0xfe/0x1d0 net/socket.c:2576 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc
The buggy address belongs to the object at ffff88800dbef300 which belongs to the cache UDPv6 of size 1344 The buggy address is located 152 bytes inside of freed 1344-byte region [ffff88800dbef300, ffff88800dbef840)
The buggy address belongs to the physical page: page:00000000d31bfed5 refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff88800dbeed40 pfn:0xdbe8 head:00000000d31bfed5 order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0 memcg:ffff888008ee0801 flags: 0x100000000010200(slab|head|node=0|zone=1) page_type: 0xffffffff() raw: 0100000000010200 ffff88800c7a3000 dead000000000122 0000000000000000 raw: ffff88800dbeed40 0000000080160015 00000001ffffffff ffff888008ee0801 page dumped because: kasan: bad access detected
Memory state around the buggy address: ffff88800dbef280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff88800dbef300: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88800dbef380: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^ ffff88800dbef400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff88800dbef480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
Fixes: e198987e7dd7 ("gtp: fix suspicious RCU usage") Reported-by: syzkaller syzkaller@googlegroups.com Signed-off-by: Kuniyuki Iwashima kuniyu@amazon.com Reviewed-by: Pablo Neira Ayuso pablo@netfilter.org Link: https://lore.kernel.org/r/20230622213231.24651-1-kuniyu@amazon.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/gtp.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index 15c7dc82107f4..acb20ad4e37eb 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -631,7 +631,9 @@ static void __gtp_encap_destroy(struct sock *sk) gtp->sk1u = NULL; udp_sk(sk)->encap_type = 0; rcu_assign_sk_user_data(sk, NULL); + release_sock(sk); sock_put(sk); + return; } release_sock(sk); }
From: Maxim Kochetkov fido_max@inbox.ru
[ Upstream commit f1bc9fc4a06de0108e0dca2a9a7e99ba1fc632f9 ]
64-bit DMA detection will fail if axienet was started before (by boot loader, boot ROM, etc). In this state axienet will not start properly. XAXIDMA_TX_CDESC_OFFSET + 4 register (MM2S_CURDESC_MSB) is used to detect 64-bit DMA capability here. But datasheet says: When DMACR.RS is 1 (axienet is in enabled state), CURDESC_PTR becomes Read Only (RO) and is used to fetch the first descriptor. So iowrite32()/ioread32() trick to this register to detect 64-bit DMA will not work. So move axienet reset before 64-bit DMA detection.
Fixes: f735c40ed93c ("net: axienet: Autodetect 64-bit DMA capability") Signed-off-by: Maxim Kochetkov fido_max@inbox.ru Reviewed-by: Robert Hancock robert.hancock@calian.com Reviewed-by: Radhey Shyam Pandey radhey.shyam.pandey@amd.com Link: https://lore.kernel.org/r/20230622192245.116864-1-fido_max@inbox.ru Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 3e310b55bce2b..734822321e0ab 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -2042,6 +2042,11 @@ static int axienet_probe(struct platform_device *pdev) goto cleanup_clk; }
+ /* Reset core now that clocks are enabled, prior to accessing MDIO */ + ret = __axienet_device_reset(lp); + if (ret) + goto cleanup_clk; + /* Autodetect the need for 64-bit DMA pointers. * When the IP is configured for a bus width bigger than 32 bits, * writing the MSB registers is mandatory, even if they are all 0. @@ -2096,11 +2101,6 @@ static int axienet_probe(struct platform_device *pdev) lp->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD; lp->coalesce_usec_tx = XAXIDMA_DFT_TX_USEC;
- /* Reset core now that clocks are enabled, prior to accessing MDIO */ - ret = __axienet_device_reset(lp); - if (ret) - goto cleanup_clk; - ret = axienet_mdio_setup(lp); if (ret) dev_warn(&pdev->dev,
From: David Howells dhowells@redhat.com
[ Upstream commit 86d7bd6e66e9925f0f04a7bcf3c92c05fdfefb5a ]
ocfs2 uses kzalloc() to allocate buffers for o2net_hand, o2net_keep_req and o2net_keep_resp and then passes these to sendpage. This isn't really allowed as the lifetime of slab objects is not controlled by page ref - though in this case it will probably work. sendmsg() with MSG_SPLICE_PAGES will, however, print a warning and give an error.
Fix it to use folio_alloc() instead to allocate a buffer for the handshake message, keepalive request and reply messages.
Fixes: 98211489d414 ("[PATCH] OCFS2: The Second Oracle Cluster Filesystem") Signed-off-by: David Howells dhowells@redhat.com cc: Mark Fasheh mark@fasheh.com cc: Kurt Hackel kurt.hackel@oracle.com cc: Joel Becker jlbec@evilplan.org cc: Joseph Qi joseph.qi@linux.alibaba.com cc: ocfs2-devel@oss.oracle.com Link: https://lore.kernel.org/r/20230623225513.2732256-14-dhowells@redhat.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ocfs2/cluster/tcp.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index aecbd712a00cf..929a1133bc180 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c @@ -2087,18 +2087,24 @@ void o2net_stop_listening(struct o2nm_node *node)
int o2net_init(void) { + struct folio *folio; + void *p; unsigned long i;
o2quo_init(); - o2net_debugfs_init();
- o2net_hand = kzalloc(sizeof(struct o2net_handshake), GFP_KERNEL); - o2net_keep_req = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL); - o2net_keep_resp = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL); - if (!o2net_hand || !o2net_keep_req || !o2net_keep_resp) + folio = folio_alloc(GFP_KERNEL | __GFP_ZERO, 0); + if (!folio) goto out;
+ p = folio_address(folio); + o2net_hand = p; + p += sizeof(struct o2net_handshake); + o2net_keep_req = p; + p += sizeof(struct o2net_msg); + o2net_keep_resp = p; + o2net_hand->protocol_version = cpu_to_be64(O2NET_PROTOCOL_VERSION); o2net_hand->connector_id = cpu_to_be64(1);
@@ -2124,9 +2130,6 @@ int o2net_init(void) return 0;
out: - kfree(o2net_hand); - kfree(o2net_keep_req); - kfree(o2net_keep_resp); o2net_debugfs_exit(); o2quo_exit(); return -ENOMEM; @@ -2135,8 +2138,6 @@ int o2net_init(void) void o2net_exit(void) { o2quo_exit(); - kfree(o2net_hand); - kfree(o2net_keep_req); - kfree(o2net_keep_resp); o2net_debugfs_exit(); + folio_put(virt_to_folio(o2net_hand)); }
From: Edward Cree ecree.xilinx@gmail.com
[ Upstream commit d1b355438b8325a486f087e506d412c4e852f37b ]
efx_net_stats() (.ndo_get_stats64) can be called during an ethtool selftest, during which time nic_data->mc_stats is NULL as the NIC has been fini'd. In this case do not attempt to fetch the latest stats from the hardware, else we will crash on a NULL dereference: BUG: kernel NULL pointer dereference, address: 0000000000000038 RIP efx_nic_update_stats abridged calltrace: efx_ef10_update_stats_pf efx_net_stats dev_get_stats dev_seq_printf_stats Skipping the read is safe, we will simply give out stale stats. To ensure that the free in efx_ef10_fini_nic() does not race against efx_ef10_update_stats_pf(), which could cause a TOCTTOU bug, take the efx->stats_lock in fini_nic (it is already held across update_stats).
Fixes: d3142c193dca ("sfc: refactor EF10 stats handling") Reviewed-by: Pieter Jansen van Vuuren pieter.jansen-van-vuuren@amd.com Signed-off-by: Edward Cree ecree.xilinx@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/sfc/ef10.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index b63e47af63655..8c019f382a7f3 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -1297,8 +1297,10 @@ static void efx_ef10_fini_nic(struct efx_nic *efx) { struct efx_ef10_nic_data *nic_data = efx->nic_data;
+ spin_lock_bh(&efx->stats_lock); kfree(nic_data->mc_stats); nic_data->mc_stats = NULL; + spin_unlock_bh(&efx->stats_lock); }
static int efx_ef10_init_nic(struct efx_nic *efx) @@ -1852,9 +1854,14 @@ static size_t efx_ef10_update_stats_pf(struct efx_nic *efx, u64 *full_stats,
efx_ef10_get_stat_mask(efx, mask);
- efx_nic_copy_stats(efx, nic_data->mc_stats); - efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, - mask, stats, nic_data->mc_stats, false); + /* If NIC was fini'd (probably resetting), then we can't read + * updated stats right now. + */ + if (nic_data->mc_stats) { + efx_nic_copy_stats(efx, nic_data->mc_stats); + efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, + mask, stats, nic_data->mc_stats, false); + }
/* Update derived statistics */ efx_nic_fix_nodesc_drop_stat(efx,
From: Lin Ma linma@zju.edu.cn
[ Upstream commit 6709d4b7bc2e079241fdef15d1160581c5261c10 ]
This commit fixes several use-after-free that caused by function nfc_llcp_find_local(). For example, one UAF can happen when below buggy time window occurs.
// nfc_genl_llc_get_params | // nfc_unregister_device | dev = nfc_get_device(idx); | device_lock(...) if (!dev) | dev->shutting_down = true; return -ENODEV; | device_unlock(...); | device_lock(...); | // nfc_llcp_unregister_device | nfc_llcp_find_local() nfc_llcp_find_local(...); | | local_cleanup() if (!local) { | rc = -ENODEV; | // nfc_llcp_local_put goto exit; | kref_put(.., local_release) } | | // local_release | list_del(&local->list) // nfc_genl_send_params | kfree() local->dev->idx !!!UAF!!! | |
and the crash trace for the one of the discussed UAF like:
BUG: KASAN: slab-use-after-free in nfc_genl_llc_get_params+0x72f/0x780 net/nfc/netlink.c:1045 Read of size 8 at addr ffff888105b0e410 by task 20114
Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x72/0xa0 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:319 [inline] print_report+0xcc/0x620 mm/kasan/report.c:430 kasan_report+0xb2/0xe0 mm/kasan/report.c:536 nfc_genl_send_params net/nfc/netlink.c:999 [inline] nfc_genl_llc_get_params+0x72f/0x780 net/nfc/netlink.c:1045 genl_family_rcv_msg_doit.isra.0+0x1ee/0x2e0 net/netlink/genetlink.c:968 genl_family_rcv_msg net/netlink/genetlink.c:1048 [inline] genl_rcv_msg+0x503/0x7d0 net/netlink/genetlink.c:1065 netlink_rcv_skb+0x161/0x430 net/netlink/af_netlink.c:2548 genl_rcv+0x28/0x40 net/netlink/genetlink.c:1076 netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline] netlink_unicast+0x644/0x900 net/netlink/af_netlink.c:1365 netlink_sendmsg+0x934/0xe70 net/netlink/af_netlink.c:1913 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg+0x1b6/0x200 net/socket.c:747 ____sys_sendmsg+0x6e9/0x890 net/socket.c:2501 ___sys_sendmsg+0x110/0x1b0 net/socket.c:2555 __sys_sendmsg+0xf7/0x1d0 net/socket.c:2584 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc RIP: 0033:0x7f34640a2389 RSP: 002b:00007f3463415168 EFLAGS: 00000246 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 00007f34641c1f80 RCX: 00007f34640a2389 RDX: 0000000000000000 RSI: 0000000020000240 RDI: 0000000000000006 RBP: 00007f34640ed493 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007ffe38449ecf R14: 00007f3463415300 R15: 0000000000022000 </TASK>
Allocated by task 20116: kasan_save_stack+0x22/0x50 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 ____kasan_kmalloc mm/kasan/common.c:374 [inline] __kasan_kmalloc+0x7f/0x90 mm/kasan/common.c:383 kmalloc include/linux/slab.h:580 [inline] kzalloc include/linux/slab.h:720 [inline] nfc_llcp_register_device+0x49/0xa40 net/nfc/llcp_core.c:1567 nfc_register_device+0x61/0x260 net/nfc/core.c:1124 nci_register_device+0x776/0xb20 net/nfc/nci/core.c:1257 virtual_ncidev_open+0x147/0x230 drivers/nfc/virtual_ncidev.c:148 misc_open+0x379/0x4a0 drivers/char/misc.c:165 chrdev_open+0x26c/0x780 fs/char_dev.c:414 do_dentry_open+0x6c4/0x12a0 fs/open.c:920 do_open fs/namei.c:3560 [inline] path_openat+0x24fe/0x37e0 fs/namei.c:3715 do_filp_open+0x1ba/0x410 fs/namei.c:3742 do_sys_openat2+0x171/0x4c0 fs/open.c:1356 do_sys_open fs/open.c:1372 [inline] __do_sys_openat fs/open.c:1388 [inline] __se_sys_openat fs/open.c:1383 [inline] __x64_sys_openat+0x143/0x200 fs/open.c:1383 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc
Freed by task 20115: kasan_save_stack+0x22/0x50 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 kasan_save_free_info+0x2e/0x50 mm/kasan/generic.c:521 ____kasan_slab_free mm/kasan/common.c:236 [inline] ____kasan_slab_free mm/kasan/common.c:200 [inline] __kasan_slab_free+0x10a/0x190 mm/kasan/common.c:244 kasan_slab_free include/linux/kasan.h:162 [inline] slab_free_hook mm/slub.c:1781 [inline] slab_free_freelist_hook mm/slub.c:1807 [inline] slab_free mm/slub.c:3787 [inline] __kmem_cache_free+0x7a/0x190 mm/slub.c:3800 local_release net/nfc/llcp_core.c:174 [inline] kref_put include/linux/kref.h:65 [inline] nfc_llcp_local_put net/nfc/llcp_core.c:182 [inline] nfc_llcp_local_put net/nfc/llcp_core.c:177 [inline] nfc_llcp_unregister_device+0x206/0x290 net/nfc/llcp_core.c:1620 nfc_unregister_device+0x160/0x1d0 net/nfc/core.c:1179 virtual_ncidev_close+0x52/0xa0 drivers/nfc/virtual_ncidev.c:163 __fput+0x252/0xa20 fs/file_table.c:321 task_work_run+0x174/0x270 kernel/task_work.c:179 resume_user_mode_work include/linux/resume_user_mode.h:49 [inline] exit_to_user_mode_loop kernel/entry/common.c:171 [inline] exit_to_user_mode_prepare+0x108/0x110 kernel/entry/common.c:204 __syscall_exit_to_user_mode_work kernel/entry/common.c:286 [inline] syscall_exit_to_user_mode+0x21/0x50 kernel/entry/common.c:297 do_syscall_64+0x4c/0x90 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x72/0xdc
Last potentially related work creation: kasan_save_stack+0x22/0x50 mm/kasan/common.c:45 __kasan_record_aux_stack+0x95/0xb0 mm/kasan/generic.c:491 kvfree_call_rcu+0x29/0xa80 kernel/rcu/tree.c:3328 drop_sysctl_table+0x3be/0x4e0 fs/proc/proc_sysctl.c:1735 unregister_sysctl_table.part.0+0x9c/0x190 fs/proc/proc_sysctl.c:1773 unregister_sysctl_table+0x24/0x30 fs/proc/proc_sysctl.c:1753 neigh_sysctl_unregister+0x5f/0x80 net/core/neighbour.c:3895 addrconf_notify+0x140/0x17b0 net/ipv6/addrconf.c:3684 notifier_call_chain+0xbe/0x210 kernel/notifier.c:87 call_netdevice_notifiers_info+0xb5/0x150 net/core/dev.c:1937 call_netdevice_notifiers_extack net/core/dev.c:1975 [inline] call_netdevice_notifiers net/core/dev.c:1989 [inline] dev_change_name+0x3c3/0x870 net/core/dev.c:1211 dev_ifsioc+0x800/0xf70 net/core/dev_ioctl.c:376 dev_ioctl+0x3d9/0xf80 net/core/dev_ioctl.c:542 sock_do_ioctl+0x160/0x260 net/socket.c:1213 sock_ioctl+0x3f9/0x670 net/socket.c:1316 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:870 [inline] __se_sys_ioctl fs/ioctl.c:856 [inline] __x64_sys_ioctl+0x19e/0x210 fs/ioctl.c:856 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc
The buggy address belongs to the object at ffff888105b0e400 which belongs to the cache kmalloc-1k of size 1024 The buggy address is located 16 bytes inside of freed 1024-byte region [ffff888105b0e400, ffff888105b0e800)
The buggy address belongs to the physical page: head:ffffea000416c200 order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0 flags: 0x200000000010200(slab|head|node=0|zone=2) raw: 0200000000010200 ffff8881000430c0 ffffea00044c7010 ffffea0004510e10 raw: 0000000000000000 00000000000a000a 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected
Memory state around the buggy address: ffff888105b0e300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff888105b0e380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff888105b0e400: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^ ffff888105b0e480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff888105b0e500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
In summary, this patch solves those use-after-free by
1. Re-implement the nfc_llcp_find_local(). The current version does not grab the reference when getting the local from the linked list. For example, the llcp_sock_bind() gets the reference like below:
// llcp_sock_bind()
local = nfc_llcp_find_local(dev); // A ..... \ | raceable ..... / llcp_sock->local = nfc_llcp_local_get(local); // B
There is an apparent race window that one can drop the reference and free the local object fetched in (A) before (B) gets the reference.
2. Some callers of the nfc_llcp_find_local() do not grab the reference at all. For example, the nfc_genl_llc_{{get/set}_params/sdreq} functions. We add the nfc_llcp_local_put() for them. Moreover, we add the necessary error handling function to put the reference.
3. Add the nfc_llcp_remove_local() helper. The local object is removed from the linked list in local_release() when all reference is gone. This patch removes it when nfc_llcp_unregister_device() is called.
Therefore, every caller of nfc_llcp_find_local() will get a reference even when the nfc_llcp_unregister_device() is called. This promises no use-after-free for the local object is ever possible.
Fixes: 52feb444a903 ("NFC: Extend netlink interface for LTO, RW, and MIUX parameters support") Fixes: c7aa12252f51 ("NFC: Take a reference on the LLCP local pointer when creating a socket") Signed-off-by: Lin Ma linma@zju.edu.cn Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/nfc/llcp.h | 1 - net/nfc/llcp_commands.c | 12 +++++++--- net/nfc/llcp_core.c | 49 +++++++++++++++++++++++++++++++++++------ net/nfc/llcp_sock.c | 18 ++++++++------- net/nfc/netlink.c | 20 ++++++++++++----- net/nfc/nfc.h | 1 + 6 files changed, 77 insertions(+), 24 deletions(-)
diff --git a/net/nfc/llcp.h b/net/nfc/llcp.h index c1d9be636933c..d8345ed57c954 100644 --- a/net/nfc/llcp.h +++ b/net/nfc/llcp.h @@ -201,7 +201,6 @@ void nfc_llcp_sock_link(struct llcp_sock_list *l, struct sock *s); void nfc_llcp_sock_unlink(struct llcp_sock_list *l, struct sock *s); void nfc_llcp_socket_remote_param_init(struct nfc_llcp_sock *sock); struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev); -struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local); int nfc_llcp_local_put(struct nfc_llcp_local *local); u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local, struct nfc_llcp_sock *sock); diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c index cdb001de06928..e2680a3bef799 100644 --- a/net/nfc/llcp_commands.c +++ b/net/nfc/llcp_commands.c @@ -359,6 +359,7 @@ int nfc_llcp_send_symm(struct nfc_dev *dev) struct sk_buff *skb; struct nfc_llcp_local *local; u16 size = 0; + int err;
local = nfc_llcp_find_local(dev); if (local == NULL) @@ -368,8 +369,10 @@ int nfc_llcp_send_symm(struct nfc_dev *dev) size += dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE;
skb = alloc_skb(size, GFP_KERNEL); - if (skb == NULL) - return -ENOMEM; + if (skb == NULL) { + err = -ENOMEM; + goto out; + }
skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE);
@@ -379,8 +382,11 @@ int nfc_llcp_send_symm(struct nfc_dev *dev)
nfc_llcp_send_to_raw_sock(local, skb, NFC_DIRECTION_TX);
- return nfc_data_exchange(dev, local->target_idx, skb, + err = nfc_data_exchange(dev, local->target_idx, skb, nfc_llcp_recv, local); +out: + nfc_llcp_local_put(local); + return err; }
int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c index a27e1842b2a09..f60e424e06076 100644 --- a/net/nfc/llcp_core.c +++ b/net/nfc/llcp_core.c @@ -17,6 +17,8 @@ static u8 llcp_magic[3] = {0x46, 0x66, 0x6d};
static LIST_HEAD(llcp_devices); +/* Protects llcp_devices list */ +static DEFINE_SPINLOCK(llcp_devices_lock);
static void nfc_llcp_rx_skb(struct nfc_llcp_local *local, struct sk_buff *skb);
@@ -141,7 +143,7 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device, write_unlock(&local->raw_sockets.lock); }
-struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local) +static struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local) { kref_get(&local->ref);
@@ -169,7 +171,6 @@ static void local_release(struct kref *ref)
local = container_of(ref, struct nfc_llcp_local, ref);
- list_del(&local->list); local_cleanup(local); kfree(local); } @@ -282,12 +283,33 @@ static void nfc_llcp_sdreq_timer(struct timer_list *t) struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev) { struct nfc_llcp_local *local; + struct nfc_llcp_local *res = NULL;
+ spin_lock(&llcp_devices_lock); list_for_each_entry(local, &llcp_devices, list) - if (local->dev == dev) + if (local->dev == dev) { + res = nfc_llcp_local_get(local); + break; + } + spin_unlock(&llcp_devices_lock); + + return res; +} + +static struct nfc_llcp_local *nfc_llcp_remove_local(struct nfc_dev *dev) +{ + struct nfc_llcp_local *local, *tmp; + + spin_lock(&llcp_devices_lock); + list_for_each_entry_safe(local, tmp, &llcp_devices, list) + if (local->dev == dev) { + list_del(&local->list); + spin_unlock(&llcp_devices_lock); return local; + } + spin_unlock(&llcp_devices_lock);
- pr_debug("No device found\n"); + pr_warn("Shutting down device not found\n");
return NULL; } @@ -608,12 +630,15 @@ u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len)
*general_bytes_len = local->gb_len;
+ nfc_llcp_local_put(local); + return local->gb; }
int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len) { struct nfc_llcp_local *local; + int err;
if (gb_len < 3 || gb_len > NFC_MAX_GT_LEN) return -EINVAL; @@ -630,12 +655,16 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len)
if (memcmp(local->remote_gb, llcp_magic, 3)) { pr_err("MAC does not support LLCP\n"); - return -EINVAL; + err = -EINVAL; + goto out; }
- return nfc_llcp_parse_gb_tlv(local, + err = nfc_llcp_parse_gb_tlv(local, &local->remote_gb[3], local->remote_gb_len - 3); +out: + nfc_llcp_local_put(local); + return err; }
static u8 nfc_llcp_dsap(const struct sk_buff *pdu) @@ -1517,6 +1546,8 @@ int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb)
__nfc_llcp_recv(local, skb);
+ nfc_llcp_local_put(local); + return 0; }
@@ -1533,6 +1564,8 @@ void nfc_llcp_mac_is_down(struct nfc_dev *dev)
/* Close and purge all existing sockets */ nfc_llcp_socket_release(local, true, 0); + + nfc_llcp_local_put(local); }
void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, @@ -1558,6 +1591,8 @@ void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, mod_timer(&local->link_timer, jiffies + msecs_to_jiffies(local->remote_lto)); } + + nfc_llcp_local_put(local); }
int nfc_llcp_register_device(struct nfc_dev *ndev) @@ -1608,7 +1643,7 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
void nfc_llcp_unregister_device(struct nfc_dev *dev) { - struct nfc_llcp_local *local = nfc_llcp_find_local(dev); + struct nfc_llcp_local *local = nfc_llcp_remove_local(dev);
if (local == NULL) { pr_debug("No such device\n"); diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c index 77642d18a3b43..645677f84dba2 100644 --- a/net/nfc/llcp_sock.c +++ b/net/nfc/llcp_sock.c @@ -99,7 +99,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) }
llcp_sock->dev = dev; - llcp_sock->local = nfc_llcp_local_get(local); + llcp_sock->local = local; llcp_sock->nfc_protocol = llcp_addr.nfc_protocol; llcp_sock->service_name_len = min_t(unsigned int, llcp_addr.service_name_len, @@ -186,7 +186,7 @@ static int llcp_raw_sock_bind(struct socket *sock, struct sockaddr *addr, }
llcp_sock->dev = dev; - llcp_sock->local = nfc_llcp_local_get(local); + llcp_sock->local = local; llcp_sock->nfc_protocol = llcp_addr.nfc_protocol;
nfc_llcp_sock_link(&local->raw_sockets, sk); @@ -696,22 +696,22 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, if (dev->dep_link_up == false) { ret = -ENOLINK; device_unlock(&dev->dev); - goto put_dev; + goto sock_llcp_put_local; } device_unlock(&dev->dev);
if (local->rf_mode == NFC_RF_INITIATOR && addr->target_idx != local->target_idx) { ret = -ENOLINK; - goto put_dev; + goto sock_llcp_put_local; }
llcp_sock->dev = dev; - llcp_sock->local = nfc_llcp_local_get(local); + llcp_sock->local = local; llcp_sock->ssap = nfc_llcp_get_local_ssap(local); if (llcp_sock->ssap == LLCP_SAP_MAX) { ret = -ENOMEM; - goto sock_llcp_put_local; + goto sock_llcp_nullify; }
llcp_sock->reserved_ssap = llcp_sock->ssap; @@ -757,11 +757,13 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, sock_llcp_release: nfc_llcp_put_ssap(local, llcp_sock->ssap);
-sock_llcp_put_local: - nfc_llcp_local_put(llcp_sock->local); +sock_llcp_nullify: llcp_sock->local = NULL; llcp_sock->dev = NULL;
+sock_llcp_put_local: + nfc_llcp_local_put(local); + put_dev: nfc_put_device(dev);
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index b9264e730fd93..e9ac6a6f934e7 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -1039,11 +1039,14 @@ static int nfc_genl_llc_get_params(struct sk_buff *skb, struct genl_info *info) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) { rc = -ENOMEM; - goto exit; + goto put_local; }
rc = nfc_genl_send_params(msg, local, info->snd_portid, info->snd_seq);
+put_local: + nfc_llcp_local_put(local); + exit: device_unlock(&dev->dev);
@@ -1105,7 +1108,7 @@ static int nfc_genl_llc_set_params(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NFC_ATTR_LLC_PARAM_LTO]) { if (dev->dep_link_up) { rc = -EINPROGRESS; - goto exit; + goto put_local; }
local->lto = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_LTO]); @@ -1117,6 +1120,9 @@ static int nfc_genl_llc_set_params(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX]) local->miux = cpu_to_be16(miux);
+put_local: + nfc_llcp_local_put(local); + exit: device_unlock(&dev->dev);
@@ -1172,7 +1178,7 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
if (rc != 0) { rc = -EINVAL; - goto exit; + goto put_local; }
if (!sdp_attrs[NFC_SDP_ATTR_URI]) @@ -1191,7 +1197,7 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info) sdreq = nfc_llcp_build_sdreq_tlv(tid, uri, uri_len); if (sdreq == NULL) { rc = -ENOMEM; - goto exit; + goto put_local; }
tlvs_len += sdreq->tlv_len; @@ -1201,10 +1207,14 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
if (hlist_empty(&sdreq_list)) { rc = -EINVAL; - goto exit; + goto put_local; }
rc = nfc_llcp_send_snl_sdreq(local, &sdreq_list, tlvs_len); + +put_local: + nfc_llcp_local_put(local); + exit: device_unlock(&dev->dev);
diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h index de2ec66d7e83a..0b1e6466f4fbf 100644 --- a/net/nfc/nfc.h +++ b/net/nfc/nfc.h @@ -52,6 +52,7 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len); u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len); int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb); struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev); +int nfc_llcp_local_put(struct nfc_llcp_local *local); int __init nfc_llcp_init(void); void nfc_llcp_exit(void); void nfc_llcp_free_sdp_tlv(struct nfc_llcp_sdp_tlv *sdp);
From: Jeremy Sowden jeremy@azazel.net
[ Upstream commit 6f67fbf8192da80c4db01a1800c7fceaca9cf1f9 ]
The `shift` variable which indicates the offset in the string at which to start matching the pattern is initialized to `bm->patlen - 1`, but it is not reset when a new block is retrieved. This means the implemen- tation may start looking at later and later positions in each successive block and miss occurrences of the pattern at the beginning. E.g., consider a HTTP packet held in a non-linear skb, where the HTTP request line occurs in the second block:
[... 52 bytes of packet headers ...] GET /bmtest HTTP/1.1\r\nHost: www.example.com\r\n\r\n
and the pattern is "GET /bmtest".
Once the first block comprising the packet headers has been examined, `shift` will be pointing to somewhere near the end of the block, and so when the second block is examined the request line at the beginning will be missed.
Reinitialize the variable for each new block.
Fixes: 8082e4ed0a61 ("[LIB]: Boyer-Moore extension for textsearch infrastructure strike #2") Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1390 Signed-off-by: Jeremy Sowden jeremy@azazel.net Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/ts_bm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/ts_bm.c b/lib/ts_bm.c index 1f2234221dd11..c8ecbf74ef295 100644 --- a/lib/ts_bm.c +++ b/lib/ts_bm.c @@ -60,10 +60,12 @@ static unsigned int bm_find(struct ts_config *conf, struct ts_state *state) struct ts_bm *bm = ts_config_priv(conf); unsigned int i, text_len, consumed = state->offset; const u8 *text; - int shift = bm->patlen - 1, bs; + int bs; const u8 icase = conf->flags & TS_IGNORECASE;
for (;;) { + int shift = bm->patlen - 1; + text_len = conf->get_next_block(consumed, &text, conf, state);
if (unlikely(text_len == 0))
From: Florian Westphal fw@strlen.de
[ Upstream commit ff0a3a7d52ff7282dbd183e7fc29a1fe386b0c30 ]
Eric Dumazet says: nf_conntrack_dccp_packet() has an unique:
dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
And nothing more is 'pulled' from the packet, depending on the content. dh->dccph_doff, and/or dh->dccph_x ...) So dccp_ack_seq() is happily reading stuff past the _dh buffer.
BUG: KASAN: stack-out-of-bounds in nf_conntrack_dccp_packet+0x1134/0x11c0 Read of size 4 at addr ffff000128f66e0c by task syz-executor.2/29371 [..]
Fix this by increasing the stack buffer to also include room for the extra sequence numbers and all the known dccp packet type headers, then pull again after the initial validation of the basic header.
While at it, mark packets invalid that lack 48bit sequence bit but where RFC says the type MUST use them.
Compile tested only.
v2: first skb_header_pointer() now needs to adjust the size to only pull the generic header. (Eric)
Heads-up: I intend to remove dccp conntrack support later this year.
Fixes: 2bc780499aa3 ("[NETFILTER]: nf_conntrack: add DCCP protocol support") Reported-by: Eric Dumazet edumazet@google.com Signed-off-by: Florian Westphal fw@strlen.de Reviewed-by: Eric Dumazet edumazet@google.com Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/netfilter/nf_conntrack_proto_dccp.c | 52 +++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c index c1557d47ccd1e..d4fd626d2b8c3 100644 --- a/net/netfilter/nf_conntrack_proto_dccp.c +++ b/net/netfilter/nf_conntrack_proto_dccp.c @@ -432,9 +432,19 @@ static bool dccp_error(const struct dccp_hdr *dh, struct sk_buff *skb, unsigned int dataoff, const struct nf_hook_state *state) { + static const unsigned long require_seq48 = 1 << DCCP_PKT_REQUEST | + 1 << DCCP_PKT_RESPONSE | + 1 << DCCP_PKT_CLOSEREQ | + 1 << DCCP_PKT_CLOSE | + 1 << DCCP_PKT_RESET | + 1 << DCCP_PKT_SYNC | + 1 << DCCP_PKT_SYNCACK; unsigned int dccp_len = skb->len - dataoff; unsigned int cscov; const char *msg; + u8 type; + + BUILD_BUG_ON(DCCP_PKT_INVALID >= BITS_PER_LONG);
if (dh->dccph_doff * 4 < sizeof(struct dccp_hdr) || dh->dccph_doff * 4 > dccp_len) { @@ -459,34 +469,70 @@ static bool dccp_error(const struct dccp_hdr *dh, goto out_invalid; }
- if (dh->dccph_type >= DCCP_PKT_INVALID) { + type = dh->dccph_type; + if (type >= DCCP_PKT_INVALID) { msg = "nf_ct_dccp: reserved packet type "; goto out_invalid; } + + if (test_bit(type, &require_seq48) && !dh->dccph_x) { + msg = "nf_ct_dccp: type lacks 48bit sequence numbers"; + goto out_invalid; + } + return false; out_invalid: nf_l4proto_log_invalid(skb, state, IPPROTO_DCCP, "%s", msg); return true; }
+struct nf_conntrack_dccp_buf { + struct dccp_hdr dh; /* generic header part */ + struct dccp_hdr_ext ext; /* optional depending dh->dccph_x */ + union { /* depends on header type */ + struct dccp_hdr_ack_bits ack; + struct dccp_hdr_request req; + struct dccp_hdr_response response; + struct dccp_hdr_reset rst; + } u; +}; + +static struct dccp_hdr * +dccp_header_pointer(const struct sk_buff *skb, int offset, const struct dccp_hdr *dh, + struct nf_conntrack_dccp_buf *buf) +{ + unsigned int hdrlen = __dccp_hdr_len(dh); + + if (hdrlen > sizeof(*buf)) + return NULL; + + return skb_header_pointer(skb, offset, hdrlen, buf); +} + int nf_conntrack_dccp_packet(struct nf_conn *ct, struct sk_buff *skb, unsigned int dataoff, enum ip_conntrack_info ctinfo, const struct nf_hook_state *state) { enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); - struct dccp_hdr _dh, *dh; + struct nf_conntrack_dccp_buf _dh; u_int8_t type, old_state, new_state; enum ct_dccp_roles role; unsigned int *timeouts; + struct dccp_hdr *dh;
- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh); + dh = skb_header_pointer(skb, dataoff, sizeof(*dh), &_dh.dh); if (!dh) return NF_DROP;
if (dccp_error(dh, skb, dataoff, state)) return -NF_ACCEPT;
+ /* pull again, including possible 48 bit sequences and subtype header */ + dh = dccp_header_pointer(skb, dataoff, dh, &_dh); + if (!dh) + return NF_DROP; + type = dh->dccph_type; if (!nf_ct_is_confirmed(ct) && !dccp_new(ct, skb, dh, state)) return -NF_ACCEPT;
From: Ilia.Gavrilov Ilia.Gavrilov@infotecs.ru
[ Upstream commit f188d30087480eab421cd8ca552fb15f55d57f4d ]
ct_sip_parse_numerical_param() returns only 0 or 1 now. But process_register_request() and process_register_response() imply checking for a negative value if parsing of a numerical header parameter failed. The invocation in nf_nat_sip() looks correct: if (ct_sip_parse_numerical_param(...) > 0 && ...) { ... }
Make the return value of the function ct_sip_parse_numerical_param() a tristate to fix all the cases a) return 1 if value is found; *val is set b) return 0 if value is not found; *val is unchanged c) return -1 on error; *val is undefined
Found by InfoTeCS on behalf of Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: 0f32a40fc91a ("[NETFILTER]: nf_conntrack_sip: create signalling expectations") Signed-off-by: Ilia.Gavrilov Ilia.Gavrilov@infotecs.ru Reviewed-by: Simon Horman simon.horman@corigine.com Reviewed-by: Florian Westphal fw@strlen.de Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/netfilter/nf_conntrack_sip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 77f5e82d8e3fe..d0eac27f6ba03 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -611,7 +611,7 @@ int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr, start += strlen(name); *val = simple_strtoul(start, &end, 0); if (start == end) - return 0; + return -1; if (matchoff && matchlen) { *matchoff = start - dptr; *matchlen = end - start;
From: Cambda Zhu cambda@linux.alibaba.com
[ Upstream commit 8a9922e7be6d042fa00f894c376473b17a162b66 ]
ipvlan_queue_xmit() should return NET_XMIT_XXX, but ipvlan_xmit_mode_l2/l3() returns rx_handler_result_t or NET_RX_XXX in some cases. ipvlan_rcv_frame() will only return RX_HANDLER_CONSUMED in ipvlan_xmit_mode_l2/l3() because 'local' is true. It's equal to NET_XMIT_SUCCESS. But dev_forward_skb() can return NET_RX_SUCCESS or NET_RX_DROP, and returning NET_RX_DROP(NET_XMIT_DROP) will increase both ipvlan and ipvlan->phy_dev drops counter.
The skb to forward can be treated as xmitted successfully. This patch makes ipvlan_queue_xmit() return NET_XMIT_SUCCESS for forward skb.
Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.") Signed-off-by: Cambda Zhu cambda@linux.alibaba.com Link: https://lore.kernel.org/r/20230626093347.7492-1-cambda@linux.alibaba.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ipvlan/ipvlan_core.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index ab5133eb1d517..e45817caaee8d 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c @@ -585,7 +585,8 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev) consume_skb(skb); return NET_XMIT_DROP; } - return ipvlan_rcv_frame(addr, &skb, true); + ipvlan_rcv_frame(addr, &skb, true); + return NET_XMIT_SUCCESS; } } out: @@ -611,7 +612,8 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev) consume_skb(skb); return NET_XMIT_DROP; } - return ipvlan_rcv_frame(addr, &skb, true); + ipvlan_rcv_frame(addr, &skb, true); + return NET_XMIT_SUCCESS; } } skb = skb_share_check(skb, GFP_ATOMIC); @@ -623,7 +625,8 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev) * the skb for the main-dev. At the RX side we just return * RX_PASS for it to be processed further on the stack. */ - return dev_forward_skb(ipvlan->phy_dev, skb); + dev_forward_skb(ipvlan->phy_dev, skb); + return NET_XMIT_SUCCESS;
} else if (is_multicast_ether_addr(eth->h_dest)) { skb_reset_mac_header(skb);
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit d06f925f13976ab82167c93467c70a337a0a3cda ]
When using the felix driver (the only one which supports UC filtering and MC filtering) as a DSA master for a random other DSA switch, one can see the following stack trace when the downstream switch ports join a VLAN-aware bridge:
============================= WARNING: suspicious RCU usage ----------------------------- net/8021q/vlan_core.c:238 suspicious rcu_dereference_protected() usage!
stack backtrace: Workqueue: dsa_ordered dsa_slave_switchdev_event_work Call trace: lockdep_rcu_suspicious+0x170/0x210 vlan_for_each+0x8c/0x188 dsa_slave_sync_uc+0x128/0x178 __hw_addr_sync_dev+0x138/0x158 dsa_slave_set_rx_mode+0x58/0x70 __dev_set_rx_mode+0x88/0xa8 dev_uc_add+0x74/0xa0 dsa_port_bridge_host_fdb_add+0xec/0x180 dsa_slave_switchdev_event_work+0x7c/0x1c8 process_one_work+0x290/0x568
What it's saying is that vlan_for_each() expects rtnl_lock() context and it's not getting it, when it's called from the DSA master's ndo_set_rx_mode().
The caller of that - dsa_slave_set_rx_mode() - is the slave DSA interface's dsa_port_bridge_host_fdb_add() which comes from the deferred dsa_slave_switchdev_event_work().
We went to great lengths to avoid the rtnl_lock() context in that call path in commit 0faf890fc519 ("net: dsa: drop rtnl_lock from dsa_slave_switchdev_event_work"), and calling rtnl_lock() is simply not an option due to the possibility of deadlocking when calling dsa_flush_workqueue() from the call paths that do hold rtnl_lock() - basically all of them.
So, when the DSA master calls vlan_for_each() from its ndo_set_rx_mode(), the state of the 8021q driver on this device is really not protected from concurrent access by anything.
Looking at net/8021q/, I don't think that vlan_info->vid_list was particularly designed with RCU traversal in mind, so introducing an RCU read-side form of vlan_for_each() - vlan_for_each_rcu() - won't be so easy, and it also wouldn't be exactly what we need anyway.
In general I believe that the solution isn't in net/8021q/ anyway; vlan_for_each() is not cut out for this task. DSA doesn't need rtnl_lock() to be held per se - since it's not a netdev state change that we're blocking, but rather, just concurrent additions/removals to a VLAN list. We don't even need sleepable context - the callback of vlan_for_each() just schedules deferred work.
The proposed escape is to remove the dependency on vlan_for_each() and to open-code a non-sleepable, rtnl-free alternative to that, based on copies of the VLAN list modified from .ndo_vlan_rx_add_vid() and .ndo_vlan_rx_kill_vid().
Fixes: 64fdc5f341db ("net: dsa: sync unicast and multicast addresses for VLAN filters too") Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Link: https://lore.kernel.org/r/20230626154402.3154454-1-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/dsa.h | 12 +++++-- net/dsa/dsa.c | 2 +- net/dsa/slave.c | 84 ++++++++++++++++++++++++++++++++--------------- net/dsa/switch.c | 4 +-- net/dsa/switch.h | 3 ++ 5 files changed, 74 insertions(+), 31 deletions(-)
diff --git a/include/net/dsa.h b/include/net/dsa.h index def06ef676dd8..56e297e7848d6 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -329,9 +329,17 @@ struct dsa_port { struct list_head fdbs; struct list_head mdbs;
- /* List of VLANs that CPU and DSA ports are members of. */ struct mutex vlans_lock; - struct list_head vlans; + union { + /* List of VLANs that CPU and DSA ports are members of. + * Access to this is serialized by the sleepable @vlans_lock. + */ + struct list_head vlans; + /* List of VLANs that user ports are members of. + * Access to this is serialized by netif_addr_lock_bh(). + */ + struct list_head user_vlans; + }; };
/* TODO: ideally DSA ports would have a single dp->link_dp member, diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 6cd8607a3928f..390d790c0b056 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -1105,7 +1105,7 @@ static struct dsa_port *dsa_port_touch(struct dsa_switch *ds, int index) mutex_init(&dp->vlans_lock); INIT_LIST_HEAD(&dp->fdbs); INIT_LIST_HEAD(&dp->mdbs); - INIT_LIST_HEAD(&dp->vlans); + INIT_LIST_HEAD(&dp->vlans); /* also initializes &dp->user_vlans */ INIT_LIST_HEAD(&dp->list); list_add_tail(&dp->list, &dst->ports);
diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 165bb2cb84316..527b1d576460f 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -27,6 +27,7 @@ #include "master.h" #include "netlink.h" #include "slave.h" +#include "switch.h" #include "tag.h"
struct dsa_switchdev_event_work { @@ -161,8 +162,7 @@ static int dsa_slave_schedule_standalone_work(struct net_device *dev, return 0; }
-static int dsa_slave_host_vlan_rx_filtering(struct net_device *vdev, int vid, - void *arg) +static int dsa_slave_host_vlan_rx_filtering(void *arg, int vid) { struct dsa_host_vlan_rx_filtering_ctx *ctx = arg;
@@ -170,6 +170,28 @@ static int dsa_slave_host_vlan_rx_filtering(struct net_device *vdev, int vid, ctx->addr, vid); }
+static int dsa_slave_vlan_for_each(struct net_device *dev, + int (*cb)(void *arg, int vid), void *arg) +{ + struct dsa_port *dp = dsa_slave_to_port(dev); + struct dsa_vlan *v; + int err; + + lockdep_assert_held(&dev->addr_list_lock); + + err = cb(arg, 0); + if (err) + return err; + + list_for_each_entry(v, &dp->user_vlans, list) { + err = cb(arg, v->vid); + if (err) + return err; + } + + return 0; +} + static int dsa_slave_sync_uc(struct net_device *dev, const unsigned char *addr) { @@ -180,18 +202,14 @@ static int dsa_slave_sync_uc(struct net_device *dev, .addr = addr, .event = DSA_UC_ADD, }; - int err;
dev_uc_add(master, addr);
if (!dsa_switch_supports_uc_filtering(dp->ds)) return 0;
- err = dsa_slave_schedule_standalone_work(dev, DSA_UC_ADD, addr, 0); - if (err) - return err; - - return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx); + return dsa_slave_vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, + &ctx); }
static int dsa_slave_unsync_uc(struct net_device *dev, @@ -204,18 +222,14 @@ static int dsa_slave_unsync_uc(struct net_device *dev, .addr = addr, .event = DSA_UC_DEL, }; - int err;
dev_uc_del(master, addr);
if (!dsa_switch_supports_uc_filtering(dp->ds)) return 0;
- err = dsa_slave_schedule_standalone_work(dev, DSA_UC_DEL, addr, 0); - if (err) - return err; - - return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx); + return dsa_slave_vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, + &ctx); }
static int dsa_slave_sync_mc(struct net_device *dev, @@ -228,18 +242,14 @@ static int dsa_slave_sync_mc(struct net_device *dev, .addr = addr, .event = DSA_MC_ADD, }; - int err;
dev_mc_add(master, addr);
if (!dsa_switch_supports_mc_filtering(dp->ds)) return 0;
- err = dsa_slave_schedule_standalone_work(dev, DSA_MC_ADD, addr, 0); - if (err) - return err; - - return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx); + return dsa_slave_vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, + &ctx); }
static int dsa_slave_unsync_mc(struct net_device *dev, @@ -252,18 +262,14 @@ static int dsa_slave_unsync_mc(struct net_device *dev, .addr = addr, .event = DSA_MC_DEL, }; - int err;
dev_mc_del(master, addr);
if (!dsa_switch_supports_mc_filtering(dp->ds)) return 0;
- err = dsa_slave_schedule_standalone_work(dev, DSA_MC_DEL, addr, 0); - if (err) - return err; - - return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx); + return dsa_slave_vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, + &ctx); }
void dsa_slave_sync_ha(struct net_device *dev) @@ -1759,6 +1765,7 @@ static int dsa_slave_vlan_rx_add_vid(struct net_device *dev, __be16 proto, struct netlink_ext_ack extack = {0}; struct dsa_switch *ds = dp->ds; struct netdev_hw_addr *ha; + struct dsa_vlan *v; int ret;
/* User port... */ @@ -1782,8 +1789,17 @@ static int dsa_slave_vlan_rx_add_vid(struct net_device *dev, __be16 proto, !dsa_switch_supports_mc_filtering(ds)) return 0;
+ v = kzalloc(sizeof(*v), GFP_KERNEL); + if (!v) { + ret = -ENOMEM; + goto rollback; + } + netif_addr_lock_bh(dev);
+ v->vid = vid; + list_add_tail(&v->list, &dp->user_vlans); + if (dsa_switch_supports_mc_filtering(ds)) { netdev_for_each_synced_mc_addr(ha, dev) { dsa_slave_schedule_standalone_work(dev, DSA_MC_ADD, @@ -1803,6 +1819,12 @@ static int dsa_slave_vlan_rx_add_vid(struct net_device *dev, __be16 proto, dsa_flush_workqueue();
return 0; + +rollback: + dsa_port_host_vlan_del(dp, &vlan); + dsa_port_vlan_del(dp, &vlan); + + return ret; }
static int dsa_slave_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, @@ -1816,6 +1838,7 @@ static int dsa_slave_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, }; struct dsa_switch *ds = dp->ds; struct netdev_hw_addr *ha; + struct dsa_vlan *v; int err;
err = dsa_port_vlan_del(dp, &vlan); @@ -1832,6 +1855,15 @@ static int dsa_slave_vlan_rx_kill_vid(struct net_device *dev, __be16 proto,
netif_addr_lock_bh(dev);
+ v = dsa_vlan_find(&dp->user_vlans, &vlan); + if (!v) { + netif_addr_unlock_bh(dev); + return -ENOENT; + } + + list_del(&v->list); + kfree(v); + if (dsa_switch_supports_mc_filtering(ds)) { netdev_for_each_synced_mc_addr(ha, dev) { dsa_slave_schedule_standalone_work(dev, DSA_MC_DEL, diff --git a/net/dsa/switch.c b/net/dsa/switch.c index d5bc4bb7310dc..36f8ffea2d168 100644 --- a/net/dsa/switch.c +++ b/net/dsa/switch.c @@ -634,8 +634,8 @@ static bool dsa_port_host_vlan_match(struct dsa_port *dp, return false; }
-static struct dsa_vlan *dsa_vlan_find(struct list_head *vlan_list, - const struct switchdev_obj_port_vlan *vlan) +struct dsa_vlan *dsa_vlan_find(struct list_head *vlan_list, + const struct switchdev_obj_port_vlan *vlan) { struct dsa_vlan *v;
diff --git a/net/dsa/switch.h b/net/dsa/switch.h index 15e67b95eb6e1..ea034677da153 100644 --- a/net/dsa/switch.h +++ b/net/dsa/switch.h @@ -111,6 +111,9 @@ struct dsa_notifier_master_state_info { bool operational; };
+struct dsa_vlan *dsa_vlan_find(struct list_head *vlan_list, + const struct switchdev_obj_port_vlan *vlan); + int dsa_tree_notify(struct dsa_switch_tree *dst, unsigned long e, void *v); int dsa_broadcast(unsigned long e, void *v);
From: Kuniyuki Iwashima kuniyu@amazon.com
[ Upstream commit 25a9c8a4431c364f97f75558cb346d2ad3f53fbb ]
syzbot reported a warning in __local_bh_enable_ip(). [0]
Commit 8d61f926d420 ("netlink: fix potential deadlock in netlink_set_err()") converted read_lock(&nl_table_lock) to read_lock_irqsave() in __netlink_diag_dump() to prevent a deadlock.
However, __netlink_diag_dump() calls sock_i_ino() that uses read_lock_bh() and read_unlock_bh(). If CONFIG_TRACE_IRQFLAGS=y, read_unlock_bh() finally enables IRQ even though it should stay disabled until the following read_unlock_irqrestore().
Using read_lock() in sock_i_ino() would trigger a lockdep splat in another place that was fixed in commit f064af1e500a ("net: fix a lockdep splat"), so let's add __sock_i_ino() that would be safe to use under BH disabled.
[0]: WARNING: CPU: 0 PID: 5012 at kernel/softirq.c:376 __local_bh_enable_ip+0xbe/0x130 kernel/softirq.c:376 Modules linked in: CPU: 0 PID: 5012 Comm: syz-executor487 Not tainted 6.4.0-rc7-syzkaller-00202-g6f68fc395f49 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/27/2023 RIP: 0010:__local_bh_enable_ip+0xbe/0x130 kernel/softirq.c:376 Code: 45 bf 01 00 00 00 e8 91 5b 0a 00 e8 3c 15 3d 00 fb 65 8b 05 ec e9 b5 7e 85 c0 74 58 5b 5d c3 65 8b 05 b2 b6 b4 7e 85 c0 75 a2 <0f> 0b eb 9e e8 89 15 3d 00 eb 9f 48 89 ef e8 6f 49 18 00 eb a8 0f RSP: 0018:ffffc90003a1f3d0 EFLAGS: 00010046 RAX: 0000000000000000 RBX: 0000000000000201 RCX: 1ffffffff1cf5996 RDX: 0000000000000000 RSI: 0000000000000201 RDI: ffffffff8805c6f3 RBP: ffffffff8805c6f3 R08: 0000000000000001 R09: ffff8880152b03a3 R10: ffffed1002a56074 R11: 0000000000000005 R12: 00000000000073e4 R13: dffffc0000000000 R14: 0000000000000002 R15: 0000000000000000 FS: 0000555556726300(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000000045ad50 CR3: 000000007c646000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> sock_i_ino+0x83/0xa0 net/core/sock.c:2559 __netlink_diag_dump+0x45c/0x790 net/netlink/diag.c:171 netlink_diag_dump+0xd6/0x230 net/netlink/diag.c:207 netlink_dump+0x570/0xc50 net/netlink/af_netlink.c:2269 __netlink_dump_start+0x64b/0x910 net/netlink/af_netlink.c:2374 netlink_dump_start include/linux/netlink.h:329 [inline] netlink_diag_handler_dump+0x1ae/0x250 net/netlink/diag.c:238 __sock_diag_cmd net/core/sock_diag.c:238 [inline] sock_diag_rcv_msg+0x31e/0x440 net/core/sock_diag.c:269 netlink_rcv_skb+0x165/0x440 net/netlink/af_netlink.c:2547 sock_diag_rcv+0x2a/0x40 net/core/sock_diag.c:280 netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline] netlink_unicast+0x547/0x7f0 net/netlink/af_netlink.c:1365 netlink_sendmsg+0x925/0xe30 net/netlink/af_netlink.c:1914 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg+0xde/0x190 net/socket.c:747 ____sys_sendmsg+0x71c/0x900 net/socket.c:2503 ___sys_sendmsg+0x110/0x1b0 net/socket.c:2557 __sys_sendmsg+0xf7/0x1c0 net/socket.c:2586 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f5303aaabb9 Code: 28 c3 e8 2a 14 00 00 66 2e 0f 1f 84 00 00 00 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 c0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffc7506e548 EFLAGS: 00000246 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f5303aaabb9 RDX: 0000000000000000 RSI: 0000000020000180 RDI: 0000000000000003 RBP: 00007f5303a6ed60 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00007f5303a6edf0 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 </TASK>
Fixes: 8d61f926d420 ("netlink: fix potential deadlock in netlink_set_err()") Reported-by: syzbot+5da61cf6a9bc1902d422@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=5da61cf6a9bc1902d422 Suggested-by: Eric Dumazet edumazet@google.com Signed-off-by: Kuniyuki Iwashima kuniyu@amazon.com Reviewed-by: Eric Dumazet edumazet@google.com Link: https://lore.kernel.org/r/20230626164313.52528-1-kuniyu@amazon.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/sock.h | 1 + net/core/sock.c | 17 ++++++++++++++--- net/netlink/diag.c | 2 +- 3 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h index f0654c44acf5f..81ad7fa03b73a 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -2100,6 +2100,7 @@ static inline void sock_graft(struct sock *sk, struct socket *parent) }
kuid_t sock_i_uid(struct sock *sk); +unsigned long __sock_i_ino(struct sock *sk); unsigned long sock_i_ino(struct sock *sk);
static inline kuid_t sock_net_uid(const struct net *net, const struct sock *sk) diff --git a/net/core/sock.c b/net/core/sock.c index b34c48f802e98..a009e1fac4a69 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -2555,13 +2555,24 @@ kuid_t sock_i_uid(struct sock *sk) } EXPORT_SYMBOL(sock_i_uid);
-unsigned long sock_i_ino(struct sock *sk) +unsigned long __sock_i_ino(struct sock *sk) { unsigned long ino;
- read_lock_bh(&sk->sk_callback_lock); + read_lock(&sk->sk_callback_lock); ino = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_ino : 0; - read_unlock_bh(&sk->sk_callback_lock); + read_unlock(&sk->sk_callback_lock); + return ino; +} +EXPORT_SYMBOL(__sock_i_ino); + +unsigned long sock_i_ino(struct sock *sk) +{ + unsigned long ino; + + local_bh_disable(); + ino = __sock_i_ino(sk); + local_bh_enable(); return ino; } EXPORT_SYMBOL(sock_i_ino); diff --git a/net/netlink/diag.c b/net/netlink/diag.c index 4143b2ea4195a..e4f21b1067bcc 100644 --- a/net/netlink/diag.c +++ b/net/netlink/diag.c @@ -168,7 +168,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, NLM_F_MULTI, - sock_i_ino(sk)) < 0) { + __sock_i_ino(sk)) < 0) { ret = 1; break; }
From: Wesley Chalmers Wesley.Chalmers@amd.com
[ Upstream commit cd8f067a46d34dee3188da184912ae3d64d98444 ]
[WHY] Add log entry for when display refresh from MALL settings are sent to SMU.
Fixes: 1664641ea946 ("drm/amd/display: Add logger for SMU msg") Signed-off-by: Wesley Chalmers Wesley.Chalmers@amd.com Acked-by: Aurabindo Pillai aurabindo.pillai@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c index 1fbf1c105dc12..bdbf183066981 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c @@ -312,6 +312,9 @@ void dcn30_smu_set_display_refresh_from_mall(struct clk_mgr_internal *clk_mgr, b /* bits 8:7 for cache timer scale, bits 6:1 for cache timer delay, bit 0 = 1 for enable, = 0 for disable */ uint32_t param = (cache_timer_scale << 7) | (cache_timer_delay << 1) | (enable ? 1 : 0);
+ smu_print("SMU Set display refresh from mall: enable = %d, cache_timer_delay = %d, cache_timer_scale = %d\n", + enable, cache_timer_delay, cache_timer_scale); + dcn30_smu_send_msg_with_param(clk_mgr, DALSMC_MSG_SetDisplayRefreshFromMall, param, NULL); }
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 3306ba4b60b2f3d9ac6bddc587a4d702e1ba2224 ]
Three functions in the amdgpu display driver cause -Wmissing-prototype warnings:
drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_resource.c:1858:6: error: no previous prototype for 'is_timing_changed' [-Werror=missing-prototypes]
is_timing_changed() is actually meant to be a global symbol, but needs a proper name and prototype.
Fixes: 17ce8a6907f7 ("drm/amd/display: Add dsc pre-validation in atomic check") Reviewed-by: Aurabindo Pillai aurabindo.pillai@amd.com Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Hamza Mahfooz hamza.mahfooz@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 5 ++--- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 6 +++--- drivers/gpu/drm/amd/display/dc/dc.h | 3 +++ 3 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 3da519957f6c8..0096614f2a8be 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -48,8 +48,7 @@ #endif
#include "dc/dcn20/dcn20_resource.h" -bool is_timing_changed(struct dc_stream_state *cur_stream, - struct dc_stream_state *new_stream); + #define PEAK_FACTOR_X1000 1006
static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, @@ -1426,7 +1425,7 @@ int pre_validate_dsc(struct drm_atomic_state *state, struct dc_stream_state *stream = dm_state->context->streams[i];
if (local_dc_state->streams[i] && - is_timing_changed(stream, local_dc_state->streams[i])) { + dc_is_timing_changed(stream, local_dc_state->streams[i])) { DRM_INFO_ONCE("crtc[%d] needs mode_changed\n", i); } else { int ind = find_crtc_index_in_state_by_stream(state, stream); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 986de684b078e..7b0fd0dc31b34 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1878,7 +1878,7 @@ bool dc_add_all_planes_for_stream( return add_all_planes_for_stream(dc, stream, &set, 1, context); }
-bool is_timing_changed(struct dc_stream_state *cur_stream, +bool dc_is_timing_changed(struct dc_stream_state *cur_stream, struct dc_stream_state *new_stream) { if (cur_stream == NULL) @@ -1903,7 +1903,7 @@ static bool are_stream_backends_same( if (stream_a == NULL || stream_b == NULL) return false;
- if (is_timing_changed(stream_a, stream_b)) + if (dc_is_timing_changed(stream_a, stream_b)) return false;
if (stream_a->signal != stream_b->signal) @@ -3527,7 +3527,7 @@ bool pipe_need_reprogram( if (pipe_ctx_old->stream_res.stream_enc != pipe_ctx->stream_res.stream_enc) return true;
- if (is_timing_changed(pipe_ctx_old->stream, pipe_ctx->stream)) + if (dc_is_timing_changed(pipe_ctx_old->stream, pipe_ctx->stream)) return true;
if (pipe_ctx_old->stream->dpms_off != pipe_ctx->stream->dpms_off) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 3fb868f2f6f5b..9307442dc2258 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -2223,4 +2223,7 @@ void dc_process_dmub_dpia_hpd_int_enable(const struct dc *dc, /* Disable acc mode Interfaces */ void dc_disable_accelerated_mode(struct dc *dc);
+bool dc_is_timing_changed(struct dc_stream_state *cur_stream, + struct dc_stream_state *new_stream); + #endif /* DC_INTERFACE_H_ */
From: Nikita Zhandarovich n.zhandarovich@fintech.ru
[ Upstream commit 20c3dffdccbd494e0dd631d1660aeecbff6775f2 ]
Several calls to ci_dpm_fini() will attempt to free resources that either have been freed before or haven't been allocated yet. This may lead to undefined or dangerous behaviour.
For instance, if r600_parse_extended_power_table() fails, it might call r600_free_extended_power_table() as will ci_dpm_fini() later during error handling.
Fix this by only freeing pointers to objects previously allocated.
Found by Linux Verification Center (linuxtesting.org) with static analysis tool SVACE.
Fixes: cc8dbbb4f62a ("drm/radeon: add dpm support for CI dGPUs (v2)") Co-developed-by: Natalia Petrova n.petrova@fintech.ru Signed-off-by: Nikita Zhandarovich n.zhandarovich@fintech.ru Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/radeon/ci_dpm.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 8ef25ab305ae7..b8f4dac68d850 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -5517,6 +5517,7 @@ static int ci_parse_power_table(struct radeon_device *rdev) u8 frev, crev; u8 *power_state_offset; struct ci_ps *ps; + int ret;
if (!atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset)) @@ -5546,11 +5547,15 @@ static int ci_parse_power_table(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]; - if (!rdev->pm.power_state[i].clock_info) - return -EINVAL; + if (!rdev->pm.power_state[i].clock_info) { + ret = -EINVAL; + goto err_free_ps; + } ps = kzalloc(sizeof(struct ci_ps), GFP_KERNEL); - if (ps == NULL) - return -ENOMEM; + if (ps == NULL) { + ret = -ENOMEM; + goto err_free_ps; + } rdev->pm.dpm.ps[i].ps_priv = ps; ci_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i], non_clock_info, @@ -5590,6 +5595,12 @@ static int ci_parse_power_table(struct radeon_device *rdev) }
return 0; + +err_free_ps: + for (i = 0; i < rdev->pm.dpm.num_ps; i++) + kfree(rdev->pm.dpm.ps[i].ps_priv); + kfree(rdev->pm.dpm.ps); + return ret; }
static int ci_get_vbios_boot_values(struct radeon_device *rdev, @@ -5678,25 +5689,26 @@ int ci_dpm_init(struct radeon_device *rdev)
ret = ci_get_vbios_boot_values(rdev, &pi->vbios_boot_state); if (ret) { - ci_dpm_fini(rdev); + kfree(rdev->pm.dpm.priv); return ret; }
ret = r600_get_platform_caps(rdev); if (ret) { - ci_dpm_fini(rdev); + kfree(rdev->pm.dpm.priv); return ret; }
ret = r600_parse_extended_power_table(rdev); if (ret) { - ci_dpm_fini(rdev); + kfree(rdev->pm.dpm.priv); return ret; }
ret = ci_parse_power_table(rdev); if (ret) { - ci_dpm_fini(rdev); + kfree(rdev->pm.dpm.priv); + r600_free_extended_power_table(rdev); return ret; }
From: Nicholas Kazlauskas nicholas.kazlauskas@amd.com
[ Upstream commit 710cc1e7cd461446a9325c9bd1e9a54daa462952 ]
[Why] The bit for flip addr is being set causing the determination for FAST vs MEDIUM to always return MEDIUM when plane info is provided as a surface update. This causes extreme stuttering for the typical atomic update path on Linux.
[How] Don't use update_flags->raw for determining FAST vs MEDIUM. It's too fragile to changes like this.
Explicitly specify the update type per update flag instead. It's not as clever as checking the bits itself but at least it's correct.
Fixes: aa5fdb1ab5b6 ("drm/amd/display: Explicitly specify update type per plane info change") Reviewed-by: Rodrigo Siqueira Rodrigo.Siqueira@amd.com Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc.c | 3 --- 1 file changed, 3 deletions(-)
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2540,9 +2540,6 @@ static enum surface_update_type det_surf enum surface_update_type overall_type = UPDATE_TYPE_FAST; union surface_update_flags *update_flags = &u->surface->update_flags;
- if (u->flip_addr) - update_flags->bits.addr_update = 1; - if (!is_surface_in_context(context, u->surface) || u->surface->force_full_update) { update_flags->raw = 0xFFFFFFFF; return UPDATE_TYPE_FULL;
From: Liu Shixin liushixin2@huawei.com
commit 028725e73375a1ff080bbdf9fb503306d0116f28 upstream.
commit dd0ff4d12dd2 ("bootmem: remove the vmemmap pages from kmemleak in put_page_bootmem") fix an overlaps existing problem of kmemleak. But the problem still existed when HAVE_BOOTMEM_INFO_NODE is disabled, because in this case, free_bootmem_page() will call free_reserved_page() directly.
Fix the problem by adding kmemleak_free_part() in free_bootmem_page() when HAVE_BOOTMEM_INFO_NODE is disabled.
Link: https://lkml.kernel.org/r/20230704101942.2819426-1-liushixin2@huawei.com Fixes: f41f2ed43ca5 ("mm: hugetlb: free the vmemmap pages associated with each HugeTLB page") Signed-off-by: Liu Shixin liushixin2@huawei.com Acked-by: Muchun Song songmuchun@bytedance.com Cc: Matthew Wilcox willy@infradead.org Cc: Mike Kravetz mike.kravetz@oracle.com Cc: Oscar Salvador osalvador@suse.de Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/bootmem_info.h | 2 ++ 1 file changed, 2 insertions(+)
--- a/include/linux/bootmem_info.h +++ b/include/linux/bootmem_info.h @@ -3,6 +3,7 @@ #define __LINUX_BOOTMEM_INFO_H
#include <linux/mm.h> +#include <linux/kmemleak.h>
/* * Types for free bootmem stored in page->lru.next. These have to be in @@ -59,6 +60,7 @@ static inline void get_page_bootmem(unsi
static inline void free_bootmem_page(struct page *page) { + kmemleak_free_part(page_to_virt(page), PAGE_SIZE); free_reserved_page(page); } #endif
From: John Harrison John.C.Harrison@Intel.com
[ Upstream commit 9847ffce9b5f83a7707504b0127aeb6a05dbd378 ]
Update a bunch more debug prints to use the new GT based scheme.
v2: Also change prints to use %pe for error values (MichalW).
Signed-off-by: John Harrison John.C.Harrison@Intel.com Reviewed-by: Michal Wajdeczko michal.wajdeczko@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20230207050717.1833718-6-John.... Stable-dep-of: 55f9720dbf23 ("drm/i915/guc/slpc: Provide sysfs for efficient freq") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c | 8 +-- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 61 ++++++++------------- 2 files changed, 26 insertions(+), 43 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c index 8f8dd05835c5a..1adec6de223c7 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c @@ -6,6 +6,7 @@ #include <linux/string_helpers.h>
#include "intel_guc_rc.h" +#include "intel_guc_print.h" #include "gt/intel_gt.h" #include "i915_drv.h"
@@ -59,13 +60,12 @@ static int __guc_rc_control(struct intel_guc *guc, bool enable)
ret = guc_action_control_gucrc(guc, enable); if (ret) { - i915_probe_error(guc_to_gt(guc)->i915, "Failed to %s GuC RC (%pe)\n", - str_enable_disable(enable), ERR_PTR(ret)); + guc_probe_error(guc, "Failed to %s RC (%pe)\n", + str_enable_disable(enable), ERR_PTR(ret)); return ret; }
- drm_info(>->i915->drm, "GuC RC: %s\n", - str_enabled_disabled(enable)); + guc_info(guc, "RC %s\n", str_enabled_disabled(enable));
return 0; } diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c index 63464933cbceb..026d73855f36c 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c @@ -9,6 +9,7 @@ #include "i915_drv.h" #include "i915_reg.h" #include "intel_guc_slpc.h" +#include "intel_guc_print.h" #include "intel_mchbar_regs.h" #include "gt/intel_gt.h" #include "gt/intel_gt_regs.h" @@ -171,14 +172,12 @@ static int guc_action_slpc_query(struct intel_guc *guc, u32 offset) static int slpc_query_task_state(struct intel_guc_slpc *slpc) { struct intel_guc *guc = slpc_to_guc(slpc); - struct drm_i915_private *i915 = slpc_to_i915(slpc); u32 offset = intel_guc_ggtt_offset(guc, slpc->vma); int ret;
ret = guc_action_slpc_query(guc, offset); if (unlikely(ret)) - i915_probe_error(i915, "Failed to query task state (%pe)\n", - ERR_PTR(ret)); + guc_probe_error(guc, "Failed to query task state: %pe\n", ERR_PTR(ret));
drm_clflush_virt_range(slpc->vaddr, SLPC_PAGE_SIZE_BYTES);
@@ -188,15 +187,14 @@ static int slpc_query_task_state(struct intel_guc_slpc *slpc) static int slpc_set_param(struct intel_guc_slpc *slpc, u8 id, u32 value) { struct intel_guc *guc = slpc_to_guc(slpc); - struct drm_i915_private *i915 = slpc_to_i915(slpc); int ret;
GEM_BUG_ON(id >= SLPC_MAX_PARAM);
ret = guc_action_slpc_set_param(guc, id, value); if (ret) - i915_probe_error(i915, "Failed to set param %d to %u (%pe)\n", - id, value, ERR_PTR(ret)); + guc_probe_error(guc, "Failed to set param %d to %u: %pe\n", + id, value, ERR_PTR(ret));
return ret; } @@ -212,8 +210,8 @@ static int slpc_unset_param(struct intel_guc_slpc *slpc, u8 id)
static int slpc_force_min_freq(struct intel_guc_slpc *slpc, u32 freq) { - struct drm_i915_private *i915 = slpc_to_i915(slpc); struct intel_guc *guc = slpc_to_guc(slpc); + struct drm_i915_private *i915 = slpc_to_i915(slpc); intel_wakeref_t wakeref; int ret = 0;
@@ -236,9 +234,8 @@ static int slpc_force_min_freq(struct intel_guc_slpc *slpc, u32 freq) SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ, freq); if (ret) - drm_notice(&i915->drm, - "Failed to send set_param for min freq(%d): (%d)\n", - freq, ret); + guc_notice(guc, "Failed to send set_param for min freq(%d): %pe\n", + freq, ERR_PTR(ret)); }
return ret; @@ -267,7 +264,6 @@ static void slpc_boost_work(struct work_struct *work) int intel_guc_slpc_init(struct intel_guc_slpc *slpc) { struct intel_guc *guc = slpc_to_guc(slpc); - struct drm_i915_private *i915 = slpc_to_i915(slpc); u32 size = PAGE_ALIGN(sizeof(struct slpc_shared_data)); int err;
@@ -275,9 +271,7 @@ int intel_guc_slpc_init(struct intel_guc_slpc *slpc)
err = intel_guc_allocate_and_map_vma(guc, size, &slpc->vma, (void **)&slpc->vaddr); if (unlikely(err)) { - i915_probe_error(i915, - "Failed to allocate SLPC struct (err=%pe)\n", - ERR_PTR(err)); + guc_probe_error(guc, "Failed to allocate SLPC struct: %pe\n", ERR_PTR(err)); return err; }
@@ -338,7 +332,6 @@ static int guc_action_slpc_reset(struct intel_guc *guc, u32 offset)
static int slpc_reset(struct intel_guc_slpc *slpc) { - struct drm_i915_private *i915 = slpc_to_i915(slpc); struct intel_guc *guc = slpc_to_guc(slpc); u32 offset = intel_guc_ggtt_offset(guc, slpc->vma); int ret; @@ -346,15 +339,14 @@ static int slpc_reset(struct intel_guc_slpc *slpc) ret = guc_action_slpc_reset(guc, offset);
if (unlikely(ret < 0)) { - i915_probe_error(i915, "SLPC reset action failed (%pe)\n", - ERR_PTR(ret)); + guc_probe_error(guc, "SLPC reset action failed: %pe\n", ERR_PTR(ret)); return ret; }
if (!ret) { if (wait_for(slpc_is_running(slpc), SLPC_RESET_TIMEOUT_MS)) { - i915_probe_error(i915, "SLPC not enabled! State = %s\n", - slpc_get_state_string(slpc)); + guc_probe_error(guc, "SLPC not enabled! State = %s\n", + slpc_get_state_string(slpc)); return -EIO; } } @@ -495,8 +487,8 @@ int intel_guc_slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 val) SLPC_PARAM_IGNORE_EFFICIENT_FREQUENCY, val < slpc->rp1_freq); if (ret) { - i915_probe_error(i915, "Failed to toggle efficient freq (%pe)\n", - ERR_PTR(ret)); + guc_probe_error(slpc_to_guc(slpc), "Failed to toggle efficient freq: %pe\n", + ERR_PTR(ret)); goto out; }
@@ -611,15 +603,12 @@ static int slpc_set_softlimits(struct intel_guc_slpc *slpc)
static bool is_slpc_min_freq_rpmax(struct intel_guc_slpc *slpc) { - struct drm_i915_private *i915 = slpc_to_i915(slpc); int slpc_min_freq; int ret;
ret = intel_guc_slpc_get_min_freq(slpc, &slpc_min_freq); if (ret) { - drm_err(&i915->drm, - "Failed to get min freq: (%d)\n", - ret); + guc_err(slpc_to_guc(slpc), "Failed to get min freq: %pe\n", ERR_PTR(ret)); return false; }
@@ -685,9 +674,8 @@ int intel_guc_slpc_override_gucrc_mode(struct intel_guc_slpc *slpc, u32 mode) with_intel_runtime_pm(&i915->runtime_pm, wakeref) { ret = slpc_set_param(slpc, SLPC_PARAM_PWRGATE_RC_MODE, mode); if (ret) - drm_err(&i915->drm, - "Override gucrc mode %d failed %d\n", - mode, ret); + guc_err(slpc_to_guc(slpc), "Override RC mode %d failed: %pe\n", + mode, ERR_PTR(ret)); }
return ret; @@ -702,9 +690,7 @@ int intel_guc_slpc_unset_gucrc_mode(struct intel_guc_slpc *slpc) with_intel_runtime_pm(&i915->runtime_pm, wakeref) { ret = slpc_unset_param(slpc, SLPC_PARAM_PWRGATE_RC_MODE); if (ret) - drm_err(&i915->drm, - "Unsetting gucrc mode failed %d\n", - ret); + guc_err(slpc_to_guc(slpc), "Unsetting RC mode failed: %pe\n", ERR_PTR(ret)); }
return ret; @@ -725,7 +711,7 @@ int intel_guc_slpc_unset_gucrc_mode(struct intel_guc_slpc *slpc) */ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc) { - struct drm_i915_private *i915 = slpc_to_i915(slpc); + struct intel_guc *guc = slpc_to_guc(slpc); int ret;
GEM_BUG_ON(!slpc->vma); @@ -734,8 +720,7 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc)
ret = slpc_reset(slpc); if (unlikely(ret < 0)) { - i915_probe_error(i915, "SLPC Reset event returned (%pe)\n", - ERR_PTR(ret)); + guc_probe_error(guc, "SLPC Reset event returned: %pe\n", ERR_PTR(ret)); return ret; }
@@ -743,7 +728,7 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc) if (unlikely(ret < 0)) return ret;
- intel_guc_pm_intrmsk_enable(to_gt(i915)); + intel_guc_pm_intrmsk_enable(slpc_to_gt(slpc));
slpc_get_rp_values(slpc);
@@ -753,16 +738,14 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc) /* Set SLPC max limit to RP0 */ ret = slpc_use_fused_rp0(slpc); if (unlikely(ret)) { - i915_probe_error(i915, "Failed to set SLPC max to RP0 (%pe)\n", - ERR_PTR(ret)); + guc_probe_error(guc, "Failed to set SLPC max to RP0: %pe\n", ERR_PTR(ret)); return ret; }
/* Revert SLPC min/max to softlimits if necessary */ ret = slpc_set_softlimits(slpc); if (unlikely(ret)) { - i915_probe_error(i915, "Failed to set SLPC softlimits (%pe)\n", - ERR_PTR(ret)); + guc_probe_error(guc, "Failed to set SLPC softlimits: %pe\n", ERR_PTR(ret)); return ret; }
From: Vinay Belgaumkar vinay.belgaumkar@intel.com
[ Upstream commit 55f9720dbf23ed640a51ea5564c22305efa8a467 ]
SLPC enables use of efficient freq at init by default. It is possible for GuC to request frequencies that are higher than the 'software' max if user has set it lower than the efficient level.
Scenarios/tests that require strict fixing of freq below the efficient level will need to disable it through this interface.
v2: Keep just one interface to toggle sysfs. With this, user will be completely responsible for toggling efficient frequency if need be. There will be no implicit disabling when user sets min < RP1 (Ashutosh)
v3: Remove unused label, review comments (Ashutosh)
v4: Toggle efficient freq usage in SLPC selftest and checkpatch fixes
v5: Review comments (Andi) and add a separate patch for selftest updates
Fixes: 95ccf312a1e4 ("drm/i915/guc/slpc: Allow SLPC to use efficient frequency") Signed-off-by: Vinay Belgaumkar vinay.belgaumkar@intel.com Reviewed-by: Rodrigo Vivi rodrigo.vivi@intel.com Reviewed-by: Ashutosh Dixit ashutosh.dixit@intel.com Reviewed-by: Andi Shyti andi.shyti@linux.intel.com Signed-off-by: John Harrison John.C.Harrison@Intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20230426003942.1924347-1-vinay... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c | 35 +++++++++++++++++ drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 38 +++++++++++++------ drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h | 1 + .../gpu/drm/i915/gt/uc/intel_guc_slpc_types.h | 1 + 4 files changed, 64 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c index 28f27091cd3b7..ee2b44f896a27 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c @@ -451,6 +451,33 @@ static ssize_t punit_req_freq_mhz_show(struct kobject *kobj, return sysfs_emit(buff, "%u\n", preq); }
+static ssize_t slpc_ignore_eff_freq_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buff) +{ + struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name); + struct intel_guc_slpc *slpc = >->uc.guc.slpc; + + return sysfs_emit(buff, "%u\n", slpc->ignore_eff_freq); +} + +static ssize_t slpc_ignore_eff_freq_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buff, size_t count) +{ + struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name); + struct intel_guc_slpc *slpc = >->uc.guc.slpc; + int err; + u32 val; + + err = kstrtou32(buff, 0, &val); + if (err) + return err; + + err = intel_guc_slpc_set_ignore_eff_freq(slpc, val); + return err ?: count; +} + struct intel_gt_bool_throttle_attr { struct attribute attr; ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, @@ -663,6 +690,8 @@ static struct kobj_attribute attr_media_freq_factor_scale = INTEL_GT_ATTR_RO(media_RP0_freq_mhz); INTEL_GT_ATTR_RO(media_RPn_freq_mhz);
+INTEL_GT_ATTR_RW(slpc_ignore_eff_freq); + static const struct attribute *media_perf_power_attrs[] = { &attr_media_freq_factor.attr, &attr_media_freq_factor_scale.attr, @@ -744,6 +773,12 @@ void intel_gt_sysfs_pm_init(struct intel_gt *gt, struct kobject *kobj) if (ret) gt_warn(gt, "failed to create punit_req_freq_mhz sysfs (%pe)", ERR_PTR(ret));
+ if (intel_uc_uses_guc_slpc(>->uc)) { + ret = sysfs_create_file(kobj, &attr_slpc_ignore_eff_freq.attr); + if (ret) + gt_warn(gt, "failed to create ignore_eff_freq sysfs (%pe)", ERR_PTR(ret)); + } + if (i915_mmio_reg_valid(intel_gt_perf_limit_reasons_reg(gt))) { ret = sysfs_create_files(kobj, throttle_reason_attrs); if (ret) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c index 026d73855f36c..56dbba1ef6684 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c @@ -277,6 +277,7 @@ int intel_guc_slpc_init(struct intel_guc_slpc *slpc)
slpc->max_freq_softlimit = 0; slpc->min_freq_softlimit = 0; + slpc->ignore_eff_freq = false; slpc->min_is_rpmax = false;
slpc->boost_freq = 0; @@ -457,6 +458,29 @@ int intel_guc_slpc_get_max_freq(struct intel_guc_slpc *slpc, u32 *val) return ret; }
+int intel_guc_slpc_set_ignore_eff_freq(struct intel_guc_slpc *slpc, bool val) +{ + struct drm_i915_private *i915 = slpc_to_i915(slpc); + intel_wakeref_t wakeref; + int ret; + + mutex_lock(&slpc->lock); + wakeref = intel_runtime_pm_get(&i915->runtime_pm); + + ret = slpc_set_param(slpc, + SLPC_PARAM_IGNORE_EFFICIENT_FREQUENCY, + val); + if (ret) + guc_probe_error(slpc_to_guc(slpc), "Failed to set efficient freq(%d): %pe\n", + val, ERR_PTR(ret)); + else + slpc->ignore_eff_freq = val; + + intel_runtime_pm_put(&i915->runtime_pm, wakeref); + mutex_unlock(&slpc->lock); + return ret; +} + /** * intel_guc_slpc_set_min_freq() - Set min frequency limit for SLPC. * @slpc: pointer to intel_guc_slpc. @@ -482,16 +506,6 @@ int intel_guc_slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 val) mutex_lock(&slpc->lock); wakeref = intel_runtime_pm_get(&i915->runtime_pm);
- /* Ignore efficient freq if lower min freq is requested */ - ret = slpc_set_param(slpc, - SLPC_PARAM_IGNORE_EFFICIENT_FREQUENCY, - val < slpc->rp1_freq); - if (ret) { - guc_probe_error(slpc_to_guc(slpc), "Failed to toggle efficient freq: %pe\n", - ERR_PTR(ret)); - goto out; - } - ret = slpc_set_param(slpc, SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ, val); @@ -499,7 +513,6 @@ int intel_guc_slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 val) if (!ret) slpc->min_freq_softlimit = val;
-out: intel_runtime_pm_put(&i915->runtime_pm, wakeref); mutex_unlock(&slpc->lock);
@@ -752,6 +765,9 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc) /* Set cached media freq ratio mode */ intel_guc_slpc_set_media_ratio_mode(slpc, slpc->media_ratio_mode);
+ /* Set cached value of ignore efficient freq */ + intel_guc_slpc_set_ignore_eff_freq(slpc, slpc->ignore_eff_freq); + return 0; }
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h index 17ed515f6a852..597eb5413ddf2 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h @@ -46,5 +46,6 @@ void intel_guc_slpc_boost(struct intel_guc_slpc *slpc); void intel_guc_slpc_dec_waiters(struct intel_guc_slpc *slpc); int intel_guc_slpc_unset_gucrc_mode(struct intel_guc_slpc *slpc); int intel_guc_slpc_override_gucrc_mode(struct intel_guc_slpc *slpc, u32 mode); +int intel_guc_slpc_set_ignore_eff_freq(struct intel_guc_slpc *slpc, bool val);
#endif diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h index a6ef53b04e047..a886513314977 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h @@ -31,6 +31,7 @@ struct intel_guc_slpc { /* frequency softlimits */ u32 min_freq_softlimit; u32 max_freq_softlimit; + bool ignore_eff_freq;
/* cached media ratio mode */ u32 media_ratio_mode;
From: Markus Elfring elfring@users.sourceforge.net
[ Upstream commit 0be05a75de2916421e88e0d64b001984f54df0bd ]
The address of a data structure member was determined before a corresponding null pointer check in the implementation of the function “receive_timing_debugfs_show”.
Thus avoid the risk for undefined behaviour by moving the assignment for the variable “vid” behind the null pointer check.
This issue was detected by using the Coccinelle software.
Fixes: b5c84a9edcd4 ("drm/bridge: add it6505 driver") Signed-off-by: Markus Elfring elfring@users.sourceforge.net Link: https://patchwork.freedesktop.org/patch/msgid/fa69384f-1485-142b-c4ee-3df54a... Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/ite-it6505.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index bc451b2a77c28..32ea61b79965e 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -3195,7 +3195,7 @@ static ssize_t receive_timing_debugfs_show(struct file *file, char __user *buf, size_t len, loff_t *ppos) { struct it6505 *it6505 = file->private_data; - struct drm_display_mode *vid = &it6505->video_info; + struct drm_display_mode *vid; u8 read_buf[READ_BUFFER_SIZE]; u8 *str = read_buf, *end = read_buf + READ_BUFFER_SIZE; ssize_t ret, count; @@ -3204,6 +3204,7 @@ static ssize_t receive_timing_debugfs_show(struct file *file, char __user *buf, return -ENODEV;
it6505_calc_video_info(it6505); + vid = &it6505->video_info; str += scnprintf(str, end - str, "---video timing---\n"); str += scnprintf(str, end - str, "PCLK:%d.%03dMHz\n", vid->clock / 1000, vid->clock % 1000);
From: Luca Weiss luca@z3ntu.xyz
[ Upstream commit efef661dfa6bf8cbafe4cd6a97433fcef0118967 ]
When doing the initial startup there's no need to poll without any delay and spam the I2C bus.
Let's sleep 15ms between each attempt, which is the same time as used in the vendor driver.
Fixes: 7132fe4f5687 ("Input: drv260x - add TI drv260x haptics driver") Signed-off-by: Luca Weiss luca@z3ntu.xyz Link: https://lore.kernel.org/r/20230430-drv260x-improvements-v1-2-1fb28b4cc698@z3... Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/input/misc/drv260x.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c index 8a9ebfc04a2d9..85371fa1a03ed 100644 --- a/drivers/input/misc/drv260x.c +++ b/drivers/input/misc/drv260x.c @@ -435,6 +435,7 @@ static int drv260x_init(struct drv260x_data *haptics) }
do { + usleep_range(15000, 15500); error = regmap_read(haptics->regmap, DRV260X_GO, &cal_buf); if (error) { dev_err(&haptics->client->dev,
From: Duoming Zhou duoming@zju.edu.cn
[ Upstream commit dbe836576f12743a7d2d170ad4ad4fd324c4d47a ]
The watchdog_timer can schedule tx_timeout_task and watchdog_work can also arm watchdog_timer. The process is shown below:
----------- timer schedules work ------------ cyttsp4_watchdog_timer() //timer handler schedule_work(&cd->watchdog_work)
----------- work arms timer ------------ cyttsp4_watchdog_work() //workqueue callback function cyttsp4_start_wd_timer() mod_timer(&cd->watchdog_timer, ...)
Although del_timer_sync() and cancel_work_sync() are called in cyttsp4_remove(), the timer and workqueue could still be rearmed. As a result, the possible use after free bugs could happen. The process is shown below:
(cleanup routine) | (timer and workqueue routine) cyttsp4_remove() | cyttsp4_watchdog_timer() //timer cyttsp4_stop_wd_timer() | schedule_work() del_timer_sync() | | cyttsp4_watchdog_work() //worker | cyttsp4_start_wd_timer() | mod_timer() cancel_work_sync() | | cyttsp4_watchdog_timer() //timer | schedule_work() del_timer_sync() | kfree(cd) //FREE | | cyttsp4_watchdog_work() // reschedule! | cd-> //USE
This patch changes del_timer_sync() to timer_shutdown_sync(), which could prevent rearming of the timer from the workqueue.
Fixes: 17fb1563d69b ("Input: cyttsp4 - add core driver for Cypress TMA4XX touchscreen devices") Signed-off-by: Duoming Zhou duoming@zju.edu.cn Link: https://lore.kernel.org/r/20230421082919.8471-1-duoming@zju.edu.cn Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/input/touchscreen/cyttsp4_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/input/touchscreen/cyttsp4_core.c b/drivers/input/touchscreen/cyttsp4_core.c index 0cd6f626adec5..7cb26929dc732 100644 --- a/drivers/input/touchscreen/cyttsp4_core.c +++ b/drivers/input/touchscreen/cyttsp4_core.c @@ -1263,9 +1263,8 @@ static void cyttsp4_stop_wd_timer(struct cyttsp4 *cd) * Ensure we wait until the watchdog timer * running on a different CPU finishes */ - del_timer_sync(&cd->watchdog_timer); + timer_shutdown_sync(&cd->watchdog_timer); cancel_work_sync(&cd->watchdog_work); - del_timer_sync(&cd->watchdog_timer); }
static void cyttsp4_watchdog_timer(struct timer_list *t)
From: Alexander Stein alexander.stein@ew.tq-group.com
[ Upstream commit 8a91b29f1f50ce7742cdbe5cf11d17f128511f3f ]
If PLL locking failed, the regulator needs to be disabled again.
Fixes: 5664e3c907e2 ("drm/bridge: ti-sn65dsi83: Add vcc supply regulator support") Signed-off-by: Alexander Stein alexander.stein@ew.tq-group.com Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230504065316.2640739-1-alexa... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c index 91ecfbe45bf90..a6534011c9214 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c @@ -478,6 +478,7 @@ static void sn65dsi83_atomic_enable(struct drm_bridge *bridge, dev_err(ctx->dev, "failed to lock PLL, ret=%i\n", ret); /* On failure, disable PLL again and exit. */ regmap_write(ctx->regmap, REG_RC_PLL_EN, 0x00); + regulator_disable(ctx->vcc); return; }
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit 75a8aeac2573ab258c53676eba9b3796ea691988 ]
Always enable HS video mode setting the TXMD bit, without this change no video output is present with DSI sinks that are setting MIPI_DSI_MODE_LPM flag (tested with LT8912B DSI-HDMI bridge).
Previously the driver was enabling HS mode only when the DSI sink was not explicitly setting the MIPI_DSI_MODE_LPM, however this is not correct.
The MIPI_DSI_MODE_LPM is supposed to indicate that the sink is willing to receive data in low power mode, however clearing the TC358768_DSI_CONTROL_TXMD bit will make the TC358768 send video in LP mode that is not the intended behavior.
Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-2-frances... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358768.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index 7c0cbe84611b9..8f349bf4fc32f 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -866,8 +866,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) val = TC358768_DSI_CONFW_MODE_SET | TC358768_DSI_CONFW_ADDR_DSI_CONTROL; val |= (dsi_dev->lanes - 1) << 1;
- if (!(dsi_dev->mode_flags & MIPI_DSI_MODE_LPM)) - val |= TC358768_DSI_CONTROL_TXMD; + val |= TC358768_DSI_CONTROL_TXMD;
if (!(mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)) val |= TC358768_DSI_CONTROL_HSCKMD;
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit 6a4020b4c63911977aaf8047f904a300d15de739 ]
According to Toshiba documentation the PLL input clock after the divider should be not less than 4MHz, fix the PLL parameters computation accordingly.
Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-3-frances... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358768.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index 8f349bf4fc32f..e9e3f9e02bba0 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -334,13 +334,17 @@ static int tc358768_calc_pll(struct tc358768_priv *priv, u32 fbd;
for (fbd = 0; fbd < 512; ++fbd) { - u32 pll, diff; + u32 pll, diff, pll_in;
pll = (u32)div_u64((u64)refclk * (fbd + 1), divisor);
if (pll >= max_pll || pll < min_pll) continue;
+ pll_in = (u32)div_u64((u64)refclk, prd + 1); + if (pll_in < 4000000) + continue; + diff = max(pll, target_pll) - min(pll, target_pll);
if (diff < best_diff) {
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit ffd2e4bbea626d565b9817312b0fcfb382fecb88 ]
Correctly compute the PLL target frequency, the current formula works correctly only when the input bus width is 24bit, actually to properly compute the PLL target frequency what is relevant is the bits-per-pixel on the DSI link.
No regression expected since the DSI format is currently hard-coded as MIPI_DSI_FMT_RGB888.
Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-4-frances... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358768.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index e9e3f9e02bba0..dba1bf3912f1e 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -146,6 +146,7 @@ struct tc358768_priv {
u32 pd_lines; /* number of Parallel Port Input Data Lines */ u32 dsi_lanes; /* number of DSI Lanes */ + u32 dsi_bpp; /* number of Bits Per Pixel over DSI */
/* Parameters for PLL programming */ u32 fbd; /* PLL feedback divider */ @@ -284,12 +285,12 @@ static void tc358768_hw_disable(struct tc358768_priv *priv)
static u32 tc358768_pll_to_pclk(struct tc358768_priv *priv, u32 pll_clk) { - return (u32)div_u64((u64)pll_clk * priv->dsi_lanes, priv->pd_lines); + return (u32)div_u64((u64)pll_clk * priv->dsi_lanes, priv->dsi_bpp); }
static u32 tc358768_pclk_to_pll(struct tc358768_priv *priv, u32 pclk) { - return (u32)div_u64((u64)pclk * priv->pd_lines, priv->dsi_lanes); + return (u32)div_u64((u64)pclk * priv->dsi_bpp, priv->dsi_lanes); }
static int tc358768_calc_pll(struct tc358768_priv *priv, @@ -426,6 +427,7 @@ static int tc358768_dsi_host_attach(struct mipi_dsi_host *host, priv->output.panel = panel;
priv->dsi_lanes = dev->lanes; + priv->dsi_bpp = mipi_dsi_pixel_format_to_bpp(dev->format);
/* get input ep (port0/endpoint0) */ ret = -EINVAL; @@ -437,7 +439,7 @@ static int tc358768_dsi_host_attach(struct mipi_dsi_host *host, }
if (ret) - priv->pd_lines = mipi_dsi_pixel_format_to_bpp(dev->format); + priv->pd_lines = priv->dsi_bpp;
drm_bridge_add(&priv->bridge);
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit f9cf811374f42fca31ac34aaf59ee2ae72b89879 ]
Correct computation of TCLK_ZEROCNT register.
This register must be set to a value that ensure that (TCLK-PREPARECNT + TCLK-ZERO) > 300ns
with the actual value of (TCLK-PREPARECNT + TCLK-ZERO) being
(1 to 2) + (TCLK_ZEROCNT + 1)) x HSByteClkCycle + (PHY output delay)
with PHY output delay being about
(2 to 3) x MIPIBitClk cycle in the BitClk conversion.
Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-5-frances... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358768.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index dba1bf3912f1e..aff400c360662 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -742,10 +742,10 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
/* 38ns < TCLK_PREPARE < 95ns */ val = tc358768_ns_to_cnt(65, dsibclk_nsk) - 1; - /* TCLK_PREPARE > 300ns */ - val2 = tc358768_ns_to_cnt(300 + tc358768_to_ns(3 * ui_nsk), - dsibclk_nsk); - val |= (val2 - tc358768_to_ns(phy_delay_nsk - dsibclk_nsk)) << 8; + /* TCLK_PREPARE + TCLK_ZERO > 300ns */ + val2 = tc358768_ns_to_cnt(300 - tc358768_to_ns(2 * ui_nsk), + dsibclk_nsk) - 2; + val |= val2 << 8; dev_dbg(priv->dev, "TCLK_HEADERCNT: 0x%x\n", val); tc358768_write(priv, TC358768_TCLK_HEADERCNT, val);
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit cec5ccef85bd0128cf895612de54a9d21d2015d0 ]
Add atomic_get_input_bus_fmts() implementation, tc358768 has a parallel RGB input interface with the actual bus format depending on the amount of parallel input data lines.
Without this change when the tc358768 is used with less than 24bit the color mapping is completely wrong.
Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230330095941.428122-7-france... Stable-dep-of: ee18698e212b ("drm/bridge: tc358768: fix TCLK_TRAILCNT computation") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358768.c | 44 +++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+)
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index aff400c360662..487bfe33edc88 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -9,6 +9,7 @@ #include <linux/gpio/consumer.h> #include <linux/i2c.h> #include <linux/kernel.h> +#include <linux/media-bus-format.h> #include <linux/module.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> @@ -918,6 +919,44 @@ static void tc358768_bridge_enable(struct drm_bridge *bridge) } }
+#define MAX_INPUT_SEL_FORMATS 1 + +static u32 * +tc358768_atomic_get_input_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts) +{ + struct tc358768_priv *priv = bridge_to_tc358768(bridge); + u32 *input_fmts; + + *num_input_fmts = 0; + + input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts), + GFP_KERNEL); + if (!input_fmts) + return NULL; + + switch (priv->pd_lines) { + case 16: + input_fmts[0] = MEDIA_BUS_FMT_RGB565_1X16; + break; + case 18: + input_fmts[0] = MEDIA_BUS_FMT_RGB666_1X18; + break; + default: + case 24: + input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24; + break; + }; + + *num_input_fmts = MAX_INPUT_SEL_FORMATS; + + return input_fmts; +} + static const struct drm_bridge_funcs tc358768_bridge_funcs = { .attach = tc358768_bridge_attach, .mode_valid = tc358768_bridge_mode_valid, @@ -925,6 +964,11 @@ static const struct drm_bridge_funcs tc358768_bridge_funcs = { .enable = tc358768_bridge_enable, .disable = tc358768_bridge_disable, .post_disable = tc358768_bridge_post_disable, + + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_reset = drm_atomic_helper_bridge_reset, + .atomic_get_input_bus_fmts = tc358768_atomic_get_input_bus_fmts, };
static const struct drm_bridge_timings default_tc358768_timings = {
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit ee18698e212b1659dd0850d7e2ae0f22e16ed3d3 ]
Correct computation of TCLK_TRAILCNT register.
The driver does not implement non-continuous clock mode, so the actual value doesn't make a practical difference yet. However this change also ensures that the value does not write to reserved registers bits in case of under/overflow.
This register must be set to a value that ensures that
TCLK-TRAIL > 60ns and TEOT <= (105 ns + 12 x UI)
with the actual value of TCLK-TRAIL being
(TCLK_TRAILCNT + (1 to 2)) xHSByteClkCycle + (2 + (1 to 2)) * HSBYTECLKCycle - (PHY output delay)
with PHY output delay being about
(2 to 3) x MIPIBitClk cycle in the BitClk conversion.
Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-2-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-3-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-4-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-5-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-2-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-3-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-4-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-5-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-2-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-3-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-4-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-5-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-2-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-3-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-4-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-5-frances... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358768.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index 487bfe33edc88..4cb46a3e6be8c 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -10,6 +10,7 @@ #include <linux/i2c.h> #include <linux/kernel.h> #include <linux/media-bus-format.h> +#include <linux/minmax.h> #include <linux/module.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> @@ -639,6 +640,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) struct mipi_dsi_device *dsi_dev = priv->output.dev; unsigned long mode_flags = dsi_dev->mode_flags; u32 val, val2, lptxcnt, hact, data_type; + s32 raw_val; const struct drm_display_mode *mode; u32 dsibclk_nsk, dsiclk_nsk, ui_nsk, phy_delay_nsk; u32 dsiclk, dsibclk, video_start; @@ -750,9 +752,9 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) dev_dbg(priv->dev, "TCLK_HEADERCNT: 0x%x\n", val); tc358768_write(priv, TC358768_TCLK_HEADERCNT, val);
- /* TCLK_TRAIL > 60ns + 3*UI */ - val = 60 + tc358768_to_ns(3 * ui_nsk); - val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 5; + /* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */ + raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(2 * ui_nsk), dsibclk_nsk) - 5; + val = clamp(raw_val, 0, 127); dev_dbg(priv->dev, "TCLK_TRAILCNT: 0x%x\n", val); tc358768_write(priv, TC358768_TCLK_TRAILCNT, val);
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit 77a089328da791118af9692543a5eedc79eb5fd4 ]
Correct computation of THS_ZEROCNT register.
This register must be set to a value that ensure that THS_PREPARE + THS_ZERO > 145ns + 10*UI
with the actual value of (THS_PREPARE + THS_ZERO) being
((1 to 2) + 1 + (TCLK_ZEROCNT + 1) + (3 to 4)) x ByteClk cycle + + HSByteClk x (2 + (1 to 2)) + (PHY delay)
with PHY delay being about
(8 + (5 to 6)) x MIPIBitClk cycle in the BitClk conversion.
Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-7-frances... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358768.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index 4cb46a3e6be8c..e3f456bfb90c1 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -761,9 +761,10 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) /* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */ val = 50 + tc358768_to_ns(4 * ui_nsk); val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1; - /* THS_ZERO > 145ns + 10*UI */ - val2 = tc358768_ns_to_cnt(145 - tc358768_to_ns(ui_nsk), dsibclk_nsk); - val |= (val2 - tc358768_to_ns(phy_delay_nsk)) << 8; + /* THS_PREPARE + THS_ZERO > 145ns + 10*UI */ + raw_val = tc358768_ns_to_cnt(145 - tc358768_to_ns(3 * ui_nsk), dsibclk_nsk) - 10; + val2 = clamp(raw_val, 0, 127); + val |= val2 << 8; dev_dbg(priv->dev, "THS_HEADERCNT: 0x%x\n", val); tc358768_write(priv, TC358768_THS_HEADERCNT, val);
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit 3666aad8185af8d0ce164fd3c4974235417d6d0b ]
Correct computation of TXTAGOCNT register.
This register must be set to a value that ensure that the TTA-GO period = (4 x TLPX)
with the actual value of TTA-GO being
4 x (TXTAGOCNT + 1) x (HSByteClk cycle)
Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-8-frances... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358768.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index e3f456bfb90c1..d8209433d5f43 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -796,7 +796,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
/* TXTAGOCNT[26:16] RXTASURECNT[10:0] */ val = tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk * 4); - val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1; + val = tc358768_ns_to_cnt(val, dsibclk_nsk) / 4 - 1; val2 = tc358768_ns_to_cnt(tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk), dsibclk_nsk) - 2; val = val << 16 | val2;
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit bac7842cd179572e8e0fc2d7b5254e40c6e9e057 ]
Correct computation of THS_TRAILCNT register.
This register must be set to a value that ensure that THS_TRAIL > 60 ns + 4 x UI and THS_TRAIL > 8 x UI and THS_TRAIL < TEOT with TEOT = 105 ns + (12 x UI)
with the actual value of THS_TRAIL being
(1 + THS_TRAILCNT) x ByteClk cycle + ((1 to 2) + 2) xHSBYTECLK cycle + - (PHY output delay)
with PHY output delay being about
(8 + (5 to 6)) x MIPIBitClk cycle in the BitClk conversion.
Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-9-frances... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358768.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index d8209433d5f43..966a25cb0b108 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -780,9 +780,10 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) dev_dbg(priv->dev, "TCLK_POSTCNT: 0x%x\n", val); tc358768_write(priv, TC358768_TCLK_POSTCNT, val);
- /* 60ns + 4*UI < THS_PREPARE < 105ns + 12*UI */ - val = tc358768_ns_to_cnt(60 + tc358768_to_ns(15 * ui_nsk), - dsibclk_nsk) - 5; + /* max(60ns + 4*UI, 8*UI) < THS_TRAILCNT < 105ns + 12*UI */ + raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(18 * ui_nsk), + dsibclk_nsk) - 4; + val = clamp(raw_val, 0, 15); dev_dbg(priv->dev, "THS_TRAILCNT: 0x%x\n", val); tc358768_write(priv, TC358768_THS_TRAILCNT, val);
From: Luc Ma luc@sietium.com
[ Upstream commit b8e392245105b50706f18418054821e71e637288 ]
Refer to drmm_vram_helper_init() instead of the non-existent drmm_vram_helper_alloc_mm().
Fixes: a5f23a72355d ("drm/vram-helper: Managed vram helpers") Signed-off-by: Luc Ma luc@sietium.com Reviewed-by: Thomas Zimmermann tzimmermann@suse.de Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Link: https://patchwork.freedesktop.org/patch/msgid/64583db2.630a0220.eb75d.8f51@m... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_gem_vram_helper.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index d40b3edb52d07..f1539d4448c69 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -45,7 +45,7 @@ static const struct drm_gem_object_funcs drm_gem_vram_object_funcs; * the frame's scanout buffer or the cursor image. If there's no more space * left in VRAM, inactive GEM objects can be moved to system memory. * - * To initialize the VRAM helper library call drmm_vram_helper_alloc_mm(). + * To initialize the VRAM helper library call drmm_vram_helper_init(). * The function allocates and initializes an instance of &struct drm_vram_mm * in &struct drm_device.vram_mm . Use &DRM_GEM_VRAM_DRIVER to initialize * &struct drm_driver and &DRM_VRAM_MM_FILE_OPERATIONS to initialize @@ -73,7 +73,7 @@ static const struct drm_gem_object_funcs drm_gem_vram_object_funcs; * // setup device, vram base and size * // ... * - * ret = drmm_vram_helper_alloc_mm(dev, vram_base, vram_size); + * ret = drmm_vram_helper_init(dev, vram_base, vram_size); * if (ret) * return ret; * return 0; @@ -86,7 +86,7 @@ static const struct drm_gem_object_funcs drm_gem_vram_object_funcs; * to userspace. * * You don't have to clean up the instance of VRAM MM. - * drmm_vram_helper_alloc_mm() is a managed interface that installs a + * drmm_vram_helper_init() is a managed interface that installs a * clean-up handler to run during the DRM device's release. * * For drawing or scanout operations, rsp. buffer objects have to be pinned
From: Rafał Miłecki rafal@milecki.pl
[ Upstream commit d3c8e2c5757153bbfad70019ec1decbca86f3def ]
There is no such property in the SPI controller binding documentation. Also Linux driver doesn't look for it.
This fixes: arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: spi@18029200: Unevaluated properties are not allowed ('clock-names' was unexpected) From schema: Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.yaml
Signed-off-by: Rafał Miłecki rafal@milecki.pl Link: https://lore.kernel.org/r/20230503122830.3200-1-zajec5@gmail.com Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/bcm5301x.dtsi | 1 - 1 file changed, 1 deletion(-)
diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi index 5fc1b847f4aa5..787a0dd8216b7 100644 --- a/arch/arm/boot/dts/bcm5301x.dtsi +++ b/arch/arm/boot/dts/bcm5301x.dtsi @@ -542,7 +542,6 @@ spi@18029200 { "spi_lr_session_done", "spi_lr_overread"; clocks = <&iprocmed>; - clock-names = "iprocmed"; num-cs = <2>; #address-cells = <1>; #size-cells = <0>;
From: hfdevel@gmx.net hfdevel@gmx.net
[ Upstream commit d542ce8d4769cdef6a7bc3437e59cfed9c68f0e4 ]
With the current device tree for meson8b, uarts B (e.g. available on pins 8/10 on Odroid-C1) and C (pins 3/5 on Odroid-C1) do not work, because they are relying on incorrect clocks. Change the references of pclk to the correct CLKID, to allow use of the two uarts.
Fixes: 3375aa77135f ("ARM: dts: meson8b: Fix the UART device-tree schema validation") Signed-off-by: Hans-Frieder Vogt hfdevel@gmx.net Reviewed-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Link: https://lore.kernel.org/r/trinity-bf20bcb9-790b-4ab9-99e3-0831ef8257f4-16808... Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/meson8b.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/meson8b.dtsi b/arch/arm/boot/dts/meson8b.dtsi index d5a3fe21e8e7e..25f7c985f9ea1 100644 --- a/arch/arm/boot/dts/meson8b.dtsi +++ b/arch/arm/boot/dts/meson8b.dtsi @@ -740,13 +740,13 @@ &uart_A {
&uart_B { compatible = "amlogic,meson8b-uart"; - clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>; + clocks = <&xtal>, <&clkc CLKID_UART1>, <&clkc CLKID_CLK81>; clock-names = "xtal", "pclk", "baud"; };
&uart_C { compatible = "amlogic,meson8b-uart"; - clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>; + clocks = <&xtal>, <&clkc CLKID_UART2>, <&clkc CLKID_CLK81>; clock-names = "xtal", "pclk", "baud"; };
From: Marek Vasut marek.vasut+renesas@mailbox.org
[ Upstream commit be3471c5bd9b921c9adfab7948e8021611639164 ]
The .driver_data content in i2c_device_id table must match the .data content in of_device_id table, else device_get_match_data() would return bogus value on i2c_device_id match. Align the two tables.
The i2c_device_id table is now converted from of_device_id using 's@.compatible = "idt,([^"]+"), .data = (.*)@"\1, .driver_data = (kernel_ulong_t)\2@'
Fixes: 9adddb01ce5f ("clk: vc5: Add structure to describe particular chip features") Signed-off-by: Marek Vasut marek.vasut+renesas@mailbox.org Link: https://lore.kernel.org/r/20230507133906.15061-1-marek.vasut+renesas@mailbox... Reviewed-by: Luca Ceresoli luca.ceresoli@bootlin.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-versaclock5.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c index fa71a57875ce8..5452471b7ba55 100644 --- a/drivers/clk/clk-versaclock5.c +++ b/drivers/clk/clk-versaclock5.c @@ -1271,14 +1271,14 @@ static const struct vc5_chip_info idt_5p49v6975_info = { };
static const struct i2c_device_id vc5_id[] = { - { "5p49v5923", .driver_data = IDT_VC5_5P49V5923 }, - { "5p49v5925", .driver_data = IDT_VC5_5P49V5925 }, - { "5p49v5933", .driver_data = IDT_VC5_5P49V5933 }, - { "5p49v5935", .driver_data = IDT_VC5_5P49V5935 }, - { "5p49v60", .driver_data = IDT_VC6_5P49V60 }, - { "5p49v6901", .driver_data = IDT_VC6_5P49V6901 }, - { "5p49v6965", .driver_data = IDT_VC6_5P49V6965 }, - { "5p49v6975", .driver_data = IDT_VC6_5P49V6975 }, + { "5p49v5923", .driver_data = (kernel_ulong_t)&idt_5p49v5923_info }, + { "5p49v5925", .driver_data = (kernel_ulong_t)&idt_5p49v5925_info }, + { "5p49v5933", .driver_data = (kernel_ulong_t)&idt_5p49v5933_info }, + { "5p49v5935", .driver_data = (kernel_ulong_t)&idt_5p49v5935_info }, + { "5p49v60", .driver_data = (kernel_ulong_t)&idt_5p49v60_info }, + { "5p49v6901", .driver_data = (kernel_ulong_t)&idt_5p49v6901_info }, + { "5p49v6965", .driver_data = (kernel_ulong_t)&idt_5p49v6965_info }, + { "5p49v6975", .driver_data = (kernel_ulong_t)&idt_5p49v6975_info }, { } }; MODULE_DEVICE_TABLE(i2c, vc5_id);
From: Marek Vasut marek.vasut+renesas@mailbox.org
[ Upstream commit b5e10beeafaa3266559c582dde7534ae3fe8cefb ]
The .driver_data content in i2c_device_id table must match the .data content in of_device_id table, else device_get_match_data() would return bogus value on i2c_device_id match. Align the two tables.
The i2c_device_id table is now converted from of_device_id using 's@.compatible = "renesas,([^"]+"), .data = (.*)@"\1, .driver_data = (kernel_ulong_t)\2@'
Fixes: 48c5e98fedd9 ("clk: Renesas versaclock7 ccf device driver") Signed-off-by: Marek Vasut marek.vasut+renesas@mailbox.org Link: https://lore.kernel.org/r/20230507133906.15061-2-marek.vasut+renesas@mailbox... Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-versaclock7.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/clk-versaclock7.c b/drivers/clk/clk-versaclock7.c index 8e4f86e852aa0..0ae191f50b4b2 100644 --- a/drivers/clk/clk-versaclock7.c +++ b/drivers/clk/clk-versaclock7.c @@ -1282,7 +1282,7 @@ static const struct regmap_config vc7_regmap_config = { };
static const struct i2c_device_id vc7_i2c_id[] = { - { "rc21008a", VC7_RC21008A }, + { "rc21008a", .driver_data = (kernel_ulong_t)&vc7_rc21008a_info }, {} }; MODULE_DEVICE_TABLE(i2c, vc7_i2c_id);
From: Alexander Stein alexander.stein@ew.tq-group.com
[ Upstream commit da751726ff2ad2322d81316ebf6aadb22dfad0d8 ]
This is in preparation to support additional devices which have different IDs as well as a slightly different register layout.
Signed-off-by: Alexander Stein alexander.stein@ew.tq-group.com Reviewed-by: Marek Vasut marex@denx.de Link: https://lore.kernel.org/r/20230310075535.3476580-1-alexander.stein@ew.tq-gro... Signed-off-by: Stephen Boyd sboyd@kernel.org Stable-dep-of: ad527ca87e4e ("clk: rs9: Fix .driver_data content in i2c_device_id") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-renesas-pcie.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
diff --git a/drivers/clk/clk-renesas-pcie.c b/drivers/clk/clk-renesas-pcie.c index ff3a52d484790..f4e9f70f412af 100644 --- a/drivers/clk/clk-renesas-pcie.c +++ b/drivers/clk/clk-renesas-pcie.c @@ -45,6 +45,13 @@ #define RS9_REG_DID 0x6 #define RS9_REG_BCP 0x7
+#define RS9_REG_VID_IDT 0x01 + +#define RS9_REG_DID_TYPE_FGV (0x0 << RS9_REG_DID_TYPE_SHIFT) +#define RS9_REG_DID_TYPE_DBV (0x1 << RS9_REG_DID_TYPE_SHIFT) +#define RS9_REG_DID_TYPE_DMV (0x2 << RS9_REG_DID_TYPE_SHIFT) +#define RS9_REG_DID_TYPE_SHIFT 0x6 + /* Supported Renesas 9-series models. */ enum rs9_model { RENESAS_9FGV0241, @@ -54,6 +61,7 @@ enum rs9_model { struct rs9_chip_info { const enum rs9_model model; unsigned int num_clks; + u8 did; };
struct rs9_driver_data { @@ -270,6 +278,7 @@ static int rs9_probe(struct i2c_client *client) { unsigned char name[5] = "DIF0"; struct rs9_driver_data *rs9; + unsigned int vid, did; struct clk_hw *hw; int i, ret;
@@ -306,6 +315,20 @@ static int rs9_probe(struct i2c_client *client) if (ret < 0) return ret;
+ ret = regmap_read(rs9->regmap, RS9_REG_VID, &vid); + if (ret < 0) + return ret; + + ret = regmap_read(rs9->regmap, RS9_REG_DID, &did); + if (ret < 0) + return ret; + + if (vid != RS9_REG_VID_IDT || did != rs9->chip_info->did) + return dev_err_probe(&client->dev, -ENODEV, + "Incorrect VID/DID: %#02x, %#02x. Expected %#02x, %#02x\n", + vid, did, RS9_REG_VID_IDT, + rs9->chip_info->did); + /* Register clock */ for (i = 0; i < rs9->chip_info->num_clks; i++) { snprintf(name, 5, "DIF%d", i); @@ -349,6 +372,7 @@ static int __maybe_unused rs9_resume(struct device *dev) static const struct rs9_chip_info renesas_9fgv0241_info = { .model = RENESAS_9FGV0241, .num_clks = 2, + .did = RS9_REG_DID_TYPE_FGV | 0x02, };
static const struct i2c_device_id rs9_id[] = {
From: Alexander Stein alexander.stein@ew.tq-group.com
[ Upstream commit 603df193ec5174ff81c32cf1a78b7819ce984b8c ]
The calculation DIFx is BIT(n) +1 is only true for 9FGV0241. With additional devices this is getting more complicated. Support a base bit for the DIF calculation, currently only devices with consecutive bits are supported, e.g. the 6-channel device needs additional logic.
Signed-off-by: Alexander Stein alexander.stein@ew.tq-group.com Reviewed-by: Marek Vasut marex@denx.de Link: https://lore.kernel.org/r/20230310075535.3476580-3-alexander.stein@ew.tq-gro... Signed-off-by: Stephen Boyd sboyd@kernel.org Stable-dep-of: ad527ca87e4e ("clk: rs9: Fix .driver_data content in i2c_device_id") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-renesas-pcie.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-)
diff --git a/drivers/clk/clk-renesas-pcie.c b/drivers/clk/clk-renesas-pcie.c index f4e9f70f412af..0710362b2545b 100644 --- a/drivers/clk/clk-renesas-pcie.c +++ b/drivers/clk/clk-renesas-pcie.c @@ -18,7 +18,6 @@ #include <linux/regmap.h>
#define RS9_REG_OE 0x0 -#define RS9_REG_OE_DIF_OE(n) BIT((n) + 1) #define RS9_REG_SS 0x1 #define RS9_REG_SS_AMP_0V6 0x0 #define RS9_REG_SS_AMP_0V7 0x1 @@ -31,9 +30,6 @@ #define RS9_REG_SS_SSC_MASK (3 << 3) #define RS9_REG_SS_SSC_LOCK BIT(5) #define RS9_REG_SR 0x2 -#define RS9_REG_SR_2V0_DIF(n) 0 -#define RS9_REG_SR_3V0_DIF(n) BIT((n) + 1) -#define RS9_REG_SR_DIF_MASK(n) BIT((n) + 1) #define RS9_REG_REF 0x3 #define RS9_REG_REF_OE BIT(4) #define RS9_REG_REF_OD BIT(5) @@ -160,17 +156,27 @@ static const struct regmap_config rs9_regmap_config = { .reg_read = rs9_regmap_i2c_read, };
+static u8 rs9_calc_dif(const struct rs9_driver_data *rs9, int idx) +{ + enum rs9_model model = rs9->chip_info->model; + + if (model == RENESAS_9FGV0241) + return BIT(idx) + 1; + + return 0; +} + static int rs9_get_output_config(struct rs9_driver_data *rs9, int idx) { struct i2c_client *client = rs9->client; + u8 dif = rs9_calc_dif(rs9, idx); unsigned char name[5] = "DIF0"; struct device_node *np; int ret; u32 sr;
/* Set defaults */ - rs9->clk_dif_sr &= ~RS9_REG_SR_DIF_MASK(idx); - rs9->clk_dif_sr |= RS9_REG_SR_3V0_DIF(idx); + rs9->clk_dif_sr |= dif;
snprintf(name, 5, "DIF%d", idx); np = of_get_child_by_name(client->dev.of_node, name); @@ -182,11 +188,9 @@ static int rs9_get_output_config(struct rs9_driver_data *rs9, int idx) of_node_put(np); if (!ret) { if (sr == 2000000) { /* 2V/ns */ - rs9->clk_dif_sr &= ~RS9_REG_SR_DIF_MASK(idx); - rs9->clk_dif_sr |= RS9_REG_SR_2V0_DIF(idx); + rs9->clk_dif_sr &= ~dif; } else if (sr == 3000000) { /* 3V/ns (default) */ - rs9->clk_dif_sr &= ~RS9_REG_SR_DIF_MASK(idx); - rs9->clk_dif_sr |= RS9_REG_SR_3V0_DIF(idx); + rs9->clk_dif_sr |= dif; } else ret = dev_err_probe(&client->dev, -EINVAL, "Invalid renesas,slew-rate value\n"); @@ -257,11 +261,13 @@ static void rs9_update_config(struct rs9_driver_data *rs9) }
for (i = 0; i < rs9->chip_info->num_clks; i++) { - if (rs9->clk_dif_sr & RS9_REG_SR_3V0_DIF(i)) + u8 dif = rs9_calc_dif(rs9, i); + + if (rs9->clk_dif_sr & dif) continue;
- regmap_update_bits(rs9->regmap, RS9_REG_SR, RS9_REG_SR_3V0_DIF(i), - rs9->clk_dif_sr & RS9_REG_SR_3V0_DIF(i)); + regmap_update_bits(rs9->regmap, RS9_REG_SR, dif, + rs9->clk_dif_sr & dif); } }
From: Alexander Stein alexander.stein@ew.tq-group.com
[ Upstream commit e44fdd114cc3c872aa5157c6b3a190bcf92a9ffb ]
This model is similar to 9FGV0241, but the DIFx bits start at bit 0.
Signed-off-by: Alexander Stein alexander.stein@ew.tq-group.com Reviewed-by: Marek Vasut marex@denx.de Link: https://lore.kernel.org/r/20230310075535.3476580-4-alexander.stein@ew.tq-gro... Signed-off-by: Stephen Boyd sboyd@kernel.org Stable-dep-of: ad527ca87e4e ("clk: rs9: Fix .driver_data content in i2c_device_id") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-renesas-pcie.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/clk-renesas-pcie.c b/drivers/clk/clk-renesas-pcie.c index 0710362b2545b..10d31c222a1cb 100644 --- a/drivers/clk/clk-renesas-pcie.c +++ b/drivers/clk/clk-renesas-pcie.c @@ -6,6 +6,7 @@ * - 9FGV/9DBV/9DMV/9FGL/9DML/9QXL/9SQ * Currently supported: * - 9FGV0241 + * - 9FGV0441 * * Copyright (C) 2022 Marek Vasut marex@denx.de */ @@ -51,6 +52,7 @@ /* Supported Renesas 9-series models. */ enum rs9_model { RENESAS_9FGV0241, + RENESAS_9FGV0441, };
/* Structure to describe features of a particular 9-series model */ @@ -64,7 +66,7 @@ struct rs9_driver_data { struct i2c_client *client; struct regmap *regmap; const struct rs9_chip_info *chip_info; - struct clk_hw *clk_dif[2]; + struct clk_hw *clk_dif[4]; u8 pll_amplitude; u8 pll_ssc; u8 clk_dif_sr; @@ -162,6 +164,8 @@ static u8 rs9_calc_dif(const struct rs9_driver_data *rs9, int idx)
if (model == RENESAS_9FGV0241) return BIT(idx) + 1; + else if (model == RENESAS_9FGV0441) + return BIT(idx);
return 0; } @@ -381,14 +385,22 @@ static const struct rs9_chip_info renesas_9fgv0241_info = { .did = RS9_REG_DID_TYPE_FGV | 0x02, };
+static const struct rs9_chip_info renesas_9fgv0441_info = { + .model = RENESAS_9FGV0441, + .num_clks = 4, + .did = RS9_REG_DID_TYPE_FGV | 0x04, +}; + static const struct i2c_device_id rs9_id[] = { { "9fgv0241", .driver_data = RENESAS_9FGV0241 }, + { "9fgv0441", .driver_data = RENESAS_9FGV0441 }, { } }; MODULE_DEVICE_TABLE(i2c, rs9_id);
static const struct of_device_id clk_rs9_of_match[] = { { .compatible = "renesas,9fgv0241", .data = &renesas_9fgv0241_info }, + { .compatible = "renesas,9fgv0441", .data = &renesas_9fgv0441_info }, { } }; MODULE_DEVICE_TABLE(of, clk_rs9_of_match);
From: Marek Vasut marek.vasut+renesas@mailbox.org
[ Upstream commit ad527ca87e4ea42d7baad2ce710b44069287931b ]
The .driver_data content in i2c_device_id table must match the .data content in of_device_id table, else device_get_match_data() would return bogus value on i2c_device_id match. Align the two tables.
The i2c_device_id table is now converted from of_device_id using 's@.compatible = "renesas,([^"]+"), .data = (.*)@"\1, .driver_data = (kernel_ulong_t)\2@'
Fixes: 892e0ddea1aa ("clk: rs9: Add Renesas 9-series PCIe clock generator driver") Signed-off-by: Marek Vasut marek.vasut+renesas@mailbox.org Link: https://lore.kernel.org/r/20230507133906.15061-3-marek.vasut+renesas@mailbox... Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-renesas-pcie.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/clk-renesas-pcie.c b/drivers/clk/clk-renesas-pcie.c index 10d31c222a1cb..6060cafe1aa22 100644 --- a/drivers/clk/clk-renesas-pcie.c +++ b/drivers/clk/clk-renesas-pcie.c @@ -392,8 +392,8 @@ static const struct rs9_chip_info renesas_9fgv0441_info = { };
static const struct i2c_device_id rs9_id[] = { - { "9fgv0241", .driver_data = RENESAS_9FGV0241 }, - { "9fgv0441", .driver_data = RENESAS_9FGV0441 }, + { "9fgv0241", .driver_data = (kernel_ulong_t)&renesas_9fgv0241_info }, + { "9fgv0441", .driver_data = (kernel_ulong_t)&renesas_9fgv0441_info }, { } }; MODULE_DEVICE_TABLE(i2c, rs9_id);
From: Marek Vasut marex@denx.de
[ Upstream commit e96220bce5176ed2309f77f061dcc0430b82b25e ]
Instead of hardcoding IRQ trigger type to IRQF_TRIGGER_HIGH, let's respect the settings specified in the firmware description.
Fixes: e27c729219ad ("Input: add driver for ADXL345/346 Digital Accelerometers") Signed-off-by: Marek Vasut marex@denx.de Acked-by: Michael Hennerich michael.hennerich@analog.com Link: https://lore.kernel.org/r/20230509203555.549158-1-marex@denx.de Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/input/misc/adxl34x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c index eecca671b5884..a3f45e0ee0c75 100644 --- a/drivers/input/misc/adxl34x.c +++ b/drivers/input/misc/adxl34x.c @@ -817,8 +817,7 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, AC_WRITE(ac, POWER_CTL, 0);
err = request_threaded_irq(ac->irq, NULL, adxl34x_irq, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, - dev_name(dev), ac); + IRQF_ONESHOT, dev_name(dev), ac); if (err) { dev_err(dev, "irq %d busy?\n", ac->irq); goto err_free_mem;
From: XuDong Liu m202071377@hust.edu.cn
[ Upstream commit 123ee07ba5b7123e0ce0e0f9d64938026c16a2ce ]
Smatch reports: drivers/gpu/drm/sun4i/sun4i_tcon.c:805 sun4i_tcon_init_clocks() warn: 'tcon->clk' from clk_prepare_enable() not released on lines: 792,801.
In the function sun4i_tcon_init_clocks(), tcon->clk and tcon->sclk0 are not disabled in the error handling, which affects the release of these variable. Although sun4i_tcon_bind(), which calls sun4i_tcon_init_clocks(), use sun4i_tcon_free_clocks to disable the variables mentioned, but the error handling branch of sun4i_tcon_init_clocks() ignores the required disable process.
To fix this issue, use the devm_clk_get_enabled to automatically balance enable and disabled calls. As original implementation use sun4i_tcon_free_clocks() to disable clk explicitly, we delete the related calls and error handling that are no longer needed.
Fixes: 9026e0d122ac ("drm: Add Allwinner A10 Display Engine support") Fixes: b14e945bda8a ("drm/sun4i: tcon: Prepare and enable TCON channel 0 clock at init") Fixes: 8e9240472522 ("drm/sun4i: support TCONs without channel 1") Fixes: 34d698f6e349 ("drm/sun4i: Add has_channel_0 TCON quirk") Signed-off-by: XuDong Liu m202071377@hust.edu.cn Reviewed-by: Dongliang Mu dzm91@hust.edu.cn Signed-off-by: Maxime Ripard maxime@cerno.tech Link: https://patchwork.freedesktop.org/patch/msgid/20230430112347.4689-1-m2020713... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/sun4i/sun4i_tcon.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 523a6d7879210..936796851ffd3 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -778,21 +778,19 @@ static irqreturn_t sun4i_tcon_handler(int irq, void *private) static int sun4i_tcon_init_clocks(struct device *dev, struct sun4i_tcon *tcon) { - tcon->clk = devm_clk_get(dev, "ahb"); + tcon->clk = devm_clk_get_enabled(dev, "ahb"); if (IS_ERR(tcon->clk)) { dev_err(dev, "Couldn't get the TCON bus clock\n"); return PTR_ERR(tcon->clk); } - clk_prepare_enable(tcon->clk);
if (tcon->quirks->has_channel_0) { - tcon->sclk0 = devm_clk_get(dev, "tcon-ch0"); + tcon->sclk0 = devm_clk_get_enabled(dev, "tcon-ch0"); if (IS_ERR(tcon->sclk0)) { dev_err(dev, "Couldn't get the TCON channel 0 clock\n"); return PTR_ERR(tcon->sclk0); } } - clk_prepare_enable(tcon->sclk0);
if (tcon->quirks->has_channel_1) { tcon->sclk1 = devm_clk_get(dev, "tcon-ch1"); @@ -805,12 +803,6 @@ static int sun4i_tcon_init_clocks(struct device *dev, return 0; }
-static void sun4i_tcon_free_clocks(struct sun4i_tcon *tcon) -{ - clk_disable_unprepare(tcon->sclk0); - clk_disable_unprepare(tcon->clk); -} - static int sun4i_tcon_init_irq(struct device *dev, struct sun4i_tcon *tcon) { @@ -1223,14 +1215,14 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, ret = sun4i_tcon_init_regmap(dev, tcon); if (ret) { dev_err(dev, "Couldn't init our TCON regmap\n"); - goto err_free_clocks; + goto err_assert_reset; }
if (tcon->quirks->has_channel_0) { ret = sun4i_dclk_create(dev, tcon); if (ret) { dev_err(dev, "Couldn't create our TCON dot clock\n"); - goto err_free_clocks; + goto err_assert_reset; } }
@@ -1293,8 +1285,6 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, err_free_dotclock: if (tcon->quirks->has_channel_0) sun4i_dclk_free(tcon); -err_free_clocks: - sun4i_tcon_free_clocks(tcon); err_assert_reset: reset_control_assert(tcon->lcd_rst); return ret; @@ -1308,7 +1298,6 @@ static void sun4i_tcon_unbind(struct device *dev, struct device *master, list_del(&tcon->list); if (tcon->quirks->has_channel_0) sun4i_dclk_free(tcon); - sun4i_tcon_free_clocks(tcon); }
static const struct component_ops sun4i_tcon_ops = {
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit dee23b2c9e3ff46d59c5d45e1436eceb878e7c9a ]
Using current settings causes panel flickering on APQ8074 dragonboard. Adjust panel settings to follow the vendor-provided mode. This also enables MIPI_DSI_MODE_VIDEO_SYNC_PULSE, which is also specified by the vendor dtsi for the mentioned dragonboard.
Fixes: ee0172383190 ("drm/panel: Add Sharp LS043T1LE01 MIPI DSI panel") Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Neil Armstrong neil.armstrong@linaro.org Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20230507172639.2320934-1-dmitr... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c index d1ec80a3e3c72..ef148504cf24a 100644 --- a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c +++ b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c @@ -192,15 +192,15 @@ static int sharp_nt_panel_enable(struct drm_panel *panel) }
static const struct drm_display_mode default_mode = { - .clock = 41118, + .clock = (540 + 48 + 32 + 80) * (960 + 3 + 10 + 15) * 60 / 1000, .hdisplay = 540, .hsync_start = 540 + 48, - .hsync_end = 540 + 48 + 80, - .htotal = 540 + 48 + 80 + 32, + .hsync_end = 540 + 48 + 32, + .htotal = 540 + 48 + 32 + 80, .vdisplay = 960, .vsync_start = 960 + 3, - .vsync_end = 960 + 3 + 15, - .vtotal = 960 + 3 + 15 + 1, + .vsync_end = 960 + 3 + 10, + .vtotal = 960 + 3 + 10 + 15, };
static int sharp_nt_panel_get_modes(struct drm_panel *panel, @@ -280,6 +280,7 @@ static int sharp_nt_panel_probe(struct mipi_dsi_device *dsi) dsi->lanes = 2; dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO | + MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_NO_EOT_PACKET;
From: Dan Carpenter dan.carpenter@linaro.org
[ Upstream commit c58da0ba3e5c86e51e2c1557afaf6f71e00c4533 ]
The hash_for_each_possible() loop dereferences "eve_data" to get the next item on the list. However the loop frees eve_data so it leads to a use after free. Use hash_for_each_possible_safe() instead.
Fixes: c7fdb2404f66 ("drivers: soc: xilinx: add xilinx event management driver") Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Link: https://lore.kernel.org/r/761e0e4a-4caf-4a71-8f47-1c6ad908a848@kili.mountain Signed-off-by: Michal Simek michal.simek@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/xilinx/xlnx_event_manager.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/soc/xilinx/xlnx_event_manager.c b/drivers/soc/xilinx/xlnx_event_manager.c index c76381899ef49..f9d9b82b562da 100644 --- a/drivers/soc/xilinx/xlnx_event_manager.c +++ b/drivers/soc/xilinx/xlnx_event_manager.c @@ -192,11 +192,12 @@ static int xlnx_remove_cb_for_suspend(event_cb_func_t cb_fun) struct registered_event_data *eve_data; struct agent_cb *cb_pos; struct agent_cb *cb_next; + struct hlist_node *tmp;
is_need_to_unregister = false;
/* Check for existing entry in hash table for given cb_type */ - hash_for_each_possible(reg_driver_map, eve_data, hentry, PM_INIT_SUSPEND_CB) { + hash_for_each_possible_safe(reg_driver_map, eve_data, tmp, hentry, PM_INIT_SUSPEND_CB) { if (eve_data->cb_type == PM_INIT_SUSPEND_CB) { /* Delete the list of callback */ list_for_each_entry_safe(cb_pos, cb_next, &eve_data->cb_list_head, list) { @@ -228,11 +229,12 @@ static int xlnx_remove_cb_for_notify_event(const u32 node_id, const u32 event, u64 key = ((u64)node_id << 32U) | (u64)event; struct agent_cb *cb_pos; struct agent_cb *cb_next; + struct hlist_node *tmp;
is_need_to_unregister = false;
/* Check for existing entry in hash table for given key id */ - hash_for_each_possible(reg_driver_map, eve_data, hentry, key) { + hash_for_each_possible_safe(reg_driver_map, eve_data, tmp, hentry, key) { if (eve_data->key == key) { /* Delete the list of callback */ list_for_each_entry_safe(cb_pos, cb_next, &eve_data->cb_list_head, list) {
From: Trevor Wu trevor.wu@mediatek.com
[ Upstream commit 1e4fe75e9746be8e40c57132bb3fba1ce3dd24af ]
The original clock names are different from the list in driver code. Correct the mismatched binding names in the patch.
Because no mt8188 upstream dts exists, it doesn't affect the existing dts file.
Fixes: 692d25b67e10 ("ASoC: dt-bindings: mediatek,mt8188-afe: add audio afe document") Signed-off-by: Trevor Wu <trevor.wu@mediatek.com Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20230510035526.18137-9-trevor.wu@mediatek.com Signed-off-by: Mark Brown <broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../bindings/sound/mediatek,mt8188-afe.yaml | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml index 82ccb32f08f27..9e877f0d19fbb 100644 --- a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml +++ b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml @@ -63,15 +63,15 @@ properties: - const: apll12_div2 - const: apll12_div3 - const: apll12_div9 - - const: a1sys_hp_sel - - const: aud_intbus_sel - - const: audio_h_sel - - const: audio_local_bus_sel - - const: dptx_m_sel - - const: i2so1_m_sel - - const: i2so2_m_sel - - const: i2si1_m_sel - - const: i2si2_m_sel + - const: top_a1sys_hp + - const: top_aud_intbus + - const: top_audio_h + - const: top_audio_local_bus + - const: top_dptx + - const: top_i2so1 + - const: top_i2so2 + - const: top_i2si1 + - const: top_i2si2 - const: adsp_audio_26m
mediatek,etdm-in1-cowork-source: @@ -193,15 +193,15 @@ examples: "apll12_div2", "apll12_div3", "apll12_div9", - "a1sys_hp_sel", - "aud_intbus_sel", - "audio_h_sel", - "audio_local_bus_sel", - "dptx_m_sel", - "i2so1_m_sel", - "i2so2_m_sel", - "i2si1_m_sel", - "i2si2_m_sel", + "top_a1sys_hp", + "top_aud_intbus", + "top_audio_h", + "top_audio_local_bus", + "top_dptx", + "top_i2so1", + "top_i2so2", + "top_i2si1", + "top_i2si2", "adsp_audio_26m"; };
From: Bard Liao yung-chuan.liao@linux.intel.com
[ Upstream commit 0db94947c9d3da16aa31d152b7d26fab78b02cb9 ]
Topologies support three HDMI links on MeteorLake devices only.
Fixes: 18489174e4fb ("ASoC: intel: sof_sdw: add RT711 SDCA card for MTL platform") Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com Link: https://lore.kernel.org/r/20230512173305.65399-3-pierre-louis.bossart@linux.... Signed-off-by: Mark Brown <broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/intel/boards/sof_sdw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 767fa89d08708..1ac5abc721c68 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -413,7 +413,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { .matches = { DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_mtlrvp"), }, - .driver_data = (void *)(RT711_JD1 | SOF_SDW_TGL_HDMI), + .driver_data = (void *)(RT711_JD1), }, {} };
From: Maíra Canal mcanal@igalia.com
[ Upstream commit 322d716a3e8a74fb75cd0f657647be4df253fd2f ]
Currently, the pixel conversion functions repeat the same loop to iterate the rows. Instead of repeating the same code for each pixel format, create a function to wrap the loop and isolate the pixel conversion functionality.
Suggested-by: Arthur Grillo arthurgrillo@riseup.net Signed-off-by: Maíra Canal mcanal@igalia.com Reviewed-by: Arthur Grillo arthurgrillo@riseup.net Signed-off-by: Maíra Canal mairacanal@riseup.net Link: https://patchwork.freedesktop.org/patch/msgid/20230418130525.128733-2-mcanal... Stable-dep-of: ab87f558dcfb ("drm/vkms: Fix RGB565 pixel conversion") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vkms/vkms_composer.c | 4 +- drivers/gpu/drm/vkms/vkms_drv.h | 4 +- drivers/gpu/drm/vkms/vkms_formats.c | 125 +++++++++++---------------- drivers/gpu/drm/vkms/vkms_formats.h | 2 +- drivers/gpu/drm/vkms/vkms_plane.c | 2 +- 5 files changed, 56 insertions(+), 81 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index 8e53fa80742b2..80164e79af006 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -99,7 +99,7 @@ static void blend(struct vkms_writeback_job *wb, if (!check_y_limit(plane[i]->frame_info, y)) continue;
- plane[i]->plane_read(stage_buffer, plane[i]->frame_info, y); + vkms_compose_row(stage_buffer, plane[i], y); pre_mul_alpha_blend(plane[i]->frame_info, stage_buffer, output_buffer); } @@ -118,7 +118,7 @@ static int check_format_funcs(struct vkms_crtc_state *crtc_state, u32 n_active_planes = crtc_state->num_active_planes;
for (size_t i = 0; i < n_active_planes; i++) - if (!planes[i]->plane_read) + if (!planes[i]->pixel_read) return -1;
if (active_wb && !active_wb->wb_write) diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 4a248567efb26..f152d54baf769 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -56,8 +56,7 @@ struct vkms_writeback_job { struct vkms_plane_state { struct drm_shadow_plane_state base; struct vkms_frame_info *frame_info; - void (*plane_read)(struct line_buffer *buffer, - const struct vkms_frame_info *frame_info, int y); + void (*pixel_read)(u8 *src_buffer, struct pixel_argb_u16 *out_pixel); };
struct vkms_plane { @@ -155,6 +154,7 @@ int vkms_verify_crc_source(struct drm_crtc *crtc, const char *source_name, /* Composer Support */ void vkms_composer_worker(struct work_struct *work); void vkms_set_composer(struct vkms_output *out, bool enabled); +void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y);
/* Writeback */ int vkms_enable_writeback_connector(struct vkms_device *vkmsdev); diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index d4950688b3f17..8d948c73741ef 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -42,100 +42,75 @@ static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int y return packed_pixels_addr(frame_info, x_src, y_src); }
-static void ARGB8888_to_argb_u16(struct line_buffer *stage_buffer, - const struct vkms_frame_info *frame_info, int y) +static void ARGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel) { - struct pixel_argb_u16 *out_pixels = stage_buffer->pixels; - u8 *src_pixels = get_packed_src_addr(frame_info, y); - int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst), - stage_buffer->n_pixels); - - for (size_t x = 0; x < x_limit; x++, src_pixels += 4) { - /* - * The 257 is the "conversion ratio". This number is obtained by the - * (2^16 - 1) / (2^8 - 1) division. Which, in this case, tries to get - * the best color value in a pixel format with more possibilities. - * A similar idea applies to others RGB color conversions. - */ - out_pixels[x].a = (u16)src_pixels[3] * 257; - out_pixels[x].r = (u16)src_pixels[2] * 257; - out_pixels[x].g = (u16)src_pixels[1] * 257; - out_pixels[x].b = (u16)src_pixels[0] * 257; - } + /* + * The 257 is the "conversion ratio". This number is obtained by the + * (2^16 - 1) / (2^8 - 1) division. Which, in this case, tries to get + * the best color value in a pixel format with more possibilities. + * A similar idea applies to others RGB color conversions. + */ + out_pixel->a = (u16)src_pixels[3] * 257; + out_pixel->r = (u16)src_pixels[2] * 257; + out_pixel->g = (u16)src_pixels[1] * 257; + out_pixel->b = (u16)src_pixels[0] * 257; }
-static void XRGB8888_to_argb_u16(struct line_buffer *stage_buffer, - const struct vkms_frame_info *frame_info, int y) +static void XRGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel) { - struct pixel_argb_u16 *out_pixels = stage_buffer->pixels; - u8 *src_pixels = get_packed_src_addr(frame_info, y); - int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst), - stage_buffer->n_pixels); - - for (size_t x = 0; x < x_limit; x++, src_pixels += 4) { - out_pixels[x].a = (u16)0xffff; - out_pixels[x].r = (u16)src_pixels[2] * 257; - out_pixels[x].g = (u16)src_pixels[1] * 257; - out_pixels[x].b = (u16)src_pixels[0] * 257; - } + out_pixel->a = (u16)0xffff; + out_pixel->r = (u16)src_pixels[2] * 257; + out_pixel->g = (u16)src_pixels[1] * 257; + out_pixel->b = (u16)src_pixels[0] * 257; }
-static void ARGB16161616_to_argb_u16(struct line_buffer *stage_buffer, - const struct vkms_frame_info *frame_info, - int y) +static void ARGB16161616_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel) { - struct pixel_argb_u16 *out_pixels = stage_buffer->pixels; - u16 *src_pixels = get_packed_src_addr(frame_info, y); - int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst), - stage_buffer->n_pixels); + u16 *pixels = (u16 *)src_pixels;
- for (size_t x = 0; x < x_limit; x++, src_pixels += 4) { - out_pixels[x].a = le16_to_cpu(src_pixels[3]); - out_pixels[x].r = le16_to_cpu(src_pixels[2]); - out_pixels[x].g = le16_to_cpu(src_pixels[1]); - out_pixels[x].b = le16_to_cpu(src_pixels[0]); - } + out_pixel->a = le16_to_cpu(pixels[3]); + out_pixel->r = le16_to_cpu(pixels[2]); + out_pixel->g = le16_to_cpu(pixels[1]); + out_pixel->b = le16_to_cpu(pixels[0]); }
-static void XRGB16161616_to_argb_u16(struct line_buffer *stage_buffer, - const struct vkms_frame_info *frame_info, - int y) +static void XRGB16161616_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel) { - struct pixel_argb_u16 *out_pixels = stage_buffer->pixels; - u16 *src_pixels = get_packed_src_addr(frame_info, y); - int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst), - stage_buffer->n_pixels); + u16 *pixels = (u16 *)src_pixels;
- for (size_t x = 0; x < x_limit; x++, src_pixels += 4) { - out_pixels[x].a = (u16)0xffff; - out_pixels[x].r = le16_to_cpu(src_pixels[2]); - out_pixels[x].g = le16_to_cpu(src_pixels[1]); - out_pixels[x].b = le16_to_cpu(src_pixels[0]); - } + out_pixel->a = (u16)0xffff; + out_pixel->r = le16_to_cpu(pixels[2]); + out_pixel->g = le16_to_cpu(pixels[1]); + out_pixel->b = le16_to_cpu(pixels[0]); }
-static void RGB565_to_argb_u16(struct line_buffer *stage_buffer, - const struct vkms_frame_info *frame_info, int y) +static void RGB565_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel) { - struct pixel_argb_u16 *out_pixels = stage_buffer->pixels; - u16 *src_pixels = get_packed_src_addr(frame_info, y); - int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst), - stage_buffer->n_pixels); + u16 *pixels = (u16 *)src_pixels;
s64 fp_rb_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(31)); s64 fp_g_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(63));
- for (size_t x = 0; x < x_limit; x++, src_pixels++) { - u16 rgb_565 = le16_to_cpu(*src_pixels); - s64 fp_r = drm_int2fixp((rgb_565 >> 11) & 0x1f); - s64 fp_g = drm_int2fixp((rgb_565 >> 5) & 0x3f); - s64 fp_b = drm_int2fixp(rgb_565 & 0x1f); + u16 rgb_565 = le16_to_cpu(*pixels); + s64 fp_r = drm_int2fixp((rgb_565 >> 11) & 0x1f); + s64 fp_g = drm_int2fixp((rgb_565 >> 5) & 0x3f); + s64 fp_b = drm_int2fixp(rgb_565 & 0x1f);
- out_pixels[x].a = (u16)0xffff; - out_pixels[x].r = drm_fixp2int(drm_fixp_mul(fp_r, fp_rb_ratio)); - out_pixels[x].g = drm_fixp2int(drm_fixp_mul(fp_g, fp_g_ratio)); - out_pixels[x].b = drm_fixp2int(drm_fixp_mul(fp_b, fp_rb_ratio)); - } + out_pixel->a = (u16)0xffff; + out_pixel->r = drm_fixp2int(drm_fixp_mul(fp_r, fp_rb_ratio)); + out_pixel->g = drm_fixp2int(drm_fixp_mul(fp_g, fp_g_ratio)); + out_pixel->b = drm_fixp2int(drm_fixp_mul(fp_b, fp_rb_ratio)); +} + +void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y) +{ + struct pixel_argb_u16 *out_pixels = stage_buffer->pixels; + struct vkms_frame_info *frame_info = plane->frame_info; + u8 *src_pixels = get_packed_src_addr(frame_info, y); + int limit = min_t(size_t, drm_rect_width(&frame_info->dst), stage_buffer->n_pixels); + + for (size_t x = 0; x < limit; x++, src_pixels += frame_info->cpp) + plane->pixel_read(src_pixels, &out_pixels[x]); }
/* @@ -249,7 +224,7 @@ static void argb_u16_to_RGB565(struct vkms_frame_info *frame_info, } }
-void *get_frame_to_line_function(u32 format) +void *get_pixel_conversion_function(u32 format) { switch (format) { case DRM_FORMAT_ARGB8888: diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h index 43b7c19790181..c5b113495d0c0 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.h +++ b/drivers/gpu/drm/vkms/vkms_formats.h @@ -5,7 +5,7 @@
#include "vkms_drv.h"
-void *get_frame_to_line_function(u32 format); +void *get_pixel_conversion_function(u32 format);
void *get_line_to_frame_function(u32 format);
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index b3f8a115cc234..eaee51358a49b 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -123,7 +123,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane, frame_info->offset = fb->offsets[0]; frame_info->pitch = fb->pitches[0]; frame_info->cpp = fb->format->cpp[0]; - vkms_plane_state->plane_read = get_frame_to_line_function(fmt); + vkms_plane_state->pixel_read = get_pixel_conversion_function(fmt); }
static int vkms_plane_atomic_check(struct drm_plane *plane,
From: Maíra Canal mcanal@igalia.com
[ Upstream commit 8b25320887d7feac98875546ea0f521628b745bb ]
Create a new fixed-point helper to allow us to return the rounded value of our fixed point value.
[v2]: * Create the function drm_fixp2int_round() (Melissa Wen). [v3]: * Use drm_fixp2int() instead of shifting manually (Arthur Grillo).
Signed-off-by: Maíra Canal mcanal@igalia.com Reviewed-by: Arthur Grillo arthurgrillo@riseup.net Signed-off-by: Maíra Canal mairacanal@riseup.net Link: https://patchwork.freedesktop.org/patch/msgid/20230512104044.65034-1-mcanal@... Stable-dep-of: ab87f558dcfb ("drm/vkms: Fix RGB565 pixel conversion") Signed-off-by: Sasha Levin sashal@kernel.org --- include/drm/drm_fixed.h | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h index 255645c1f9a89..6ea339d5de088 100644 --- a/include/drm/drm_fixed.h +++ b/include/drm/drm_fixed.h @@ -71,6 +71,7 @@ static inline u32 dfixed_div(fixed20_12 A, fixed20_12 B) }
#define DRM_FIXED_POINT 32 +#define DRM_FIXED_POINT_HALF 16 #define DRM_FIXED_ONE (1ULL << DRM_FIXED_POINT) #define DRM_FIXED_DECIMAL_MASK (DRM_FIXED_ONE - 1) #define DRM_FIXED_DIGITS_MASK (~DRM_FIXED_DECIMAL_MASK) @@ -87,6 +88,11 @@ static inline int drm_fixp2int(s64 a) return ((s64)a) >> DRM_FIXED_POINT; }
+static inline int drm_fixp2int_round(s64 a) +{ + return drm_fixp2int(a + (1 << (DRM_FIXED_POINT_HALF - 1))); +} + static inline int drm_fixp2int_ceil(s64 a) { if (a > 0)
From: Maíra Canal mcanal@igalia.com
[ Upstream commit ab87f558dcfb2562c3497e89600dec798a446665 ]
Currently, the pixel conversion isn't rounding the fixed-point values before assigning it to the RGB coefficients, which is causing the IGT pixel-format tests to fail. So, use the drm_fixp2int_round() fixed-point helper to round the values when assigning it to the RGB coefficients.
Tested with igt@kms_plane@pixel-format and igt@kms_plane@pixel-format-source-clamping.
[v2]: * Use drm_fixp2int_round() to fix the pixel conversion instead of casting the values to s32 (Melissa Wen).
Fixes: 89b03aeaef16 ("drm/vkms: fix 32bit compilation error by replacing macros") Signed-off-by: Maíra Canal mcanal@igalia.com Reviewed-by: Arthur Grillo arthurgrillo@riseup.net Signed-off-by: Maíra Canal mairacanal@riseup.net Link: https://patchwork.freedesktop.org/patch/msgid/20230512104044.65034-2-mcanal@... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vkms/vkms_formats.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index 8d948c73741ef..b11342026485f 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -97,9 +97,9 @@ static void RGB565_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel) s64 fp_b = drm_int2fixp(rgb_565 & 0x1f);
out_pixel->a = (u16)0xffff; - out_pixel->r = drm_fixp2int(drm_fixp_mul(fp_r, fp_rb_ratio)); - out_pixel->g = drm_fixp2int(drm_fixp_mul(fp_g, fp_g_ratio)); - out_pixel->b = drm_fixp2int(drm_fixp_mul(fp_b, fp_rb_ratio)); + out_pixel->r = drm_fixp2int_round(drm_fixp_mul(fp_r, fp_rb_ratio)); + out_pixel->g = drm_fixp2int_round(drm_fixp_mul(fp_g, fp_g_ratio)); + out_pixel->b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio)); }
void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y) @@ -216,9 +216,9 @@ static void argb_u16_to_RGB565(struct vkms_frame_info *frame_info, s64 fp_g = drm_int2fixp(in_pixels[x].g); s64 fp_b = drm_int2fixp(in_pixels[x].b);
- u16 r = drm_fixp2int(drm_fixp_div(fp_r, fp_rb_ratio)); - u16 g = drm_fixp2int(drm_fixp_div(fp_g, fp_g_ratio)); - u16 b = drm_fixp2int(drm_fixp_div(fp_b, fp_rb_ratio)); + u16 r = drm_fixp2int_round(drm_fixp_div(fp_r, fp_rb_ratio)); + u16 g = drm_fixp2int_round(drm_fixp_div(fp_g, fp_g_ratio)); + u16 b = drm_fixp2int_round(drm_fixp_div(fp_b, fp_rb_ratio));
*dst_pixels = cpu_to_le16(r << 11 | g << 5 | b); }
From: Marek Vasut marex@denx.de
[ Upstream commit 9660efc2af37f3c12dc6e6a5511ad99e0addc297 ]
The ethernet MAC EEPROM is not populated on the SoM itself, it has to be populated on each carrier board. Move the EEPROM into the correct place in DTs, i.e. the carrier board DTs. Add label to the EEPROM too.
Fixes: 7e76f82acd9e1 ("ARM: dts: stm32: Split Avenger96 into DHCOR SoM and Avenger96 board") Signed-off-by: Marek Vasut marex@denx.de Signed-off-by: Alexandre Torgue alexandre.torgue@foss.st.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi | 6 ++++++ arch/arm/boot/dts/stm32mp15xx-dhcor-drc-compact.dtsi | 6 ++++++ arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi | 6 ------ arch/arm/boot/dts/stm32mp15xx-dhcor-testbench.dtsi | 8 ++++++++ 4 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi index 50af4a27d6be4..e67c0fa209cde 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi @@ -321,6 +321,12 @@ adv7513_i2s0: endpoint { }; }; }; + + dh_mac_eeprom: eeprom@53 { + compatible = "atmel,24c02"; + reg = <0x53>; + pagesize = <16>; + }; };
<dc { diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-drc-compact.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-drc-compact.dtsi index c32c160f97f20..39af79dc654cc 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcor-drc-compact.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-drc-compact.dtsi @@ -192,6 +192,12 @@ eeprom@50 { reg = <0x50>; pagesize = <16>; }; + + dh_mac_eeprom: eeprom@53 { + compatible = "atmel,24c02"; + reg = <0x53>; + pagesize = <16>; + }; };
&sdmmc1 { /* MicroSD */ diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi index bb40fb46da81d..bba19f21e5277 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi @@ -213,12 +213,6 @@ watchdog { status = "disabled"; }; }; - - eeprom@53 { - compatible = "atmel,24c02"; - reg = <0x53>; - pagesize = <16>; - }; };
&ipcc { diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-testbench.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-testbench.dtsi index 5fdb74b652aca..faed31b6d84a1 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcor-testbench.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-testbench.dtsi @@ -90,6 +90,14 @@ phy0: ethernet-phy@7 { }; };
+&i2c4 { + dh_mac_eeprom: eeprom@53 { + compatible = "atmel,24c02"; + reg = <0x53>; + pagesize = <16>; + }; +}; + &sdmmc1 { pinctrl-names = "default", "opendrain", "sleep"; pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_b>;
From: Tony Lindgren tony@atomide.com
[ Upstream commit f620596fa347170852da499e778a5736d79a4b79 ]
Fix warning drivers/bus/ti-sysc.c:1806 sysc_quirk_dispc() warn: masking a bool.
While at it let's add a comment for what were doing to make the code a bit easier to follow.
Fixes: 7324a7a0d5e2 ("bus: ti-sysc: Implement display subsystem reset quirk") Reported-by: Dan Carpenter dan.carpenter@linaro.org Closes: https://lore.kernel.org/linux-omap/a8ec8a68-9c2c-4076-bf47-09fccce7659f@kili... Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bus/ti-sysc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index 6afae98978434..b5ceec2b2d84f 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -1814,7 +1814,7 @@ static u32 sysc_quirk_dispc(struct sysc *ddata, int dispc_offset, if (!ddata->module_va) return -EIO;
- /* DISP_CONTROL */ + /* DISP_CONTROL, shut down lcd and digit on disable if enabled */ val = sysc_read(ddata, dispc_offset + 0x40); lcd_en = val & lcd_en_mask; digit_en = val & digit_en_mask; @@ -1826,7 +1826,7 @@ static u32 sysc_quirk_dispc(struct sysc *ddata, int dispc_offset, else irq_mask |= BIT(2) | BIT(3); /* EVSYNC bits */ } - if (disable & (lcd_en | digit_en)) + if (disable && (lcd_en || digit_en)) sysc_write(ddata, dispc_offset + 0x40, val & ~(lcd_en_mask | digit_en_mask));
From: Robert Marko robert.marko@sartura.hr
[ Upstream commit 70be83708c925b3f72c508e4756e48ad2330c830 ]
PSCI is not implemented on SparX-5 at all, there is no ATF and U-boot that is shipped does not implement it as well.
I have tried flashing the latest BSP 2022.12 U-boot which did not work. After contacting Microchip, they confirmed that there is no ATF for the SoC nor PSCI implementation which is unfortunate in 2023.
So, disable PSCI as otherwise kernel crashes as soon as it tries probing PSCI with, and the crash is only visible if earlycon is used.
Since PSCI is not implemented, switch core bringup to use spin-tables which are implemented in the vendor U-boot and actually work.
Tested on PCB134 with eMMC (VSC5640EV).
Fixes: 6694aee00a4b ("arm64: dts: sparx5: Add basic cpu support") Signed-off-by: Robert Marko robert.marko@sartura.hr Acked-by: Steen Hegelund Steen.Hegelund@microchip.com Link: https://lore.kernel.org/r/20230221105039.316819-1-robert.marko@sartura.hr Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/microchip/sparx5.dtsi | 2 +- arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/microchip/sparx5.dtsi b/arch/arm64/boot/dts/microchip/sparx5.dtsi index 0367a00a269b3..5eae6e7fd248e 100644 --- a/arch/arm64/boot/dts/microchip/sparx5.dtsi +++ b/arch/arm64/boot/dts/microchip/sparx5.dtsi @@ -61,7 +61,7 @@ arm-pmu { interrupt-affinity = <&cpu0>, <&cpu1>; };
- psci { + psci: psci { compatible = "arm,psci-0.2"; method = "smc"; }; diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi b/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi index 9d1a082de3e29..32bb76b3202a0 100644 --- a/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi +++ b/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi @@ -6,6 +6,18 @@ /dts-v1/; #include "sparx5.dtsi"
+&psci { + status = "disabled"; +}; + +&cpu0 { + enable-method = "spin-table"; +}; + +&cpu1 { + enable-method = "spin-table"; +}; + &uart0 { status = "okay"; };
From: Alexander Stein alexander.stein@ew.tq-group.com
[ Upstream commit f47d6140b7a4c858d82d263e7577ff6fb5279a9c ]
DSI device registering and attaching needs to be undone upon deregistration. This fixes module unload/load.
Fixes: bbfd3190b656 ("drm/bridge: tc358767: Add DSI-to-DPI mode support") Signed-off-by: Alexander Stein alexander.stein@ew.tq-group.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230517122107.1766673-1-alexa... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358767.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index 6d16ec45ea614..232e23a1bfcc0 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -1890,7 +1890,7 @@ static int tc_mipi_dsi_host_attach(struct tc_data *tc) if (dsi_lanes < 0) return dsi_lanes;
- dsi = mipi_dsi_device_register_full(host, &info); + dsi = devm_mipi_dsi_device_register_full(dev, host, &info); if (IS_ERR(dsi)) return dev_err_probe(dev, PTR_ERR(dsi), "failed to create dsi device\n"); @@ -1901,7 +1901,7 @@ static int tc_mipi_dsi_host_attach(struct tc_data *tc) dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
- ret = mipi_dsi_attach(dsi); + ret = devm_mipi_dsi_attach(dev, dsi); if (ret < 0) { dev_err(dev, "failed to attach dsi to host: %d\n", ret); return ret;
From: Dan Carpenter dan.carpenter@linaro.org
[ Upstream commit 632c60ecd25dbacee54d5581fe3aeb834b57010a ]
This loop is freeing "clk" so it needs to use list_for_each_entry_safe(). Otherwise it dereferences a freed variable to get the next item on the loop.
Fixes: 77d8f3068c63 ("clk: imx: scu: add two cells binding support") Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Reviewed-by: Abel Vesa abel.vesa@linaro.org Link: https://lore.kernel.org/r/0793fbd1-d2b5-4ec2-9403-3c39343a3e2d@kili.mountain Signed-off-by: Abel Vesa abel.vesa@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/imx/clk-scu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c index 1e6870f3671f6..db307890e4c16 100644 --- a/drivers/clk/imx/clk-scu.c +++ b/drivers/clk/imx/clk-scu.c @@ -707,11 +707,11 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name,
void imx_clk_scu_unregister(void) { - struct imx_scu_clk_node *clk; + struct imx_scu_clk_node *clk, *n; int i;
for (i = 0; i < IMX_SC_R_LAST; i++) { - list_for_each_entry(clk, &imx_scu_clks[i], node) { + list_for_each_entry_safe(clk, n, &imx_scu_clks[i], node) { clk_hw_unregister(clk->hw); kfree(clk); }
From: Nikita Zhandarovich n.zhandarovich@fintech.ru
[ Upstream commit 0babf89c9cca7e074d6e59893e462e4886f481cc ]
In the unlikely event that something goes wrong with the device and its registers, the fan_from_reg() function may return 0. This value will cause a division-by-zero error in the show_pwm() function.
To prevent this, test the value of fan_from_reg(data->fan_full_speed[nr]) against 0 before performing the division. If the division-by-zero error is avoided, assign 0 to the val variable.
Found by Linux Verification Center (linuxtesting.org) with static analysis tool SVACE.
Fixes: df9ec2dae094 ("hwmon: (f71882fg) Reorder symbols to get rid of a few forward declarations") Signed-off-by: Nikita Zhandarovich n.zhandarovich@fintech.ru Link: https://lore.kernel.org/r/20230510143537.145060-1-n.zhandarovich@fintech.ru Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/f71882fg.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 70121482a6173..27207ec6f7feb 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c @@ -1096,8 +1096,11 @@ static ssize_t show_pwm(struct device *dev, val = data->pwm[nr]; else { /* RPM mode */ - val = 255 * fan_from_reg(data->fan_target[nr]) - / fan_from_reg(data->fan_full_speed[nr]); + if (fan_from_reg(data->fan_full_speed[nr])) + val = 255 * fan_from_reg(data->fan_target[nr]) + / fan_from_reg(data->fan_full_speed[nr]); + else + val = 0; } mutex_unlock(&data->update_lock); return sprintf(buf, "%d\n", val);
From: Selvin Xavier selvin.xavier@broadcom.com
[ Upstream commit ab112ee7899d6171da5acd77a7ed7ae103f488de ]
When the ulp hook to start the IRQ fails because the rings are not available, tasklets are not enabled. In this case when the driver is unloaded, driver calls CREQ tasklet_kill. This causes an indefinite hang as the tasklet is not enabled.
Driver shouldn't call tasklet_kill if it is not enabled. So using the creq->requested and nq->requested flags to identify if both tasklets/irqs are registered. Checking this flag while scheduling the tasklet from ISR. Also, added a cleanup for disabling tasklet, in case request_irq fails during start_irq.
Check for return value for bnxt_qplib_rcfw_start_irq and in case the bnxt_qplib_rcfw_start_irq fails, return bnxt_re_start_irq without attempting to start NQ IRQs.
Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") Link: https://lore.kernel.org/r/1684478897-12247-2-git-send-email-selvin.xavier@br... Signed-off-by: Kalesh AP kalesh-anakkur.purayil@broadcom.com Signed-off-by: Selvin Xavier selvin.xavier@broadcom.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/bnxt_re/main.c | 12 +++++++++--- drivers/infiniband/hw/bnxt_re/qplib_fp.c | 16 ++++++++++------ drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 14 +++++++++----- 3 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c index 85e36c9f8e797..a9cc65614a9ee 100644 --- a/drivers/infiniband/hw/bnxt_re/main.c +++ b/drivers/infiniband/hw/bnxt_re/main.c @@ -283,15 +283,21 @@ static void bnxt_re_start_irq(void *handle, struct bnxt_msix_entry *ent) for (indx = 0; indx < rdev->num_msix; indx++) rdev->en_dev->msix_entries[indx].vector = ent[indx].vector;
- bnxt_qplib_rcfw_start_irq(rcfw, msix_ent[BNXT_RE_AEQ_IDX].vector, - false); + rc = bnxt_qplib_rcfw_start_irq(rcfw, msix_ent[BNXT_RE_AEQ_IDX].vector, + false); + if (rc) { + ibdev_warn(&rdev->ibdev, "Failed to reinit CREQ\n"); + return; + } for (indx = BNXT_RE_NQ_IDX ; indx < rdev->num_msix; indx++) { nq = &rdev->nq[indx - 1]; rc = bnxt_qplib_nq_start_irq(nq, indx - 1, msix_ent[indx].vector, false); - if (rc) + if (rc) { ibdev_warn(&rdev->ibdev, "Failed to reinit NQ index %d\n", indx - 1); + return; + } } }
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c index ab2cc1c67f70b..a143bd3580a27 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c @@ -405,6 +405,9 @@ static irqreturn_t bnxt_qplib_nq_irq(int irq, void *dev_instance)
void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill) { + if (!nq->requested) + return; + tasklet_disable(&nq->nq_tasklet); /* Mask h/w interrupt */ bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, false); @@ -412,11 +415,10 @@ void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill) synchronize_irq(nq->msix_vec); if (kill) tasklet_kill(&nq->nq_tasklet); - if (nq->requested) { - irq_set_affinity_hint(nq->msix_vec, NULL); - free_irq(nq->msix_vec, nq); - nq->requested = false; - } + + irq_set_affinity_hint(nq->msix_vec, NULL); + free_irq(nq->msix_vec, nq); + nq->requested = false; }
void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq) @@ -455,8 +457,10 @@ int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx,
snprintf(nq->name, sizeof(nq->name), "bnxt_qplib_nq-%d", nq_indx); rc = request_irq(nq->msix_vec, bnxt_qplib_nq_irq, 0, nq->name, nq); - if (rc) + if (rc) { + tasklet_disable(&nq->nq_tasklet); return rc; + }
cpumask_clear(&nq->mask); cpumask_set_cpu(nq_indx, &nq->mask); diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c index 061b2895dd9b5..e28f0eb5b55d4 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c @@ -635,6 +635,10 @@ void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill) struct bnxt_qplib_creq_ctx *creq;
creq = &rcfw->creq; + + if (!creq->requested) + return; + tasklet_disable(&creq->creq_tasklet); /* Mask h/w interrupts */ bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, false); @@ -643,10 +647,8 @@ void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill) if (kill) tasklet_kill(&creq->creq_tasklet);
- if (creq->requested) { - free_irq(creq->msix_vec, rcfw); - creq->requested = false; - } + free_irq(creq->msix_vec, rcfw); + creq->requested = false; }
void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw) @@ -692,8 +694,10 @@ int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector, tasklet_enable(&creq->creq_tasklet); rc = request_irq(creq->msix_vec, bnxt_qplib_creq_irq, 0, "bnxt_qplib_creq", rcfw); - if (rc) + if (rc) { + tasklet_disable(&creq->creq_tasklet); return rc; + } creq->requested = true;
bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, true);
From: Kalesh AP kalesh-anakkur.purayil@broadcom.com
[ Upstream commit 9b3ee47796f529e5bc31a355d6cb756d68a7079a ]
If there is no cleanup needed then just return directly. This cleans up the code and improve readability.
Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") Link: https://lore.kernel.org/r/1684478897-12247-3-git-send-email-selvin.xavier@br... Reviewed-by: Kashyap Desai kashyap.desai@broadcom.com Reviewed-by: Saravanan Vajravel saravanan.vajravel@broadcom.com Signed-off-by: Kalesh AP kalesh-anakkur.purayil@broadcom.com Signed-off-by: Selvin Xavier selvin.xavier@broadcom.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/bnxt_re/qplib_fp.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c index a143bd3580a27..4abe1f59b3689 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c @@ -1605,7 +1605,7 @@ static int bnxt_qplib_put_inline(struct bnxt_qplib_qp *qp, il_src = (void *)wqe->sg_list[indx].addr; t_len += len; if (t_len > qp->max_inline_data) - goto bad; + return -ENOMEM; while (len) { if (pull_dst) { pull_dst = false; @@ -1629,8 +1629,6 @@ static int bnxt_qplib_put_inline(struct bnxt_qplib_qp *qp, }
return t_len; -bad: - return -ENOMEM; }
static u32 bnxt_qplib_put_sges(struct bnxt_qplib_hwq *hwq, @@ -2060,7 +2058,7 @@ int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq) hwq_attr.sginfo = &cq->sg_info; rc = bnxt_qplib_alloc_init_hwq(&cq->hwq, &hwq_attr); if (rc) - goto exit; + return rc;
RCFW_CMD_PREP(req, CREATE_CQ, cmd_flags);
@@ -2101,7 +2099,6 @@ int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
fail: bnxt_qplib_free_hwq(res, &cq->hwq); -exit: return rc; }
From: Kalesh AP kalesh-anakkur.purayil@broadcom.com
[ Upstream commit ff2e4bfd162cf66a112a81509e419805add44d64 ]
bnxt_re currently uses the names "bnxt_qplib_creq" and "bnxt_qplib_nq-0" while registering IRQs. There is no way to distinguish the IRQs of different device ports when there are multiple IB devices registered. This could make the scenarios worse where one want to pin IRQs of a device port to certain CPUs.
Fixed the code to use unique names which has PCI BDF information while registering interrupts like: "bnxt_re-nq-0@pci:0000:65:00.0" and "bnxt_re-creq@pci:0000:65:00.1".
Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") Link: https://lore.kernel.org/r/1684478897-12247-4-git-send-email-selvin.xavier@br... Reviewed-by: Bhargava Chenna Marreddy bhargava.marreddy@broadcom.com Signed-off-by: Kalesh AP kalesh-anakkur.purayil@broadcom.com Signed-off-by: Selvin Xavier selvin.xavier@broadcom.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/bnxt_re/qplib_fp.c | 12 ++++++++++-- drivers/infiniband/hw/bnxt_re/qplib_fp.h | 2 +- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 15 +++++++++++++-- drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 1 + 4 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c index 4abe1f59b3689..640d932bec376 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c @@ -418,6 +418,8 @@ void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill)
irq_set_affinity_hint(nq->msix_vec, NULL); free_irq(nq->msix_vec, nq); + kfree(nq->name); + nq->name = NULL; nq->requested = false; }
@@ -444,6 +446,7 @@ void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq) int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx, int msix_vector, bool need_init) { + struct bnxt_qplib_res *res = nq->res; int rc;
if (nq->requested) @@ -455,9 +458,14 @@ int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx, else tasklet_enable(&nq->nq_tasklet);
- snprintf(nq->name, sizeof(nq->name), "bnxt_qplib_nq-%d", nq_indx); + nq->name = kasprintf(GFP_KERNEL, "bnxt_re-nq-%d@pci:%s", + nq_indx, pci_name(res->pdev)); + if (!nq->name) + return -ENOMEM; rc = request_irq(nq->msix_vec, bnxt_qplib_nq_irq, 0, nq->name, nq); if (rc) { + kfree(nq->name); + nq->name = NULL; tasklet_disable(&nq->nq_tasklet); return rc; } @@ -471,7 +479,7 @@ int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx, nq->msix_vec, nq_indx); } nq->requested = true; - bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, true); + bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, res->cctx, true);
return rc; } diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h index 0375019525431..f859710f9a7f4 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h @@ -471,7 +471,7 @@ typedef int (*srqn_handler_t)(struct bnxt_qplib_nq *nq, struct bnxt_qplib_nq { struct pci_dev *pdev; struct bnxt_qplib_res *res; - char name[32]; + char *name; struct bnxt_qplib_hwq hwq; struct bnxt_qplib_nq_db nq_db; u16 ring_id; diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c index e28f0eb5b55d4..9c63b8b62edfc 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c @@ -648,6 +648,8 @@ void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill) tasklet_kill(&creq->creq_tasklet);
free_irq(creq->msix_vec, rcfw); + kfree(creq->irq_name); + creq->irq_name = NULL; creq->requested = false; }
@@ -680,9 +682,11 @@ int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector, bool need_init) { struct bnxt_qplib_creq_ctx *creq; + struct bnxt_qplib_res *res; int rc;
creq = &rcfw->creq; + res = rcfw->res;
if (creq->requested) return -EFAULT; @@ -692,15 +696,22 @@ int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector, tasklet_setup(&creq->creq_tasklet, bnxt_qplib_service_creq); else tasklet_enable(&creq->creq_tasklet); + + creq->irq_name = kasprintf(GFP_KERNEL, "bnxt_re-creq@pci:%s", + pci_name(res->pdev)); + if (!creq->irq_name) + return -ENOMEM; rc = request_irq(creq->msix_vec, bnxt_qplib_creq_irq, 0, - "bnxt_qplib_creq", rcfw); + creq->irq_name, rcfw); if (rc) { + kfree(creq->irq_name); + creq->irq_name = NULL; tasklet_disable(&creq->creq_tasklet); return rc; } creq->requested = true;
- bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, true); + bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, res->cctx, true);
return 0; } diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h index 0a3d8e7da3d42..b887e7fbad9ef 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h +++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h @@ -174,6 +174,7 @@ struct bnxt_qplib_creq_ctx { u16 ring_id; int msix_vec; bool requested; /*irq handler installed */ + char *irq_name; };
/* RCFW Communication Channels */
From: Kalesh AP kalesh-anakkur.purayil@broadcom.com
[ Upstream commit b989f90cef0af48aa5679b6a75476371705ec53c ]
The NULL check inside bnxt_re_update_gid() always return false. If sgid_tbl->tbl is not allocated, then dev_init would have failed.
Fixes: 5fac5b1b297f ("RDMA/bnxt_re: Add vlan tag for untagged RoCE traffic when PFC is configured") Link: https://lore.kernel.org/r/1684478897-12247-5-git-send-email-selvin.xavier@br... Reviewed-by: Saravanan Vajravel saravanan.vajravel@broadcom.com Reviewed-by: Damodharam Ammepalli damodharam.ammepalli@broadcom.com Reviewed-by: Ajit Khaparde ajit.khaparde@broadcom.com Signed-off-by: Selvin Xavier selvin.xavier@broadcom.com Signed-off-by: Kalesh AP kalesh-anakkur.purayil@broadcom.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/bnxt_re/main.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c index a9cc65614a9ee..b4edcf12d0d19 100644 --- a/drivers/infiniband/hw/bnxt_re/main.c +++ b/drivers/infiniband/hw/bnxt_re/main.c @@ -1010,12 +1010,6 @@ static int bnxt_re_update_gid(struct bnxt_re_dev *rdev) if (!ib_device_try_get(&rdev->ibdev)) return 0;
- if (!sgid_tbl) { - ibdev_err(&rdev->ibdev, "QPLIB: SGID table not allocated"); - rc = -EINVAL; - goto out; - } - for (index = 0; index < sgid_tbl->active; index++) { gid_idx = sgid_tbl->hw_id[index];
@@ -1033,7 +1027,7 @@ static int bnxt_re_update_gid(struct bnxt_re_dev *rdev) rc = bnxt_qplib_update_sgid(sgid_tbl, &gid, gid_idx, rdev->qplib_res.netdev->dev_addr); } -out: + ib_device_put(&rdev->ibdev); return rc; }
From: Kalesh AP kalesh-anakkur.purayil@broadcom.com
[ Upstream commit 43774bc156614346fe5dacabc8e8c229167f2536 ]
During destroy_qp, driver sets the qp handle in the existing CQEs belonging to the QP being destroyed to NULL. As a result, a poll_cq after destroy_qp can report unnecessary messages. Remove this noise from system logs.
Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") Link: https://lore.kernel.org/r/1684478897-12247-6-git-send-email-selvin.xavier@br... Signed-off-by: Kalesh AP kalesh-anakkur.purayil@broadcom.com Signed-off-by: Selvin Xavier selvin.xavier@broadcom.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/bnxt_re/qplib_fp.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c index 640d932bec376..74d56900387a1 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c @@ -2734,11 +2734,8 @@ static int bnxt_qplib_cq_process_terminal(struct bnxt_qplib_cq *cq,
qp = (struct bnxt_qplib_qp *)((unsigned long) le64_to_cpu(hwcqe->qp_handle)); - if (!qp) { - dev_err(&cq->hwq.pdev->dev, - "FP: CQ Process terminal qp is NULL\n"); + if (!qp) return -EINVAL; - }
/* Must block new posting of SQ and RQ */ qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 1e0a97f84d73ea1182740f62069690c7f3271abb ]
If the dispcc uses CLK_OPS_PARENT_ENABLE (e.g. on QCM2290), CCF can try enabling VCO before the rate has been programmed. This can cause clock lockups and/or other boot issues. Program the VCO to the minimal PLL rate if the read rate is 0 Hz.
Cc: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reported-by: Vladimir Zapolskiy vladimir.zapolskiy@linaro.org Reported-by: Konrad Dybcio konrad.dybcio@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Fixes: f079f6d999cb ("drm/msm/dsi: Add PHY/PLL for 8x96") Patchwork: https://patchwork.freedesktop.org/patch/534813/ Link: https://lore.kernel.org/r/20230501011257.3460103-1-dmitry.baryshkov@linaro.o... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index 9f488adea7f54..3ce45b023e637 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -539,6 +539,9 @@ static int dsi_pll_14nm_vco_prepare(struct clk_hw *hw) if (unlikely(pll_14nm->phy->pll_on)) return 0;
+ if (dsi_pll_14nm_vco_recalc_rate(hw, VCO_REF_CLK_RATE) == 0) + dsi_pll_14nm_vco_set_rate(hw, pll_14nm->phy->cfg->min_pll_rate, VCO_REF_CLK_RATE); + dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_VREF_CFG1, 0x10); dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 1);
From: Vinod Polimera quic_vpolimer@quicinc.com
[ Upstream commit e3969eadc8ee78a5bdca65b8ed0a421a359e4090 ]
Recommended way of reading the interface timing gen status is via status register. Timing gen status register will give a reliable status of the interface especially during ON/OFF transitions. This support was added from DPU version 5.0.0.
Signed-off-by: Vinod Polimera quic_vpolimer@quicinc.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/524724/ Link: https://lore.kernel.org/r/1677774797-31063-6-git-send-email-quic_vpolimer@qu... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Stable-dep-of: a7129231edf3 ("drm/msm/dpu: Set DPU_DATA_HCTL_EN for in INTF_SC7180_MASK") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 3 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 12 +++++++----- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 8 +++++++- 3 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index f7214c4401e19..900cdb40c7b40 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -94,7 +94,8 @@
#define INTF_SDM845_MASK (0)
-#define INTF_SC7180_MASK BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE) +#define INTF_SC7180_MASK \ + (BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE) | BIT(DPU_INTF_STATUS_SUPPORTED))
#define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 5f96dd8def092..d7d45e1e7b310 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -214,17 +214,19 @@ enum {
/** * INTF sub-blocks - * @DPU_INTF_INPUT_CTRL Supports the setting of pp block from which - * pixel data arrives to this INTF - * @DPU_INTF_TE INTF block has TE configuration support - * @DPU_DATA_HCTL_EN Allows data to be transferred at different rate - than video timing + * @DPU_INTF_INPUT_CTRL Supports the setting of pp block from which + * pixel data arrives to this INTF + * @DPU_INTF_TE INTF block has TE configuration support + * @DPU_DATA_HCTL_EN Allows data to be transferred at different rate + * than video timing + * @DPU_INTF_STATUS_SUPPORTED INTF block has INTF_STATUS register * @DPU_INTF_MAX */ enum { DPU_INTF_INPUT_CTRL = 0x1, DPU_INTF_TE, DPU_DATA_HCTL_EN, + DPU_INTF_STATUS_SUPPORTED, DPU_INTF_MAX };
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index b2a94b9a3e987..b9dddf576c029 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -57,6 +57,7 @@ #define INTF_PROG_FETCH_START 0x170 #define INTF_PROG_ROT_START 0x174 #define INTF_MUX 0x25C +#define INTF_STATUS 0x26C
#define INTF_CFG_ACTIVE_H_EN BIT(29) #define INTF_CFG_ACTIVE_V_EN BIT(30) @@ -292,8 +293,13 @@ static void dpu_hw_intf_get_status( struct intf_status *s) { struct dpu_hw_blk_reg_map *c = &intf->hw; + unsigned long cap = intf->cap->features; + + if (cap & BIT(DPU_INTF_STATUS_SUPPORTED)) + s->is_en = DPU_REG_READ(c, INTF_STATUS) & BIT(0); + else + s->is_en = DPU_REG_READ(c, INTF_TIMING_ENGINE_EN);
- s->is_en = DPU_REG_READ(c, INTF_TIMING_ENGINE_EN); s->is_prog_fetch_en = !!(DPU_REG_READ(c, INTF_CONFIG) & BIT(31)); if (s->is_en) { s->frame_count = DPU_REG_READ(c, INTF_FRAME_COUNT);
From: Konrad Dybcio konrad.dybcio@linaro.org
[ Upstream commit a7129231edf329a00e92dbd2d741f6da728a4a06 ]
DPU5 and newer targets enable this unconditionally. Move it from the SC7280 mask to the SC7180 one.
Fixes: 7e6ee55320f0 ("drm/msm/disp/dpu1: enable DATA_HCTL_EN for sc7280 target") Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Marijn Suijten marijn.suijten@somainline.org Signed-off-by: Konrad Dybcio konrad.dybcio@linaro.org Reviewed-by: Abhinav Kumar quic_abhinavk@quicinc.com Patchwork: https://patchwork.freedesktop.org/patch/538159/ Link: https://lore.kernel.org/r/20230508-topic-hctl_en-v2-1-e7bea9f1f5dd@linaro.or... [DB: removed BIT(DPU_INTF_DATA_COMPRESS), which is not yet merged] Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 900cdb40c7b40..f41bbceef70cf 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -95,9 +95,12 @@ #define INTF_SDM845_MASK (0)
#define INTF_SC7180_MASK \ - (BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE) | BIT(DPU_INTF_STATUS_SUPPORTED)) + (BIT(DPU_INTF_INPUT_CTRL) | \ + BIT(DPU_INTF_TE) | \ + BIT(DPU_INTF_STATUS_SUPPORTED) | \ + BIT(DPU_DATA_HCTL_EN))
-#define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN) +#define INTF_SC7280_MASK (INTF_SC7180_MASK)
#define IRQ_SDM845_MASK (BIT(MDP_SSPP_TOP0_INTR) | \ BIT(MDP_SSPP_TOP0_INTR2) | \
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 504e72ed3a1b1c0d4450712a42ae6070d3a05a8e ]
nv50_display_create() is declared in another header, along with a couple of declarations that are now outdated:
drivers/gpu/drm/nouveau/dispnv50/disp.c:2517:1: error: no previous prototype for 'nv50_display_create'
Fixes: ba801ef068c1 ("drm/nouveau/kms: display destroy/init/fini hooks can be static") Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Karol Herbst kherbst@redhat.com Signed-off-by: Karol Herbst kherbst@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20230417210329.2469722-1-arnd@... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 1 + drivers/gpu/drm/nouveau/nv50_display.h | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 5bb777ff13130..9b6824f6b9e4b 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -64,6 +64,7 @@ #include "nouveau_connector.h" #include "nouveau_encoder.h" #include "nouveau_fence.h" +#include "nv50_display.h"
#include <subdev/bios/dp.h>
diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h index fbd3b15583bc8..60f77766766e9 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.h +++ b/drivers/gpu/drm/nouveau/nv50_display.h @@ -31,7 +31,5 @@ #include "nouveau_reg.h"
int nv50_display_create(struct drm_device *); -void nv50_display_destroy(struct drm_device *); -int nv50_display_init(struct drm_device *); -void nv50_display_fini(struct drm_device *); + #endif /* __NV50_DISPLAY_H__ */
From: Jean-Philippe Brucker jean-philippe@linaro.org
[ Upstream commit 809d0810e3520da669d231303608cdf5fe5c1a70 ]
When an endpoint is released, for example a PCIe VF being destroyed or a function hot-unplugged, it should be detached from its domain. Send a DETACH request.
Fixes: edcd69ab9a32 ("iommu: Add virtio-iommu driver") Reported-by: Akihiko Odaki akihiko.odaki@daynix.com Link: https://lore.kernel.org/all/15bf1b00-3aa0-973a-3a86-3fa5c4d41d2c@daynix.com/ Signed-off-by: Jean-Philippe Brucker jean-philippe@linaro.org Tested-by: Akihiko Odaki akihiko.odaki@daynix.com Link: https://lore.kernel.org/r/20230515113946.1017624-2-jean-philippe@linaro.org Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/virtio-iommu.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c index 5b8fe9bfa9a5b..fd316a37d7562 100644 --- a/drivers/iommu/virtio-iommu.c +++ b/drivers/iommu/virtio-iommu.c @@ -788,6 +788,29 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev) return 0; }
+static void viommu_detach_dev(struct viommu_endpoint *vdev) +{ + int i; + struct virtio_iommu_req_detach req; + struct viommu_domain *vdomain = vdev->vdomain; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(vdev->dev); + + if (!vdomain) + return; + + req = (struct virtio_iommu_req_detach) { + .head.type = VIRTIO_IOMMU_T_DETACH, + .domain = cpu_to_le32(vdomain->id), + }; + + for (i = 0; i < fwspec->num_ids; i++) { + req.endpoint = cpu_to_le32(fwspec->ids[i]); + WARN_ON(viommu_send_req_sync(vdev->viommu, &req, sizeof(req))); + } + vdomain->nr_endpoints--; + vdev->vdomain = NULL; +} + static int viommu_map_pages(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t pgsize, size_t pgcount, int prot, gfp_t gfp, size_t *mapped) @@ -990,6 +1013,7 @@ static void viommu_release_device(struct device *dev) { struct viommu_endpoint *vdev = dev_iommu_priv_get(dev);
+ viommu_detach_dev(vdev); iommu_put_resv_regions(dev, &vdev->resv_regions); kfree(vdev); }
From: Jean-Philippe Brucker jean-philippe@linaro.org
[ Upstream commit 7061b6af34686e7e2364b7240cfb061293218f2d ]
When map() is called on a detached domain, the domain does not exist in the device so we do not send a MAP request, but we do update the internal mapping tree, to be replayed on the next attach. Since this constitutes a successful iommu_map() call, return *mapped in this case too.
Fixes: 7e62edd7a33a ("iommu/virtio: Add map/unmap_pages() callbacks implementation") Signed-off-by: Jean-Philippe Brucker jean-philippe@linaro.org Reviewed-by: Jason Gunthorpe jgg@nvidia.com Link: https://lore.kernel.org/r/20230515113946.1017624-3-jean-philippe@linaro.org Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/virtio-iommu.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-)
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c index fd316a37d7562..3551ed057774e 100644 --- a/drivers/iommu/virtio-iommu.c +++ b/drivers/iommu/virtio-iommu.c @@ -833,25 +833,26 @@ static int viommu_map_pages(struct iommu_domain *domain, unsigned long iova, if (ret) return ret;
- map = (struct virtio_iommu_req_map) { - .head.type = VIRTIO_IOMMU_T_MAP, - .domain = cpu_to_le32(vdomain->id), - .virt_start = cpu_to_le64(iova), - .phys_start = cpu_to_le64(paddr), - .virt_end = cpu_to_le64(end), - .flags = cpu_to_le32(flags), - }; - - if (!vdomain->nr_endpoints) - return 0; + if (vdomain->nr_endpoints) { + map = (struct virtio_iommu_req_map) { + .head.type = VIRTIO_IOMMU_T_MAP, + .domain = cpu_to_le32(vdomain->id), + .virt_start = cpu_to_le64(iova), + .phys_start = cpu_to_le64(paddr), + .virt_end = cpu_to_le64(end), + .flags = cpu_to_le32(flags), + };
- ret = viommu_send_req_sync(vdomain->viommu, &map, sizeof(map)); - if (ret) - viommu_del_mappings(vdomain, iova, end); - else if (mapped) + ret = viommu_send_req_sync(vdomain->viommu, &map, sizeof(map)); + if (ret) { + viommu_del_mappings(vdomain, iova, end); + return ret; + } + } + if (mapped) *mapped = size;
- return ret; + return 0; }
static size_t viommu_unmap_pages(struct iommu_domain *domain, unsigned long iova,
From: Biju Das biju.das.jz@bp.renesas.com
[ Upstream commit d1c20885d3b01e6a62e920af4b227abd294d22f3 ]
As per the RZ/G2L HW(Rev.1.30 May2023) manual, there are no "write enable" bits in the CPG_SIPLL5_CLK1 register. So fix the CPG_SIPLL5_CLK register write by removing the "write enable" bits.
Fixes: 1561380ee72f ("clk: renesas: rzg2l: Add FOUTPOSTDIV clk support") Signed-off-by: Biju Das biju.das.jz@bp.renesas.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/20230518152334.514922-1-biju.das.jz@bp.renesas.com [geert: Remove CPG_SIPLL5_CLK1_*_WEN bit definitions] Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/renesas/rzg2l-cpg.c | 6 ++---- drivers/clk/renesas/rzg2l-cpg.h | 3 --- 2 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index 4bf40f6ccd1d1..22ed543fe6b06 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -603,10 +603,8 @@ static int rzg2l_cpg_sipll5_set_rate(struct clk_hw *hw, }
/* Output clock setting 1 */ - writel(CPG_SIPLL5_CLK1_POSTDIV1_WEN | CPG_SIPLL5_CLK1_POSTDIV2_WEN | - CPG_SIPLL5_CLK1_REFDIV_WEN | (params.pl5_postdiv1 << 0) | - (params.pl5_postdiv2 << 4) | (params.pl5_refdiv << 8), - priv->base + CPG_SIPLL5_CLK1); + writel((params.pl5_postdiv1 << 0) | (params.pl5_postdiv2 << 4) | + (params.pl5_refdiv << 8), priv->base + CPG_SIPLL5_CLK1);
/* Output clock setting, SSCG modulation value setting 3 */ writel((params.pl5_fracin << 8), priv->base + CPG_SIPLL5_CLK3); diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h index eee780276a9e2..6cee9e56acc72 100644 --- a/drivers/clk/renesas/rzg2l-cpg.h +++ b/drivers/clk/renesas/rzg2l-cpg.h @@ -32,9 +32,6 @@ #define CPG_SIPLL5_STBY_RESETB_WEN BIT(16) #define CPG_SIPLL5_STBY_SSCG_EN_WEN BIT(18) #define CPG_SIPLL5_STBY_DOWNSPREAD_WEN BIT(20) -#define CPG_SIPLL5_CLK1_POSTDIV1_WEN BIT(16) -#define CPG_SIPLL5_CLK1_POSTDIV2_WEN BIT(20) -#define CPG_SIPLL5_CLK1_REFDIV_WEN BIT(24) #define CPG_SIPLL5_CLK4_RESV_LSB (0xFF) #define CPG_SIPLL5_MON_PLL5_LOCK BIT(4)
From: Tony Lindgren tony@atomide.com
[ Upstream commit 4ffec92e70ac5097b9f67ec154065305b16a3b46 ]
The model property should be at the top level, let's move it out of the pinctrl node.
Fixes: d2eaf949d2c3 ("ARM: dts: omap3-gta04a5one: define GTA04A5 variant with OneNAND") Cc: Andreas Kemnade andreas@kemnade.info Cc: H. Nikolaus Schaller hns@goldelico.com Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/omap3-gta04a5one.dts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/omap3-gta04a5one.dts b/arch/arm/boot/dts/omap3-gta04a5one.dts index 9db9fe67cd63b..95df45cc70c09 100644 --- a/arch/arm/boot/dts/omap3-gta04a5one.dts +++ b/arch/arm/boot/dts/omap3-gta04a5one.dts @@ -5,9 +5,11 @@
#include "omap3-gta04a5.dts"
-&omap3_pmx_core { +/ { model = "Goldelico GTA04A5/Letux 2804 with OneNAND"; +};
+&omap3_pmx_core { gpmc_pins: pinmux_gpmc_pins { pinctrl-single,pins = <
From: Nícolas F. R. A. Prado nfraprado@collabora.com
[ Upstream commit 1464e48d69ab7a50a377c9d39f5e5eb3cee2722e ]
During probe, the driver registers i2c dummy devices and populates the aux bus, which registers a device for the panel. After doing that, the driver can still defer probe if needed. This ordering of operations is troublesome however, because the deferred probe work will retry probing all pending devices every time a new device is registered. Therefore, if modules need to be loaded in order to satisfy the dependencies for this driver to complete probe, the kernel will stall, since it'll keep trying to probe the anx7625 driver, but never succeed, given that modules would only be loaded after the deferred probe work completes.
Two changes are required to avoid this issue: * Move of_find_mipi_dsi_host_by_node(), which can defer probe, to before anx7625_register_i2c_dummy_clients() and devm_of_dp_aux_populate_ep_devices(), which register devices. * Make use of the done_probing callback when populating the aux bus, so that the bridge registration is only done after the panel is probed. This is required because the panel might need to defer probe, but the aux bus population needs the i2c dummy devices working, so this call couldn't just be moved to an earlier point in probe. One caveat is that if the panel is described outside the aux bus, the probe loop issue can still happen, but we don't have a way to avoid it in that case since there's no callback available.
With this patch applied, it's possible to boot on mt8192-asurada-spherion with
CONFIG_DRM_ANALOGIX_ANX7625=y CONFIG_MTK_MMSYS=m CONFIG_BACKLIGHT_PWM=y
and also with
CONFIG_DRM_ANALOGIX_ANX7625=y CONFIG_MTK_MMSYS=y CONFIG_BACKLIGHT_PWM=m
Fixes: adca62ec370c ("drm/bridge: anx7625: Support reading edid through aux channel") Fixes: 269332997a16 ("drm/bridge: anx7625: Return -EPROBE_DEFER if the dsi host was not found") Reported-by: "kernelci.org bot" bot@kernelci.org Signed-off-by: Nícolas F. R. A. Prado nfraprado@collabora.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230518193902.891121-1-nfrapr... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/analogix/anx7625.c | 128 +++++++++++++++------- 1 file changed, 88 insertions(+), 40 deletions(-)
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 6846199a2ee14..9e387c3e9b696 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1687,6 +1687,14 @@ static int anx7625_parse_dt(struct device *dev, if (of_property_read_bool(np, "analogix,audio-enable")) pdata->audio_en = 1;
+ return 0; +} + +static int anx7625_parse_dt_panel(struct device *dev, + struct anx7625_platform_data *pdata) +{ + struct device_node *np = dev->of_node; + pdata->panel_bridge = devm_drm_of_get_bridge(dev, np, 1, 0); if (IS_ERR(pdata->panel_bridge)) { if (PTR_ERR(pdata->panel_bridge) == -ENODEV) { @@ -2032,7 +2040,7 @@ static int anx7625_register_audio(struct device *dev, struct anx7625_data *ctx) return 0; }
-static int anx7625_attach_dsi(struct anx7625_data *ctx) +static int anx7625_setup_dsi_device(struct anx7625_data *ctx) { struct mipi_dsi_device *dsi; struct device *dev = &ctx->client->dev; @@ -2042,9 +2050,6 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx) .channel = 0, .node = NULL, }; - int ret; - - DRM_DEV_DEBUG_DRIVER(dev, "attach dsi\n");
host = of_find_mipi_dsi_host_by_node(ctx->pdata.mipi_host_node); if (!host) { @@ -2065,14 +2070,24 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx) MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_HS_PKT_END_ALIGNED;
- ret = devm_mipi_dsi_attach(dev, dsi); + ctx->dsi = dsi; + + return 0; +} + +static int anx7625_attach_dsi(struct anx7625_data *ctx) +{ + struct device *dev = &ctx->client->dev; + int ret; + + DRM_DEV_DEBUG_DRIVER(dev, "attach dsi\n"); + + ret = devm_mipi_dsi_attach(dev, ctx->dsi); if (ret) { DRM_DEV_ERROR(dev, "fail to attach dsi to host.\n"); return ret; }
- ctx->dsi = dsi; - DRM_DEV_DEBUG_DRIVER(dev, "attach dsi succeeded.\n");
return 0; @@ -2560,6 +2575,40 @@ static void anx7625_runtime_disable(void *data) pm_runtime_disable(data); }
+static int anx7625_link_bridge(struct drm_dp_aux *aux) +{ + struct anx7625_data *platform = container_of(aux, struct anx7625_data, aux); + struct device *dev = aux->dev; + int ret; + + ret = anx7625_parse_dt_panel(dev, &platform->pdata); + if (ret) { + DRM_DEV_ERROR(dev, "fail to parse DT for panel : %d\n", ret); + return ret; + } + + platform->bridge.funcs = &anx7625_bridge_funcs; + platform->bridge.of_node = dev->of_node; + if (!anx7625_of_panel_on_aux_bus(dev)) + platform->bridge.ops |= DRM_BRIDGE_OP_EDID; + if (!platform->pdata.panel_bridge) + platform->bridge.ops |= DRM_BRIDGE_OP_HPD | + DRM_BRIDGE_OP_DETECT; + platform->bridge.type = platform->pdata.panel_bridge ? + DRM_MODE_CONNECTOR_eDP : + DRM_MODE_CONNECTOR_DisplayPort; + + drm_bridge_add(&platform->bridge); + + if (!platform->pdata.is_dpi) { + ret = anx7625_attach_dsi(platform); + if (ret) + drm_bridge_remove(&platform->bridge); + } + + return ret; +} + static int anx7625_i2c_probe(struct i2c_client *client) { struct anx7625_data *platform; @@ -2634,6 +2683,24 @@ static int anx7625_i2c_probe(struct i2c_client *client) platform->aux.wait_hpd_asserted = anx7625_wait_hpd_asserted; drm_dp_aux_init(&platform->aux);
+ ret = anx7625_parse_dt(dev, pdata); + if (ret) { + if (ret != -EPROBE_DEFER) + DRM_DEV_ERROR(dev, "fail to parse DT : %d\n", ret); + goto free_wq; + } + + if (!platform->pdata.is_dpi) { + ret = anx7625_setup_dsi_device(platform); + if (ret < 0) + goto free_wq; + } + + /* + * Registering the i2c devices will retrigger deferred probe, so it + * needs to be done after calls that might return EPROBE_DEFER, + * otherwise we can get an infinite loop. + */ if (anx7625_register_i2c_dummy_clients(platform, client) != 0) { ret = -ENOMEM; DRM_DEV_ERROR(dev, "fail to reserve I2C bus.\n"); @@ -2648,13 +2715,21 @@ static int anx7625_i2c_probe(struct i2c_client *client) if (ret) goto free_wq;
- devm_of_dp_aux_populate_ep_devices(&platform->aux); - - ret = anx7625_parse_dt(dev, pdata); + /* + * Populating the aux bus will retrigger deferred probe, so it needs to + * be done after calls that might return EPROBE_DEFER, otherwise we can + * get an infinite loop. + */ + ret = devm_of_dp_aux_populate_bus(&platform->aux, anx7625_link_bridge); if (ret) { - if (ret != -EPROBE_DEFER) - DRM_DEV_ERROR(dev, "fail to parse DT : %d\n", ret); - goto free_wq; + if (ret != -ENODEV) { + DRM_DEV_ERROR(dev, "failed to populate aux bus : %d\n", ret); + goto free_wq; + } + + ret = anx7625_link_bridge(&platform->aux); + if (ret) + goto free_wq; }
if (!platform->pdata.low_power_mode) { @@ -2667,27 +2742,6 @@ static int anx7625_i2c_probe(struct i2c_client *client) if (platform->pdata.intp_irq) queue_work(platform->workqueue, &platform->work);
- platform->bridge.funcs = &anx7625_bridge_funcs; - platform->bridge.of_node = client->dev.of_node; - if (!anx7625_of_panel_on_aux_bus(&client->dev)) - platform->bridge.ops |= DRM_BRIDGE_OP_EDID; - if (!platform->pdata.panel_bridge) - platform->bridge.ops |= DRM_BRIDGE_OP_HPD | - DRM_BRIDGE_OP_DETECT; - platform->bridge.type = platform->pdata.panel_bridge ? - DRM_MODE_CONNECTOR_eDP : - DRM_MODE_CONNECTOR_DisplayPort; - - drm_bridge_add(&platform->bridge); - - if (!platform->pdata.is_dpi) { - ret = anx7625_attach_dsi(platform); - if (ret) { - DRM_DEV_ERROR(dev, "Fail to attach to dsi : %d\n", ret); - goto unregister_bridge; - } - } - if (platform->pdata.audio_en) anx7625_register_audio(dev, platform);
@@ -2695,12 +2749,6 @@ static int anx7625_i2c_probe(struct i2c_client *client)
return 0;
-unregister_bridge: - drm_bridge_remove(&platform->bridge); - - if (!platform->pdata.low_power_mode) - pm_runtime_put_sync_suspend(&client->dev); - free_wq: if (platform->workqueue) destroy_workqueue(platform->workqueue);
From: Linus Walleij linus.walleij@linaro.org
[ Upstream commit c32c81f3dbdfd68f6ab20a29ad86f811aed36e4e ]
Aaro reports problems on the OSK1 board after we altered the dynamic base for GPIO allocations.
It appears this happens because the OMAP driver now allocates GPIO numbers dynamically, so all that is references by number is a bit up in the air.
Let's bite the bullet and try to just move the gpio_chip in the tps65010 MFD driver over to using dynamic allocations. Alter everything in the OSK1 board file to use a GPIO descriptor table and lookups.
Utilize the NULL device to define some board-specific GPIO lookups and use these to immediately look up the same GPIOs, convert to IRQ numbers and pass as resources to the devices. This is ugly but should work.
The .setup() callback for tps65010 was used for some GPIO hogging, but since the OSK1 is the only user in the entire kernel we can alter the signatures to something that is helpful and make a clean transition.
Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base") Cc: Christophe Leroy christophe.leroy@csgroup.eu Cc: andy.shevchenko@gmail.com Cc: Andreas Kemnade andreas@kemnade.info Acked-by: Lee Jones lee@kernel.org Reviewed-by: Lee Jones lee@kernel.org Reported-by: Aaro Koskinen aaro.koskinen@iki.fi Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-omap1/board-osk.c | 139 ++++++++++++++++++++++---------- drivers/mfd/tps65010.c | 14 ++-- include/linux/mfd/tps65010.h | 11 +-- 3 files changed, 104 insertions(+), 60 deletions(-)
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index df758c1f92373..a8ca8d427182d 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -25,7 +25,8 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> +#include <linux/gpio/driver.h> #include <linux/gpio/machine.h> #include <linux/kernel.h> #include <linux/init.h> @@ -64,13 +65,12 @@ /* TPS65010 has four GPIOs. nPG and LED2 can be treated like GPIOs with * alternate pin configurations for hardware-controlled blinking. */ -#define OSK_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */) -# define OSK_TPS_GPIO_USB_PWR_EN (OSK_TPS_GPIO_BASE + 0) -# define OSK_TPS_GPIO_LED_D3 (OSK_TPS_GPIO_BASE + 1) -# define OSK_TPS_GPIO_LAN_RESET (OSK_TPS_GPIO_BASE + 2) -# define OSK_TPS_GPIO_DSP_PWR_EN (OSK_TPS_GPIO_BASE + 3) -# define OSK_TPS_GPIO_LED_D9 (OSK_TPS_GPIO_BASE + 4) -# define OSK_TPS_GPIO_LED_D2 (OSK_TPS_GPIO_BASE + 5) +#define OSK_TPS_GPIO_USB_PWR_EN 0 +#define OSK_TPS_GPIO_LED_D3 1 +#define OSK_TPS_GPIO_LAN_RESET 2 +#define OSK_TPS_GPIO_DSP_PWR_EN 3 +#define OSK_TPS_GPIO_LED_D9 4 +#define OSK_TPS_GPIO_LED_D2 5
static struct mtd_partition osk_partitions[] = { /* bootloader (U-Boot, etc) in first sector */ @@ -174,11 +174,20 @@ static const struct gpio_led tps_leds[] = { /* NOTE: D9 and D2 have hardware blink support. * Also, D9 requires non-battery power. */ - { .gpio = OSK_TPS_GPIO_LED_D9, .name = "d9", - .default_trigger = "disk-activity", }, - { .gpio = OSK_TPS_GPIO_LED_D2, .name = "d2", }, - { .gpio = OSK_TPS_GPIO_LED_D3, .name = "d3", .active_low = 1, - .default_trigger = "heartbeat", }, + { .name = "d9", .default_trigger = "disk-activity", }, + { .name = "d2", }, + { .name = "d3", .default_trigger = "heartbeat", }, +}; + +static struct gpiod_lookup_table tps_leds_gpio_table = { + .dev_id = "leds-gpio", + .table = { + /* Use local offsets on TPS65010 */ + GPIO_LOOKUP_IDX("tps65010", OSK_TPS_GPIO_LED_D9, NULL, 0, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("tps65010", OSK_TPS_GPIO_LED_D2, NULL, 1, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("tps65010", OSK_TPS_GPIO_LED_D3, NULL, 2, GPIO_ACTIVE_LOW), + { } + }, };
static struct gpio_led_platform_data tps_leds_data = { @@ -192,29 +201,34 @@ static struct platform_device osk5912_tps_leds = { .dev.platform_data = &tps_leds_data, };
-static int osk_tps_setup(struct i2c_client *client, void *context) +/* The board just hold these GPIOs hogged from setup to teardown */ +static struct gpio_desc *eth_reset; +static struct gpio_desc *vdd_dsp; + +static int osk_tps_setup(struct i2c_client *client, struct gpio_chip *gc) { + struct gpio_desc *d; if (!IS_BUILTIN(CONFIG_TPS65010)) return -ENOSYS;
/* Set GPIO 1 HIGH to disable VBUS power supply; * OHCI driver powers it up/down as needed. */ - gpio_request(OSK_TPS_GPIO_USB_PWR_EN, "n_vbus_en"); - gpio_direction_output(OSK_TPS_GPIO_USB_PWR_EN, 1); + d = gpiochip_request_own_desc(gc, OSK_TPS_GPIO_USB_PWR_EN, "n_vbus_en", + GPIO_ACTIVE_HIGH, GPIOD_OUT_HIGH); /* Free the GPIO again as the driver will request it */ - gpio_free(OSK_TPS_GPIO_USB_PWR_EN); + gpiochip_free_own_desc(d);
/* Set GPIO 2 high so LED D3 is off by default */ tps65010_set_gpio_out_value(GPIO2, HIGH);
/* Set GPIO 3 low to take ethernet out of reset */ - gpio_request(OSK_TPS_GPIO_LAN_RESET, "smc_reset"); - gpio_direction_output(OSK_TPS_GPIO_LAN_RESET, 0); + eth_reset = gpiochip_request_own_desc(gc, OSK_TPS_GPIO_LAN_RESET, "smc_reset", + GPIO_ACTIVE_HIGH, GPIOD_OUT_LOW);
/* GPIO4 is VDD_DSP */ - gpio_request(OSK_TPS_GPIO_DSP_PWR_EN, "dsp_power"); - gpio_direction_output(OSK_TPS_GPIO_DSP_PWR_EN, 1); + vdd_dsp = gpiochip_request_own_desc(gc, OSK_TPS_GPIO_DSP_PWR_EN, "dsp_power", + GPIO_ACTIVE_HIGH, GPIOD_OUT_HIGH); /* REVISIT if DSP support isn't configured, power it off ... */
/* Let LED1 (D9) blink; leds-gpio may override it */ @@ -232,15 +246,22 @@ static int osk_tps_setup(struct i2c_client *client, void *context)
/* register these three LEDs */ osk5912_tps_leds.dev.parent = &client->dev; + gpiod_add_lookup_table(&tps_leds_gpio_table); platform_device_register(&osk5912_tps_leds);
return 0; }
+static void osk_tps_teardown(struct i2c_client *client, struct gpio_chip *gc) +{ + gpiochip_free_own_desc(eth_reset); + gpiochip_free_own_desc(vdd_dsp); +} + static struct tps65010_board tps_board = { - .base = OSK_TPS_GPIO_BASE, .outmask = 0x0f, .setup = osk_tps_setup, + .teardown = osk_tps_teardown, };
static struct i2c_board_info __initdata osk_i2c_board_info[] = { @@ -263,11 +284,6 @@ static void __init osk_init_smc91x(void) { u32 l;
- if ((gpio_request(0, "smc_irq")) < 0) { - printk("Error requesting gpio 0 for smc91x irq\n"); - return; - } - /* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */ l = omap_readl(EMIFS_CCS(1)); l |= 0x3; @@ -279,10 +295,6 @@ static void __init osk_init_cf(int seg) struct resource *res = &osk5912_cf_resources[1];
omap_cfg_reg(M7_1610_GPIO62); - if ((gpio_request(62, "cf_irq")) < 0) { - printk("Error requesting gpio 62 for CF irq\n"); - return; - }
switch (seg) { /* NOTE: CS0 could be configured too ... */ @@ -308,18 +320,17 @@ static void __init osk_init_cf(int seg) seg, omap_readl(EMIFS_CCS(seg)), omap_readl(EMIFS_ACS(seg))); omap_writel(0x0004a1b3, EMIFS_CCS(seg)); /* synch mode 4 etc */ omap_writel(0x00000000, EMIFS_ACS(seg)); /* OE hold/setup */ - - /* the CF I/O IRQ is really active-low */ - irq_set_irq_type(gpio_to_irq(62), IRQ_TYPE_EDGE_FALLING); }
static struct gpiod_lookup_table osk_usb_gpio_table = { .dev_id = "ohci", .table = { /* Power GPIO on the I2C-attached TPS65010 */ - GPIO_LOOKUP("tps65010", 0, "power", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("tps65010", OSK_TPS_GPIO_USB_PWR_EN, "power", + GPIO_ACTIVE_HIGH), GPIO_LOOKUP(OMAP_GPIO_LABEL, 9, "overcurrent", GPIO_ACTIVE_HIGH), + { } }, };
@@ -341,8 +352,25 @@ static struct omap_usb_config osk_usb_config __initdata = {
#define EMIFS_CS3_VAL (0x88013141)
+static struct gpiod_lookup_table osk_irq_gpio_table = { + .dev_id = NULL, + .table = { + /* GPIO used for SMC91x IRQ */ + GPIO_LOOKUP(OMAP_GPIO_LABEL, 0, "smc_irq", + GPIO_ACTIVE_HIGH), + /* GPIO used for CF IRQ */ + GPIO_LOOKUP("gpio-48-63", 14, "cf_irq", + GPIO_ACTIVE_HIGH), + /* GPIO used by the TPS65010 chip */ + GPIO_LOOKUP("mpuio", 1, "tps65010", + GPIO_ACTIVE_HIGH), + { } + }, +}; + static void __init osk_init(void) { + struct gpio_desc *d; u32 l;
osk_init_smc91x(); @@ -359,10 +387,31 @@ static void __init osk_init(void)
osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys(); osk_flash_resource.end += SZ_32M - 1; - osk5912_smc91x_resources[1].start = gpio_to_irq(0); - osk5912_smc91x_resources[1].end = gpio_to_irq(0); - osk5912_cf_resources[0].start = gpio_to_irq(62); - osk5912_cf_resources[0].end = gpio_to_irq(62); + + /* + * Add the GPIOs to be used as IRQs and immediately look them up + * to be passed as an IRQ resource. This is ugly but should work + * until the day we convert to device tree. + */ + gpiod_add_lookup_table(&osk_irq_gpio_table); + + d = gpiod_get(NULL, "smc_irq", GPIOD_IN); + if (IS_ERR(d)) { + pr_err("Unable to get SMC IRQ GPIO descriptor\n"); + } else { + irq_set_irq_type(gpiod_to_irq(d), IRQ_TYPE_EDGE_RISING); + osk5912_smc91x_resources[1] = DEFINE_RES_IRQ(gpiod_to_irq(d)); + } + + d = gpiod_get(NULL, "cf_irq", GPIOD_IN); + if (IS_ERR(d)) { + pr_err("Unable to get CF IRQ GPIO descriptor\n"); + } else { + /* the CF I/O IRQ is really active-low */ + irq_set_irq_type(gpiod_to_irq(d), IRQ_TYPE_EDGE_FALLING); + osk5912_cf_resources[0] = DEFINE_RES_IRQ(gpiod_to_irq(d)); + } + platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices));
l = omap_readl(USB_TRANSCEIVER_CTRL); @@ -372,13 +421,15 @@ static void __init osk_init(void) gpiod_add_lookup_table(&osk_usb_gpio_table); omap1_usb_init(&osk_usb_config);
+ omap_serial_init(); + /* irq for tps65010 chip */ /* bootloader effectively does: omap_cfg_reg(U19_1610_MPUIO1); */ - if (gpio_request(OMAP_MPUIO(1), "tps65010") == 0) - gpio_direction_input(OMAP_MPUIO(1)); - - omap_serial_init(); - osk_i2c_board_info[0].irq = gpio_to_irq(OMAP_MPUIO(1)); + d = gpiod_get(NULL, "tps65010", GPIOD_IN); + if (IS_ERR(d)) + pr_err("Unable to get TPS65010 IRQ GPIO descriptor\n"); + else + osk_i2c_board_info[0].irq = gpiod_to_irq(d); omap_register_i2c_bus(1, 400, osk_i2c_board_info, ARRAY_SIZE(osk_i2c_board_info)); } diff --git a/drivers/mfd/tps65010.c b/drivers/mfd/tps65010.c index fb733288cca3b..faea4ff44c6fe 100644 --- a/drivers/mfd/tps65010.c +++ b/drivers/mfd/tps65010.c @@ -506,12 +506,8 @@ static void tps65010_remove(struct i2c_client *client) struct tps65010 *tps = i2c_get_clientdata(client); struct tps65010_board *board = dev_get_platdata(&client->dev);
- if (board && board->teardown) { - int status = board->teardown(client, board->context); - if (status < 0) - dev_dbg(&client->dev, "board %s %s err %d\n", - "teardown", client->name, status); - } + if (board && board->teardown) + board->teardown(client, &tps->chip); if (client->irq > 0) free_irq(client->irq, tps); cancel_delayed_work_sync(&tps->work); @@ -619,7 +615,7 @@ static int tps65010_probe(struct i2c_client *client) tps, DEBUG_FOPS);
/* optionally register GPIOs */ - if (board && board->base != 0) { + if (board) { tps->outmask = board->outmask;
tps->chip.label = client->name; @@ -632,7 +628,7 @@ static int tps65010_probe(struct i2c_client *client) /* NOTE: only partial support for inputs; nyet IRQs */ tps->chip.get = tps65010_gpio_get;
- tps->chip.base = board->base; + tps->chip.base = -1; tps->chip.ngpio = 7; tps->chip.can_sleep = 1;
@@ -641,7 +637,7 @@ static int tps65010_probe(struct i2c_client *client) dev_err(&client->dev, "can't add gpiochip, err %d\n", status); else if (board->setup) { - status = board->setup(client, board->context); + status = board->setup(client, &tps->chip); if (status < 0) { dev_dbg(&client->dev, "board %s %s err %d\n", diff --git a/include/linux/mfd/tps65010.h b/include/linux/mfd/tps65010.h index a1fb9bc5311de..5edf1aef11185 100644 --- a/include/linux/mfd/tps65010.h +++ b/include/linux/mfd/tps65010.h @@ -28,6 +28,8 @@ #ifndef __LINUX_I2C_TPS65010_H #define __LINUX_I2C_TPS65010_H
+struct gpio_chip; + /* * ---------------------------------------------------------------------------- * Registers, all 8 bits @@ -176,12 +178,10 @@ struct i2c_client;
/** * struct tps65010_board - packages GPIO and LED lines - * @base: the GPIO number to assign to GPIO-1 * @outmask: bit (N-1) is set to allow GPIO-N to be used as an * (open drain) output * @setup: optional callback issued once the GPIOs are valid * @teardown: optional callback issued before the GPIOs are invalidated - * @context: optional parameter passed to setup() and teardown() * * Board data may be used to package the GPIO (and LED) lines for use * in by the generic GPIO and LED frameworks. The first four GPIOs @@ -193,12 +193,9 @@ struct i2c_client; * devices in their initial states using these GPIOs. */ struct tps65010_board { - int base; unsigned outmask; - - int (*setup)(struct i2c_client *client, void *context); - int (*teardown)(struct i2c_client *client, void *context); - void *context; + int (*setup)(struct i2c_client *client, struct gpio_chip *gc); + void (*teardown)(struct i2c_client *client, struct gpio_chip *gc); };
#endif /* __LINUX_I2C_TPS65010_H */
From: Linus Walleij linus.walleij@linaro.org
[ Upstream commit fa1ae0cd897b089b5cc05ab471518ad13db2d567 ]
The AMS Delta board uses GPIO descriptors exclusively and does not have any dependencies on the legacy <linux/gpio.h> header, so just drop it.
Acked-by: Janusz Krzysztofik jmkrzyszt@gmail.com Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base") Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-omap1/board-ams-delta.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index 0f67ac4c6fd25..d9d2fef1b74a7 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -11,7 +11,6 @@ #include <linux/gpio/driver.h> #include <linux/gpio/machine.h> #include <linux/gpio/consumer.h> -#include <linux/gpio.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/input.h>
From: Linus Walleij linus.walleij@linaro.org
[ Upstream commit 4c40db6249ff1da335b276bdd6c3c3462efbc2ab ]
It appears this happens because the OMAP driver now allocates GPIO numbers dynamically, so all that is references by number is a bit up in the air.
Utilize the NULL device to define some board-specific GPIO lookups and use these to immediately look up the same GPIOs, convert to IRQ numbers and pass as resources to the devices. This is ugly but should work.
Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base") Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-omap1/board-palmte.c | 51 ++++++++++++++++++------------ 1 file changed, 31 insertions(+), 20 deletions(-)
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index f79c497f04d57..49b7757cb2fd3 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c @@ -13,7 +13,8 @@ * * Copyright (c) 2006 Andrzej Zaborowski balrog@zabor.org */ -#include <linux/gpio.h> +#include <linux/gpio/machine.h> +#include <linux/gpio/consumer.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/input.h> @@ -187,23 +188,6 @@ static struct spi_board_info palmte_spi_info[] __initdata = { }, };
-static void __init palmte_misc_gpio_setup(void) -{ - /* Set TSC2102 PINTDAV pin as input (used by TSC2102 driver) */ - if (gpio_request(PALMTE_PINTDAV_GPIO, "TSC2102 PINTDAV") < 0) { - printk(KERN_ERR "Could not reserve PINTDAV GPIO!\n"); - return; - } - gpio_direction_input(PALMTE_PINTDAV_GPIO); - - /* Set USB-or-DC-IN pin as input (unused) */ - if (gpio_request(PALMTE_USB_OR_DC_GPIO, "USB/DC-IN") < 0) { - printk(KERN_ERR "Could not reserve cable signal GPIO!\n"); - return; - } - gpio_direction_input(PALMTE_USB_OR_DC_GPIO); -} - #if IS_ENABLED(CONFIG_MMC_OMAP)
static struct omap_mmc_platform_data _palmte_mmc_config = { @@ -231,8 +215,23 @@ static void palmte_mmc_init(void)
#endif /* CONFIG_MMC_OMAP */
+static struct gpiod_lookup_table palmte_irq_gpio_table = { + .dev_id = NULL, + .table = { + /* GPIO used for TSC2102 PINTDAV IRQ */ + GPIO_LOOKUP("gpio-0-15", PALMTE_PINTDAV_GPIO, "tsc2102_irq", + GPIO_ACTIVE_HIGH), + /* GPIO used for USB or DC input detection */ + GPIO_LOOKUP("gpio-0-15", PALMTE_USB_OR_DC_GPIO, "usb_dc_irq", + GPIO_ACTIVE_HIGH), + { } + }, +}; + static void __init omap_palmte_init(void) { + struct gpio_desc *d; + /* mux pins for uarts */ omap_cfg_reg(UART1_TX); omap_cfg_reg(UART1_RTS); @@ -243,9 +242,21 @@ static void __init omap_palmte_init(void)
platform_add_devices(palmte_devices, ARRAY_SIZE(palmte_devices));
- palmte_spi_info[0].irq = gpio_to_irq(PALMTE_PINTDAV_GPIO); + gpiod_add_lookup_table(&palmte_irq_gpio_table); + d = gpiod_get(NULL, "tsc2102_irq", GPIOD_IN); + if (IS_ERR(d)) + pr_err("Unable to get TSC2102 IRQ GPIO descriptor\n"); + else + palmte_spi_info[0].irq = gpiod_to_irq(d); spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info)); - palmte_misc_gpio_setup(); + + /* We are getting this just to set it up as input */ + d = gpiod_get(NULL, "usb_dc_irq", GPIOD_IN); + if (IS_ERR(d)) + pr_err("Unable to get USB/DC IRQ GPIO descriptor\n"); + else + gpiod_put(d); + omap_serial_init(); omap1_usb_init(&palmte_usb_config); omap_register_i2c_bus(1, 100, NULL, 0);
From: Linus Walleij linus.walleij@linaro.org
[ Upstream commit 480c82daa3e41873421dc2c9e2918ad7e21d7a0b ]
It appears this happens because the OMAP driver now allocates GPIO numbers dynamically, so all that is references by number is a bit up in the air.
Utilize the NULL device to define some board-specific GPIO lookups and use these to immediately look up the same GPIOs, convert to IRQ numbers and pass as resources to the devices. This is ugly but should work.
Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base") Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-omap1/board-sx1.c | 40 +++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c index 0c0cdd5e77c79..a13c630be7b7f 100644 --- a/arch/arm/mach-omap1/board-sx1.c +++ b/arch/arm/mach-omap1/board-sx1.c @@ -11,7 +11,8 @@ * Maintainters : Vladimir Ananiev (aka Vovan888), Sergge * oslik.ru */ -#include <linux/gpio.h> +#include <linux/gpio/machine.h> +#include <linux/gpio/consumer.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/input.h> @@ -304,8 +305,23 @@ static struct platform_device *sx1_devices[] __initdata = {
/*-----------------------------------------*/
+static struct gpiod_lookup_table sx1_gpio_table = { + .dev_id = NULL, + .table = { + GPIO_LOOKUP("gpio-0-15", 1, "irda_off", + GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio-0-15", 11, "switch", + GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio-0-15", 15, "usb_on", + GPIO_ACTIVE_HIGH), + { } + }, +}; + static void __init omap_sx1_init(void) { + struct gpio_desc *d; + /* mux pins for uarts */ omap_cfg_reg(UART1_TX); omap_cfg_reg(UART1_RTS); @@ -320,15 +336,25 @@ static void __init omap_sx1_init(void) omap_register_i2c_bus(1, 100, NULL, 0); omap1_usb_init(&sx1_usb_config); sx1_mmc_init(); + gpiod_add_lookup_table(&sx1_gpio_table);
/* turn on USB power */ /* sx1_setusbpower(1); can't do it here because i2c is not ready */ - gpio_request(1, "A_IRDA_OFF"); - gpio_request(11, "A_SWITCH"); - gpio_request(15, "A_USB_ON"); - gpio_direction_output(1, 1); /*A_IRDA_OFF = 1 */ - gpio_direction_output(11, 0); /*A_SWITCH = 0 */ - gpio_direction_output(15, 0); /*A_USB_ON = 0 */ + d = gpiod_get(NULL, "irda_off", GPIOD_OUT_HIGH); + if (IS_ERR(d)) + pr_err("Unable to get IRDA OFF GPIO descriptor\n"); + else + gpiod_put(d); + d = gpiod_get(NULL, "switch", GPIOD_OUT_LOW); + if (IS_ERR(d)) + pr_err("Unable to get SWITCH GPIO descriptor\n"); + else + gpiod_put(d); + d = gpiod_get(NULL, "usb_on", GPIOD_OUT_LOW); + if (IS_ERR(d)) + pr_err("Unable to get USB ON GPIO descriptor\n"); + else + gpiod_put(d);
omapfb_set_lcd_config(&sx1_lcd_config); }
From: Linus Walleij linus.walleij@linaro.org
[ Upstream commit e519f0bb64efc2c9c8b67bb2d114dda458bdc34d ]
A recent change to the OMAP driver making it use a dynamic GPIO base created problems with some old OMAP1 board files, among them Nokia 770, SX1 and also the OMAP2 Nokia n8x0.
Fix up all instances of GPIOs being used for the MMC driver by pushing the handling of power, slot selection and MMC "cover" into the driver as optional GPIOs.
This is maybe not the most perfect solution as the MMC framework have some central handlers for some of the stuff, but it at least makes the situtation better and solves the immediate issue.
Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base") Acked-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-omap1/board-nokia770.c | 43 ++++--------- arch/arm/mach-omap1/board-sx1-mmc.c | 1 - arch/arm/mach-omap2/board-n8x0.c | 85 ++++++++------------------ drivers/mmc/host/omap.c | 46 +++++++++++++- include/linux/platform_data/mmc-omap.h | 2 - 5 files changed, 83 insertions(+), 94 deletions(-)
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index a501a473ffd68..bde472d0c82f6 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -156,27 +156,23 @@ static struct omap_usb_config nokia770_usb_config __initdata = {
#if IS_ENABLED(CONFIG_MMC_OMAP)
-#define NOKIA770_GPIO_MMC_POWER 41 -#define NOKIA770_GPIO_MMC_SWITCH 23 - -static int nokia770_mmc_set_power(struct device *dev, int slot, int power_on, - int vdd) -{ - gpio_set_value(NOKIA770_GPIO_MMC_POWER, power_on); - return 0; -} - -static int nokia770_mmc_get_cover_state(struct device *dev, int slot) -{ - return gpio_get_value(NOKIA770_GPIO_MMC_SWITCH); -} +static struct gpiod_lookup_table nokia770_mmc_gpio_table = { + .dev_id = "mmci-omap.1", + .table = { + /* Slot index 0, VSD power, GPIO 41 */ + GPIO_LOOKUP_IDX("gpio-32-47", 9, + "vsd", 0, GPIO_ACTIVE_HIGH), + /* Slot index 0, switch, GPIO 23 */ + GPIO_LOOKUP_IDX("gpio-16-31", 7, + "cover", 0, GPIO_ACTIVE_HIGH), + { } + }, +};
static struct omap_mmc_platform_data nokia770_mmc2_data = { .nr_slots = 1, .max_freq = 12000000, .slots[0] = { - .set_power = nokia770_mmc_set_power, - .get_cover_state = nokia770_mmc_get_cover_state, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .name = "mmcblk", }, @@ -186,20 +182,7 @@ static struct omap_mmc_platform_data *nokia770_mmc_data[OMAP16XX_NR_MMC];
static void __init nokia770_mmc_init(void) { - int ret; - - ret = gpio_request(NOKIA770_GPIO_MMC_POWER, "MMC power"); - if (ret < 0) - return; - gpio_direction_output(NOKIA770_GPIO_MMC_POWER, 0); - - ret = gpio_request(NOKIA770_GPIO_MMC_SWITCH, "MMC cover"); - if (ret < 0) { - gpio_free(NOKIA770_GPIO_MMC_POWER); - return; - } - gpio_direction_input(NOKIA770_GPIO_MMC_SWITCH); - + gpiod_add_lookup_table(&nokia770_mmc_gpio_table); /* Only the second MMC controller is used */ nokia770_mmc_data[1] = &nokia770_mmc2_data; omap1_init_mmc(nokia770_mmc_data, OMAP16XX_NR_MMC); diff --git a/arch/arm/mach-omap1/board-sx1-mmc.c b/arch/arm/mach-omap1/board-sx1-mmc.c index f1c160924dfe4..f183a8448a7b0 100644 --- a/arch/arm/mach-omap1/board-sx1-mmc.c +++ b/arch/arm/mach-omap1/board-sx1-mmc.c @@ -9,7 +9,6 @@ * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT */
-#include <linux/gpio.h> #include <linux/platform_device.h>
#include "hardware.h" diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index 3353b0a923d96..50b88eb23f9f8 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -11,6 +11,7 @@ #include <linux/clk.h> #include <linux/delay.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/init.h> #include <linux/io.h> #include <linux/irq.h> @@ -170,22 +171,32 @@ static struct spi_board_info n800_spi_board_info[] __initdata = { * GPIO23 and GPIO9 slot 2 EMMC on N810 * */ -#define N8X0_SLOT_SWITCH_GPIO 96 -#define N810_EMMC_VSD_GPIO 23 -#define N810_EMMC_VIO_GPIO 9 - static int slot1_cover_open; static int slot2_cover_open; static struct device *mmc_device;
-static int n8x0_mmc_switch_slot(struct device *dev, int slot) -{ -#ifdef CONFIG_MMC_DEBUG - dev_dbg(dev, "Choose slot %d\n", slot + 1); -#endif - gpio_set_value(N8X0_SLOT_SWITCH_GPIO, slot); - return 0; -} +static struct gpiod_lookup_table nokia8xx_mmc_gpio_table = { + .dev_id = "mmci-omap.0", + .table = { + /* Slot switch, GPIO 96 */ + GPIO_LOOKUP("gpio-80-111", 16, + "switch", GPIO_ACTIVE_HIGH), + { } + }, +}; + +static struct gpiod_lookup_table nokia810_mmc_gpio_table = { + .dev_id = "mmci-omap.0", + .table = { + /* Slot index 1, VSD power, GPIO 23 */ + GPIO_LOOKUP_IDX("gpio-16-31", 7, + "vsd", 1, GPIO_ACTIVE_HIGH), + /* Slot index 1, VIO power, GPIO 9 */ + GPIO_LOOKUP_IDX("gpio-0-15", 9, + "vsd", 1, GPIO_ACTIVE_HIGH), + { } + }, +};
static int n8x0_mmc_set_power_menelaus(struct device *dev, int slot, int power_on, int vdd) @@ -256,31 +267,13 @@ static int n8x0_mmc_set_power_menelaus(struct device *dev, int slot, return 0; }
-static void n810_set_power_emmc(struct device *dev, - int power_on) -{ - dev_dbg(dev, "Set EMMC power %s\n", power_on ? "on" : "off"); - - if (power_on) { - gpio_set_value(N810_EMMC_VSD_GPIO, 1); - msleep(1); - gpio_set_value(N810_EMMC_VIO_GPIO, 1); - msleep(1); - } else { - gpio_set_value(N810_EMMC_VIO_GPIO, 0); - msleep(50); - gpio_set_value(N810_EMMC_VSD_GPIO, 0); - msleep(50); - } -} - static int n8x0_mmc_set_power(struct device *dev, int slot, int power_on, int vdd) { if (board_is_n800() || slot == 0) return n8x0_mmc_set_power_menelaus(dev, slot, power_on, vdd);
- n810_set_power_emmc(dev, power_on); + /* The n810 power will be handled by GPIO code in the driver */
return 0; } @@ -418,13 +411,6 @@ static void n8x0_mmc_shutdown(struct device *dev) static void n8x0_mmc_cleanup(struct device *dev) { menelaus_unregister_mmc_callback(); - - gpio_free(N8X0_SLOT_SWITCH_GPIO); - - if (board_is_n810()) { - gpio_free(N810_EMMC_VSD_GPIO); - gpio_free(N810_EMMC_VIO_GPIO); - } }
/* @@ -433,7 +419,6 @@ static void n8x0_mmc_cleanup(struct device *dev) */ static struct omap_mmc_platform_data mmc1_data = { .nr_slots = 0, - .switch_slot = n8x0_mmc_switch_slot, .init = n8x0_mmc_late_init, .cleanup = n8x0_mmc_cleanup, .shutdown = n8x0_mmc_shutdown, @@ -463,14 +448,9 @@ static struct omap_mmc_platform_data mmc1_data = {
static struct omap_mmc_platform_data *mmc_data[OMAP24XX_NR_MMC];
-static struct gpio n810_emmc_gpios[] __initdata = { - { N810_EMMC_VSD_GPIO, GPIOF_OUT_INIT_LOW, "MMC slot 2 Vddf" }, - { N810_EMMC_VIO_GPIO, GPIOF_OUT_INIT_LOW, "MMC slot 2 Vdd" }, -}; - static void __init n8x0_mmc_init(void) { - int err; + gpiod_add_lookup_table(&nokia8xx_mmc_gpio_table);
if (board_is_n810()) { mmc1_data.slots[0].name = "external"; @@ -483,20 +463,7 @@ static void __init n8x0_mmc_init(void) */ mmc1_data.slots[1].name = "internal"; mmc1_data.slots[1].ban_openended = 1; - } - - err = gpio_request_one(N8X0_SLOT_SWITCH_GPIO, GPIOF_OUT_INIT_LOW, - "MMC slot switch"); - if (err) - return; - - if (board_is_n810()) { - err = gpio_request_array(n810_emmc_gpios, - ARRAY_SIZE(n810_emmc_gpios)); - if (err) { - gpio_free(N8X0_SLOT_SWITCH_GPIO); - return; - } + gpiod_add_lookup_table(&nokia810_mmc_gpio_table); }
mmc1_data.nr_slots = 2; diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index cc2213ea324f1..566a09faaaced 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -26,6 +26,7 @@ #include <linux/clk.h> #include <linux/scatterlist.h> #include <linux/slab.h> +#include <linux/gpio/consumer.h> #include <linux/platform_data/mmc-omap.h>
@@ -111,6 +112,9 @@ struct mmc_omap_slot { struct mmc_request *mrq; struct mmc_omap_host *host; struct mmc_host *mmc; + struct gpio_desc *vsd; + struct gpio_desc *vio; + struct gpio_desc *cover; struct omap_mmc_slot_data *pdata; };
@@ -133,6 +137,7 @@ struct mmc_omap_host { int irq; unsigned char bus_mode; unsigned int reg_shift; + struct gpio_desc *slot_switch;
struct work_struct cmd_abort_work; unsigned abort:1; @@ -216,8 +221,13 @@ static void mmc_omap_select_slot(struct mmc_omap_slot *slot, int claimed)
if (host->current_slot != slot) { OMAP_MMC_WRITE(host, CON, slot->saved_con & 0xFC00); - if (host->pdata->switch_slot != NULL) - host->pdata->switch_slot(mmc_dev(slot->mmc), slot->id); + if (host->slot_switch) + /* + * With two slots and a simple GPIO switch, setting + * the GPIO to 0 selects slot ID 0, setting it to 1 + * selects slot ID 1. + */ + gpiod_set_value(host->slot_switch, slot->id); host->current_slot = slot; }
@@ -297,6 +307,9 @@ static void mmc_omap_release_slot(struct mmc_omap_slot *slot, int clk_enabled) static inline int mmc_omap_cover_is_open(struct mmc_omap_slot *slot) { + /* If we have a GPIO then use that */ + if (slot->cover) + return gpiod_get_value(slot->cover); if (slot->pdata->get_cover_state) return slot->pdata->get_cover_state(mmc_dev(slot->mmc), slot->id); @@ -1106,6 +1119,11 @@ static void mmc_omap_set_power(struct mmc_omap_slot *slot, int power_on,
host = slot->host;
+ if (slot->vsd) + gpiod_set_value(slot->vsd, power_on); + if (slot->vio) + gpiod_set_value(slot->vio, power_on); + if (slot->pdata->set_power != NULL) slot->pdata->set_power(mmc_dev(slot->mmc), slot->id, power_on, vdd); @@ -1240,6 +1258,23 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id) slot->power_mode = MMC_POWER_UNDEFINED; slot->pdata = &host->pdata->slots[id];
+ /* Check for some optional GPIO controls */ + slot->vsd = gpiod_get_index_optional(host->dev, "vsd", + id, GPIOD_OUT_LOW); + if (IS_ERR(slot->vsd)) + return dev_err_probe(host->dev, PTR_ERR(slot->vsd), + "error looking up VSD GPIO\n"); + slot->vio = gpiod_get_index_optional(host->dev, "vio", + id, GPIOD_OUT_LOW); + if (IS_ERR(slot->vio)) + return dev_err_probe(host->dev, PTR_ERR(slot->vio), + "error looking up VIO GPIO\n"); + slot->cover = gpiod_get_index_optional(host->dev, "cover", + id, GPIOD_IN); + if (IS_ERR(slot->cover)) + return dev_err_probe(host->dev, PTR_ERR(slot->cover), + "error looking up cover switch GPIO\n"); + host->slots[id] = slot;
mmc->caps = 0; @@ -1350,6 +1385,13 @@ static int mmc_omap_probe(struct platform_device *pdev) if (IS_ERR(host->virt_base)) return PTR_ERR(host->virt_base);
+ host->slot_switch = gpiod_get_optional(host->dev, "switch", + GPIOD_OUT_LOW); + if (IS_ERR(host->slot_switch)) + return dev_err_probe(host->dev, PTR_ERR(host->slot_switch), + "error looking up slot switch GPIO\n"); + + INIT_WORK(&host->slot_release_work, mmc_omap_slot_release_work); INIT_WORK(&host->send_stop_work, mmc_omap_send_stop_work);
diff --git a/include/linux/platform_data/mmc-omap.h b/include/linux/platform_data/mmc-omap.h index 91051e9907f34..054d0c3c5ec58 100644 --- a/include/linux/platform_data/mmc-omap.h +++ b/include/linux/platform_data/mmc-omap.h @@ -20,8 +20,6 @@ struct omap_mmc_platform_data { * maximum frequency on the MMC bus */ unsigned int max_freq;
- /* switch the bus to a new slot */ - int (*switch_slot)(struct device *dev, int slot); /* initialize board-specific MMC functionality, can be NULL if * not supported */ int (*init)(struct device *dev);
From: Linus Walleij linus.walleij@linaro.org
[ Upstream commit c729baa8604226a8f878296bd145ab4046c80b12 ]
After fixing all the offending users referencing the global GPIO numberspace in OMAP1, a few sites still remain including the legacy <linus/gpio.h> header for no reason.
Delete the last remaining users, and OMAP1 is free from legacy GPIO dependencies.
Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base") Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-omap1/devices.c | 1 - arch/arm/mach-omap1/gpio15xx.c | 1 - arch/arm/mach-omap1/gpio16xx.c | 1 - arch/arm/mach-omap1/irq.c | 1 - 4 files changed, 4 deletions(-)
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index 5304699c7a97e..8b2c5f911e973 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c @@ -6,7 +6,6 @@ */
#include <linux/dma-mapping.h> -#include <linux/gpio.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c index 61fa26efd8653..6724af4925f24 100644 --- a/arch/arm/mach-omap1/gpio15xx.c +++ b/arch/arm/mach-omap1/gpio15xx.c @@ -8,7 +8,6 @@ * Charulatha V charu@ti.com */
-#include <linux/gpio.h> #include <linux/platform_data/gpio-omap.h> #include <linux/soc/ti/omap1-soc.h> #include <asm/irq.h> diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c index cf052714b3f8a..55acec22fef4e 100644 --- a/arch/arm/mach-omap1/gpio16xx.c +++ b/arch/arm/mach-omap1/gpio16xx.c @@ -8,7 +8,6 @@ * Charulatha V charu@ti.com */
-#include <linux/gpio.h> #include <linux/platform_data/gpio-omap.h> #include <linux/soc/ti/omap1-io.h>
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c index 9ccc784fd6140..c780fa56bc638 100644 --- a/arch/arm/mach-omap1/irq.c +++ b/arch/arm/mach-omap1/irq.c @@ -35,7 +35,6 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/gpio.h> #include <linux/init.h> #include <linux/module.h> #include <linux/sched.h>
From: Linus Walleij linus.walleij@linaro.org
[ Upstream commit 8e0285ab95a9baf374f2c13eb152221c8ecb3f28 ]
The TUSB6010 (MUSB) device is picking up some GPIO lines hardcoded by number and passing on to the TUSB6010 device when registering it.
Instead of nasty workarounds, provide a GPIO descriptor table and then make the TUSB6010 MUSB glue driver pick up the GPIO lines directly, convert it to an IRQ and pass down to the MUSB driver. OMAP2 is the only system using the TUSB6010.
Stash the GPIO descriptors in the glue layer and use then to power up and down the TUSB6010 on-demand, instead of using boardfile callbacks.
Since the OMAP2 boards are the only boards using the .set_power() and .board_set_power() callbacks, we can just delete them as the power is now handled directly in the TUSB6010 glue code.
Cc: Bin Liu b-liu@ti.com Cc: linux-usb@vger.kernel.org Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base") Acked-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-omap2/board-n8x0.c | 71 ++++++++---------------------- arch/arm/mach-omap2/usb-tusb6010.c | 20 ++------- arch/arm/mach-omap2/usb-tusb6010.h | 12 +++++ drivers/usb/musb/musb_core.c | 1 - drivers/usb/musb/musb_core.h | 2 - drivers/usb/musb/tusb6010.c | 53 ++++++++++++++++------ include/linux/usb/musb.h | 13 ------ 7 files changed, 73 insertions(+), 99 deletions(-) create mode 100644 arch/arm/mach-omap2/usb-tusb6010.h
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index 50b88eb23f9f8..564bf80a26212 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -10,8 +10,8 @@
#include <linux/clk.h> #include <linux/delay.h> -#include <linux/gpio.h> #include <linux/gpio/machine.h> +#include <linux/gpio/consumer.h> #include <linux/init.h> #include <linux/io.h> #include <linux/irq.h> @@ -29,13 +29,12 @@
#include "common.h" #include "mmc.h" +#include "usb-tusb6010.h" #include "soc.h" #include "common-board-devices.h"
#define TUSB6010_ASYNC_CS 1 #define TUSB6010_SYNC_CS 4 -#define TUSB6010_GPIO_INT 58 -#define TUSB6010_GPIO_ENABLE 0 #define TUSB6010_DMACHAN 0x3f
#define NOKIA_N810_WIMAX (1 << 2) @@ -62,37 +61,6 @@ static void board_check_revision(void) }
#if IS_ENABLED(CONFIG_USB_MUSB_TUSB6010) -/* - * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and - * 1.5 V voltage regulators of PM companion chip. Companion chip will then - * provide then PGOOD signal to TUSB6010 which will release it from reset. - */ -static int tusb_set_power(int state) -{ - int i, retval = 0; - - if (state) { - gpio_set_value(TUSB6010_GPIO_ENABLE, 1); - msleep(1); - - /* Wait until TUSB6010 pulls INT pin down */ - i = 100; - while (i && gpio_get_value(TUSB6010_GPIO_INT)) { - msleep(1); - i--; - } - - if (!i) { - printk(KERN_ERR "tusb: powerup failed\n"); - retval = -ENODEV; - } - } else { - gpio_set_value(TUSB6010_GPIO_ENABLE, 0); - msleep(10); - } - - return retval; -}
static struct musb_hdrc_config musb_config = { .multipoint = 1, @@ -103,39 +71,36 @@ static struct musb_hdrc_config musb_config = {
static struct musb_hdrc_platform_data tusb_data = { .mode = MUSB_OTG, - .set_power = tusb_set_power, .min_power = 25, /* x2 = 50 mA drawn from VBUS as peripheral */ .power = 100, /* Max 100 mA VBUS for host mode */ .config = &musb_config, };
+static struct gpiod_lookup_table tusb_gpio_table = { + .dev_id = "musb-tusb", + .table = { + GPIO_LOOKUP("gpio-0-15", 0, "enable", + GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio-48-63", 10, "int", + GPIO_ACTIVE_HIGH), + { } + }, +}; + static void __init n8x0_usb_init(void) { int ret = 0; - static const char announce[] __initconst = KERN_INFO "TUSB 6010\n"; - - /* PM companion chip power control pin */ - ret = gpio_request_one(TUSB6010_GPIO_ENABLE, GPIOF_OUT_INIT_LOW, - "TUSB6010 enable"); - if (ret != 0) { - printk(KERN_ERR "Could not get TUSB power GPIO%i\n", - TUSB6010_GPIO_ENABLE); - return; - } - tusb_set_power(0);
+ gpiod_add_lookup_table(&tusb_gpio_table); ret = tusb6010_setup_interface(&tusb_data, TUSB6010_REFCLK_19, 2, - TUSB6010_ASYNC_CS, TUSB6010_SYNC_CS, - TUSB6010_GPIO_INT, TUSB6010_DMACHAN); + TUSB6010_ASYNC_CS, TUSB6010_SYNC_CS, + TUSB6010_DMACHAN); if (ret != 0) - goto err; + return;
- printk(announce); + pr_info("TUSB 6010\n");
return; - -err: - gpio_free(TUSB6010_GPIO_ENABLE); } #else
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c index 18fa52f828dc7..b46c254c2bc41 100644 --- a/arch/arm/mach-omap2/usb-tusb6010.c +++ b/arch/arm/mach-omap2/usb-tusb6010.c @@ -11,12 +11,12 @@ #include <linux/errno.h> #include <linux/delay.h> #include <linux/platform_device.h> -#include <linux/gpio.h> #include <linux/export.h> #include <linux/platform_data/usb-omap.h>
#include <linux/usb/musb.h>
+#include "usb-tusb6010.h" #include "gpmc.h"
static u8 async_cs, sync_cs; @@ -132,10 +132,6 @@ static struct resource tusb_resources[] = { { /* Synchronous access */ .flags = IORESOURCE_MEM, }, - { /* IRQ */ - .name = "mc", - .flags = IORESOURCE_IRQ, - }, };
static u64 tusb_dmamask = ~(u32)0; @@ -154,9 +150,9 @@ static struct platform_device tusb_device = {
/* this may be called only from board-*.c setup code */ int __init tusb6010_setup_interface(struct musb_hdrc_platform_data *data, - unsigned ps_refclk, unsigned waitpin, - unsigned async, unsigned sync, - unsigned irq, unsigned dmachan) + unsigned int ps_refclk, unsigned int waitpin, + unsigned int async, unsigned int sync, + unsigned int dmachan) { int status; static char error[] __initdata = @@ -192,14 +188,6 @@ int __init tusb6010_setup_interface(struct musb_hdrc_platform_data *data, if (status < 0) return status;
- /* IRQ */ - status = gpio_request_one(irq, GPIOF_IN, "TUSB6010 irq"); - if (status < 0) { - printk(error, 3, status); - return status; - } - tusb_resources[2].start = gpio_to_irq(irq); - /* set up memory timings ... can speed them up later */ if (!ps_refclk) { printk(error, 4, status); diff --git a/arch/arm/mach-omap2/usb-tusb6010.h b/arch/arm/mach-omap2/usb-tusb6010.h new file mode 100644 index 0000000000000..d210ff6238c26 --- /dev/null +++ b/arch/arm/mach-omap2/usb-tusb6010.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __USB_TUSB6010_H +#define __USB_TUSB6010_H + +extern int __init tusb6010_setup_interface( + struct musb_hdrc_platform_data *data, + unsigned int ps_refclk, unsigned int waitpin, + unsigned int async_cs, unsigned int sync_cs, + unsigned int dmachan); + +#endif /* __USB_TUSB6010_H */ diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 648bb6021c5ef..dc773f4f6df2d 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2330,7 +2330,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
spin_lock_init(&musb->lock); spin_lock_init(&musb->list_lock); - musb->board_set_power = plat->set_power; musb->min_power = plat->min_power; musb->ops = plat->platform_ops; musb->port_mode = plat->mode; diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index b7588d11cfc59..91b5b6b66f963 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -352,8 +352,6 @@ struct musb { u16 epmask; u8 nr_endpoints;
- int (*board_set_power)(int state); - u8 min_power; /* vbus for periph, in mA/2 */
enum musb_mode port_mode; diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 5609b4e84d40a..b5ba713d08592 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -11,6 +11,8 @@ * interface. */
+#include <linux/gpio/consumer.h> +#include <linux/delay.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -30,6 +32,8 @@ struct tusb6010_glue { struct device *dev; struct platform_device *musb; struct platform_device *phy; + struct gpio_desc *enable; + struct gpio_desc *intpin; };
static void tusb_musb_set_vbus(struct musb *musb, int is_on); @@ -1021,16 +1025,29 @@ static void tusb_setup_cpu_interface(struct musb *musb)
static int tusb_musb_start(struct musb *musb) { + struct tusb6010_glue *glue = dev_get_drvdata(musb->controller->parent); void __iomem *tbase = musb->ctrl_base; - int ret = 0; unsigned long flags; u32 reg; + int i;
- if (musb->board_set_power) - ret = musb->board_set_power(1); - if (ret != 0) { - printk(KERN_ERR "tusb: Cannot enable TUSB6010\n"); - return ret; + /* + * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and + * 1.5 V voltage regulators of PM companion chip. Companion chip will then + * provide then PGOOD signal to TUSB6010 which will release it from reset. + */ + gpiod_set_value(glue->enable, 1); + msleep(1); + + /* Wait for 100ms until TUSB6010 pulls INT pin down */ + i = 100; + while (i && gpiod_get_value(glue->intpin)) { + msleep(1); + i--; + } + if (!i) { + pr_err("tusb: Powerup respones failed\n"); + return -ENODEV; }
spin_lock_irqsave(&musb->lock, flags); @@ -1083,8 +1100,8 @@ static int tusb_musb_start(struct musb *musb) err: spin_unlock_irqrestore(&musb->lock, flags);
- if (musb->board_set_power) - musb->board_set_power(0); + gpiod_set_value(glue->enable, 0); + msleep(10);
return -ENODEV; } @@ -1158,11 +1175,13 @@ static int tusb_musb_init(struct musb *musb)
static int tusb_musb_exit(struct musb *musb) { + struct tusb6010_glue *glue = dev_get_drvdata(musb->controller->parent); + del_timer_sync(&musb->dev_timer); the_musb = NULL;
- if (musb->board_set_power) - musb->board_set_power(0); + gpiod_set_value(glue->enable, 0); + msleep(10);
iounmap(musb->sync_va);
@@ -1218,6 +1237,15 @@ static int tusb_probe(struct platform_device *pdev)
glue->dev = &pdev->dev;
+ glue->enable = devm_gpiod_get(glue->dev, "enable", GPIOD_OUT_LOW); + if (IS_ERR(glue->enable)) + return dev_err_probe(glue->dev, PTR_ERR(glue->enable), + "could not obtain power on/off GPIO\n"); + glue->intpin = devm_gpiod_get(glue->dev, "int", GPIOD_IN); + if (IS_ERR(glue->intpin)) + return dev_err_probe(glue->dev, PTR_ERR(glue->intpin), + "could not obtain INT GPIO\n"); + pdata->platform_ops = &tusb_ops;
usb_phy_generic_register(); @@ -1236,10 +1264,7 @@ static int tusb_probe(struct platform_device *pdev) musb_resources[1].end = pdev->resource[1].end; musb_resources[1].flags = pdev->resource[1].flags;
- musb_resources[2].name = pdev->resource[2].name; - musb_resources[2].start = pdev->resource[2].start; - musb_resources[2].end = pdev->resource[2].end; - musb_resources[2].flags = pdev->resource[2].flags; + musb_resources[2] = DEFINE_RES_IRQ_NAMED(gpiod_to_irq(glue->intpin), "mc");
pinfo = tusb_dev_info; pinfo.parent = &pdev->dev; diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h index e4a3ad3c800f5..3963e55e88a31 100644 --- a/include/linux/usb/musb.h +++ b/include/linux/usb/musb.h @@ -99,9 +99,6 @@ struct musb_hdrc_platform_data { /* (HOST or OTG) program PHY for external Vbus */ unsigned extvbus:1;
- /* Power the device on or off */ - int (*set_power)(int state); - /* MUSB configuration-specific details */ const struct musb_hdrc_config *config;
@@ -135,14 +132,4 @@ static inline int musb_mailbox(enum musb_vbus_id_status status) #define TUSB6010_REFCLK_24 41667 /* psec/clk @ 24.0 MHz XI */ #define TUSB6010_REFCLK_19 52083 /* psec/clk @ 19.2 MHz CLKIN */
-#ifdef CONFIG_ARCH_OMAP2 - -extern int __init tusb6010_setup_interface( - struct musb_hdrc_platform_data *data, - unsigned ps_refclk, unsigned waitpin, - unsigned async_cs, unsigned sync_cs, - unsigned irq, unsigned dmachan); - -#endif /* OMAP2 */ - #endif /* __LINUX_USB_MUSB_H */
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 311bbc884b2edcf584b67d331be85ce43b27586f ]
Align RPM requests node with DT schema by using hyphen instead of underscore.
Fixes: f300826d27be ("ARM: dts: qcom-msm8974: Sort and clean up nodes") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230410175232.22317-1-krzysztof.kozlowski@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/qcom-msm8974.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index 834ad95515b17..1c3d36701b8e5 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -300,7 +300,7 @@ rpm { qcom,ipc = <&apcs 8 0>; qcom,smd-edge = <15>;
- rpm_requests: rpm_requests { + rpm_requests: rpm-requests { compatible = "qcom,rpm-msm8974"; qcom,smd-channels = "rpm_requests";
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit d9ef7a805a709a0b07341857d97a25598a7f92da ]
Unlike typical GIC interrupts, first cell for SPMI interrupts is the USID rather than GIC_SPI/GIC_PPI/GIC_LPI qualifier. Fix the resin interrupt to use USID value 0x0 rather than GIC_SPI define.
Fixes: f86ae6f23a9e ("arm64: dts: qcom: sagit: add initial device tree for sagit") Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230409182145.122895-1-dmitry.baryshkov@linaro.or... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/pm8998.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/pm8998.dtsi b/arch/arm64/boot/dts/qcom/pm8998.dtsi index adbba9f4089ab..13925ac44669d 100644 --- a/arch/arm64/boot/dts/qcom/pm8998.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8998.dtsi @@ -55,7 +55,7 @@ pm8998_pwrkey: pwrkey {
pm8998_resin: resin { compatible = "qcom,pm8941-resin"; - interrupts = <GIC_SPI 0x8 1 IRQ_TYPE_EDGE_BOTH>; + interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>; debounce = <15625>; bias-pull-up; status = "disabled";
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 085058786a7890dd44ec623fe5ac74db870f6b93 ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc/qrng@e1000: simple-bus unit address format error, expected "e3000"
Fixes: 5bf635621245 ("arm64: dts: ipq6018: Add a few device nodes") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-1-krzysztof.kozlowski@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/ipq6018.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi index 9ff4e9d45065b..8ec9e282b412c 100644 --- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi @@ -301,7 +301,7 @@ mdio: mdio@90000 { status = "disabled"; };
- prng: qrng@e1000 { + prng: qrng@e3000 { compatible = "qcom,prng-ee"; reg = <0x0 0x000e3000 0x0 0x1000>; clocks = <&gcc GCC_PRNG_AHB_CLK>;
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 48798d992ce276cf0d57bf75318daf8eabd02aa4 ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc@0/camss@1b00000: simple-bus unit address format error, expected "1b0ac00"
Fixes: 58f479f90a7c ("arm64: dts: qcom: msm8916: Add CAMSS support") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-2-krzysztof.kozlowski@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 0d5283805f42c..7f09b7f56dfa4 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -1161,7 +1161,7 @@ dsi_phy0: phy@1a98300 { }; };
- camss: camss@1b00000 { + camss: camss@1b0ac00 { compatible = "qcom,msm8916-camss"; reg = <0x01b0ac00 0x200>, <0x01b00030 0x4>,
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 72644bc76d5145c098c268829554a0b98fab1de1 ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc@0/mmc@7824000: simple-bus unit address format error, expected "7824900" Warning (simple_bus_reg): /soc@0/mmc@7864000: simple-bus unit address format error, expected "7864900"
Fixes: c4da5a561627 ("arm64: dts: qcom: Add msm8916 sdhci configuration nodes") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-3-krzysztof.kozlowski@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 7f09b7f56dfa4..9bbe97902f0fe 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -1553,7 +1553,7 @@ lpass_codec: audio-codec@771c000 { #sound-dai-cells = <1>; };
- sdhc_1: mmc@7824000 { + sdhc_1: mmc@7824900 { compatible = "qcom,msm8916-sdhci", "qcom,sdhci-msm-v4"; reg = <0x07824900 0x11c>, <0x07824000 0x800>; reg-names = "hc", "core"; @@ -1571,7 +1571,7 @@ sdhc_1: mmc@7824000 { status = "disabled"; };
- sdhc_2: mmc@7864000 { + sdhc_2: mmc@7864900 { compatible = "qcom,msm8916-sdhci", "qcom,sdhci-msm-v4"; reg = <0x07864900 0x11c>, <0x07864000 0x800>; reg-names = "hc", "core";
From: Stephan Gerhold stephan.gerhold@kernkonzept.com
[ Upstream commit 3244442406ff49e8f75a1f2def211c497710570f ]
On MSM8916 the wireless connectivity functionality (WiFi/Bluetooth) is split into the digital part inside the SoC and the analog RF part inside a supplementary WCN36xx chip. For MSM8916, three different options exist:
- WCN3620 (WLAN 802.11 b/g/n 2.4 GHz + Bluetooth) - WCN3660B (WLAN 802.11 a/b/g/n 2.4/5 GHz + Bluetooth) - WCN3680B (WLAN 802.11ac 2.4/5 GHz + Bluetooth)
Choosing one of these is up to the board vendor. This means that the compatible belongs into the board-specific DT part so people porting new boards pay attention to set the correct compatible.
Right now msm8916.dtsi sets "qcom,wcn3620" as default compatible, which does not work at all for boards that have WCN3660B or WCN3680B.
Remove the default compatible from msm8196.dtsi and move it to the board DT as follows:
- Boards with only &pronto { status = "okay"; } used the default "qcom,wcn3620" so far. They now set this explicitly for &wcnss_iris. - Boards with &pronto { ... iris { compatible = "qcom,wcn3660b"; }}; already had an override that just moves to &wcnss_iris now. - For msm8916-samsung-a2015-common.dtsi the WCN compatible differs for boards making use of it (a3u: wcn3620, a5u: wcn3660b, e2015: wcn3620) so the definitions move to the board-specific DT part.
Since this requires touching all the board DTs, use this as a chance to name the WCNSS-related labels consistently, so everything is grouped properly when sorted alphabetically.
No functional change, just clean-up for more clarity & easier porting. Aside from ordering the generated DTBs are identical.
Signed-off-by: Stephan Gerhold stephan.gerhold@kernkonzept.com Reviewed-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230309091452.1011776-1-stephan.gerhold@kernkonze... Stable-dep-of: 1f9a41bb0bba ("arm64: dts: qcom: msm8916: correct WCNSS unit address") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 15 ++++++++----- .../boot/dts/qcom/msm8916-acer-a1-724.dts | 12 ++++++---- .../boot/dts/qcom/msm8916-alcatel-idol347.dts | 12 ++++++---- .../arm64/boot/dts/qcom/msm8916-asus-z00l.dts | 12 ++++++---- .../boot/dts/qcom/msm8916-gplus-fl8005a.dts | 12 ++++++---- .../arm64/boot/dts/qcom/msm8916-huawei-g7.dts | 12 ++++++---- .../boot/dts/qcom/msm8916-longcheer-l8150.dts | 12 ++++++---- .../boot/dts/qcom/msm8916-longcheer-l8910.dts | 12 ++++++---- arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi | 22 +++++++++---------- .../qcom/msm8916-samsung-a2015-common.dtsi | 4 ---- .../boot/dts/qcom/msm8916-samsung-a3u-eur.dts | 8 +++++++ .../boot/dts/qcom/msm8916-samsung-a5u-eur.dts | 14 +++++++----- .../qcom/msm8916-samsung-e2015-common.dtsi | 8 +++++++ .../dts/qcom/msm8916-samsung-gt5-common.dtsi | 16 +++++++------- .../dts/qcom/msm8916-samsung-j5-common.dtsi | 12 ++++++---- .../dts/qcom/msm8916-samsung-serranove.dts | 16 +++++++------- arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi | 12 ++++++---- .../dts/qcom/msm8916-wingtech-wt88047.dts | 12 ++++++---- arch/arm64/boot/dts/qcom/msm8916.dtsi | 13 +++++------ 19 files changed, 146 insertions(+), 90 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts index c52d79a55d80c..27ceaa94c8bda 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts @@ -325,12 +325,6 @@ &pm8916_resin { linux,code = <KEY_VOLUMEDOWN>; };
-&pronto { - status = "okay"; - - firmware-name = "qcom/apq8016/wcnss.mbn"; -}; - &sdhc_1 { status = "okay";
@@ -411,10 +405,19 @@ &wcd_codec { qcom,mbhc-vthreshold-high = <75 150 237 450 500>; };
+&wcnss { + status = "okay"; + firmware-name = "qcom/apq8016/wcnss.mbn"; +}; + &wcnss_ctrl { firmware-name = "qcom/apq8016/WCNSS_qcom_wlan_nv_sbc.bin"; };
+&wcnss_iris { + compatible = "qcom,wcn3620"; +}; + /* Enable CoreSight */ &cti0 { status = "okay"; }; &cti1 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts b/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts index ed3fa7b3575b7..13cd9ad167df7 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts @@ -118,10 +118,6 @@ &pm8916_vib { status = "okay"; };
-&pronto { - status = "okay"; -}; - &sdhc_1 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>; @@ -149,6 +145,14 @@ &usb_hs_phy { extcon = <&usb_id>; };
+&wcnss { + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3620"; +}; + &smd_rpm_regulators { vdd_l1_l2_l3-supply = <&pm8916_s3>; vdd_l4_l5_l6-supply = <&pm8916_s4>; diff --git a/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts b/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts index 701a5585d77e4..fecb69944cfa3 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts @@ -160,10 +160,6 @@ &pm8916_vib { status = "okay"; };
-&pronto { - status = "okay"; -}; - &sdhc_1 { status = "okay";
@@ -191,6 +187,14 @@ &usb_hs_phy { extcon = <&usb_id>; };
+&wcnss { + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3620"; +}; + &smd_rpm_regulators { vdd_l1_l2_l3-supply = <&pm8916_s3>; vdd_l4_l5_l6-supply = <&pm8916_s4>; diff --git a/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts b/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts index 3618704a53309..91284a1d0966f 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts @@ -128,10 +128,6 @@ &blsp1_uart2 { status = "okay"; };
-&pronto { - status = "okay"; -}; - &sdhc_1 { status = "okay";
@@ -159,6 +155,14 @@ &usb_hs_phy { extcon = <&usb_id>; };
+&wcnss { + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3620"; +}; + &smd_rpm_regulators { vdd_l1_l2_l3-supply = <&pm8916_s3>; vdd_l4_l5_l6-supply = <&pm8916_s4>; diff --git a/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts b/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts index a0e520edde029..525ec76efeeb7 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts @@ -118,10 +118,6 @@ &pm8916_vib { status = "okay"; };
-&pronto { - status = "okay"; -}; - &sdhc_1 { pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>; pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>; @@ -149,6 +145,14 @@ &usb_hs_phy { extcon = <&usb_id>; };
+&wcnss { + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3620"; +}; + &smd_rpm_regulators { vdd_l1_l2_l3-supply = <&pm8916_s3>; vdd_l4_l5_l6-supply = <&pm8916_s4>; diff --git a/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts b/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts index 8c07eca900d3f..5b1bac8f51220 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts @@ -227,10 +227,6 @@ &pm8916_vib { status = "okay"; };
-&pronto { - status = "okay"; -}; - &sdhc_1 { status = "okay";
@@ -312,6 +308,14 @@ &wcd_codec { qcom,hphl-jack-type-normally-open; };
+&wcnss { + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3620"; +}; + &smd_rpm_regulators { vdd_l1_l2_l3-supply = <&pm8916_s3>; vdd_l4_l5_l6-supply = <&pm8916_s4>; diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts index d1e8cf2f50c0d..f1dd625e18227 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts @@ -231,10 +231,6 @@ &pm8916_vib { status = "okay"; };
-&pronto { - status = "okay"; -}; - &sdhc_1 { status = "okay";
@@ -263,6 +259,14 @@ &usb_hs_phy { extcon = <&pm8916_usbin>; };
+&wcnss { + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3620"; +}; + &smd_rpm_regulators { vdd_l1_l2_l3-supply = <&pm8916_s3>; vdd_l4_l5_l6-supply = <&pm8916_s4>; diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts index 3899e11b9843b..b79e80913af9f 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts @@ -99,10 +99,6 @@ &pm8916_vib { status = "okay"; };
-&pronto { - status = "okay"; -}; - &sdhc_1 { status = "okay";
@@ -130,6 +126,14 @@ &usb_hs_phy { extcon = <&usb_id>; };
+&wcnss { + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3620"; +}; + &smd_rpm_regulators { vdd_l1_l2_l3-supply = <&pm8916_s3>; vdd_l4_l5_l6-supply = <&pm8916_s4>; diff --git a/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi index 8cac23b5240c6..6eb5e0a395100 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi @@ -20,17 +20,6 @@ &mpss { pll-supply = <&pm8916_l7>; };
-&pronto { - vddpx-supply = <&pm8916_l7>; - - iris { - vddxo-supply = <&pm8916_l7>; - vddrfa-supply = <&pm8916_s3>; - vddpa-supply = <&pm8916_l9>; - vdddig-supply = <&pm8916_l5>; - }; -}; - &sdhc_1 { vmmc-supply = <&pm8916_l8>; vqmmc-supply = <&pm8916_l5>; @@ -46,6 +35,17 @@ &usb_hs_phy { v3p3-supply = <&pm8916_l13>; };
+&wcnss { + vddpx-supply = <&pm8916_l7>; +}; + +&wcnss_iris { + vddxo-supply = <&pm8916_l7>; + vddrfa-supply = <&pm8916_s3>; + vddpa-supply = <&pm8916_l9>; + vdddig-supply = <&pm8916_l5>; +}; + &rpm_requests { smd_rpm_regulators: regulators { compatible = "qcom,rpm-pm8916-regulators"; diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi index a2ed7bdbf528f..16d67749960e0 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi @@ -252,10 +252,6 @@ &pm8916_resin { linux,code = <KEY_VOLUMEDOWN>; };
-&pronto { - status = "okay"; -}; - &sdhc_1 { status = "okay";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts index c691cca2eb459..a1ca4d8834201 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts @@ -112,6 +112,14 @@ &vibrator { status = "okay"; };
+&wcnss { + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3620"; +}; + &msmgpio { panel_vdd3_default: panel-vdd3-default-state { pins = "gpio9"; diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts index 3dd819458785d..4e10b8a5e9f9c 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts @@ -54,12 +54,6 @@ &clk_pwm { status = "okay"; };
-&pronto { - iris { - compatible = "qcom,wcn3660b"; - }; -}; - &touchkey { vcc-supply = <®_touch_key>; vdd-supply = <®_touch_key>; @@ -69,6 +63,14 @@ &vibrator { status = "okay"; };
+&wcnss { + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3660b"; +}; + &msmgpio { tkey_en_default: tkey-en-default-state { pins = "gpio97"; diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi index c95f0b4bc61f3..f6c4a011fdfd2 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi @@ -58,6 +58,14 @@ &touchkey { vdd-supply = <®_touch_key>; };
+&wcnss { + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3620"; +}; + &msmgpio { tkey_en_default: tkey-en-default-state { pins = "gpio97"; diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi index d920b7247d823..74ffd04db8d84 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi @@ -125,14 +125,6 @@ &pm8916_usbin { status = "okay"; };
-&pronto { - status = "okay"; - - iris { - compatible = "qcom,wcn3660b"; - }; -}; - &sdhc_1 { pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>; pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>; @@ -162,6 +154,14 @@ &usb_hs_phy { extcon = <&pm8916_usbin>; };
+&wcnss { + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3660b"; +}; + &smd_rpm_regulators { vdd_l1_l2_l3-supply = <&pm8916_s3>; vdd_l4_l5_l6-supply = <&pm8916_s4>; diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi index f3b81b6f0a2f1..adeee0830e768 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi @@ -93,10 +93,6 @@ &pm8916_resin { linux,code = <KEY_VOLUMEDOWN>; };
-&pronto { - status = "okay"; -}; - &sdhc_1 { status = "okay";
@@ -124,6 +120,14 @@ &usb_hs_phy { extcon = <&muic>; };
+&wcnss { + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3620"; +}; + &smd_rpm_regulators { vdd_l1_l2_l3-supply = <&pm8916_s3>; vdd_l4_l5_l6-supply = <&pm8916_s4>; diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts index d4984b3af8023..1a41a4db874da 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts @@ -272,14 +272,6 @@ &pm8916_vib { status = "okay"; };
-&pronto { - status = "okay"; - - iris { - compatible = "qcom,wcn3660b"; - }; -}; - &sdhc_1 { status = "okay";
@@ -320,6 +312,14 @@ &usb_hs_phy { extcon = <&muic>; };
+&wcnss { + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3660b"; +}; + &smd_rpm_regulators { vdd_l1_l2_l3-supply = <&pm8916_s3>; vdd_l4_l5_l6-supply = <&pm8916_s4>; diff --git a/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi b/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi index cdf34b74fa8fa..50bae6f214f1f 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi @@ -99,10 +99,6 @@ &pm8916_usbin { status = "okay"; };
-&pronto { - status = "okay"; -}; - &sdhc_1 { pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>; pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>; @@ -122,6 +118,14 @@ &usb_hs_phy { extcon = <&pm8916_usbin>; };
+&wcnss { + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3620"; +}; + &smd_rpm_regulators { vdd_l1_l2_l3-supply = <&pm8916_s3>; vdd_l4_l5_l6-supply = <&pm8916_s4>; diff --git a/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts b/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts index a87be1d95b14b..ac56c7595f78a 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts @@ -153,10 +153,6 @@ &pm8916_vib { status = "okay"; };
-&pronto { - status = "okay"; -}; - &sdhc_1 { status = "okay";
@@ -184,6 +180,14 @@ &usb_hs_phy { extcon = <&usb_id>; };
+&wcnss { + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3620"; +}; + &smd_rpm_regulators { vdd_l1_l2_l3-supply = <&pm8916_s3>; vdd_l4_l5_l6-supply = <&pm8916_s4>; diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 9bbe97902f0fe..80f210e55657c 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -1870,7 +1870,7 @@ usb_hs_phy: phy { }; };
- pronto: remoteproc@a21b000 { + wcnss: remoteproc@a21b000 { compatible = "qcom,pronto-v2-pil", "qcom,pronto"; reg = <0x0a204000 0x2000>, <0x0a202000 0x1000>, <0x0a21b000 0x3000>; reg-names = "ccu", "dxe", "pmu"; @@ -1896,9 +1896,8 @@ pronto: remoteproc@a21b000 {
status = "disabled";
- iris { - compatible = "qcom,wcn3620"; - + wcnss_iris: iris { + /* Separate chip, compatible is board-specific */ clocks = <&rpmcc RPM_SMD_RF_CLK2>; clock-names = "xo"; }; @@ -1916,13 +1915,13 @@ wcnss_ctrl: wcnss { compatible = "qcom,wcnss"; qcom,smd-channels = "WCNSS_CTRL";
- qcom,mmio = <&pronto>; + qcom,mmio = <&wcnss>;
- bluetooth { + wcnss_bt: bluetooth { compatible = "qcom,wcnss-bt"; };
- wifi { + wcnss_wifi: wifi { compatible = "qcom,wcnss-wlan";
interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 1f9a41bb0bba7b373c26a6f2cc8d35cc3159c861 ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc@0/remoteproc@a21b000: simple-bus unit address format error, expected "a204000"
Fixes: 88106096cbf8 ("ARM: dts: msm8916: Add and enable wcnss node") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-4-krzysztof.kozlowski@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 80f210e55657c..7cc3d0d92cb9e 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -1870,7 +1870,7 @@ usb_hs_phy: phy { }; };
- wcnss: remoteproc@a21b000 { + wcnss: remoteproc@a204000 { compatible = "qcom,pronto-v2-pil", "qcom,pronto"; reg = <0x0a204000 0x2000>, <0x0a202000 0x1000>, <0x0a21b000 0x3000>; reg-names = "ccu", "dxe", "pmu";
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 1c06b93461ec9df8a5878947db4a9d2d1cb72855 ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc@0/iommu@1e00000: simple-bus unit address format error, expected "1e20000"
Fixes: c0b9575a3606 ("arm64: dts: qcom: msm8953: add APPS IOMMU") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-5-krzysztof.kozlowski@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8953.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi index 610f3e3fc0c22..7001f6b0b9f9a 100644 --- a/arch/arm64/boot/dts/qcom/msm8953.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi @@ -878,7 +878,7 @@ dsi1_phy: phy@1a96400 { }; };
- apps_iommu: iommu@1e00000 { + apps_iommu: iommu@1e20000 { compatible = "qcom,msm8953-iommu", "qcom,msm-iommu-v1"; ranges = <0 0x1e20000 0x20000>;
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 80284797a4cb8ceae71e3c403bafc6648263a060 ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc@0/mmc@7824000: simple-bus unit address format error, expected "7824900" Warning (simple_bus_reg): /soc@0/mmc@7864000: simple-bus unit address format error, expected "7864900" Warning (simple_bus_reg): /soc@0/mmc@7a24000: simple-bus unit address format error, expected "7a24900"
Fixes: 0484d3ce0902 ("arm64: dts: qcom: Add DTS for MSM8976 and MSM8956 SoCs") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Marijn Suijten marijn.suijten@somainline.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-7-krzysztof.kozlowski@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8976.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8976.dtsi b/arch/arm64/boot/dts/qcom/msm8976.dtsi index e55baafd9efd0..e1617b9a73df2 100644 --- a/arch/arm64/boot/dts/qcom/msm8976.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8976.dtsi @@ -821,7 +821,7 @@ spmi_bus: spmi@200f000 { cell-index = <0>; };
- sdhc_1: mmc@7824000 { + sdhc_1: mmc@7824900 { compatible = "qcom,msm8976-sdhci", "qcom,sdhci-msm-v4"; reg = <0x07824900 0x500>, <0x07824000 0x800>; reg-names = "hc", "core"; @@ -837,7 +837,7 @@ sdhc_1: mmc@7824000 { status = "disabled"; };
- sdhc_2: mmc@7864000 { + sdhc_2: mmc@7864900 { compatible = "qcom,msm8976-sdhci", "qcom,sdhci-msm-v4"; reg = <0x07864900 0x11c>, <0x07864000 0x800>; reg-names = "hc", "core"; @@ -956,7 +956,7 @@ otg: usb@78db000 { #reset-cells = <1>; };
- sdhc_3: mmc@7a24000 { + sdhc_3: mmc@7a24900 { compatible = "qcom,msm8976-sdhci", "qcom,sdhci-msm-v4"; reg = <0x07a24900 0x11c>, <0x07a24000 0x800>; reg-names = "hc", "core";
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 24f0f6a8059c7108d4ee3476c95db1e7ff4feb79 ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc/spmi@fc4c0000: simple-bus unit address format error, expected "fc4cf000"
Fixes: b0ad598f8ec0 ("arm64: dts: qcom: msm8994: Add SPMI PMIC arbiter device") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-8-krzysztof.kozlowski@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8994.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi index 24c3fced8df71..5ce23306fd844 100644 --- a/arch/arm64/boot/dts/qcom/msm8994.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi @@ -745,7 +745,7 @@ restart@fc4ab000 { reg = <0xfc4ab000 0x4>; };
- spmi_bus: spmi@fc4c0000 { + spmi_bus: spmi@fc4cf000 { compatible = "qcom,spmi-pmic-arb"; reg = <0xfc4cf000 0x1000>, <0xfc4cb000 0x1000>,
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit e959ced1d0e5ef0b1f66a0c2d0e1ae80790e5ca5 ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc/camss@a00000: simple-bus unit address format error, expected "a34000"
Fixes: e0531312e78f ("arm64: dts: qcom: msm8996: Add CAMSS support") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-9-krzysztof.kozlowski@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8996.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index 73da1a4d52462..771db923b2e33 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -2069,7 +2069,7 @@ ufsphy_lane: phy@627400 { }; };
- camss: camss@a00000 { + camss: camss@a34000 { compatible = "qcom,msm8996-camss"; reg = <0x00a34000 0x1000>, <0x00a00030 0x4>,
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit c8b7faa7e9913a94444b3f00b6480e53a174fcfd ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc/camss@ca00000: simple-bus unit address format error, expected "ca00020"
Fixes: f3d5d3cc6971 ("arm64: dts: qcom: sdm630: Configure the camera subsystem") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-10-krzysztof.kozlowski@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm630.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi index 5827cda270a0e..07c720c5721d4 100644 --- a/arch/arm64/boot/dts/qcom/sdm630.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi @@ -1893,7 +1893,7 @@ pil-reloc@94c { }; };
- camss: camss@ca00000 { + camss: camss@ca00020 { compatible = "qcom,sdm660-camss"; reg = <0x0ca00020 0x10>, <0x0ca30000 0x100>,
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit a05b913a27e46926ba60ba2bcacc7ec7a8403e4c ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc@0/camss@a00000: simple-bus unit address format error, expected "acb3000"
Fixes: d48a6698a6b7 ("arm64: dts: qcom: sdm845: Add CAMSS ISP node") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-11-krzysztof.kozlowski@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index c5e92851a4f08..bc89a2b4bc258 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -4158,7 +4158,7 @@ videocc: clock-controller@ab00000 { #reset-cells = <1>; };
- camss: camss@a00000 { + camss: camss@acb3000 { compatible = "qcom,sdm845-camss";
reg = <0 0x0acb3000 0 0x1000>,
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 2358b43256080459fcc5642265ed4fec75558f8c ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc@0/thermal-sensor@4410000: simple-bus unit address format error, expected "4411000"
Fixes: 7b74cba6b13f ("arm64: dts: qcom: sm6115: Add TSENS node") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-12-krzysztof.kozlowski@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sm6115.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sm6115.dtsi b/arch/arm64/boot/dts/qcom/sm6115.dtsi index fbd67d2c8d781..62b1c1674a68d 100644 --- a/arch/arm64/boot/dts/qcom/sm6115.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6115.dtsi @@ -693,7 +693,7 @@ spmi_bus: spmi@1c40000 { #interrupt-cells = <4>; };
- tsens0: thermal-sensor@4410000 { + tsens0: thermal-sensor@4411000 { compatible = "qcom,sm6115-tsens", "qcom,tsens-v2"; reg = <0x0 0x04411000 0x0 0x1ff>, /* TM */ <0x0 0x04410000 0x0 0x8>; /* SROT */
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 41d6bca799b3f40d4d3c22dd4545aeac7c210e33 ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc@0/dma-controller@900000: simple-bus unit address format error, expected "9800000"
Fixes: bc08fbf49bc8 ("arm64: dts: qcom: sm8350: Define GPI DMA engines") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-13-krzysztof.kozlowski@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sm8350.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi index 9cb52d7efdd8d..f0453730ab59b 100644 --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi @@ -892,7 +892,7 @@ spi19: spi@894000 { }; };
- gpi_dma0: dma-controller@900000 { + gpi_dma0: dma-controller@9800000 { compatible = "qcom,sm8350-gpi-dma", "qcom,sm6350-gpi-dma"; reg = <0 0x09800000 0 0x60000>; interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>,
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit ab98c21bc9246f421a6ae70e69f1b73cea6f85e3 ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc@0/phy@1c0f000: simple-bus unit address format error, expected "1c0e000"
Fixes: 6daee40678a0 ("arm64: dts: qcom: sm8350: add PCIe devices") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-14-krzysztof.kozlowski@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sm8350.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi index f0453730ab59b..1a258a5461acf 100644 --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi @@ -1625,7 +1625,7 @@ pcie1: pci@1c08000 { status = "disabled"; };
- pcie1_phy: phy@1c0f000 { + pcie1_phy: phy@1c0e000 { compatible = "qcom,sm8350-qmp-gen3x2-pcie-phy"; reg = <0 0x01c0e000 0 0x2000>; clocks = <&gcc GCC_PCIE_1_AUX_CLK>,
From: Vladimir Zapolskiy vladimir.zapolskiy@linaro.org
[ Upstream commit e47a80784306a544a58f5c7febaaa3cc646f51a2 ]
Add a family compatible for QCE IP on SM8550 SoC, which is equal to QCE IP found on SM8150 SoC and described in the recently updated device tree bindings documentation, as well add a generic QCE IP family compatible.
Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Vladimir Zapolskiy vladimir.zapolskiy@linaro.org Reviewed-by: Neil Armstrong neil.armstrong@linaro.org Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Stable-dep-of: 3cbf49ef1696 ("arm64: dts: qcom: sm8550: correct crypto unit address") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sm8550.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi index 90e3fb11e6e70..b451e94f2b4c0 100644 --- a/arch/arm64/boot/dts/qcom/sm8550.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi @@ -1844,7 +1844,7 @@ cryptobam: dma-controller@1dc4000 { };
crypto: crypto@1de0000 { - compatible = "qcom,sm8550-qce"; + compatible = "qcom,sm8550-qce", "qcom,sm8150-qce", "qcom,qce"; reg = <0x0 0x01dfa000 0x0 0x6000>; dmas = <&cryptobam 4>, <&cryptobam 5>; dma-names = "rx", "tx";
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 3cbf49ef16962ab6d99a3659cb34a33c5f147b50 ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc@0/crypto@1de0000: simple-bus unit address format error, expected "1dfa000"
Fixes: 433477c3bf0b ("arm64: dts: qcom: sm8550: add QCrypto nodes") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-16-krzysztof.kozlowski@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sm8550.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi index b451e94f2b4c0..3af9da58f65c6 100644 --- a/arch/arm64/boot/dts/qcom/sm8550.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi @@ -1843,7 +1843,7 @@ cryptobam: dma-controller@1dc4000 { <&apps_smmu 0x481 0x0>; };
- crypto: crypto@1de0000 { + crypto: crypto@1dfa000 { compatible = "qcom,sm8550-qce", "qcom,sm8150-qce", "qcom,qce"; reg = <0x0 0x01dfa000 0x0 0x6000>; dmas = <&cryptobam 4>, <&cryptobam 5>;
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 950a4fe6ec8498799d1c7bd31a489a718f94a87e ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc@0/pinctrl@f000000: simple-bus unit address format error, expected "f100000"
Fixes: ffc50b2d3828 ("arm64: dts: qcom: Add base SM8550 dtsi") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-17-krzysztof.kozlowski@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sm8550.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi index 3af9da58f65c6..5f254a4675265 100644 --- a/arch/arm64/boot/dts/qcom/sm8550.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi @@ -2536,7 +2536,7 @@ spmi_bus: spmi@c400000 { #interrupt-cells = <4>; };
- tlmm: pinctrl@f000000 { + tlmm: pinctrl@f100000 { compatible = "qcom,sm8550-tlmm"; reg = <0 0x0f100000 0 0x300000>; interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 4a0156b8862665a3e31c8280607388e3001ace3d ]
Add missing reg property to touchscreen child node to fix dtbs W=1 warnings:
Warning (unit_address_vs_reg): /soc@0/geniqup@ac0000/i2c@a98000/touchscreen@20/rmi4-f12@12: node has a unit name, but no reg or ranges property
Fixes: be497abe19bf ("arm64: dts: qcom: Add support for Xiaomi Mi Mix2s") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Reviewed-by: Molly Sophia mollysophia379@gmail.com Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-18-krzysztof.kozlowski@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts index 56f2d855df78d..406f0224581a7 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts @@ -483,6 +483,7 @@ rmi4-f01@1 { };
rmi4-f12@12 { + reg = <0x12>; syna,rezero-wait-ms = <0xc8>; syna,clip-x-high = <0x438>; syna,clip-y-high = <0x870>;
From: Stephan Gerhold stephan@gerhold.net
[ Upstream commit e27654df20d77ad7549a3cf6739ebaa3aa59a088 ]
For some reason DB410c has completely bogus regulator constraints that actually just correspond to the programmable voltages which are already provided by the regulator driver. Some of them are not just outside the recommended operating conditions of the APQ8016E SoC but even exceed the absolute maximum ratings, potentially risking permanent device damage.
In practice it's not quite as dangerous thanks to the RPM firmware: It turns out that it has its own voltage constraints and silently clamps all regulator requests. For example, requesting 3.3V for L5 (allowed by the current regulator constraints!) still results in 1.8V being programmed in the actual regulator hardware.
Experimentation with various voltages shows that the internal RPM voltage constraints roughly correspond to the safe "specified range" in the PM8916 Device Specification (rather than the "programmable range" used inside apq8016-sbc.dtsi right now).
Combine those together with some fixed voltages used in the old msm-3.10 device tree from Qualcomm to give DB410c some actually valid voltage constraints.
Cc: Srinivas Kandagatla srinivas.kandagatla@linaro.org Fixes: 4c7d53d16d77 ("arm64: dts: apq8016-sbc: add regulators support") Signed-off-by: Stephan Gerhold stephan@gerhold.net Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230510-msm8916-regulators-v1-1-54d4960a05fc@gerh... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 64 ++++++++++++------------ 1 file changed, 32 insertions(+), 32 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts index 27ceaa94c8bda..d7d7a826b8be4 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts @@ -447,21 +447,21 @@ &smd_rpm_regulators { vdd_l7-supply = <&pm8916_s4>;
s3 { - regulator-min-microvolt = <375000>; - regulator-max-microvolt = <1562000>; + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1350000>; };
s4 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1850000>; + regulator-max-microvolt = <2150000>;
regulator-always-on; regulator-boot-on; };
l1 { - regulator-min-microvolt = <375000>; - regulator-max-microvolt = <1525000>; + regulator-min-microvolt = <1225000>; + regulator-max-microvolt = <1225000>; };
l2 { @@ -470,13 +470,13 @@ l2 { };
l4 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <2050000>; + regulator-max-microvolt = <2050000>; };
l5 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; };
l6 { @@ -485,45 +485,45 @@ l6 { };
l7 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; };
l8 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; };
l9 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; };
l10 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; };
l11 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; regulator-allow-set-load; regulator-system-load = <200000>; };
l12 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2950000>; };
l13 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <3075000>; + regulator-max-microvolt = <3075000>; };
l14 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; };
/** @@ -531,14 +531,14 @@ l14 { * for mezzanine boards */ l15 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; regulator-always-on; };
l16 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; };
l17 { @@ -547,8 +547,8 @@ l17 { };
l18 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2700000>; }; };
From: Stephan Gerhold stephan@gerhold.net
[ Upstream commit 5500f823db38db073d30557af159b77fb1f2bf26 ]
The 96Boards specification expects a 1.8V power rail on the low-speed expansion connector that is able to provide at least 0.18W / 100 mA. According to the DB410c hardware user manual this is done by connecting both L15 and L16 in parallel with up to 55mA each (for 110 mA total) [1].
Unfortunately the current regulator setup in the DB410c device tree does not implement the specification correctly and only provides 5 mA:
- Only L15 is marked always-on, so L16 is never enabled. - Without specifying a load the regulator is put into LPM where it can only provide 5 mA.
Fix this by:
- Adding proper voltage constraints for L16. - Making L16 always-on. - Adding regulator-system-load for both L15 and L16. 100 mA should be available in total, so specify 50 mA for each. (The regulator hardware can only be in normal (55 mA) or low-power mode (5 mA) so this will actually result in the expected 110 mA total...)
[1]: https://www.96boards.org/documentation/consumer/dragonboard/dragonboard410c/...
Cc: Srinivas Kandagatla srinivas.kandagatla@linaro.org Fixes: 828dd5d66f0f ("arm64: dts: apq8016-sbc: make 1.8v available on LS expansion") Signed-off-by: Stephan Gerhold stephan@gerhold.net Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230510-msm8916-regulators-v1-2-54d4960a05fc@gerh... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts index d7d7a826b8be4..dbdb8077857ef 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts @@ -526,19 +526,27 @@ l14 { regulator-max-microvolt = <3300000>; };
- /** - * 1.8v required on LS expansion - * for mezzanine boards + /* + * The 96Boards specification expects a 1.8V power rail on the low-speed + * expansion connector that is able to provide at least 0.18W / 100 mA. + * L15/L16 are connected in parallel to provide 55 mA each. A minimum load + * must be specified to ensure the regulators are not put in LPM where they + * would only provide 5 mA. */ l15 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; + regulator-system-load = <50000>; + regulator-allow-set-load; regulator-always-on; };
l16 { regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; + regulator-max-microvolt = <1800000>; + regulator-system-load = <50000>; + regulator-allow-set-load; + regulator-always-on; };
l17 {
From: Frieder Schrempf frieder.schrempf@kontron.de
[ Upstream commit dd9e329af7236e34c566d3705ea32a63069b9b13 ]
The datasheet describes the following initialization flow including minimum delay times between each step:
1. DSI data lanes need to be in LP-11 and the clock lane in HS mode 2. toggle EN signal 3. initialize registers 4. enable PLL 5. soft reset 6. enable DSI stream 7. check error status register
To meet this requirement we need to make sure the host bridge's pre_enable() is called first by using the pre_enable_prev_first flag.
Furthermore we need to split enable() into pre_enable() which covers steps 2-5 from above and enable() which covers step 7 and is called after the host bridge's enable().
Signed-off-by: Frieder Schrempf frieder.schrempf@kontron.de Fixes: ceb515ba29ba ("drm/bridge: ti-sn65dsi83: Add TI SN65DSI83 and SN65DSI84 driver") Tested-by: Alexander Stein alexander.stein@ew.tq-group.com #TQMa8MxML/MBa8Mx Reviewed-by: Neil Armstrong neil.armstrong@linaro.org Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20230503163313.2640898-3-fried... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c index a6534011c9214..e4ee2904d0893 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c @@ -321,8 +321,8 @@ static u8 sn65dsi83_get_dsi_div(struct sn65dsi83 *ctx) return dsi_div - 1; }
-static void sn65dsi83_atomic_enable(struct drm_bridge *bridge, - struct drm_bridge_state *old_bridge_state) +static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge); struct drm_atomic_state *state = old_bridge_state->base.state; @@ -485,11 +485,22 @@ static void sn65dsi83_atomic_enable(struct drm_bridge *bridge, /* Trigger reset after CSR register update. */ regmap_write(ctx->regmap, REG_RC_RESET, REG_RC_RESET_SOFT_RESET);
+ /* Wait for 10ms after soft reset as specified in datasheet */ + usleep_range(10000, 12000); +} + +static void sn65dsi83_atomic_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) +{ + struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge); + unsigned int pval; + /* Clear all errors that got asserted during initialization. */ regmap_read(ctx->regmap, REG_IRQ_STAT, &pval); regmap_write(ctx->regmap, REG_IRQ_STAT, pval);
- usleep_range(10000, 12000); + /* Wait for 1ms and check for errors in status register */ + usleep_range(1000, 1100); regmap_read(ctx->regmap, REG_IRQ_STAT, &pval); if (pval) dev_err(ctx->dev, "Unexpected link status 0x%02x\n", pval); @@ -556,6 +567,7 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = { .attach = sn65dsi83_attach, .detach = sn65dsi83_detach, .atomic_enable = sn65dsi83_atomic_enable, + .atomic_pre_enable = sn65dsi83_atomic_pre_enable, .atomic_disable = sn65dsi83_atomic_disable, .mode_valid = sn65dsi83_mode_valid,
@@ -696,6 +708,7 @@ static int sn65dsi83_probe(struct i2c_client *client)
ctx->bridge.funcs = &sn65dsi83_funcs; ctx->bridge.of_node = dev->of_node; + ctx->bridge.pre_enable_prev_first = true; drm_bridge_add(&ctx->bridge);
ret = sn65dsi83_host_attach(ctx);
From: Dario Binacchi dario.binacchi@amarulasolutions.com
[ Upstream commit f24b49550814fdee4a98b9552e35e243ccafd4a8 ]
The previous setting was related to the overall dimension and not to the active display area. In the "PHYSICAL SPECIFICATIONS" section, the datasheet shows the following parameters:
---------------------------------------------------------- | Item | Specifications | unit | ---------------------------------------------------------- | Display area | 98.7 (W) x 57.5 (H) | mm | ---------------------------------------------------------- | Overall dimension | 105.5(W) x 67.2(H) x 4.96(D) | mm | ----------------------------------------------------------
Fixes: 966fea78adf2 ("drm/panel: simple: Add support for Ampire AM-480272H3TMQW-T01H") Signed-off-by: Dario Binacchi dario.binacchi@amarulasolutions.com Reviewed-by: Neil Armstrong neil.armstrong@linaro.org [narmstrong: fixed Fixes commit id length] Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20230516085039.3797303-1-dario... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/panel/panel-simple.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 065f378bba9d2..d8efbcee9bc12 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -759,8 +759,8 @@ static const struct panel_desc ampire_am_480272h3tmqw_t01h = { .num_modes = 1, .bpc = 8, .size = { - .width = 105, - .height = 67, + .width = 99, + .height = 58, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X24, };
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 419013740ea1e4343d8ade535d999f59fa28e460 ]
ep93xx_clocksource_read() is only called from the file it is declared in, while ep93xx_timer_init() is declared in a header that is not included here.
arch/arm/mach-ep93xx/timer-ep93xx.c:120:13: error: no previous prototype for 'ep93xx_timer_init' arch/arm/mach-ep93xx/timer-ep93xx.c:63:5: error: no previous prototype for 'ep93xx_clocksource_read'
Fixes: 000bc17817bf ("ARM: ep93xx: switch to GENERIC_CLOCKEVENTS") Acked-by: Alexander Sverdlin alexander.sverdlin@gmail.com Link: https://lore.kernel.org/r/20230516153109.514251-3-arnd@kernel.org Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-ep93xx/timer-ep93xx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-ep93xx/timer-ep93xx.c b/arch/arm/mach-ep93xx/timer-ep93xx.c index dd4b164d18317..a9efa7bc2fa12 100644 --- a/arch/arm/mach-ep93xx/timer-ep93xx.c +++ b/arch/arm/mach-ep93xx/timer-ep93xx.c @@ -9,6 +9,7 @@ #include <linux/io.h> #include <asm/mach/time.h> #include "soc.h" +#include "platform.h"
/************************************************************************* * Timer handling for EP93xx @@ -60,7 +61,7 @@ static u64 notrace ep93xx_read_sched_clock(void) return ret; }
-u64 ep93xx_clocksource_read(struct clocksource *c) +static u64 ep93xx_clocksource_read(struct clocksource *c) { u64 ret;
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 861bc1d2886d47bd57a2cbf2cda87fdbe3eb9d08 ]
omap2 contains a hack to define tick_broadcast() on non-SMP configurations in place of the normal SMP definition. This one causes a warning because of a missing prototype:
arch/arm/mach-omap2/board-generic.c:44:6: error: no previous prototype for 'tick_broadcast'
Make sure to always include the header with the declaration.
Fixes: d86ad463d670 ("ARM: OMAP2+: Fix regression for using local timer on non-SMP SoCs") Acked-by: Aaro Koskinen aaro.koskinen@iki.fi Link: https://lore.kernel.org/r/20230516153109.514251-9-arnd@kernel.org Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-omap2/board-generic.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 1610c567a6a3a..10d2f078e4a8e 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -13,6 +13,7 @@ #include <linux/of_platform.h> #include <linux/irqdomain.h> #include <linux/clocksource.h> +#include <linux/clockchips.h>
#include <asm/setup.h> #include <asm/mach/arch.h>
From: Luca Weiss luca.weiss@fairphone.com
[ Upstream commit 83022f6484b11a60dbf9a95a88c7ef8e59c4b19c ]
This file is using definitions from the spmi-vadc header, so we need to include it.
Fixes: 11975b9b8135 ("arm64: dts: qcom: Add pm7250b PMIC") Signed-off-by: Luca Weiss luca.weiss@fairphone.com Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230407-pm7250b-sid-v1-1-fc648478cc25@fairphone.c... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/pm7250b.dtsi | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/qcom/pm7250b.dtsi b/arch/arm64/boot/dts/qcom/pm7250b.dtsi index d709d955a2f5a..daa6f1d30efa0 100644 --- a/arch/arm64/boot/dts/qcom/pm7250b.dtsi +++ b/arch/arm64/boot/dts/qcom/pm7250b.dtsi @@ -3,6 +3,7 @@ * Copyright (C) 2022 Luca Weiss luca.weiss@fairphone.com */
+#include <dt-bindings/iio/qcom,spmi-vadc.h> #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/spmi/spmi.h>
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit c77612a07d18d4425fd8ddd532a8a9b8e1970c53 ]
Correct the typo in 'regulator-name' property.
apq8096-ifc6640.dtb: v1p05-regulator: 'regulator-name' is a required property apq8096-ifc6640.dtb: v1p05-regulator: Unevaluated properties are not allowed ('reglator-name' was unexpected)
Fixes: 6cbdec2d3ca6 ("arm64: dts: qcom: msm8996: Introduce IFC6640") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230507174516.264936-3-krzysztof.kozlowski@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts b/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts index 71e0a500599c8..ed2e2f6c6775a 100644 --- a/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts +++ b/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts @@ -26,7 +26,7 @@ chosen {
v1p05: v1p05-regulator { compatible = "regulator-fixed"; - reglator-name = "v1p05"; + regulator-name = "v1p05"; regulator-always-on; regulator-boot-on;
@@ -38,7 +38,7 @@ v1p05: v1p05-regulator {
v12_poe: v12-poe-regulator { compatible = "regulator-fixed"; - reglator-name = "v12_poe"; + regulator-name = "v12_poe"; regulator-always-on; regulator-boot-on;
From: Douglas Anderson dianders@chromium.org
[ Upstream commit 42127f578ebde652d1373e0233356fbd351675c4 ]
Firmware shipped on mt8183 Chromebooks is affected by the GICR save/restore issue as described by the patch ("dt-bindings: interrupt-controller: arm,gic-v3: Add quirk for Mediatek SoCs w/ broken FW"). Add the quirk property.
Fixes: cd894e274b74 ("arm64: dts: mt8183: Add krane-sku176 board") Reviewed-by: Julius Werner jwerner@chromium.org Signed-off-by: Douglas Anderson dianders@chromium.org Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Link: https://lore.kernel.org/r/20230515131353.v2.3.I525a2ed4260046d43c885ee1275e9... Signed-off-by: Matthias Brugger matthias.bgg@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi index fbe14b13051a6..4836ad55fd4ae 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi @@ -292,6 +292,10 @@ dsi_out: endpoint { }; };
+&gic { + mediatek,broken-save-restore-fw; +}; + &gpu { mali-supply = <&mt6358_vgpu_reg>; sram-supply = <&mt6358_vsram_gpu_reg>;
From: Marek Vasut marex@denx.de
[ Upstream commit 0cf765e598712addec34d0208cc1418c151fefb2 ]
Fix the following error in kernel log due to too long sound card name: " asoc-audio-graph-card sound: ASoC: driver name too long 'STM32MP1-AV96-HDMI' -> 'STM32MP1-AV96-H' "
Fixes: e027da342772 ("ARM: dts: stm32: Add bindings for audio on AV96") Signed-off-by: Marek Vasut marex@denx.de Signed-off-by: Alexandre Torgue alexandre.torgue@foss.st.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi index e67c0fa209cde..7d5d6d4360385 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi @@ -87,7 +87,7 @@ sd_switch: regulator-sd_switch {
sound { compatible = "audio-graph-card"; - label = "STM32MP1-AV96-HDMI"; + label = "STM32-AV96-HDMI"; dais = <&sai2a_port>; status = "okay"; };
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 1d9e93fad549bc38f593147479ee063f2872c170 ]
Code should first check for valid value of array offset, then use it as the index. Fixes smatch warning:
drivers/memory/brcmstb_dpfe.c:443 __send_command() error: testing array offset 'cmd' after use.
Fixes: 2f330caff577 ("memory: brcmstb: Add driver for DPFE") Acked-by: Markus Mayer mmayer@broadcom.com Reviewed-by: Florian Fainelli florian.fainelli@broadcom.com Link: https://lore.kernel.org/r/20230513112931.176066-1-krzysztof.kozlowski@linaro... Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/memory/brcmstb_dpfe.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/memory/brcmstb_dpfe.c b/drivers/memory/brcmstb_dpfe.c index 76c82e9c8fceb..9339f80b21c50 100644 --- a/drivers/memory/brcmstb_dpfe.c +++ b/drivers/memory/brcmstb_dpfe.c @@ -434,15 +434,17 @@ static void __finalize_command(struct brcmstb_dpfe_priv *priv) static int __send_command(struct brcmstb_dpfe_priv *priv, unsigned int cmd, u32 result[]) { - const u32 *msg = priv->dpfe_api->command[cmd]; void __iomem *regs = priv->regs; unsigned int i, chksum, chksum_idx; + const u32 *msg; int ret = 0; u32 resp;
if (cmd >= DPFE_CMD_MAX) return -1;
+ msg = priv->dpfe_api->command[cmd]; + mutex_lock(&priv->lock);
/* Wait for DCPU to become ready */
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit e60c230588d88036f974cec7e93361e2c4f62226 ]
Add the qcom,controlled-remotely property for the blsp2_bam controller node. This board requires this, otherwise the board stalls during the boot for some reason (most probably because TZ mishandles the protection error and keeps on looping somewhere inside).
Fixes: 62bc81792223 dts: msm8974: Add blsp2_bam dma node Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230507190735.2333145-3-dmitry.baryshkov@linaro.o... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/qcom-apq8074-dragonboard.dts | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts index 1345df7cbd002..6b047c6793707 100644 --- a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts +++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts @@ -23,6 +23,10 @@ &blsp1_uart2 { status = "okay"; };
+&blsp2_dma { + qcom,controlled-remotely; +}; + &blsp2_i2c5 { status = "okay"; clock-frequency = <200000>;
From: Cristian Ciocaltea cristian.ciocaltea@collabora.com
[ Upstream commit 6f073429037cd79d7311cd8236311c53f5ea8f01 ]
The following error occurs when trying to restore a previously saved ALSA mixer state (tested on a Rock 5B board):
$ alsactl --no-ucm -f /tmp/asound.state store hw:Analog $ alsactl --no-ucm -I -f /tmp/asound.state restore hw:Analog alsactl: set_control:1475: Cannot write control '2:0:0:ALC Capture Target Volume:0' : Invalid argument
According to ES8316 datasheet, the register at address 0x2B, which is related to the above mixer control, contains by default the value 0xB0. Considering the corresponding ALC target bits (ALCLVL) are 7:4, the control is initialized with 11, which is one step above the maximum value allowed by the driver:
ALCLVL | dB gain -------+-------- 0000 | -16.5 0001 | -15.0 0010 | -13.5 .... | ..... 0111 | -6.0 1000 | -4.5 1001 | -3.0 1010 | -1.5 .... | ..... 1111 | -1.5
The tests performed using the VU meter feature (--vumeter=TYPE) of arecord/aplay confirm the specs are correct and there is no measured gain if the 1011-1111 range would have been mapped to 0 dB:
dB gain | VU meter % --------+----------- -6.0 | 30-31 -4.5 | 35-36 -3.0 | 42-43 -1.5 | 50-51 0.0 | 50-51
Increment the max value allowed for ALC Capture Target Volume control, so that it matches the hardware default. Additionally, update the related TLV to prevent an artificial extension of the dB gain range.
Fixes: b8b88b70875a ("ASoC: add es8316 codec driver") Signed-off-by: Cristian Ciocaltea cristian.ciocaltea@collabora.com Link: https://lore.kernel.org/r/20230530181140.483936-2-cristian.ciocaltea@collabo... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/es8316.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index f7d7a9c91e04c..2bfcd9af39172 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -52,7 +52,12 @@ static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(dac_vol_tlv, -9600, 50, 1); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_vol_tlv, -9600, 50, 1); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_max_gain_tlv, -650, 150, 0); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_min_gain_tlv, -1200, 150, 0); -static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_target_tlv, -1650, 150, 0); + +static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(alc_target_tlv, + 0, 10, TLV_DB_SCALE_ITEM(-1650, 150, 0), + 11, 11, TLV_DB_SCALE_ITEM(-150, 0, 0), +); + static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(hpmixer_gain_tlv, 0, 4, TLV_DB_SCALE_ITEM(-1200, 150, 0), 8, 11, TLV_DB_SCALE_ITEM(-450, 150, 0), @@ -115,7 +120,7 @@ static const struct snd_kcontrol_new es8316_snd_controls[] = { alc_max_gain_tlv), SOC_SINGLE_TLV("ALC Capture Min Volume", ES8316_ADC_ALC2, 0, 28, 0, alc_min_gain_tlv), - SOC_SINGLE_TLV("ALC Capture Target Volume", ES8316_ADC_ALC3, 4, 10, 0, + SOC_SINGLE_TLV("ALC Capture Target Volume", ES8316_ADC_ALC3, 4, 11, 0, alc_target_tlv), SOC_SINGLE("ALC Capture Hold Time", ES8316_ADC_ALC3, 0, 10, 0), SOC_SINGLE("ALC Capture Decay Time", ES8316_ADC_ALC4, 4, 10, 0),
From: Cristian Ciocaltea cristian.ciocaltea@collabora.com
[ Upstream commit 60413129ee2b38a80347489270af7f6e1c1de4d0 ]
When using the codec through the generic audio graph card, there are at least two calls of es8316_set_dai_sysclk(), with the effect of limiting the allowed sample rates according to the MCLK/LRCK ratios supported by the codec:
1. During audio card setup, to set the initial MCLK - see asoc_simple_init_dai().
2. Before opening a stream, to update MCLK, according to the stream sample rate and the multiplication factor - see asoc_simple_hw_params().
In some cases the initial MCLK might be set to a frequency that doesn't match any of the supported ratios, e.g. 12287999 instead of 12288000, which is only 1 Hz below the supported clock, as that is what the hardware reports. This creates an empty list of rate constraints, which is further passed to snd_pcm_hw_constraint_list() via es8316_pcm_startup(), and causes the following error on the very first access of the sound card:
$ speaker-test -D hw:Analog,0 -F S16_LE -c 2 -t wav Broken configuration for playback: no configurations available: Invalid argument Setting of hwparams failed: Invalid argument
Note that all subsequent retries succeed thanks to the updated MCLK set at point 2 above, which uses a computed frequency value instead of a reading from the hardware registers. Normally this would have mitigated the issue, but es8316_pcm_startup() executes before the 2nd call to es8316_set_dai_sysclk(), hence it cannot make use of the updated constraints.
Since es8316_pcm_hw_params() performs anyway a final validation of MCLK against the stream sample rate and the supported MCLK/LRCK ratios, fix the issue by ensuring that sysclk_constraints list is only set when at least one supported sample rate is autodetected by the codec.
Fixes: b8b88b70875a ("ASoC: add es8316 codec driver") Signed-off-by: Cristian Ciocaltea cristian.ciocaltea@collabora.com Link: https://lore.kernel.org/r/20230530181140.483936-3-cristian.ciocaltea@collabo... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/es8316.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index 2bfcd9af39172..87775378362e7 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -369,13 +369,11 @@ static int es8316_set_dai_sysclk(struct snd_soc_dai *codec_dai, int count = 0;
es8316->sysclk = freq; + es8316->sysclk_constraints.list = NULL; + es8316->sysclk_constraints.count = 0;
- if (freq == 0) { - es8316->sysclk_constraints.list = NULL; - es8316->sysclk_constraints.count = 0; - + if (freq == 0) return 0; - }
ret = clk_set_rate(es8316->mclk, freq); if (ret) @@ -391,8 +389,10 @@ static int es8316_set_dai_sysclk(struct snd_soc_dai *codec_dai, es8316->allowed_rates[count++] = freq / ratio; }
- es8316->sysclk_constraints.list = es8316->allowed_rates; - es8316->sysclk_constraints.count = count; + if (count) { + es8316->sysclk_constraints.list = es8316->allowed_rates; + es8316->sysclk_constraints.count = count; + }
return 0; }
From: Martin Blumenstingl martin.blumenstingl@googlemail.com
[ Upstream commit 98b503c7fb13a17a47d8ebf15fa8f7c10118e75c ]
On Meson8 uart_B and uart_C do not work, because they are relying on incorrect clocks. Change the references of pclk to the correct CLKID (UART1 for uart_B and UART2 for uart_C), to allow use of the two uarts.
This was originally reported by Hans-Frieder Vogt for Meson8b [0], but the same bug is also present in meson8.dtsi
[0] https://lore.kernel.org/linux-amlogic/trinity-bf20bcb9-790b-4ab9-99e3-0831ef...
Fixes: 57007bfb5469 ("ARM: dts: meson8: Fix the UART device-tree schema validation") Reported-by: Hans-Frieder Vogt hfdevel@gmx.net # for meson8b.dtsi Signed-off-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Link: https://lore.kernel.org/r/20230516203029.1031174-1-martin.blumenstingl@googl... Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/meson8.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi index 21eb59041a7d9..8432efd48f610 100644 --- a/arch/arm/boot/dts/meson8.dtsi +++ b/arch/arm/boot/dts/meson8.dtsi @@ -752,13 +752,13 @@ &uart_A {
&uart_B { compatible = "amlogic,meson8-uart"; - clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>; + clocks = <&xtal>, <&clkc CLKID_UART1>, <&clkc CLKID_CLK81>; clock-names = "xtal", "pclk", "baud"; };
&uart_C { compatible = "amlogic,meson8-uart"; - clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>; + clocks = <&xtal>, <&clkc CLKID_UART2>, <&clkc CLKID_CLK81>; clock-names = "xtal", "pclk", "baud"; };
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 7b1a78babd0d2cd27aa07255dee0c2d7ac0f31e3 ]
Fix build errors in soc/fsl/qe/usb.c when QUICC_ENGINE is not set. This happens when PPC_EP88XC is set, which selects CPM1 & CPM. When CPM is set, USB_FSL_QE can be set without QUICC_ENGINE being set. When USB_FSL_QE is set, QE_USB deafults to y, which causes build errors when QUICC_ENGINE is not set. Making QE_USB depend on QUICC_ENGINE prevents QE_USB from defaulting to y.
Fixes these build errors:
drivers/soc/fsl/qe/usb.o: in function `qe_usb_clock_set': usb.c:(.text+0x1e): undefined reference to `qe_immr' powerpc-linux-ld: usb.c:(.text+0x2a): undefined reference to `qe_immr' powerpc-linux-ld: usb.c:(.text+0xbc): undefined reference to `qe_setbrg' powerpc-linux-ld: usb.c:(.text+0xca): undefined reference to `cmxgcr_lock' powerpc-linux-ld: usb.c:(.text+0xce): undefined reference to `cmxgcr_lock'
Fixes: 5e41486c408e ("powerpc/QE: add support for QE USB clocks routing") Signed-off-by: Randy Dunlap rdunlap@infradead.org Reported-by: kernel test robot lkp@intel.com Link: https://lore.kernel.org/all/202301101500.pillNv6R-lkp@intel.com/ Suggested-by: Michael Ellerman mpe@ellerman.id.au Cc: Christophe Leroy christophe.leroy@csgroup.eu Cc: Leo Li leoyang.li@nxp.com Cc: Masahiro Yamada masahiroy@kernel.org Cc: Nicolas Schier nicolas@fjasle.eu Cc: Qiang Zhao qiang.zhao@nxp.com Cc: linuxppc-dev linuxppc-dev@lists.ozlabs.org Cc: linux-arm-kernel@lists.infradead.org Cc: Kumar Gala galak@kernel.crashing.org Acked-by: Nicolas Schier nicolas@jasle.eu Signed-off-by: Li Yang leoyang.li@nxp.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/fsl/qe/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/soc/fsl/qe/Kconfig b/drivers/soc/fsl/qe/Kconfig index 357c5800b112f..7afa796dbbb89 100644 --- a/drivers/soc/fsl/qe/Kconfig +++ b/drivers/soc/fsl/qe/Kconfig @@ -39,6 +39,7 @@ config QE_TDM
config QE_USB bool + depends on QUICC_ENGINE default y if USB_FSL_QE help QE USB Controller support
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit b002760f877c0d91ecd3c78565b52f4bbac379dd ]
Commit df8fc4e934c1 ("kbuild: Enable -fstrict-flex-arrays=3") triggers a warning for fortified memset():
In function 'fortify_memset_chk', inlined from 'irdma_clr_wqes' at drivers/infiniband/hw/irdma/uk.c:103:4: include/linux/fortify-string.h:493:25: error: call to '__write_overflow_field' declared with attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror=attribute-warning] 493 | __write_overflow_field(p_size_field, size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The problem here isthat the inner array only has four 8-byte elements, so clearing 4096 bytes overflows that. As this structure is part of an outer array, change the code to pass a pointer to the irdma_qp_quanta instead, and change the size argument for readability, matching the comment above it.
Fixes: 551c46edc769 ("RDMA/irdma: Add user/kernel shared libraries") Link: https://lore.kernel.org/r/20230523111859.2197825-1-arnd@kernel.org Signed-off-by: Arnd Bergmann arnd@arndb.de Acked-by: Shiraz Saleem shiraz.saleem@intel.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/irdma/uk.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/infiniband/hw/irdma/uk.c b/drivers/infiniband/hw/irdma/uk.c index 16183e894da77..dd428d915c175 100644 --- a/drivers/infiniband/hw/irdma/uk.c +++ b/drivers/infiniband/hw/irdma/uk.c @@ -93,16 +93,18 @@ static int irdma_nop_1(struct irdma_qp_uk *qp) */ void irdma_clr_wqes(struct irdma_qp_uk *qp, u32 qp_wqe_idx) { - __le64 *wqe; + struct irdma_qp_quanta *sq; u32 wqe_idx;
if (!(qp_wqe_idx & 0x7F)) { wqe_idx = (qp_wqe_idx + 128) % qp->sq_ring.size; - wqe = qp->sq_base[wqe_idx].elem; + sq = qp->sq_base + wqe_idx; if (wqe_idx) - memset(wqe, qp->swqe_polarity ? 0 : 0xFF, 0x1000); + memset(sq, qp->swqe_polarity ? 0 : 0xFF, + 128 * sizeof(*sq)); else - memset(wqe, qp->swqe_polarity ? 0xFF : 0, 0x1000); + memset(sq, qp->swqe_polarity ? 0xFF : 0, + 128 * sizeof(*sq)); } }
From: Brendan Cunningham bcunningham@cornelisnetworks.com
[ Upstream commit c9358de193ecfb360c3ce75f27ce839ca0b0bc8c ]
The hfi1 user SDMA pinned-page cache will leave a stale cache entry when the cache-entry's virtual address range is invalidated but that cache entry is in-use by an outstanding SDMA request.
Subsequent user SDMA requests with buffers in or spanning the virtual address range of the stale cache entry will result in packets constructed from the wrong memory, the physical pages pointed to by the stale cache entry.
To fix this, remove mmu_rb_node cache entries from the mmu_rb_handler cache independent of the cache entry's refcount. Add 'struct kref refcount' to struct mmu_rb_node and manage mmu_rb_node lifetime with kref_get() and kref_put().
mmu_rb_node.refcount makes sdma_mmu_node.refcount redundant. Remove 'atomic_t refcount' from struct sdma_mmu_node and change sdma_mmu_node code to use mmu_rb_node.refcount.
Move the mmu_rb_handler destructor call after a wait-for-SDMA-request-completion call so mmu_rb_nodes that need mmu_rb_handler's workqueue to queue themselves up for destruction from an interrupt context may do so.
Fixes: f48ad614c100 ("IB/hfi1: Move driver out of staging") Fixes: 00cbce5cbf88 ("IB/hfi1: Fix bugs with non-PAGE_SIZE-end multi-iovec user SDMA requests") Link: https://lore.kernel.org/r/168451393605.3700681.13493776139032178861.stgit@aw... Reviewed-by: Dean Luick dean.luick@cornelisnetworks.com Signed-off-by: Brendan Cunningham bcunningham@cornelisnetworks.com Signed-off-by: Dennis Dalessandro dennis.dalessandro@cornelisnetworks.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hfi1/ipoib_tx.c | 4 +- drivers/infiniband/hw/hfi1/mmu_rb.c | 101 ++++++++++------- drivers/infiniband/hw/hfi1/mmu_rb.h | 3 + drivers/infiniband/hw/hfi1/sdma.c | 23 +++- drivers/infiniband/hw/hfi1/sdma.h | 47 +++++--- drivers/infiniband/hw/hfi1/sdma_txreq.h | 2 + drivers/infiniband/hw/hfi1/user_sdma.c | 137 ++++++++++-------------- drivers/infiniband/hw/hfi1/user_sdma.h | 1 - drivers/infiniband/hw/hfi1/vnic_sdma.c | 4 +- 9 files changed, 177 insertions(+), 145 deletions(-)
diff --git a/drivers/infiniband/hw/hfi1/ipoib_tx.c b/drivers/infiniband/hw/hfi1/ipoib_tx.c index 8973a081d641e..e7d831330278d 100644 --- a/drivers/infiniband/hw/hfi1/ipoib_tx.c +++ b/drivers/infiniband/hw/hfi1/ipoib_tx.c @@ -215,11 +215,11 @@ static int hfi1_ipoib_build_ulp_payload(struct ipoib_txreq *tx, const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
ret = sdma_txadd_page(dd, - NULL, txreq, skb_frag_page(frag), frag->bv_offset, - skb_frag_size(frag)); + skb_frag_size(frag), + NULL, NULL, NULL); if (unlikely(ret)) break; } diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c index 71b9ac0188875..94f1701667301 100644 --- a/drivers/infiniband/hw/hfi1/mmu_rb.c +++ b/drivers/infiniband/hw/hfi1/mmu_rb.c @@ -19,8 +19,7 @@ static int mmu_notifier_range_start(struct mmu_notifier *, const struct mmu_notifier_range *); static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *, unsigned long, unsigned long); -static void do_remove(struct mmu_rb_handler *handler, - struct list_head *del_list); +static void release_immediate(struct kref *refcount); static void handle_remove(struct work_struct *work);
static const struct mmu_notifier_ops mn_opts = { @@ -103,7 +102,11 @@ void hfi1_mmu_rb_unregister(struct mmu_rb_handler *handler) } spin_unlock_irqrestore(&handler->lock, flags);
- do_remove(handler, &del_list); + while (!list_empty(&del_list)) { + rbnode = list_first_entry(&del_list, struct mmu_rb_node, list); + list_del(&rbnode->list); + kref_put(&rbnode->refcount, release_immediate); + }
/* Now the mm may be freed. */ mmdrop(handler->mn.mm); @@ -131,12 +134,6 @@ int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler, } __mmu_int_rb_insert(mnode, &handler->root); list_add_tail(&mnode->list, &handler->lru_list); - - ret = handler->ops->insert(handler->ops_arg, mnode); - if (ret) { - __mmu_int_rb_remove(mnode, &handler->root); - list_del(&mnode->list); /* remove from LRU list */ - } mnode->handler = handler; unlock: spin_unlock_irqrestore(&handler->lock, flags); @@ -180,6 +177,48 @@ static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler, return node; }
+/* + * Must NOT call while holding mnode->handler->lock. + * mnode->handler->ops->remove() may sleep and mnode->handler->lock is a + * spinlock. + */ +static void release_immediate(struct kref *refcount) +{ + struct mmu_rb_node *mnode = + container_of(refcount, struct mmu_rb_node, refcount); + mnode->handler->ops->remove(mnode->handler->ops_arg, mnode); +} + +/* Caller must hold mnode->handler->lock */ +static void release_nolock(struct kref *refcount) +{ + struct mmu_rb_node *mnode = + container_of(refcount, struct mmu_rb_node, refcount); + list_move(&mnode->list, &mnode->handler->del_list); + queue_work(mnode->handler->wq, &mnode->handler->del_work); +} + +/* + * struct mmu_rb_node->refcount kref_put() callback. + * Adds mmu_rb_node to mmu_rb_node->handler->del_list and queues + * handler->del_work on handler->wq. + * Does not remove mmu_rb_node from handler->lru_list or handler->rb_root. + * Acquires mmu_rb_node->handler->lock; do not call while already holding + * handler->lock. + */ +void hfi1_mmu_rb_release(struct kref *refcount) +{ + struct mmu_rb_node *mnode = + container_of(refcount, struct mmu_rb_node, refcount); + struct mmu_rb_handler *handler = mnode->handler; + unsigned long flags; + + spin_lock_irqsave(&handler->lock, flags); + list_move(&mnode->list, &mnode->handler->del_list); + spin_unlock_irqrestore(&handler->lock, flags); + queue_work(handler->wq, &handler->del_work); +} + void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg) { struct mmu_rb_node *rbnode, *ptr; @@ -194,6 +233,10 @@ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg)
spin_lock_irqsave(&handler->lock, flags); list_for_each_entry_safe(rbnode, ptr, &handler->lru_list, list) { + /* refcount == 1 implies mmu_rb_handler has only rbnode ref */ + if (kref_read(&rbnode->refcount) > 1) + continue; + if (handler->ops->evict(handler->ops_arg, rbnode, evict_arg, &stop)) { __mmu_int_rb_remove(rbnode, &handler->root); @@ -206,7 +249,7 @@ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg) spin_unlock_irqrestore(&handler->lock, flags);
list_for_each_entry_safe(rbnode, ptr, &del_list, list) { - handler->ops->remove(handler->ops_arg, rbnode); + kref_put(&rbnode->refcount, release_immediate); } }
@@ -218,7 +261,6 @@ static int mmu_notifier_range_start(struct mmu_notifier *mn, struct rb_root_cached *root = &handler->root; struct mmu_rb_node *node, *ptr = NULL; unsigned long flags; - bool added = false;
spin_lock_irqsave(&handler->lock, flags); for (node = __mmu_int_rb_iter_first(root, range->start, range->end-1); @@ -227,38 +269,16 @@ static int mmu_notifier_range_start(struct mmu_notifier *mn, ptr = __mmu_int_rb_iter_next(node, range->start, range->end - 1); trace_hfi1_mmu_mem_invalidate(node->addr, node->len); - if (handler->ops->invalidate(handler->ops_arg, node)) { - __mmu_int_rb_remove(node, root); - /* move from LRU list to delete list */ - list_move(&node->list, &handler->del_list); - added = true; - } + /* Remove from rb tree and lru_list. */ + __mmu_int_rb_remove(node, root); + list_del_init(&node->list); + kref_put(&node->refcount, release_nolock); } spin_unlock_irqrestore(&handler->lock, flags);
- if (added) - queue_work(handler->wq, &handler->del_work); - return 0; }
-/* - * Call the remove function for the given handler and the list. This - * is expected to be called with a delete list extracted from handler. - * The caller should not be holding the handler lock. - */ -static void do_remove(struct mmu_rb_handler *handler, - struct list_head *del_list) -{ - struct mmu_rb_node *node; - - while (!list_empty(del_list)) { - node = list_first_entry(del_list, struct mmu_rb_node, list); - list_del(&node->list); - handler->ops->remove(handler->ops_arg, node); - } -} - /* * Work queue function to remove all nodes that have been queued up to * be removed. The key feature is that mm->mmap_lock is not being held @@ -271,11 +291,16 @@ static void handle_remove(struct work_struct *work) del_work); struct list_head del_list; unsigned long flags; + struct mmu_rb_node *node;
/* remove anything that is queued to get removed */ spin_lock_irqsave(&handler->lock, flags); list_replace_init(&handler->del_list, &del_list); spin_unlock_irqrestore(&handler->lock, flags);
- do_remove(handler, &del_list); + while (!list_empty(&del_list)) { + node = list_first_entry(&del_list, struct mmu_rb_node, list); + list_del(&node->list); + handler->ops->remove(handler->ops_arg, node); + } } diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.h b/drivers/infiniband/hw/hfi1/mmu_rb.h index ed75acdb7b839..dd2c4a0ae95b1 100644 --- a/drivers/infiniband/hw/hfi1/mmu_rb.h +++ b/drivers/infiniband/hw/hfi1/mmu_rb.h @@ -16,6 +16,7 @@ struct mmu_rb_node { struct rb_node node; struct mmu_rb_handler *handler; struct list_head list; + struct kref refcount; };
/* @@ -51,6 +52,8 @@ int hfi1_mmu_rb_register(void *ops_arg, void hfi1_mmu_rb_unregister(struct mmu_rb_handler *handler); int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler, struct mmu_rb_node *mnode); +void hfi1_mmu_rb_release(struct kref *refcount); + void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg); struct mmu_rb_node *hfi1_mmu_rb_get_first(struct mmu_rb_handler *handler, unsigned long addr, diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c index bb2552dd29c1e..26c62162759ba 100644 --- a/drivers/infiniband/hw/hfi1/sdma.c +++ b/drivers/infiniband/hw/hfi1/sdma.c @@ -1593,7 +1593,20 @@ static inline void sdma_unmap_desc( struct hfi1_devdata *dd, struct sdma_desc *descp) { - system_descriptor_complete(dd, descp); + switch (sdma_mapping_type(descp)) { + case SDMA_MAP_SINGLE: + dma_unmap_single(&dd->pcidev->dev, sdma_mapping_addr(descp), + sdma_mapping_len(descp), DMA_TO_DEVICE); + break; + case SDMA_MAP_PAGE: + dma_unmap_page(&dd->pcidev->dev, sdma_mapping_addr(descp), + sdma_mapping_len(descp), DMA_TO_DEVICE); + break; + } + + if (descp->pinning_ctx && descp->ctx_put) + descp->ctx_put(descp->pinning_ctx); + descp->pinning_ctx = NULL; }
/* @@ -3113,8 +3126,8 @@ int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx,
/* Add descriptor for coalesce buffer */ tx->desc_limit = MAX_DESC; - return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, NULL, tx, - addr, tx->tlen); + return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, tx, + addr, tx->tlen, NULL, NULL, NULL); }
return 1; @@ -3157,9 +3170,9 @@ int _pad_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx) make_tx_sdma_desc( tx, SDMA_MAP_NONE, - NULL, dd->sdma_pad_phys, - sizeof(u32) - (tx->packet_len & (sizeof(u32) - 1))); + sizeof(u32) - (tx->packet_len & (sizeof(u32) - 1)), + NULL, NULL, NULL); tx->num_desc++; _sdma_close_tx(dd, tx); return rval; diff --git a/drivers/infiniband/hw/hfi1/sdma.h b/drivers/infiniband/hw/hfi1/sdma.h index 95aaec14c6c28..7fdebab202c4f 100644 --- a/drivers/infiniband/hw/hfi1/sdma.h +++ b/drivers/infiniband/hw/hfi1/sdma.h @@ -594,9 +594,11 @@ static inline dma_addr_t sdma_mapping_addr(struct sdma_desc *d) static inline void make_tx_sdma_desc( struct sdma_txreq *tx, int type, - void *pinning_ctx, dma_addr_t addr, - size_t len) + size_t len, + void *pinning_ctx, + void (*ctx_get)(void *), + void (*ctx_put)(void *)) { struct sdma_desc *desc = &tx->descp[tx->num_desc];
@@ -613,7 +615,11 @@ static inline void make_tx_sdma_desc( << SDMA_DESC0_PHY_ADDR_SHIFT) | (((u64)len & SDMA_DESC0_BYTE_COUNT_MASK) << SDMA_DESC0_BYTE_COUNT_SHIFT); + desc->pinning_ctx = pinning_ctx; + desc->ctx_put = ctx_put; + if (pinning_ctx && ctx_get) + ctx_get(pinning_ctx); }
/* helper to extend txreq */ @@ -645,18 +651,20 @@ static inline void _sdma_close_tx(struct hfi1_devdata *dd, static inline int _sdma_txadd_daddr( struct hfi1_devdata *dd, int type, - void *pinning_ctx, struct sdma_txreq *tx, dma_addr_t addr, - u16 len) + u16 len, + void *pinning_ctx, + void (*ctx_get)(void *), + void (*ctx_put)(void *)) { int rval = 0;
make_tx_sdma_desc( tx, type, - pinning_ctx, - addr, len); + addr, len, + pinning_ctx, ctx_get, ctx_put); WARN_ON(len > tx->tlen); tx->num_desc++; tx->tlen -= len; @@ -676,11 +684,18 @@ static inline int _sdma_txadd_daddr( /** * sdma_txadd_page() - add a page to the sdma_txreq * @dd: the device to use for mapping - * @pinning_ctx: context to be released at descriptor retirement * @tx: tx request to which the page is added * @page: page to map * @offset: offset within the page * @len: length in bytes + * @pinning_ctx: context to be stored on struct sdma_desc .pinning_ctx. Not + * added if coalesce buffer is used. E.g. pointer to pinned-page + * cache entry for the sdma_desc. + * @ctx_get: optional function to take reference to @pinning_ctx. Not called if + * @pinning_ctx is NULL. + * @ctx_put: optional function to release reference to @pinning_ctx after + * sdma_desc completes. May be called in interrupt context so must + * not sleep. Not called if @pinning_ctx is NULL. * * This is used to add a page/offset/length descriptor. * @@ -692,11 +707,13 @@ static inline int _sdma_txadd_daddr( */ static inline int sdma_txadd_page( struct hfi1_devdata *dd, - void *pinning_ctx, struct sdma_txreq *tx, struct page *page, unsigned long offset, - u16 len) + u16 len, + void *pinning_ctx, + void (*ctx_get)(void *), + void (*ctx_put)(void *)) { dma_addr_t addr; int rval; @@ -720,7 +737,8 @@ static inline int sdma_txadd_page( return -ENOSPC; }
- return _sdma_txadd_daddr(dd, SDMA_MAP_PAGE, pinning_ctx, tx, addr, len); + return _sdma_txadd_daddr(dd, SDMA_MAP_PAGE, tx, addr, len, + pinning_ctx, ctx_get, ctx_put); }
/** @@ -754,8 +772,8 @@ static inline int sdma_txadd_daddr( return rval; }
- return _sdma_txadd_daddr(dd, SDMA_MAP_NONE, NULL, tx, - addr, len); + return _sdma_txadd_daddr(dd, SDMA_MAP_NONE, tx, addr, len, + NULL, NULL, NULL); }
/** @@ -801,7 +819,8 @@ static inline int sdma_txadd_kvaddr( return -ENOSPC; }
- return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, NULL, tx, addr, len); + return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, tx, addr, len, + NULL, NULL, NULL); }
struct iowait_work; @@ -1034,6 +1053,4 @@ u16 sdma_get_descq_cnt(void); extern uint mod_num_sdma;
void sdma_update_lmc(struct hfi1_devdata *dd, u64 mask, u32 lid); - -void system_descriptor_complete(struct hfi1_devdata *dd, struct sdma_desc *descp); #endif diff --git a/drivers/infiniband/hw/hfi1/sdma_txreq.h b/drivers/infiniband/hw/hfi1/sdma_txreq.h index fad946cb5e0d8..85ae7293c2741 100644 --- a/drivers/infiniband/hw/hfi1/sdma_txreq.h +++ b/drivers/infiniband/hw/hfi1/sdma_txreq.h @@ -20,6 +20,8 @@ struct sdma_desc { /* private: don't use directly */ u64 qw[2]; void *pinning_ctx; + /* Release reference to @pinning_ctx. May be called in interrupt context. Must not sleep. */ + void (*ctx_put)(void *ctx); };
/** diff --git a/drivers/infiniband/hw/hfi1/user_sdma.c b/drivers/infiniband/hw/hfi1/user_sdma.c index ae58b48afe074..02bd62b857b75 100644 --- a/drivers/infiniband/hw/hfi1/user_sdma.c +++ b/drivers/infiniband/hw/hfi1/user_sdma.c @@ -62,18 +62,14 @@ static int defer_packet_queue( static void activate_packet_queue(struct iowait *wait, int reason); static bool sdma_rb_filter(struct mmu_rb_node *node, unsigned long addr, unsigned long len); -static int sdma_rb_insert(void *arg, struct mmu_rb_node *mnode); static int sdma_rb_evict(void *arg, struct mmu_rb_node *mnode, void *arg2, bool *stop); static void sdma_rb_remove(void *arg, struct mmu_rb_node *mnode); -static int sdma_rb_invalidate(void *arg, struct mmu_rb_node *mnode);
static struct mmu_rb_ops sdma_rb_ops = { .filter = sdma_rb_filter, - .insert = sdma_rb_insert, .evict = sdma_rb_evict, .remove = sdma_rb_remove, - .invalidate = sdma_rb_invalidate };
static int add_system_pages_to_sdma_packet(struct user_sdma_request *req, @@ -247,14 +243,14 @@ int hfi1_user_sdma_free_queues(struct hfi1_filedata *fd, spin_unlock(&fd->pq_rcu_lock); synchronize_srcu(&fd->pq_srcu); /* at this point there can be no more new requests */ - if (pq->handler) - hfi1_mmu_rb_unregister(pq->handler); iowait_sdma_drain(&pq->busy); /* Wait until all requests have been freed. */ wait_event_interruptible( pq->wait, !atomic_read(&pq->n_reqs)); kfree(pq->reqs); + if (pq->handler) + hfi1_mmu_rb_unregister(pq->handler); bitmap_free(pq->req_in_use); kmem_cache_destroy(pq->txreq_cache); flush_pq_iowait(pq); @@ -1275,25 +1271,17 @@ static void free_system_node(struct sdma_mmu_node *node) kfree(node); }
-static inline void acquire_node(struct sdma_mmu_node *node) -{ - atomic_inc(&node->refcount); - WARN_ON(atomic_read(&node->refcount) < 0); -} - -static inline void release_node(struct mmu_rb_handler *handler, - struct sdma_mmu_node *node) -{ - atomic_dec(&node->refcount); - WARN_ON(atomic_read(&node->refcount) < 0); -} - +/* + * kref_get()'s an additional kref on the returned rb_node to prevent rb_node + * from being released until after rb_node is assigned to an SDMA descriptor + * (struct sdma_desc) under add_system_iovec_to_sdma_packet(), even if the + * virtual address range for rb_node is invalidated between now and then. + */ static struct sdma_mmu_node *find_system_node(struct mmu_rb_handler *handler, unsigned long start, unsigned long end) { struct mmu_rb_node *rb_node; - struct sdma_mmu_node *node; unsigned long flags;
spin_lock_irqsave(&handler->lock, flags); @@ -1302,11 +1290,12 @@ static struct sdma_mmu_node *find_system_node(struct mmu_rb_handler *handler, spin_unlock_irqrestore(&handler->lock, flags); return NULL; } - node = container_of(rb_node, struct sdma_mmu_node, rb); - acquire_node(node); + + /* "safety" kref to prevent release before add_system_iovec_to_sdma_packet() */ + kref_get(&rb_node->refcount); spin_unlock_irqrestore(&handler->lock, flags);
- return node; + return container_of(rb_node, struct sdma_mmu_node, rb); }
static int pin_system_pages(struct user_sdma_request *req, @@ -1355,6 +1344,13 @@ static int pin_system_pages(struct user_sdma_request *req, return 0; }
+/* + * kref refcount on *node_p will be 2 on successful addition: one kref from + * kref_init() for mmu_rb_handler and one kref to prevent *node_p from being + * released until after *node_p is assigned to an SDMA descriptor (struct + * sdma_desc) under add_system_iovec_to_sdma_packet(), even if the virtual + * address range for *node_p is invalidated between now and then. + */ static int add_system_pinning(struct user_sdma_request *req, struct sdma_mmu_node **node_p, unsigned long start, unsigned long len) @@ -1368,6 +1364,12 @@ static int add_system_pinning(struct user_sdma_request *req, if (!node) return -ENOMEM;
+ /* First kref "moves" to mmu_rb_handler */ + kref_init(&node->rb.refcount); + + /* "safety" kref to prevent release before add_system_iovec_to_sdma_packet() */ + kref_get(&node->rb.refcount); + node->pq = pq; ret = pin_system_pages(req, start, len, node, PFN_DOWN(len)); if (ret == 0) { @@ -1431,15 +1433,15 @@ static int get_system_cache_entry(struct user_sdma_request *req, return 0; }
- SDMA_DBG(req, "prepend: node->rb.addr %lx, node->refcount %d", - node->rb.addr, atomic_read(&node->refcount)); + SDMA_DBG(req, "prepend: node->rb.addr %lx, node->rb.refcount %d", + node->rb.addr, kref_read(&node->rb.refcount)); prepend_len = node->rb.addr - start;
/* * This node will not be returned, instead a new node * will be. So release the reference. */ - release_node(handler, node); + kref_put(&node->rb.refcount, hfi1_mmu_rb_release);
/* Prepend a node to cover the beginning of the allocation */ ret = add_system_pinning(req, node_p, start, prepend_len); @@ -1451,6 +1453,20 @@ static int get_system_cache_entry(struct user_sdma_request *req, } }
+static void sdma_mmu_rb_node_get(void *ctx) +{ + struct mmu_rb_node *node = ctx; + + kref_get(&node->refcount); +} + +static void sdma_mmu_rb_node_put(void *ctx) +{ + struct sdma_mmu_node *node = ctx; + + kref_put(&node->rb.refcount, hfi1_mmu_rb_release); +} + static int add_mapping_to_sdma_packet(struct user_sdma_request *req, struct user_sdma_txreq *tx, struct sdma_mmu_node *cache_entry, @@ -1494,9 +1510,12 @@ static int add_mapping_to_sdma_packet(struct user_sdma_request *req, ctx = cache_entry; }
- ret = sdma_txadd_page(pq->dd, ctx, &tx->txreq, + ret = sdma_txadd_page(pq->dd, &tx->txreq, cache_entry->pages[page_index], - page_offset, from_this_page); + page_offset, from_this_page, + ctx, + sdma_mmu_rb_node_get, + sdma_mmu_rb_node_put); if (ret) { /* * When there's a failure, the entire request is freed by @@ -1518,8 +1537,6 @@ static int add_system_iovec_to_sdma_packet(struct user_sdma_request *req, struct user_sdma_iovec *iovec, size_t from_this_iovec) { - struct mmu_rb_handler *handler = req->pq->handler; - while (from_this_iovec > 0) { struct sdma_mmu_node *cache_entry; size_t from_this_cache_entry; @@ -1540,15 +1557,15 @@ static int add_system_iovec_to_sdma_packet(struct user_sdma_request *req,
ret = add_mapping_to_sdma_packet(req, tx, cache_entry, start, from_this_cache_entry); + + /* + * Done adding cache_entry to zero or more sdma_desc. Can + * kref_put() the "safety" kref taken under + * get_system_cache_entry(). + */ + kref_put(&cache_entry->rb.refcount, hfi1_mmu_rb_release); + if (ret) { - /* - * We're guaranteed that there will be no descriptor - * completion callback that releases this node - * because only the last descriptor referencing it - * has a context attached, and a failure means the - * last descriptor was never added. - */ - release_node(handler, cache_entry); SDMA_DBG(req, "add system segment failed %d", ret); return ret; } @@ -1599,42 +1616,12 @@ static int add_system_pages_to_sdma_packet(struct user_sdma_request *req, return 0; }
-void system_descriptor_complete(struct hfi1_devdata *dd, - struct sdma_desc *descp) -{ - switch (sdma_mapping_type(descp)) { - case SDMA_MAP_SINGLE: - dma_unmap_single(&dd->pcidev->dev, sdma_mapping_addr(descp), - sdma_mapping_len(descp), DMA_TO_DEVICE); - break; - case SDMA_MAP_PAGE: - dma_unmap_page(&dd->pcidev->dev, sdma_mapping_addr(descp), - sdma_mapping_len(descp), DMA_TO_DEVICE); - break; - } - - if (descp->pinning_ctx) { - struct sdma_mmu_node *node = descp->pinning_ctx; - - release_node(node->rb.handler, node); - } -} - static bool sdma_rb_filter(struct mmu_rb_node *node, unsigned long addr, unsigned long len) { return (bool)(node->addr == addr); }
-static int sdma_rb_insert(void *arg, struct mmu_rb_node *mnode) -{ - struct sdma_mmu_node *node = - container_of(mnode, struct sdma_mmu_node, rb); - - atomic_inc(&node->refcount); - return 0; -} - /* * Return 1 to remove the node from the rb tree and call the remove op. * @@ -1647,10 +1634,6 @@ static int sdma_rb_evict(void *arg, struct mmu_rb_node *mnode, container_of(mnode, struct sdma_mmu_node, rb); struct evict_data *evict_data = evict_arg;
- /* is this node still being used? */ - if (atomic_read(&node->refcount)) - return 0; /* keep this node */ - /* this node will be evicted, add its pages to our count */ evict_data->cleared += node->npages;
@@ -1668,13 +1651,3 @@ static void sdma_rb_remove(void *arg, struct mmu_rb_node *mnode)
free_system_node(node); } - -static int sdma_rb_invalidate(void *arg, struct mmu_rb_node *mnode) -{ - struct sdma_mmu_node *node = - container_of(mnode, struct sdma_mmu_node, rb); - - if (!atomic_read(&node->refcount)) - return 1; - return 0; -} diff --git a/drivers/infiniband/hw/hfi1/user_sdma.h b/drivers/infiniband/hw/hfi1/user_sdma.h index a241836371dc1..548347d4c5bc2 100644 --- a/drivers/infiniband/hw/hfi1/user_sdma.h +++ b/drivers/infiniband/hw/hfi1/user_sdma.h @@ -104,7 +104,6 @@ struct hfi1_user_sdma_comp_q { struct sdma_mmu_node { struct mmu_rb_node rb; struct hfi1_user_sdma_pkt_q *pq; - atomic_t refcount; struct page **pages; unsigned int npages; }; diff --git a/drivers/infiniband/hw/hfi1/vnic_sdma.c b/drivers/infiniband/hw/hfi1/vnic_sdma.c index 727eedfba332a..cc6324d2d1ddc 100644 --- a/drivers/infiniband/hw/hfi1/vnic_sdma.c +++ b/drivers/infiniband/hw/hfi1/vnic_sdma.c @@ -64,11 +64,11 @@ static noinline int build_vnic_ulp_payload(struct sdma_engine *sde,
/* combine physically continuous fragments later? */ ret = sdma_txadd_page(sde->dd, - NULL, &tx->txreq, skb_frag_page(frag), skb_frag_off(frag), - skb_frag_size(frag)); + skb_frag_size(frag), + NULL, NULL, NULL); if (unlikely(ret)) goto bail_txadd; }
From: Chengchang Tang tangchengchang@huawei.com
[ Upstream commit cf5b608fb0e369c473a8303cad6ddb386505e5b8 ]
The return value of set_hem has been fixed to ENODEV, which will lead a diagnostic information missing.
Fixes: 9a4435375cd1 ("IB/hns: Add driver files for hns RoCE driver") Link: https://lore.kernel.org/r/20230523121641.3132102-3-huangjunxian6@hisilicon.c... Signed-off-by: Chengchang Tang tangchengchang@huawei.com Signed-off-by: Junxian Huang huangjunxian6@hisilicon.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hns/hns_roce_hem.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c index aa8a08d1c0145..f30274986c0da 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hem.c +++ b/drivers/infiniband/hw/hns/hns_roce_hem.c @@ -595,11 +595,12 @@ int hns_roce_table_get(struct hns_roce_dev *hr_dev, }
/* Set HEM base address(128K/page, pa) to Hardware */ - if (hr_dev->hw->set_hem(hr_dev, table, obj, HEM_HOP_STEP_DIRECT)) { + ret = hr_dev->hw->set_hem(hr_dev, table, obj, HEM_HOP_STEP_DIRECT); + if (ret) { hns_roce_free_hem(hr_dev, table->hem[i]); table->hem[i] = NULL; - ret = -ENODEV; - dev_err(dev, "set HEM base address to HW failed.\n"); + dev_err(dev, "set HEM base address to HW failed, ret = %d.\n", + ret); goto out; }
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 0501fdec106a291c43b3c1b525cf22ab4c24b2d8 ]
make dtbs_check:
arch/arm/boot/dts/renesas/r8a7743-iwg20d-q7.dtb: backlight: pwms: [[58, 0, 5000000], [0]] is too long From schema: Documentation/devicetree/bindings/leds/backlight/pwm-backlight.yaml arch/arm/boot/dts/renesas/r8a7743-iwg20d-q7-dbcm-ca.dtb: backlight: pwms: [[67, 0, 5000000], [0]] is too long From schema: Documentation/devicetree/bindings/leds/backlight/pwm-backlight.yaml arch/arm/boot/dts/renesas/r8a7744-iwg20d-q7-dbcm-ca.dtb: backlight: pwms: [[67, 0, 5000000], [0]] is too long From schema: Documentation/devicetree/bindings/leds/backlight/pwm-backlight.yaml arch/arm/boot/dts/renesas/r8a7744-iwg20d-q7.dtb: backlight: pwms: [[58, 0, 5000000], [0]] is too long From schema: Documentation/devicetree/bindings/leds/backlight/pwm-backlight.yaml
PWM specifiers referring to R-Car PWM Timer Controllers should contain only two cells.
Fix this by dropping the bogus third cell.
Fixes: 6f89dd9e9325d05b ("ARM: dts: iwg20d-q7-common: Add LCD support") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/6e5c3167424a43faf8c1fa68d9667b3d87dc86d8.168485591... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/iwg20d-q7-common.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/iwg20d-q7-common.dtsi b/arch/arm/boot/dts/iwg20d-q7-common.dtsi index 03caea6fc6ffa..4351c5a02fa59 100644 --- a/arch/arm/boot/dts/iwg20d-q7-common.dtsi +++ b/arch/arm/boot/dts/iwg20d-q7-common.dtsi @@ -49,7 +49,7 @@ audio_clock: audio_clock { lcd_backlight: backlight { compatible = "pwm-backlight";
- pwms = <&pwm3 0 5000000 0>; + pwms = <&pwm3 0 5000000>; brightness-levels = <0 4 8 16 32 64 128 255>; default-brightness-level = <7>; enable-gpios = <&gpio5 14 GPIO_ACTIVE_HIGH>;
From: Wolfram Sang wsa+renesas@sang-engineering.com
[ Upstream commit 1a2c4e5635177939a088d22fa35c6a7032725663 ]
The schematics are misleading, the flow control is for HSCIF1. We need SCIF1 for GNSS/GPS which does not use flow control.
Fixes: c6c816e22bc8 ("arm64: dts: ulcb-kf: enable SCIF1") Signed-off-by: Wolfram Sang wsa+renesas@sang-engineering.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/20230525084823.4195-2-wsa+renesas@sang-engineering... Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi index efc80960380f4..c78b7a5c2e2aa 100644 --- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi +++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi @@ -367,7 +367,7 @@ hscif0_pins: hscif0 { };
scif1_pins: scif1 { - groups = "scif1_data_b", "scif1_ctrl"; + groups = "scif1_data_b"; function = "scif1"; };
@@ -397,7 +397,6 @@ &sound_clk_pins &scif1 { pinctrl-0 = <&scif1_pins>; pinctrl-names = "default"; - uart-has-rtscts;
status = "okay"; };
From: Kuogee Hsieh quic_khsieh@quicinc.com
[ Upstream commit 12cef323c903bd8b13d1f6ff24a9695c2cdc360b ]
The CTL_FLUSH register should be programmed with the 22th bit (DSC_IDX) to flush the DSC hardware blocks, not the literal value of 22 (which corresponds to flushing VIG1, VIG2 and RGB1 instead).
Changes in V12: -- split this patch out of "separate DSC flush update out of interface"
Changes in V13: -- rewording the commit text
Changes in V14: -- drop 'DSC" from "The DSC CTL_FLUSH register" at commit text
Fixes: 77f6da90487c ("drm/msm/disp/dpu1: Add DSC support in hw_ctl") Signed-off-by: Kuogee Hsieh quic_khsieh@quicinc.com Reviewed-by: Marijn Suijten marijn.suijten@somainline.org Patchwork: https://patchwork.freedesktop.org/patch/539496/ Link: https://lore.kernel.org/r/1685036458-22683-2-git-send-email-quic_khsieh@quic... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 6c53ea560ffaa..3ef2e37b41087 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -505,7 +505,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, BIT(cfg->merge_3d - MERGE_3D_0)); if (cfg->dsc) { - DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, DSC_IDX); + DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, BIT(DSC_IDX)); DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc); } }
From: Kuogee Hsieh quic_khsieh@quicinc.com
[ Upstream commit 625cbb077007698060b12d0ae5657a4d8411b153 ]
There are two tiers of pending flush control, top level and individual hardware block. Currently only the top level of flush mask is reset to 0 but the individual pending flush masks of particular hardware blocks are left at their previous values, eventually accumulating all possible bit values and typically flushing more than necessary. Reset all individual hardware block flush masks to 0 to avoid accidentally flushing them.
Changes in V13: -- rewording commit text -- add an empty space line as suggested
Changes in V14: -- add Fixes tag
Fixes: 73bfb790ac78 ("msm:disp:dpu1: setup display datapath for SC7180 target") Signed-off-by: Kuogee Hsieh quic_khsieh@quicinc.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Marijn Suijten marijn.suijten@somainline.org Patchwork: https://patchwork.freedesktop.org/patch/539508/ Link: https://lore.kernel.org/r/1685036458-22683-8-git-send-email-quic_khsieh@quic... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 3ef2e37b41087..4072638c37918 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -115,6 +115,9 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx) trace_dpu_hw_ctl_clear_pending_flush(ctx->pending_flush_mask, dpu_hw_ctl_get_flush_register(ctx)); ctx->pending_flush_mask = 0x0; + ctx->pending_intf_flush_mask = 0; + ctx->pending_wb_flush_mask = 0; + ctx->pending_merge_3d_flush_mask = 0; }
static inline void dpu_hw_ctl_update_pending_flush(struct dpu_hw_ctl *ctx,
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 79a3908d1ea6c35157a6d907b1a9d8ec06015e7a ]
If 'mipid_detect()' fails, we must free 'md' to avoid a memory leak.
Fixes: 66d2f99d0bb5 ("omapfb: add support for MIPI-DCS compatible LCDs") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/fbdev/omap/lcd_mipid.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/video/fbdev/omap/lcd_mipid.c b/drivers/video/fbdev/omap/lcd_mipid.c index 03cff39d392db..cc1079aad61f2 100644 --- a/drivers/video/fbdev/omap/lcd_mipid.c +++ b/drivers/video/fbdev/omap/lcd_mipid.c @@ -563,11 +563,15 @@ static int mipid_spi_probe(struct spi_device *spi)
r = mipid_detect(md); if (r < 0) - return r; + goto free_md;
omapfb_register_panel(&md->panel);
return 0; + +free_md: + kfree(md); + return r; }
static void mipid_spi_remove(struct spi_device *spi)
From: Keerthy j-keerthy@ti.com
[ Upstream commit 3d011933000ed9054c649952d83162d24f020a93 ]
wkup_pmx splits into multiple regions. Like
wkup_pmx0 -> 13 pins (WKUP_PADCONFIG 0 - 12) wkup_pmx1 -> 2 pins (WKUP_PADCONFIG 14 - 15) wkup_pmx2 -> 59 pins (WKUP_PADCONFIG 26 - 84) wkup_pmx3 -> 8 pins (WKUP_PADCONFIG 93 - 100)
With this split, pin offset needs to be adjusted to match with new pmx for all pins above wkup_pmx0.
Example a pin under wkup_pmx1 should start from 0 instead of old offset(0x38 WKUP_PADCONFIG 14 offset)
J7200 Datasheet (Table 6-106, Section 6.4 Pin Multiplexing) : https://www.ti.com/lit/ds/symlink/dra821u.pdf
Fixes: 9ae21ac445e9 ("arm64: dts: ti: k3-j7200: Fix wakeup pinmux range")
Signed-off-by: Keerthy j-keerthy@ti.com Signed-off-by: Udit Kumar u-kumar1@ti.com Link: https://lore.kernel.org/r/20230419040007.3022780-2-u-kumar1@ti.com Signed-off-by: Vignesh Raghavendra vigneshr@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../dts/ti/k3-j7200-common-proc-board.dts | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts index 0d39d6b8cc0ca..63633e4f6c59f 100644 --- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts +++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts @@ -83,25 +83,25 @@ vdd_sd_dv: gpio-regulator-TLV71033 { &wkup_pmx2 { mcu_cpsw_pins_default: mcu-cpsw-pins-default { pinctrl-single,pins = < - J721E_WKUP_IOPAD(0x0068, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */ - J721E_WKUP_IOPAD(0x006c, PIN_INPUT, 0) /* MCU_RGMII1_RX_CTL */ - J721E_WKUP_IOPAD(0x0070, PIN_OUTPUT, 0) /* MCU_RGMII1_TD3 */ - J721E_WKUP_IOPAD(0x0074, PIN_OUTPUT, 0) /* MCU_RGMII1_TD2 */ - J721E_WKUP_IOPAD(0x0078, PIN_OUTPUT, 0) /* MCU_RGMII1_TD1 */ - J721E_WKUP_IOPAD(0x007c, PIN_OUTPUT, 0) /* MCU_RGMII1_TD0 */ - J721E_WKUP_IOPAD(0x0088, PIN_INPUT, 0) /* MCU_RGMII1_RD3 */ - J721E_WKUP_IOPAD(0x008c, PIN_INPUT, 0) /* MCU_RGMII1_RD2 */ - J721E_WKUP_IOPAD(0x0090, PIN_INPUT, 0) /* MCU_RGMII1_RD1 */ - J721E_WKUP_IOPAD(0x0094, PIN_INPUT, 0) /* MCU_RGMII1_RD0 */ - J721E_WKUP_IOPAD(0x0080, PIN_OUTPUT, 0) /* MCU_RGMII1_TXC */ - J721E_WKUP_IOPAD(0x0084, PIN_INPUT, 0) /* MCU_RGMII1_RXC */ + J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */ + J721E_WKUP_IOPAD(0x0004, PIN_INPUT, 0) /* MCU_RGMII1_RX_CTL */ + J721E_WKUP_IOPAD(0x0008, PIN_OUTPUT, 0) /* MCU_RGMII1_TD3 */ + J721E_WKUP_IOPAD(0x000c, PIN_OUTPUT, 0) /* MCU_RGMII1_TD2 */ + J721E_WKUP_IOPAD(0x0010, PIN_OUTPUT, 0) /* MCU_RGMII1_TD1 */ + J721E_WKUP_IOPAD(0x0014, PIN_OUTPUT, 0) /* MCU_RGMII1_TD0 */ + J721E_WKUP_IOPAD(0x0020, PIN_INPUT, 0) /* MCU_RGMII1_RD3 */ + J721E_WKUP_IOPAD(0x0024, PIN_INPUT, 0) /* MCU_RGMII1_RD2 */ + J721E_WKUP_IOPAD(0x0028, PIN_INPUT, 0) /* MCU_RGMII1_RD1 */ + J721E_WKUP_IOPAD(0x002c, PIN_INPUT, 0) /* MCU_RGMII1_RD0 */ + J721E_WKUP_IOPAD(0x0018, PIN_OUTPUT, 0) /* MCU_RGMII1_TXC */ + J721E_WKUP_IOPAD(0x001c, PIN_INPUT, 0) /* MCU_RGMII1_RXC */ >; };
mcu_mdio_pins_default: mcu-mdio1-pins-default { pinctrl-single,pins = < - J721E_WKUP_IOPAD(0x009c, PIN_OUTPUT, 0) /* (L1) MCU_MDIO0_MDC */ - J721E_WKUP_IOPAD(0x0098, PIN_INPUT, 0) /* (L4) MCU_MDIO0_MDIO */ + J721E_WKUP_IOPAD(0x0034, PIN_OUTPUT, 0) /* (L1) MCU_MDIO0_MDC */ + J721E_WKUP_IOPAD(0x0030, PIN_INPUT, 0) /* (L4) MCU_MDIO0_MDIO */ >; }; };
From: Caleb Connolly caleb.connolly@linaro.org
[ Upstream commit 8c9cce9cb81b5fdc6e66bf3f129727b89e8daab7 ]
Since PM8998/PM660, the power key debounce register was redefined to support shorter debounce times. On PM8941 the shortest debounce time (represented by register value 0) was 15625us, on PM8998 the shortest debounce time is 62us, with the default being 2ms.
Adjust the bit shift to correctly program debounce on PM8998 and newer.
Fixes: 68c581d5e7d8 ("Input: add Qualcomm PM8941 power key driver") Signed-off-by: Caleb Connolly caleb.connolly@linaro.org Link: https://lore.kernel.org/r/20230529-pm8941-pwrkey-debounce-v1-2-c043a6d5c814@... Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/input/misc/pm8941-pwrkey.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/input/misc/pm8941-pwrkey.c b/drivers/input/misc/pm8941-pwrkey.c index b6a27ebae977b..74d77d8aaeff2 100644 --- a/drivers/input/misc/pm8941-pwrkey.c +++ b/drivers/input/misc/pm8941-pwrkey.c @@ -50,7 +50,10 @@ #define PON_RESIN_PULL_UP BIT(0)
#define PON_DBC_CTL 0x71 -#define PON_DBC_DELAY_MASK 0x7 +#define PON_DBC_DELAY_MASK_GEN1 0x7 +#define PON_DBC_DELAY_MASK_GEN2 0xf +#define PON_DBC_SHIFT_GEN1 6 +#define PON_DBC_SHIFT_GEN2 14
struct pm8941_data { unsigned int pull_up_bit; @@ -247,7 +250,7 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev) struct device *parent; struct device_node *regmap_node; const __be32 *addr; - u32 req_delay; + u32 req_delay, mask, delay_shift; int error;
if (of_property_read_u32(pdev->dev.of_node, "debounce", &req_delay)) @@ -336,12 +339,20 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev) pwrkey->input->phys = pwrkey->data->phys;
if (pwrkey->data->supports_debounce_config) { - req_delay = (req_delay << 6) / USEC_PER_SEC; + if (pwrkey->subtype >= PON_SUBTYPE_GEN2_PRIMARY) { + mask = PON_DBC_DELAY_MASK_GEN2; + delay_shift = PON_DBC_SHIFT_GEN2; + } else { + mask = PON_DBC_DELAY_MASK_GEN1; + delay_shift = PON_DBC_SHIFT_GEN1; + } + + req_delay = (req_delay << delay_shift) / USEC_PER_SEC; req_delay = ilog2(req_delay);
error = regmap_update_bits(pwrkey->regmap, pwrkey->baseaddr + PON_DBC_CTL, - PON_DBC_DELAY_MASK, + mask, req_delay); if (error) { dev_err(&pdev->dev, "failed to set debounce: %d\n",
From: Marek Vasut marex@denx.de
[ Upstream commit e3f2778b1b6ced649bffdc7cbb05b80bb92f2108 ]
The audio routing flow is not correct, the flow should be from source (second element in the pair) to sink (first element in the pair). The flow now is from "HP_OUT" to "Playback", where "Playback" is source and "HP_OUT" is sink, i.e. the direction is swapped and there is no direct link between the two either.
Fill in the correct routing, where "HP_OUT" supplies the "Headphone Jack", "Line In Jack" supplies "LINE_IN" input, "Microphone Jack" supplies "MIC_IN" input and "Mic Bias" supplies "Microphone Jack".
Fixes: 34e0c7847dcf ("ARM: dts: stm32: Add DH Electronics DHCOM STM32MP1 SoM and PDK2 board") Signed-off-by: Marek Vasut marex@denx.de Signed-off-by: Alexandre Torgue alexandre.torgue@foss.st.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi index 4709677151aac..46b87a27d8b37 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi @@ -137,10 +137,13 @@ reg_panel_supply: regulator-panel-supply {
sound { compatible = "audio-graph-card"; - routing = - "MIC_IN", "Capture", - "Capture", "Mic Bias", - "Playback", "HP_OUT"; + widgets = "Headphone", "Headphone Jack", + "Line", "Line In Jack", + "Microphone", "Microphone Jack"; + routing = "Headphone Jack", "HP_OUT", + "LINE_IN", "Line In Jack", + "MIC_IN", "Microphone Jack", + "Microphone Jack", "Mic Bias"; dais = <&sai2a_port &sai2b_port>; status = "okay"; };
From: Olivier Moysan olivier.moysan@foss.st.com
[ Upstream commit 076c74c592cabe4a47537fe5205b5b678bed010d ]
Use "dai-format" to configure DAI audio format as specified in audio-graph-port.yaml bindings.
Fixes: 144d1ba70548 ("ARM: dts: stm32: Adapt STM32MP157 DK boards to stm32 DT diversity") Signed-off-by: Olivier Moysan olivier.moysan@foss.st.com Signed-off-by: Alexandre Torgue alexandre.torgue@foss.st.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/stm32mp15xx-dkx.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi index 11370ae0d868b..030b7ace63f1e 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi @@ -438,7 +438,7 @@ &i2s2 { i2s2_port: port { i2s2_endpoint: endpoint { remote-endpoint = <&sii9022_tx_endpoint>; - format = "i2s"; + dai-format = "i2s"; mclk-fs = <256>; }; };
From: Tim Harvey tharvey@gateworks.com
[ Upstream commit a6d80df47ee2c69db99e4f2f8871aa4db154620b ]
The GSC fan pwm temperature register is in centidegrees celcius but the Linux hwmon convention is to use milidegrees celcius. Fix the scaling.
Fixes: 3bce5377ef66 ("hwmon: Add Gateworks System Controller support") Signed-off-by: Tim Harvey tharvey@gateworks.com Link: https://lore.kernel.org/r/20230606153004.1448086-1-tharvey@gateworks.com Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/gsc-hwmon.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/gsc-hwmon.c b/drivers/hwmon/gsc-hwmon.c index 73e5d92b200b0..1501ceb551e79 100644 --- a/drivers/hwmon/gsc-hwmon.c +++ b/drivers/hwmon/gsc-hwmon.c @@ -82,8 +82,8 @@ static ssize_t pwm_auto_point_temp_store(struct device *dev, if (kstrtol(buf, 10, &temp)) return -EINVAL;
- temp = clamp_val(temp, 0, 10000); - temp = DIV_ROUND_CLOSEST(temp, 10); + temp = clamp_val(temp, 0, 100000); + temp = DIV_ROUND_CLOSEST(temp, 100);
regs[0] = temp & 0xff; regs[1] = (temp >> 8) & 0xff; @@ -100,7 +100,7 @@ static ssize_t pwm_auto_point_pwm_show(struct device *dev, { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- return sprintf(buf, "%d\n", 255 * (50 + (attr->index * 10)) / 100); + return sprintf(buf, "%d\n", 255 * (50 + (attr->index * 10))); }
static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point1_pwm, pwm_auto_point_pwm, 0);
From: Guenter Roeck linux@roeck-us.net
[ Upstream commit b153a0bb4199566abd337119207f82b59a8cd1ca ]
The PMON_CONFIG register on ADM1272 is a 16 bit register. Writing a 8 bit value into it clears the upper 8 bits of the register, resulting in unexpected side effects. Fix by writing the 16 bit register value.
Also, it has been reported that temperature readings are sometimes widely inaccurate, to the point where readings may result in device shutdown due to errant overtemperature faults. Improve by enabling temperature sampling.
While at it, move the common code for ADM1272 and ADM1278 into a separate function, and clarify in the error message that an attempt was made to enable both VOUT and temperature monitoring.
Last but not least, return the error code reported by the underlying I2C controller and not -ENODEV if updating the PMON_CONFIG register fails. After all, this does not indicate that the chip is not present, but an error in the communication with the chip.
Fixes: 4ff0ce227a1e ("hwmon: (pmbus/adm1275) Add support for ADM1272") Fixes: 9da9c2dc57b2 ("hwmon: (adm1275) enable adm1272 temperature reporting") Signed-off-by: Guenter Roeck linux@roeck-us.net Link: https://lore.kernel.org/r/20230602213447.3557346-1-linux@roeck-us.net Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/pmbus/adm1275.c | 52 +++++++++++++++++------------------ 1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c index 3b07bfb43e937..b8543c06d022a 100644 --- a/drivers/hwmon/pmbus/adm1275.c +++ b/drivers/hwmon/pmbus/adm1275.c @@ -37,10 +37,13 @@ enum chips { adm1075, adm1272, adm1275, adm1276, adm1278, adm1293, adm1294 };
#define ADM1272_IRANGE BIT(0)
+#define ADM1278_TSFILT BIT(15) #define ADM1278_TEMP1_EN BIT(3) #define ADM1278_VIN_EN BIT(2) #define ADM1278_VOUT_EN BIT(1)
+#define ADM1278_PMON_DEFCONFIG (ADM1278_VOUT_EN | ADM1278_TEMP1_EN | ADM1278_TSFILT) + #define ADM1293_IRANGE_25 0 #define ADM1293_IRANGE_50 BIT(6) #define ADM1293_IRANGE_100 BIT(7) @@ -462,6 +465,22 @@ static const struct i2c_device_id adm1275_id[] = { }; MODULE_DEVICE_TABLE(i2c, adm1275_id);
+/* Enable VOUT & TEMP1 if not enabled (disabled by default) */ +static int adm1275_enable_vout_temp(struct i2c_client *client, int config) +{ + int ret; + + if ((config & ADM1278_PMON_DEFCONFIG) != ADM1278_PMON_DEFCONFIG) { + config |= ADM1278_PMON_DEFCONFIG; + ret = i2c_smbus_write_word_data(client, ADM1275_PMON_CONFIG, config); + if (ret < 0) { + dev_err(&client->dev, "Failed to enable VOUT/TEMP1 monitoring\n"); + return ret; + } + } + return 0; +} + static int adm1275_probe(struct i2c_client *client) { s32 (*config_read_fn)(const struct i2c_client *client, u8 reg); @@ -615,19 +634,10 @@ static int adm1275_probe(struct i2c_client *client) PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
- /* Enable VOUT & TEMP1 if not enabled (disabled by default) */ - if ((config & (ADM1278_VOUT_EN | ADM1278_TEMP1_EN)) != - (ADM1278_VOUT_EN | ADM1278_TEMP1_EN)) { - config |= ADM1278_VOUT_EN | ADM1278_TEMP1_EN; - ret = i2c_smbus_write_byte_data(client, - ADM1275_PMON_CONFIG, - config); - if (ret < 0) { - dev_err(&client->dev, - "Failed to enable VOUT monitoring\n"); - return -ENODEV; - } - } + ret = adm1275_enable_vout_temp(client, config); + if (ret) + return ret; + if (config & ADM1278_VIN_EN) info->func[0] |= PMBUS_HAVE_VIN; break; @@ -684,19 +694,9 @@ static int adm1275_probe(struct i2c_client *client) PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
- /* Enable VOUT & TEMP1 if not enabled (disabled by default) */ - if ((config & (ADM1278_VOUT_EN | ADM1278_TEMP1_EN)) != - (ADM1278_VOUT_EN | ADM1278_TEMP1_EN)) { - config |= ADM1278_VOUT_EN | ADM1278_TEMP1_EN; - ret = i2c_smbus_write_word_data(client, - ADM1275_PMON_CONFIG, - config); - if (ret < 0) { - dev_err(&client->dev, - "Failed to enable VOUT monitoring\n"); - return -ENODEV; - } - } + ret = adm1275_enable_vout_temp(client, config); + if (ret) + return ret;
if (config & ADM1278_VIN_EN) info->func[0] |= PMBUS_HAVE_VIN;
From: Christian Lamparter chunkeey@gmail.com
[ Upstream commit fd274b733bfdde3ca72f0fa2a37f032f3a8c402c ]
this typo was found by the dtbs_check | ports:port@5:fixed-link: 'oneOf' conditional failed, | {'speed': [[1000]], 'duplex-full': True} is not of type 'array' | 'duplex-full' does not match any of the regexes: 'pinctrl-[0-]..."
this should have been full-duplex;
Fixes: 935327a73553 ("ARM: dts: BCM5301X: Add DT for Meraki MR26") Fixes: ec88a9c344d9 ("ARM: BCM5301X: Add DT for Meraki MR32") Signed-off-by: Christian Lamparter chunkeey@gmail.com Link: https://lore.kernel.org/r/50522f45566951a9eabd22820647924cc6b4a264.168623855... Signed-off-by: Florian Fainelli florian.fainelli@broadcom.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 2 +- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts index 14f58033efeb9..ca2266b936ee2 100644 --- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts +++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts @@ -128,7 +128,7 @@ port@5 {
fixed-link { speed = <1000>; - duplex-full; + full-duplex; }; }; }; diff --git a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts index 46c2c93b01d88..a34e1746a6c59 100644 --- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts +++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts @@ -187,7 +187,7 @@ port@5 {
fixed-link { speed = <1000>; - duplex-full; + full-duplex; }; }; };
From: Maxime Ripard maxime@cerno.tech
[ Upstream commit ed046ac74da0b5602566073023a1519b5ae657b7 ]
Commit 262ca38f4b6e ("clk: Stop forwarding clk_rate_requests to the parent") introduced the public clk_hw_forward_rate_request() function, but didn't export the symbol. Make sure it's the case.
Fixes: 262ca38f4b6e ("clk: Stop forwarding clk_rate_requests to the parent") Signed-off-by: Maxime Ripard maxime@cerno.tech Link: https://lore.kernel.org/r/20221018-clk-range-checks-fixes-v4-1-971d5077e7d2@... Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index ae07685c7588b..657b27743c4dd 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1547,6 +1547,7 @@ void clk_hw_forward_rate_request(const struct clk_hw *hw, parent->core, req, parent_rate); } +EXPORT_SYMBOL_GPL(clk_hw_forward_rate_request);
static bool clk_core_can_round(struct clk_core * const core) {
From: Paul Cercueil paul@crapouillou.net
[ Upstream commit 08384e80a70fb1942510ab5f0ce27bad134e634e ]
The Device Tree was using invalid node names for the ACT8600 regulators. To be fair, it is not the original committer's fault, as the documentation did gives invalid names as well.
In theory, the fix should have been to modify the driver to accept the alternative names. However, even though the act8865 driver spits warnings, the kernel seemed to work fine with what is currently supported upstream. For that reason, I think it is okay to just update the DTS.
I removed the "regulator-name" too, since they really didn't bring any information. The node names are enough.
Fixes: 73f2b940474d ("MIPS: CI20: DTS: Add I2C nodes") Signed-off-by: Paul Cercueil paul@crapouillou.net Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/boot/dts/ingenic/ci20.dts | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-)
diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts index 239c4537484d0..2b1284c6c64a6 100644 --- a/arch/mips/boot/dts/ingenic/ci20.dts +++ b/arch/mips/boot/dts/ingenic/ci20.dts @@ -237,59 +237,49 @@ &i2c0 { act8600: act8600@5a { compatible = "active-semi,act8600"; reg = <0x5a>; - status = "okay";
regulators { - vddcore: SUDCDC1 { - regulator-name = "DCDC_REG1"; + vddcore: DCDC1 { regulator-min-microvolt = <1100000>; regulator-max-microvolt = <1100000>; regulator-always-on; }; - vddmem: SUDCDC2 { - regulator-name = "DCDC_REG2"; + vddmem: DCDC2 { regulator-min-microvolt = <1500000>; regulator-max-microvolt = <1500000>; regulator-always-on; }; - vcc_33: SUDCDC3 { - regulator-name = "DCDC_REG3"; + vcc_33: DCDC3 { regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; regulator-always-on; }; - vcc_50: SUDCDC4 { - regulator-name = "SUDCDC_REG4"; + vcc_50: SUDCDC_REG4 { regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; regulator-always-on; }; - vcc_25: LDO_REG5 { - regulator-name = "LDO_REG5"; + vcc_25: LDO5 { regulator-min-microvolt = <2500000>; regulator-max-microvolt = <2500000>; regulator-always-on; }; - wifi_io: LDO_REG6 { - regulator-name = "LDO_REG6"; + wifi_io: LDO6 { regulator-min-microvolt = <2500000>; regulator-max-microvolt = <2500000>; regulator-always-on; }; - vcc_28: LDO_REG7 { - regulator-name = "LDO_REG7"; + cim_io_28: LDO7 { regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; regulator-always-on; }; - vcc_15: LDO_REG8 { - regulator-name = "LDO_REG8"; + cim_io_15: LDO8 { regulator-min-microvolt = <1500000>; regulator-max-microvolt = <1500000>; regulator-always-on; }; vrtc_18: LDO_REG9 { - regulator-name = "LDO_REG9"; /* Despite the datasheet stating 3.3V * for REG9 and the driver expecting that, * REG9 outputs 1.8V. @@ -303,7 +293,6 @@ vrtc_18: LDO_REG9 { regulator-always-on; }; vcc_11: LDO_REG10 { - regulator-name = "LDO_REG10"; regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; regulator-always-on;
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 960e27a5741cd3001996ff6ddfb3eb0ed3a4909d ]
It is likely Height was expected here, instead of Width.
Test the correct variable.
Fixes: 17529ea2acfa ("drm/amd/display: Optimizations for DML math") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: Hamza Mahfooz hamza.mahfooz@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c index b7c2844d0cbee..f294f2f8c75bc 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c @@ -810,7 +810,7 @@ static bool CalculatePrefetchSchedule( *swath_width_chroma_ub = dml_ceil(SwathWidthY / 2 - 1, myPipe->BlockWidth256BytesC) + myPipe->BlockWidth256BytesC; } else { *swath_width_luma_ub = dml_ceil(SwathWidthY - 1, myPipe->BlockHeight256BytesY) + myPipe->BlockHeight256BytesY; - if (myPipe->BlockWidth256BytesC > 0) + if (myPipe->BlockHeight256BytesC > 0) *swath_width_chroma_ub = dml_ceil(SwathWidthY / 2 - 1, myPipe->BlockHeight256BytesC) + myPipe->BlockHeight256BytesC; }
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit bafc31166aa7df5fa26ae0ad8196d1717e6cdea9 ]
It is likely p1_min_meta_chunk_bytes was expected here, instead of min_meta_chunk_bytes.
Test the correct variable.
Fixes: dda4fb85e433 ("drm/amd/display: DML changes for DCN32/321") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: Hamza Mahfooz hamza.mahfooz@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c index 395ae8761980f..9ba6cb67655f4 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c @@ -116,7 +116,7 @@ void dml32_rq_dlg_get_rq_reg(display_rq_regs_st *rq_regs, else rq_regs->rq_regs_l.min_meta_chunk_size = dml_log2(min_meta_chunk_bytes) - 6 + 1;
- if (min_meta_chunk_bytes == 0) + if (p1_min_meta_chunk_bytes == 0) rq_regs->rq_regs_c.min_meta_chunk_size = 0; else rq_regs->rq_regs_c.min_meta_chunk_size = dml_log2(p1_min_meta_chunk_bytes) - 6 + 1;
From: Daniil Dulov d.dulov@aladdin.ru
[ Upstream commit cabbdea1f1861098991768d7bbf5a49ed1608213 ]
Pointer mqd_mem_obj can be deallocated in kfd_gtt_sa_allocate(). The function then returns non-zero value, which causes the second deallocation.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: d1f8f0d17d40 ("drm/amdkfd: Move non-sdma mqd allocation out of init_mqd") Signed-off-by: Daniil Dulov d.dulov@aladdin.ru Signed-off-by: Felix Kuehling Felix.Kuehling@amd.com Reviewed-by: Felix Kuehling Felix.Kuehling@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c index 0778e587a2d68..eaf084acb706f 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c @@ -115,18 +115,19 @@ static struct kfd_mem_obj *allocate_mqd(struct kfd_dev *kfd, &(mqd_mem_obj->gtt_mem), &(mqd_mem_obj->gpu_addr), (void *)&(mqd_mem_obj->cpu_ptr), true); + + if (retval) { + kfree(mqd_mem_obj); + return NULL; + } } else { retval = kfd_gtt_sa_allocate(kfd, sizeof(struct v9_mqd), &mqd_mem_obj); - } - - if (retval) { - kfree(mqd_mem_obj); - return NULL; + if (retval) + return NULL; }
return mqd_mem_obj; - }
static void init_mqd(struct mqd_manager *mm, void **mqd,
From: Chen-Yu Tsai wenst@chromium.org
[ Upstream commit 95094495401bdf6a0649d220dfd095e6079b5e39 ]
Device tree node names should be generic. The planned device node name for the GPU, according to the bindings and posted DT changes, is "gpu", not "mali".
Fix the GPU node name in the SVS driver to follow.
Fixes: 0bbb09b2af9d ("soc: mediatek: SVS: add mt8192 SVS GPU driver") Signed-off-by: Chen-Yu Tsai wenst@chromium.org Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Alexandre Mergnat amergnat@baylibre.com Link: https://lore.kernel.org/r/20230531063532.2240038-1-wenst@chromium.org Signed-off-by: Matthias Brugger matthias.bgg@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/mediatek/mtk-svs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c index f26eb2f637d52..77d6299774427 100644 --- a/drivers/soc/mediatek/mtk-svs.c +++ b/drivers/soc/mediatek/mtk-svs.c @@ -2101,9 +2101,9 @@ static int svs_mt8192_platform_probe(struct svs_platform *svsp) svsb = &svsp->banks[idx];
if (svsb->type == SVSB_HIGH) - svsb->opp_dev = svs_add_device_link(svsp, "mali"); + svsb->opp_dev = svs_add_device_link(svsp, "gpu"); else if (svsb->type == SVSB_LOW) - svsb->opp_dev = svs_get_subsys_device(svsp, "mali"); + svsb->opp_dev = svs_get_subsys_device(svsp, "gpu");
if (IS_ERR(svsb->opp_dev)) return dev_err_probe(svsp->dev, PTR_ERR(svsb->opp_dev),
From: Aurabindo Pillai aurabindo.pillai@amd.com
[ Upstream commit b18f05a0666aecd5cb19c26a8305bcfa4e9d6502 ]
[Why] When freesync video mode is enabled, switching resolution from native mode to one of the freesync video compatible modes can trigger continous artifacts on some eDP panels when running under KDE. The articating can be seen in the attached bug report.
[How] Fix this by restricting updates that require full commit by using the same checks for stream and scaling changes in the the enable pass of dm_update_crtc_state() along with the check for compatible timings for freesync vide mode.
Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2162 Fixes: da5e14909776 ("drm/amd/display: Fix hang when skipping modeset") Signed-off-by: Aurabindo Pillai aurabindo.pillai@amd.com Reviewed-by: Rodrigo Siqueira Rodrigo.Siqueira@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 2cbd6949804f5..261dbd417c2f8 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -9276,6 +9276,8 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
/* Now check if we should set freesync video mode */ if (amdgpu_freesync_vid_mode && dm_new_crtc_state->stream && + dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) && + dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream) && is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state)) { new_crtc_state->mode_changed = false;
From: Nikita Zhandarovich n.zhandarovich@fintech.ru
[ Upstream commit 1becc57cd1a905e2aa0e1eca60d2a37744525c4a ]
Function rv740_get_decoded_reference_divider() may return 0 due to unpredictable reference divider value calculated in radeon_atom_get_clock_dividers(). This will lead to division-by-zero error once that value is used as a divider in calculating 'clk_s'. While unlikely, this issue should nonetheless be prevented so add a sanity check for such cases by testing 'decoded_ref' value against 0.
Found by Linux Verification Center (linuxtesting.org) with static analysis tool SVACE.
v2: minor coding style fixes (Alex) In practice this should actually happen as the vbios should be properly populated.
Fixes: 66229b200598 ("drm/radeon/kms: add dpm support for rv7xx (v4)") Signed-off-by: Nikita Zhandarovich n.zhandarovich@fintech.ru Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/radeon/cypress_dpm.c | 8 ++++++-- drivers/gpu/drm/radeon/ni_dpm.c | 8 ++++++-- drivers/gpu/drm/radeon/rv740_dpm.c | 8 ++++++-- 3 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c index fdddbbaecbb74..72a0768df00f7 100644 --- a/drivers/gpu/drm/radeon/cypress_dpm.c +++ b/drivers/gpu/drm/radeon/cypress_dpm.c @@ -557,8 +557,12 @@ static int cypress_populate_mclk_value(struct radeon_device *rdev, ASIC_INTERNAL_MEMORY_SS, vco_freq)) { u32 reference_clock = rdev->clock.mpll.reference_freq; u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div); - u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate); - u32 clk_v = ss.percentage * + u32 clk_s, clk_v; + + if (!decoded_ref) + return -EINVAL; + clk_s = reference_clock * 5 / (decoded_ref * ss.rate); + clk_v = ss.percentage * (0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625);
mpll_ss1 &= ~CLKV_MASK; diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index 672d2239293e0..3e1c1a392fb7b 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c @@ -2241,8 +2241,12 @@ static int ni_populate_mclk_value(struct radeon_device *rdev, ASIC_INTERNAL_MEMORY_SS, vco_freq)) { u32 reference_clock = rdev->clock.mpll.reference_freq; u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div); - u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate); - u32 clk_v = ss.percentage * + u32 clk_s, clk_v; + + if (!decoded_ref) + return -EINVAL; + clk_s = reference_clock * 5 / (decoded_ref * ss.rate); + clk_v = ss.percentage * (0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625);
mpll_ss1 &= ~CLKV_MASK; diff --git a/drivers/gpu/drm/radeon/rv740_dpm.c b/drivers/gpu/drm/radeon/rv740_dpm.c index d57a3e1df8d63..4464fd21a3029 100644 --- a/drivers/gpu/drm/radeon/rv740_dpm.c +++ b/drivers/gpu/drm/radeon/rv740_dpm.c @@ -249,8 +249,12 @@ int rv740_populate_mclk_value(struct radeon_device *rdev, ASIC_INTERNAL_MEMORY_SS, vco_freq)) { u32 reference_clock = rdev->clock.mpll.reference_freq; u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div); - u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate); - u32 clk_v = 0x40000 * ss.percentage * + u32 clk_s, clk_v; + + if (!decoded_ref) + return -EINVAL; + clk_s = reference_clock * 5 / (decoded_ref * ss.rate); + clk_v = 0x40000 * ss.percentage * (dividers.whole_fb_div + (dividers.frac_fb_div / 8)) / (clk_s * 10000);
mpll_ss1 &= ~CLKV_MASK;
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 49904a0ebf23b15aad288a10f5354e7cd8193121 ]
While KUnit tests that cannot be built as a loadable module must depend on "KUNIT=y", this is not true for modular tests, where it adds an unnecessary limitation.
Fix this by relaxing the dependency to "KUNIT".
Fixes: 08809e482a1c44d9 ("HID: uclogic: KUnit best practices and naming conventions") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: David Gow davidgow@google.com Reviewed-by: José Expósito jose.exposito89@gmail.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 4ce012f83253e..b977450cac752 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -1285,7 +1285,7 @@ config HID_MCP2221
config HID_KUNIT_TEST tristate "KUnit tests for HID" if !KUNIT_ALL_TESTS - depends on KUNIT=y + depends on KUNIT depends on HID_BATTERY_STRENGTH depends on HID_UCLOGIC default KUNIT_ALL_TESTS
From: Bob Pearson rpearsonhpe@gmail.com
[ Upstream commit 425e1c9018fdf25cb4531606cc92d9d01a55534f ]
The subroutine rxe_check_bind_mw() in rxe_mw.c performs checks on the mw access flags before they are set so they always succeed. This patch instead checks the access flags passed in the send wqe.
Fixes: 32a577b4c3a9 ("RDMA/rxe: Add support for bind MW work requests") Link: https://lore.kernel.org/r/20230530221334.89432-4-rpearsonhpe@gmail.com Signed-off-by: Bob Pearson rpearsonhpe@gmail.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rxe/rxe_mw.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_mw.c b/drivers/infiniband/sw/rxe/rxe_mw.c index afa5ce1a71166..a7ec57ab8fadd 100644 --- a/drivers/infiniband/sw/rxe/rxe_mw.c +++ b/drivers/infiniband/sw/rxe/rxe_mw.c @@ -48,7 +48,7 @@ int rxe_dealloc_mw(struct ib_mw *ibmw) }
static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, - struct rxe_mw *mw, struct rxe_mr *mr) + struct rxe_mw *mw, struct rxe_mr *mr, int access) { if (mw->ibmw.type == IB_MW_TYPE_1) { if (unlikely(mw->state != RXE_MW_STATE_VALID)) { @@ -58,7 +58,7 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, }
/* o10-36.2.2 */ - if (unlikely((mw->access & IB_ZERO_BASED))) { + if (unlikely((access & IB_ZERO_BASED))) { rxe_dbg_mw(mw, "attempt to bind a zero based type 1 MW\n"); return -EINVAL; } @@ -104,7 +104,7 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, }
/* C10-74 */ - if (unlikely((mw->access & + if (unlikely((access & (IB_ACCESS_REMOTE_WRITE | IB_ACCESS_REMOTE_ATOMIC)) && !(mr->access & IB_ACCESS_LOCAL_WRITE))) { rxe_dbg_mw(mw, @@ -113,7 +113,7 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, }
/* C10-75 */ - if (mw->access & IB_ZERO_BASED) { + if (access & IB_ZERO_BASED) { if (unlikely(wqe->wr.wr.mw.length > mr->ibmr.length)) { rxe_dbg_mw(mw, "attempt to bind a ZB MW outside of the MR\n"); @@ -133,12 +133,12 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, }
static void rxe_do_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, - struct rxe_mw *mw, struct rxe_mr *mr) + struct rxe_mw *mw, struct rxe_mr *mr, int access) { u32 key = wqe->wr.wr.mw.rkey & 0xff;
mw->rkey = (mw->rkey & ~0xff) | key; - mw->access = wqe->wr.wr.mw.access; + mw->access = access; mw->state = RXE_MW_STATE_VALID; mw->addr = wqe->wr.wr.mw.addr; mw->length = wqe->wr.wr.mw.length; @@ -169,6 +169,7 @@ int rxe_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe) struct rxe_dev *rxe = to_rdev(qp->ibqp.device); u32 mw_rkey = wqe->wr.wr.mw.mw_rkey; u32 mr_lkey = wqe->wr.wr.mw.mr_lkey; + int access = wqe->wr.wr.mw.access;
mw = rxe_pool_get_index(&rxe->mw_pool, mw_rkey >> 8); if (unlikely(!mw)) { @@ -198,11 +199,11 @@ int rxe_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe)
spin_lock_bh(&mw->lock);
- ret = rxe_check_bind_mw(qp, wqe, mw, mr); + ret = rxe_check_bind_mw(qp, wqe, mw, mr, access); if (ret) goto err_unlock;
- rxe_do_bind_mw(qp, wqe, mw, mr); + rxe_do_bind_mw(qp, wqe, mw, mr, access); err_unlock: spin_unlock_bh(&mw->lock); err_drop_mr:
From: Chia-I Wu olvaffe@gmail.com
[ Upstream commit 9f0bcf49e9895cb005d78b33a5eebfa11711b425 ]
This is motivated by OOB access in amdgpu_vm_update_range when offset_in_bo+map_size overflows.
v2: keep the validations in amdgpu_vm_bo_map v3: add the validations to amdgpu_vm_bo_map/amdgpu_vm_bo_replace_map rather than to amdgpu_gem_va_ioctl
Fixes: 9f7eb5367d00 ("drm/amdgpu: actually use the VM map parameters") Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Chia-I Wu olvaffe@gmail.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 587879f3ac2e6..30c0c49b37105 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1436,14 +1436,14 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, uint64_t eaddr;
/* validate the parameters */ - if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || - size == 0 || size & ~PAGE_MASK) + if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK) + return -EINVAL; + if (saddr + size <= saddr || offset + size <= offset) return -EINVAL;
/* make sure object fit at this offset */ eaddr = saddr + size - 1; - if (saddr >= eaddr || - (bo && offset + size > amdgpu_bo_size(bo)) || + if ((bo && offset + size > amdgpu_bo_size(bo)) || (eaddr >= adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT)) return -EINVAL;
@@ -1502,14 +1502,14 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev, int r;
/* validate the parameters */ - if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || - size == 0 || size & ~PAGE_MASK) + if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK) + return -EINVAL; + if (saddr + size <= saddr || offset + size <= offset) return -EINVAL;
/* make sure object fit at this offset */ eaddr = saddr + size - 1; - if (saddr >= eaddr || - (bo && offset + size > amdgpu_bo_size(bo)) || + if ((bo && offset + size > amdgpu_bo_size(bo)) || (eaddr >= adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT)) return -EINVAL;
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 38e27a6fbf2206b18417c5985dbcdeca0f2026b8 ]
If the Adreno SMMU is dma-coherent, allocation will fail unless we disable IO_PGTABLE_QUIRK_ARM_OUTER_WBWA. Skip setting this quirk for the coherent SMMUs (like we have on sm8350 platform).
Fixes: 54af0ceb7595 ("arm64: dts: qcom: sm8350: add GPU, GMU, GPU CC and SMMU nodes") Reported-by: David Heidelberg david@ixit.cz Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Tested-by: David Heidelberg david@ixit.cz Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Tested-by: Konrad Dybcio konrad.dybcio@linaro.org # SM8450 HDK Patchwork: https://patchwork.freedesktop.org/patch/531562/ Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 2942d2548ce69..f74495dcbd966 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1793,7 +1793,8 @@ a6xx_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev) * This allows GPU to set the bus attributes required to use system * cache on behalf of the iommu page table walker. */ - if (!IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice)) + if (!IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice) && + !device_iommu_capable(&pdev->dev, IOMMU_CAP_CACHE_COHERENCY)) quirks |= IO_PGTABLE_QUIRK_ARM_OUTER_WBWA;
return adreno_iommu_create_address_space(gpu, pdev, quirks);
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 736a9327365644b460e4498b1ce172ca411efcbc ]
The commit 010c8bbad2cb ("drm: msm: adreno: Disable preemption on Adreno 510") added special handling for a510 (this SKU doesn't seem to support preemption, so the driver should clamp nr_rings to 1). However the gpu->revn is not yet set (it is set later, in adreno_gpu_init()) and thus the condition is always false. Check config->rev instead.
Fixes: 010c8bbad2cb ("drm: msm: adreno: Disable preemption on Adreno 510") Reported-by: Adam Skladowski a39.skl@gmail.com Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Tested-by: Adam Skladowski a39.skl@gmail.com Patchwork: https://patchwork.freedesktop.org/patch/531511/ Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 0372f89082022..660c830c68764 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1740,6 +1740,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; struct platform_device *pdev = priv->gpu_pdev; + struct adreno_platform_config *config = pdev->dev.platform_data; struct a5xx_gpu *a5xx_gpu = NULL; struct adreno_gpu *adreno_gpu; struct msm_gpu *gpu; @@ -1766,7 +1767,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
nr_rings = 4;
- if (adreno_is_a510(adreno_gpu)) + if (adreno_cmp_rev(ADRENO_REV(5, 1, 0, ANY_ID), config->rev)) nr_rings = 1;
ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, nr_rings);
From: Kashyap Desai kashyap.desai@broadcom.com
[ Upstream commit 0af91306e17ef3d18e5f100aa58aa787869118af ]
Driver is not handling the wraparound of the mbox producer index correctly. Currently the wraparound happens once u32 max is reached.
Bit 31 of the producer index register is special and should be set only once for the first command. Because the producer index overflow setting bit31 after a long time, FW goes to initialization sequence and this causes FW hang.
Fix is to wraparound the mbox producer index once it reaches u16 max.
Fixes: cee0c7bba486 ("RDMA/bnxt_re: Refactor command queue management code") Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") Signed-off-by: Kashyap Desai kashyap.desai@broadcom.com Signed-off-by: Selvin Xavier selvin.xavier@broadcom.com Link: https://lore.kernel.org/r/1686308514-11996-2-git-send-email-selvin.xavier@br... Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c index 9c63b8b62edfc..3d76fa71641a4 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c @@ -181,7 +181,7 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, struct cmdq_base *req, } while (size > 0); cmdq->seq_num++;
- cmdq_prod = hwq->prod; + cmdq_prod = hwq->prod & 0xFFFF; if (test_bit(FIRMWARE_FIRST_FLAG, &cmdq->flags)) { /* The very first doorbell write * is required to set this flag @@ -598,7 +598,7 @@ int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res, rcfw->cmdq_depth = BNXT_QPLIB_CMDQE_MAX_CNT_8192;
sginfo.pgsize = bnxt_qplib_cmdqe_page_size(rcfw->cmdq_depth); - hwq_attr.depth = rcfw->cmdq_depth; + hwq_attr.depth = rcfw->cmdq_depth & 0x7FFFFFFF; hwq_attr.stride = BNXT_QPLIB_CMDQE_UNITS; hwq_attr.type = HWQ_TYPE_CTX; if (bnxt_qplib_alloc_init_hwq(&cmdq->hwq, &hwq_attr)) {
From: Kashyap Desai kashyap.desai@broadcom.com
[ Upstream commit 3099bcdc19b701f732f638ee45679858c08559bb ]
bnxt_qplib_service_creq can be called from interrupt or tasklet or process context. So the function take irq variant of spin_lock. But when wake_up is invoked with the lock held, it is putting the calling context to sleep.
[exception RIP: __wake_up_common+190] RIP: ffffffffb7539d7e RSP: ffffa73300207ad8 RFLAGS: 00000083 RAX: 0000000000000001 RBX: ffff91fa295f69b8 RCX: dead000000000200 RDX: ffffa733344af940 RSI: ffffa73336527940 RDI: ffffa73336527940 RBP: 000000000000001c R8: 0000000000000002 R9: 00000000000299c0 R10: 0000017230de82c5 R11: 0000000000000002 R12: ffffa73300207b28 R13: 0000000000000000 R14: ffffa733341bf928 R15: 0000000000000000 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
Call the wakeup after releasing the lock.
Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") Signed-off-by: Kashyap Desai kashyap.desai@broadcom.com Signed-off-by: Selvin Xavier selvin.xavier@broadcom.com Link: https://lore.kernel.org/r/1686308514-11996-3-git-send-email-selvin.xavier@br... Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c index 3d76fa71641a4..75e0c42f6f424 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c @@ -299,7 +299,8 @@ static int bnxt_qplib_process_func_event(struct bnxt_qplib_rcfw *rcfw, }
static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw, - struct creq_qp_event *qp_event) + struct creq_qp_event *qp_event, + u32 *num_wait) { struct creq_qp_error_notification *err_event; struct bnxt_qplib_hwq *hwq = &rcfw->cmdq.hwq; @@ -308,6 +309,7 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw, u16 cbit, blocked = 0; struct pci_dev *pdev; unsigned long flags; + u32 wait_cmds = 0; __le16 mcookie; u16 cookie; int rc = 0; @@ -367,9 +369,10 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw, crsqe->req_size = 0;
if (!blocked) - wake_up(&rcfw->cmdq.waitq); + wait_cmds++; spin_unlock_irqrestore(&hwq->lock, flags); } + *num_wait += wait_cmds; return rc; }
@@ -383,6 +386,7 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t) struct creq_base *creqe; u32 sw_cons, raw_cons; unsigned long flags; + u32 num_wakeup = 0;
/* Service the CREQ until budget is over */ spin_lock_irqsave(&hwq->lock, flags); @@ -401,7 +405,8 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t) switch (type) { case CREQ_BASE_TYPE_QP_EVENT: bnxt_qplib_process_qp_event - (rcfw, (struct creq_qp_event *)creqe); + (rcfw, (struct creq_qp_event *)creqe, + &num_wakeup); creq->stats.creq_qp_event_processed++; break; case CREQ_BASE_TYPE_FUNC_EVENT: @@ -429,6 +434,8 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t) rcfw->res->cctx, true); } spin_unlock_irqrestore(&hwq->lock, flags); + if (num_wakeup) + wake_up_nr(&rcfw->cmdq.waitq, num_wakeup); }
static irqreturn_t bnxt_qplib_creq_irq(int irq, void *dev_instance)
From: Kai Ma kaima@hust.edu.cn
[ Upstream commit 1b280598ab3bd8a2dc8b96a12530d5b1ee7a8f4a ]
Use devm_of_iomap() instead of of_iomap() to automatically handle the unused ioremap region. If any error occurs, regions allocated by kzalloc() will leak, but using devm_kzalloc() instead will automatically free the memory using devm_kfree().
Also, fix error handling of hws by adding unregister_hws label, which unregisters remaining hws when iomap failed.
Fixes: 7154b046d8f3 ("clk: imx: Add initial support for i.MXRT1050 clock driver") Signed-off-by: Kai Ma kaima@hust.edu.cn Reviewed-by: Peng Fan peng.fan@nxp.com Acked-by: Jesse Taube Mr.Bossman075@gmail.com Reviewed-by: Abel Vesa abel.vesa@linaro.org Link: https://lore.kernel.org/r/20230418113451.151312-1-kaima@hust.edu.cn Signed-off-by: Abel Vesa abel.vesa@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/imx/clk-imxrt1050.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/drivers/clk/imx/clk-imxrt1050.c b/drivers/clk/imx/clk-imxrt1050.c index fd5c51fc92c0e..08d155feb035a 100644 --- a/drivers/clk/imx/clk-imxrt1050.c +++ b/drivers/clk/imx/clk-imxrt1050.c @@ -42,7 +42,7 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev) struct device_node *anp; int ret;
- clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, + clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMXRT1050_CLK_END), GFP_KERNEL); if (WARN_ON(!clk_hw_data)) return -ENOMEM; @@ -53,10 +53,12 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev) hws[IMXRT1050_CLK_OSC] = imx_get_clk_hw_by_name(np, "osc");
anp = of_find_compatible_node(NULL, NULL, "fsl,imxrt-anatop"); - pll_base = of_iomap(anp, 0); + pll_base = devm_of_iomap(dev, anp, 0, NULL); of_node_put(anp); - if (WARN_ON(!pll_base)) - return -ENOMEM; + if (WARN_ON(IS_ERR(pll_base))) { + ret = PTR_ERR(pll_base); + goto unregister_hws; + }
/* Anatop clocks */ hws[IMXRT1050_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0UL); @@ -104,8 +106,10 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev)
/* CCM clocks */ ccm_base = devm_platform_ioremap_resource(pdev, 0); - if (WARN_ON(IS_ERR(ccm_base))) - return PTR_ERR(ccm_base); + if (WARN_ON(IS_ERR(ccm_base))) { + ret = PTR_ERR(ccm_base); + goto unregister_hws; + }
hws[IMXRT1050_CLK_ARM_PODF] = imx_clk_hw_divider("arm_podf", "pll1_arm", ccm_base + 0x10, 0, 3); hws[IMXRT1050_CLK_PRE_PERIPH_SEL] = imx_clk_hw_mux("pre_periph_sel", ccm_base + 0x18, 18, 2, @@ -149,8 +153,12 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev) ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); if (ret < 0) { dev_err(dev, "Failed to register clks for i.MXRT1050.\n"); - imx_unregister_hw_clocks(hws, IMXRT1050_CLK_END); + goto unregister_hws; } + return 0; + +unregister_hws: + imx_unregister_hw_clocks(hws, IMXRT1050_CLK_END); return ret; } static const struct of_device_id imxrt1050_clk_of_match[] = {
From: Hao Luo m202171776@hust.edu.cn
[ Upstream commit 188d070de9132667956f5aadd98d2bd87d3eac89 ]
Use devm_of_iomap() instead of of_iomap() to automatically handle the unused ioremap region.
If any error occurs, regions allocated by kzalloc() will leak, but using devm_kzalloc() instead will automatically free the memory using devm_kfree().
Fixes: daeb14545514 ("clk: imx: imx8mn: Switch to clk_hw based API") Fixes: 96d6392b54db ("clk: imx: Add support for i.MX8MN clock driver") Signed-off-by: Hao Luo m202171776@hust.edu.cn Reviewed-by: Dongliang Mu dzm91@hust.edu.cn Reviewed-by: Peng Fan peng.fan@nxp.com Link: https://lore.kernel.org/r/20230411015107.2645-1-m202171776@hust.edu.cn Signed-off-by: Abel Vesa abel.vesa@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/imx/clk-imx8mn.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index a042ed3a9d6c2..569b2abf40525 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -323,7 +323,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) void __iomem *base; int ret;
- clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, + clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX8MN_CLK_END), GFP_KERNEL); if (WARN_ON(!clk_hw_data)) return -ENOMEM; @@ -340,10 +340,10 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) hws[IMX8MN_CLK_EXT4] = imx_get_clk_hw_by_name(np, "clk_ext4");
np = of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop"); - base = of_iomap(np, 0); + base = devm_of_iomap(dev, np, 0, NULL); of_node_put(np); - if (WARN_ON(!base)) { - ret = -ENOMEM; + if (WARN_ON(IS_ERR(base))) { + ret = PTR_ERR(base); goto unregister_hws; }
From: Zhanhao Hu zero12113@hust.edu.cn
[ Upstream commit e02ba11b457647050cb16e7cad16cec3c252fade ]
In function probe(), it returns directly without unregistered hws when error occurs.
Fix this by adding 'goto unregister_hws;' on line 295 and line 310.
Use devm_kzalloc() instead of kzalloc() to automatically free the memory using devm_kfree() when error occurs.
Replace of_iomap() with devm_of_iomap() to automatically handle the unused ioremap region and delete 'iounmap(anatop_base);' in unregister_hws.
Fixes: 24defbe194b6 ("clk: imx: add i.MX93 clk") Signed-off-by: Zhanhao Hu zero12113@hust.edu.cn Reviewed-by: Abel Vesa abel.vesa@linaro.org Link: https://lore.kernel.org/r/20230601033825.336558-1-zero12113@hust.edu.cn Signed-off-by: Abel Vesa abel.vesa@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/imx/clk-imx93.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c index 8d0974db6bfd8..face30012b7dd 100644 --- a/drivers/clk/imx/clk-imx93.c +++ b/drivers/clk/imx/clk-imx93.c @@ -262,7 +262,7 @@ static int imx93_clocks_probe(struct platform_device *pdev) void __iomem *base, *anatop_base; int i, ret;
- clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, + clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX93_CLK_END), GFP_KERNEL); if (!clk_hw_data) return -ENOMEM; @@ -286,10 +286,12 @@ static int imx93_clocks_probe(struct platform_device *pdev) "sys_pll_pfd2", 1, 2);
np = of_find_compatible_node(NULL, NULL, "fsl,imx93-anatop"); - anatop_base = of_iomap(np, 0); + anatop_base = devm_of_iomap(dev, np, 0, NULL); of_node_put(np); - if (WARN_ON(!anatop_base)) - return -ENOMEM; + if (WARN_ON(IS_ERR(anatop_base))) { + ret = PTR_ERR(base); + goto unregister_hws; + }
clks[IMX93_CLK_AUDIO_PLL] = imx_clk_fracn_gppll("audio_pll", "osc_24m", anatop_base + 0x1200, &imx_fracn_gppll); @@ -299,8 +301,8 @@ static int imx93_clocks_probe(struct platform_device *pdev) np = dev->of_node; base = devm_platform_ioremap_resource(pdev, 0); if (WARN_ON(IS_ERR(base))) { - iounmap(anatop_base); - return PTR_ERR(base); + ret = PTR_ERR(base); + goto unregister_hws; }
for (i = 0; i < ARRAY_SIZE(root_array); i++) { @@ -332,7 +334,6 @@ static int imx93_clocks_probe(struct platform_device *pdev)
unregister_hws: imx_unregister_hw_clocks(clks, IMX93_CLK_END); - iounmap(anatop_base);
return ret; }
From: Yuxing Liu lyx2022@hust.edu.cn
[ Upstream commit 878b02d5f3b56cb090dbe2c70c89273be144087f ]
Replace of_iomap() and kzalloc() with devm_of_iomap() and devm_kzalloc() which can automatically release the related memory when the device or driver is removed or unloaded to avoid potential memory leak.
In this case, iounmap(anatop_base) in line 427,433 are removed as manual release is not required.
Besides, referring to clk-imx8mq.c, check the return code of of_clk_add_hw_provider, if it returns negtive, print error info and unregister hws, which makes the program more robust.
Fixes: 9c140d992676 ("clk: imx: Add support for i.MX8MP clock driver") Signed-off-by: Yuxing Liu lyx2022@hust.edu.cn Reviewed-by: Dongliang Mu dzm91@hust.edu.cn Reviewed-by: Abel Vesa abel.vesa@linaro.org Link: https://lore.kernel.org/r/20230503070607.2462-1-lyx2022@hust.edu.cn Signed-off-by: Abel Vesa abel.vesa@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/imx/clk-imx8mp.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index 3253589851ffb..de7d2d2176bea 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -414,25 +414,22 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np; void __iomem *anatop_base, *ccm_base; + int err;
np = of_find_compatible_node(NULL, NULL, "fsl,imx8mp-anatop"); - anatop_base = of_iomap(np, 0); + anatop_base = devm_of_iomap(dev, np, 0, NULL); of_node_put(np); - if (WARN_ON(!anatop_base)) - return -ENOMEM; + if (WARN_ON(IS_ERR(anatop_base))) + return PTR_ERR(anatop_base);
np = dev->of_node; ccm_base = devm_platform_ioremap_resource(pdev, 0); - if (WARN_ON(IS_ERR(ccm_base))) { - iounmap(anatop_base); + if (WARN_ON(IS_ERR(ccm_base))) return PTR_ERR(ccm_base); - }
- clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL); - if (WARN_ON(!clk_hw_data)) { - iounmap(anatop_base); + clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL); + if (WARN_ON(!clk_hw_data)) return -ENOMEM; - }
clk_hw_data->num = IMX8MP_CLK_END; hws = clk_hw_data->hws; @@ -721,7 +718,12 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
imx_check_clk_hws(hws, IMX8MP_CLK_END);
- of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); + err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); + if (err < 0) { + dev_err(dev, "failed to register hws for i.MX8MP\n"); + imx_unregister_hw_clocks(hws, IMX8MP_CLK_END); + return err; + }
imx_register_uart_clocks();
From: Bosi Zhang u201911157@hust.edu.cn
[ Upstream commit 3db7285e044144fd88a356f5b641b9cd4b231a77 ]
Smatch reports: drivers/clk/mediatek/clk-mtk.c:583 mtk_clk_simple_probe() warn: 'base' from of_iomap() not released on lines: 496.
This problem was also found in linux-next. In mtk_clk_simple_probe(), base is not released when handling errors if clk_data is not existed, which may cause a leak. So free_base should be added here to release base.
Fixes: c58cd0e40ffa ("clk: mediatek: Add mtk_clk_simple_probe() to simplify clock providers") Signed-off-by: Bosi Zhang u201911157@hust.edu.cn Reviewed-by: Dongliang Mu dzm91@hust.edu.cn Link: https://lore.kernel.org/r/20230422084331.47198-1-u201911157@hust.edu.cn Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/mediatek/clk-mtk.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index 14e8b64a32a3c..b93fb1d80878c 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -492,8 +492,10 @@ int mtk_clk_simple_probe(struct platform_device *pdev) num_clks += mcd->num_mux_clks;
clk_data = mtk_alloc_clk_data(num_clks); - if (!clk_data) - return -ENOMEM; + if (!clk_data) { + r = -ENOMEM; + goto free_base; + }
if (mcd->fixed_clks) { r = mtk_clk_register_fixed_clks(mcd->fixed_clks, @@ -578,6 +580,7 @@ int mtk_clk_simple_probe(struct platform_device *pdev) mcd->num_fixed_clks, clk_data); free_data: mtk_free_clk_data(clk_data); +free_base: if (mcd->shared_io && base) iounmap(base); return r;
From: Konrad Dybcio konrad.dybcio@linaro.org
[ Upstream commit ab033e7846f91953244d0626b28ce66412b813b3 ]
The rpmh driver will cache sleep and wake votes until the cluster power-domain is about to enter idle, to avoid unnecessary writes. So associate the apps_rsc with the cluster pd, so that it can be notified about this event.
Without this, only AMC votes are being commited.
Fixes: 6bd20c54b589 ("arm64: dts: qcom: Add base QDU1000/QRU1000 DTSIs") Signed-off-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230531-topic-rsc-v1-3-b4a985f57b8b@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/qdu1000.dtsi | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/qcom/qdu1000.dtsi b/arch/arm64/boot/dts/qcom/qdu1000.dtsi index c72a51c32a300..eeb4e51b31cfc 100644 --- a/arch/arm64/boot/dts/qcom/qdu1000.dtsi +++ b/arch/arm64/boot/dts/qcom/qdu1000.dtsi @@ -1238,6 +1238,7 @@ apps_rsc: rsc@17a00000 { qcom,tcs-config = <ACTIVE_TCS 2>, <SLEEP_TCS 3>, <WAKE_TCS 3>, <CONTROL_TCS 0>; label = "apps_rsc"; + power-domains = <&CLUSTER_PD>;
apps_bcm_voter: bcm-voter { compatible = "qcom,bcm-voter";
From: Konrad Dybcio konrad.dybcio@linaro.org
[ Upstream commit 7b04cbd81b0e60c5151a310e7b730dc4a951a211 ]
The rpmh driver will cache sleep and wake votes until the cluster power-domain is about to enter idle, to avoid unnecessary writes. So associate the apps_rsc with the cluster pd, so that it can be notified about this event.
Without this, only AMC votes are being commited.
Fixes: 07c8ded6e373 ("arm64: dts: qcom: add sdm670 and pixel 3a device trees") Signed-off-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230531-topic-rsc-v1-5-b4a985f57b8b@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm670.dtsi | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi index 02f14692dd9da..50dd050eb132d 100644 --- a/arch/arm64/boot/dts/qcom/sdm670.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi @@ -1155,6 +1155,7 @@ apps_rsc: rsc@179c0000 { <SLEEP_TCS 3>, <WAKE_TCS 3>, <CONTROL_TCS 1>; + power-domains = <&CLUSTER_PD>;
apps_bcm_voter: bcm-voter { compatible = "qcom,bcm-voter";
From: Konrad Dybcio konrad.dybcio@linaro.org
[ Upstream commit 91e83140b5dd5598fbcfada3ee1f8b2b410c3731 ]
The rpmh driver will cache sleep and wake votes until the cluster power-domain is about to enter idle, to avoid unnecessary writes. So associate the apps_rsc with the cluster pd, so that it can be notified about this event.
Without this, only AMC votes are being commited.
Fixes: c83545d95376 ("arm64: dts: sdm845: Add rpmh-rsc node") Signed-off-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230531-topic-rsc-v1-6-b4a985f57b8b@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index bc89a2b4bc258..a818a81408dfb 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -5058,6 +5058,7 @@ apps_rsc: rsc@179c0000 { <SLEEP_TCS 3>, <WAKE_TCS 3>, <CONTROL_TCS 1>; + power-domains = <&CLUSTER_PD>;
apps_bcm_voter: bcm-voter { compatible = "qcom,bcm-voter";
From: Konrad Dybcio konrad.dybcio@linaro.org
[ Upstream commit 4b2c7ac8e469ab7f92e50c34ad4012a77e79d078 ]
The rpmh driver will cache sleep and wake votes until the cluster power-domain is about to enter idle, to avoid unnecessary writes. So associate the apps_rsc with the cluster pd, so that it can be notified about this event.
Without this, only AMC votes are being commited.
Fixes: ffc50b2d3828 ("arm64: dts: qcom: Add base SM8550 dtsi") Signed-off-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230531-topic-rsc-v1-8-b4a985f57b8b@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sm8550.dtsi | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi index 5f254a4675265..429746447441f 100644 --- a/arch/arm64/boot/dts/qcom/sm8550.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi @@ -3250,6 +3250,7 @@ apps_rsc: rsc@17a00000 { qcom,drv-id = <2>; qcom,tcs-config = <ACTIVE_TCS 3>, <SLEEP_TCS 2>, <WAKE_TCS 2>, <CONTROL_TCS 0>; + power-domains = <&CLUSTER_PD>;
apps_bcm_voter: bcm-voter { compatible = "qcom,bcm-voter";
From: Marijn Suijten marijn.suijten@somainline.org
[ Upstream commit 223ce29c8b7e5b00f01a68387aabeefd77d97f06 ]
The framebuffer configuration for edo pdx203, written in edo dtsi (which is overwritten in pdx206 dts for its smaller panel) has to use a 1096x2560 configuration as this is what the panel (and framebuffer area) has been initialized to. Downstream userspace also has access to (and uses) this 2.5k mode by default, and only switches the panel to 4k when requested.
This is similar to commit be8de06dc397 ("arm64: dts: qcom: sm8150-kumano: Panel framebuffer is 2.5k instead of 4k") which fixed the same for the previous generation Sony platform.
Fixes: 69cdb97ef652 ("arm64: dts: qcom: sm8250: Add support for SONY Xperia 1 II / 5 II (Edo platform)") Signed-off-by: Marijn Suijten marijn.suijten@somainline.org Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230606211418.587676-1-marijn.suijten@somainline.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi index b9c982a059dfb..c0f22a3bea5ce 100644 --- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi @@ -26,9 +26,10 @@ chosen { framebuffer: framebuffer@9c000000 { compatible = "simple-framebuffer"; reg = <0 0x9c000000 0 0x2300000>; - width = <1644>; - height = <3840>; - stride = <(1644 * 4)>; + /* pdx203 BL initializes in 2.5k mode, not 4k */ + width = <1096>; + height = <2560>; + stride = <(1096 * 4)>; format = "a8r8g8b8"; /* * That's a lot of clocks, but it's necessary due
From: Abel Vesa abel.vesa@linaro.org
[ Upstream commit 11a1397bbf69e408223bb691858a0fcd295a8f76 ]
The USB HC node is missing the interconnect paths, so add them.
Fixes: 7f7e5c1b037f ("arm64: dts: qcom: sm8550: Add USB PHYs and controller nodes") Signed-off-by: Abel Vesa abel.vesa@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230601103817.4066446-1-abel.vesa@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sm8550.dtsi | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi index 429746447441f..75bd5f2ae681f 100644 --- a/arch/arm64/boot/dts/qcom/sm8550.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi @@ -2441,6 +2441,10 @@ usb_1: usb@a6f8800 {
resets = <&gcc GCC_USB30_PRIM_BCR>;
+ interconnects = <&aggre1_noc MASTER_USB3_0 0 &mc_virt SLAVE_EBI1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_0 0>; + interconnect-names = "usb-ddr", "apps-usb"; + status = "disabled";
usb_1_dwc3: usb@a600000 {
From: Dan Carpenter dan.carpenter@linaro.org
[ Upstream commit da2edb3e3c09fd1451b7f400ccd1070ef086619a ]
Smatch detected an off by one in this code: drivers/clk/bcm/clk-raspberrypi.c:374 raspberrypi_discover_clocks() error: buffer overflow 'data->hws' 16 <= 16
The data->hws[] array has RPI_FIRMWARE_NUM_CLK_ID elements so the > comparison needs to changed to >=.
Fixes: 12c90f3f27bb ("clk: bcm: rpi: Add variant structure") Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Link: https://lore.kernel.org/r/5a850b08-d2f5-4794-aceb-a6b468965139@kili.mountain Reviewed-by: Stefan Wahren stefan.wahren@i2se.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/bcm/clk-raspberrypi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c index ce2f934797369..5df19f571a474 100644 --- a/drivers/clk/bcm/clk-raspberrypi.c +++ b/drivers/clk/bcm/clk-raspberrypi.c @@ -356,9 +356,9 @@ static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi, while (clks->id) { struct raspberrypi_clk_variant *variant;
- if (clks->id > RPI_FIRMWARE_NUM_CLK_ID) { + if (clks->id >= RPI_FIRMWARE_NUM_CLK_ID) { dev_err(rpi->dev, "Unknown clock id: %u (max: %u)\n", - clks->id, RPI_FIRMWARE_NUM_CLK_ID); + clks->id, RPI_FIRMWARE_NUM_CLK_ID - 1); return -EINVAL; }
From: Dan Carpenter dan.carpenter@linaro.org
[ Upstream commit 9c632a6396505a019ea6d12b5ab45e659a542a93 ]
Smatch detected this potential error pointer dereference clk_wzrd_register_divider(). If devm_clk_hw_register() fails then it sets "hw" to an error pointer and then dereferences it on the next line. Return the error directly instead.
Fixes: 5a853722eb32 ("staging: clocking-wizard: Add support for dynamic reconfiguration") Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Link: https://lore.kernel.org/r/f0e39b5c-4554-41e0-80d9-54ca3fabd060@kili.mountain Reviewed-by: Michal Simek michal.simek@amd.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c index eb1dfe7ecc1b4..4a23583933bcc 100644 --- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c +++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c @@ -354,7 +354,7 @@ static struct clk *clk_wzrd_register_divider(struct device *dev, hw = &div->hw; ret = devm_clk_hw_register(dev, hw); if (ret) - hw = ERR_PTR(ret); + return ERR_PTR(ret);
return hw->clk; }
From: Yuan Can yuancan@huawei.com
[ Upstream commit 53a06e5924c0d43c11379a08c5a78529c3e61595 ]
The tegra and tegra needs to be freed in the error handling path, otherwise it will be leaked.
Fixes: 2db04f16b589 ("clk: tegra: Add EMC clock driver") Signed-off-by: Yuan Can yuancan@huawei.com Link: https://lore.kernel.org/r/20221209094124.71043-1-yuancan@huawei.com Acked-by: Thierry Reding treding@nvidia.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/tegra/clk-tegra124-emc.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/clk/tegra/clk-tegra124-emc.c b/drivers/clk/tegra/clk-tegra124-emc.c index 219c80653dbdb..2a6db04342815 100644 --- a/drivers/clk/tegra/clk-tegra124-emc.c +++ b/drivers/clk/tegra/clk-tegra124-emc.c @@ -464,6 +464,7 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra, err = load_one_timing_from_dt(tegra, timing, child); if (err) { of_node_put(child); + kfree(tegra->timings); return err; }
@@ -515,6 +516,7 @@ struct clk *tegra124_clk_register_emc(void __iomem *base, struct device_node *np err = load_timings_from_dt(tegra, node, node_ram_code); if (err) { of_node_put(node); + kfree(tegra); return ERR_PTR(err); } }
From: Andrew Davis afd@ti.com
[ Upstream commit 155e7635ed1f3814d94d12556a3a0fed41d05b76 ]
Mailbox nodes are now disabled by default. The BeagleBoard AI64 DT addition went in at around the same time and must have missed that change so the mailboxes are not re-enabled. Do that here.
Fixes: fae14a1cb8dd ("arm64: dts: ti: Add k3-j721e-beagleboneai64") Signed-off-by: Andrew Davis afd@ti.com Reviewed-by: Nishanth Menon nm@ti.com Link: https://lore.kernel.org/r/20230515172137.474626-1-afd@ti.com Signed-off-by: Vignesh Raghavendra vigneshr@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts index 37c24b077b6aa..8a62ac263b89a 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts +++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts @@ -936,6 +936,7 @@ &ufs_wrapper { };
&mailbox0_cluster0 { + status = "okay"; interrupts = <436>;
mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 { @@ -950,6 +951,7 @@ mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 { };
&mailbox0_cluster1 { + status = "okay"; interrupts = <432>;
mbox_main_r5fss0_core0: mbox-main-r5fss0-core0 { @@ -964,6 +966,7 @@ mbox_main_r5fss0_core1: mbox-main-r5fss0-core1 { };
&mailbox0_cluster2 { + status = "okay"; interrupts = <428>;
mbox_main_r5fss1_core0: mbox-main-r5fss1-core0 { @@ -978,6 +981,7 @@ mbox_main_r5fss1_core1: mbox-main-r5fss1-core1 { };
&mailbox0_cluster3 { + status = "okay"; interrupts = <424>;
mbox_c66_0: mbox-c66-0 { @@ -992,6 +996,7 @@ mbox_c66_1: mbox-c66-1 { };
&mailbox0_cluster4 { + status = "okay"; interrupts = <420>;
mbox_c71_0: mbox-c71-0 {
From: Nishanth Menon nm@ti.com
[ Upstream commit c10a9df30e3401bd5a5ee43f1afd6c2b2ca75ad7 ]
main_i2c0 is aliased as i2c0 which creates a problem for u-boot R5 SPL attempting to reuse the same definition in the common board detection logic as it looks for the first i2c instance as the bus on which to detect the eeprom to understand the board variant involved. Switch main_i2c0 to i2c3 alias allowing us to introduce wkup_i2c0 and potentially space for mcu_i2c instances in the gap for follow on patches.
Fixes: e20a06aca5c9 ("arm64: dts: ti: Add support for J784S4 EVM board") Signed-off-by: Nishanth Menon nm@ti.com Reviewed-by: Udit Kumar u-kumar1@ti.com Link: https://lore.kernel.org/r/20230602214937.2349545-2-nm@ti.com Signed-off-by: Vignesh Raghavendra vigneshr@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/ti/k3-j784s4-evm.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts index 8cd4a7ecc121e..6b2d93d3c5e27 100644 --- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts +++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts @@ -22,7 +22,7 @@ chosen { aliases { serial2 = &main_uart8; mmc1 = &main_sdhci1; - i2c0 = &main_i2c0; + i2c3 = &main_i2c0; };
memory@80000000 {
From: Siddharth Vadapalli s-vadapalli@ti.com
[ Upstream commit 6cd4b7cfbcca4a45f06a8031f299c4019221a4ce ]
Add device tree support to enable MCU CPSW with J784S4 EVM.
Signed-off-by: Siddharth Vadapalli s-vadapalli@ti.com Reviewed-by: Andrew Davis afd@ti.com Link: https://lore.kernel.org/r/20230315042548.1500528-1-s-vadapalli@ti.com Signed-off-by: Nishanth Menon nm@ti.com Stable-dep-of: 14462bd0b247 ("arm64: dts: ti: k3-j784s4: Fix wakeup pinmux range and pinctrl node offsets") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/ti/k3-j784s4-evm.dts | 50 ++++++++++++++++++++++++ 1 file changed, 50 insertions(+)
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts index 6b2d93d3c5e27..0c4ee83fc9d75 100644 --- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts +++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts @@ -140,6 +140,32 @@ J784S4_IOPAD(0x020, PIN_INPUT, 7) /* (AJ35) MCAN15_RX.GPIO0_8 */ }; };
+&wkup_pmx0 { + mcu_cpsw_pins_default: mcu-cpsw-pins-default { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x094, PIN_INPUT, 0) /* (A35) MCU_RGMII1_RD0 */ + J784S4_WKUP_IOPAD(0x090, PIN_INPUT, 0) /* (B36) MCU_RGMII1_RD1 */ + J784S4_WKUP_IOPAD(0x08c, PIN_INPUT, 0) /* (C36) MCU_RGMII1_RD2 */ + J784S4_WKUP_IOPAD(0x088, PIN_INPUT, 0) /* (D36) MCU_RGMII1_RD3 */ + J784S4_WKUP_IOPAD(0x084, PIN_INPUT, 0) /* (B37) MCU_RGMII1_RXC */ + J784S4_WKUP_IOPAD(0x06c, PIN_INPUT, 0) /* (C37) MCU_RGMII1_RX_CTL */ + J784S4_WKUP_IOPAD(0x07c, PIN_OUTPUT, 0) /* (D37) MCU_RGMII1_TD0 */ + J784S4_WKUP_IOPAD(0x078, PIN_OUTPUT, 0) /* (D38) MCU_RGMII1_TD1 */ + J784S4_WKUP_IOPAD(0x074, PIN_OUTPUT, 0) /* (E37) MCU_RGMII1_TD2 */ + J784S4_WKUP_IOPAD(0x070, PIN_OUTPUT, 0) /* (E38) MCU_RGMII1_TD3 */ + J784S4_WKUP_IOPAD(0x080, PIN_OUTPUT, 0) /* (E36) MCU_RGMII1_TXC */ + J784S4_WKUP_IOPAD(0x068, PIN_OUTPUT, 0) /* (C38) MCU_RGMII1_TX_CTL */ + >; + }; + + mcu_mdio_pins_default: mcu-mdio-pins-default { + pinctrl-single,pins = < + J784S4_WKUP_IOPAD(0x09c, PIN_OUTPUT, 0) /* (A36) MCU_MDIO0_MDC */ + J784S4_WKUP_IOPAD(0x098, PIN_INPUT, 0) /* (B35) MCU_MDIO0_MDIO */ + >; + }; +}; + &main_uart8 { status = "okay"; pinctrl-names = "default"; @@ -194,3 +220,27 @@ &main_sdhci1 { &main_gpio0 { status = "okay"; }; + +&mcu_cpsw { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&mcu_cpsw_pins_default>; +}; + +&davinci_mdio { + pinctrl-names = "default"; + pinctrl-0 = <&mcu_mdio_pins_default>; + + mcu_phy0: ethernet-phy@0 { + reg = <0>; + ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>; + ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>; + ti,min-output-impedance; + }; +}; + +&mcu_cpsw_port1 { + status = "okay"; + phy-mode = "rgmii-rxid"; + phy-handle = <&mcu_phy0>; +};
From: Thejasvi Konduru t-konduru@ti.com
[ Upstream commit 14462bd0b247d05070d48d0f02eb7ca2680ab7bd ]
The wkup_pmx register region in j784s4 has multiple non-addressable regions, hence the existing wkup_pmx region is split as follows to avoid the non-addressable regions. The pinctrl node offsets are also corrected as per the newly split wkup_pmx* nodes.
wkup_pmx0 -> 13 pins (WKUP_PADCONFIG 0 - 12) wkup_pmx1 -> 11 pins (WKUP_PADCONFIG 14 - 24) wkup_pmx2 -> 72 pins (WKUP_PADCONFIG 26 - 97) wkup_pmx3 -> 1 pin (WKUP_PADCONFIG 100)
Fixes: 4664ebd8346a ("arm64: dts: ti: Add initial support for J784S4 SoC") Signed-off-by: Thejasvi Konduru t-konduru@ti.com Reviewed-by: Nishanth Menon nm@ti.com Link: https://lore.kernel.org/r/20230503083143.32369-1-t-konduru@ti.com Signed-off-by: Vignesh Raghavendra vigneshr@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/ti/k3-j784s4-evm.dts | 30 +++++++++---------- .../boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi | 29 +++++++++++++++++- 2 files changed, 43 insertions(+), 16 deletions(-)
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts index 0c4ee83fc9d75..ed575f17935b6 100644 --- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts +++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts @@ -140,28 +140,28 @@ J784S4_IOPAD(0x020, PIN_INPUT, 7) /* (AJ35) MCAN15_RX.GPIO0_8 */ }; };
-&wkup_pmx0 { +&wkup_pmx2 { mcu_cpsw_pins_default: mcu-cpsw-pins-default { pinctrl-single,pins = < - J784S4_WKUP_IOPAD(0x094, PIN_INPUT, 0) /* (A35) MCU_RGMII1_RD0 */ - J784S4_WKUP_IOPAD(0x090, PIN_INPUT, 0) /* (B36) MCU_RGMII1_RD1 */ - J784S4_WKUP_IOPAD(0x08c, PIN_INPUT, 0) /* (C36) MCU_RGMII1_RD2 */ - J784S4_WKUP_IOPAD(0x088, PIN_INPUT, 0) /* (D36) MCU_RGMII1_RD3 */ - J784S4_WKUP_IOPAD(0x084, PIN_INPUT, 0) /* (B37) MCU_RGMII1_RXC */ - J784S4_WKUP_IOPAD(0x06c, PIN_INPUT, 0) /* (C37) MCU_RGMII1_RX_CTL */ - J784S4_WKUP_IOPAD(0x07c, PIN_OUTPUT, 0) /* (D37) MCU_RGMII1_TD0 */ - J784S4_WKUP_IOPAD(0x078, PIN_OUTPUT, 0) /* (D38) MCU_RGMII1_TD1 */ - J784S4_WKUP_IOPAD(0x074, PIN_OUTPUT, 0) /* (E37) MCU_RGMII1_TD2 */ - J784S4_WKUP_IOPAD(0x070, PIN_OUTPUT, 0) /* (E38) MCU_RGMII1_TD3 */ - J784S4_WKUP_IOPAD(0x080, PIN_OUTPUT, 0) /* (E36) MCU_RGMII1_TXC */ - J784S4_WKUP_IOPAD(0x068, PIN_OUTPUT, 0) /* (C38) MCU_RGMII1_TX_CTL */ + J784S4_WKUP_IOPAD(0x02c, PIN_INPUT, 0) /* (A35) MCU_RGMII1_RD0 */ + J784S4_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (B36) MCU_RGMII1_RD1 */ + J784S4_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (C36) MCU_RGMII1_RD2 */ + J784S4_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (D36) MCU_RGMII1_RD3 */ + J784S4_WKUP_IOPAD(0x01c, PIN_INPUT, 0) /* (B37) MCU_RGMII1_RXC */ + J784S4_WKUP_IOPAD(0x004, PIN_INPUT, 0) /* (C37) MCU_RGMII1_RX_CTL */ + J784S4_WKUP_IOPAD(0x014, PIN_OUTPUT, 0) /* (D37) MCU_RGMII1_TD0 */ + J784S4_WKUP_IOPAD(0x010, PIN_OUTPUT, 0) /* (D38) MCU_RGMII1_TD1 */ + J784S4_WKUP_IOPAD(0x00c, PIN_OUTPUT, 0) /* (E37) MCU_RGMII1_TD2 */ + J784S4_WKUP_IOPAD(0x008, PIN_OUTPUT, 0) /* (E38) MCU_RGMII1_TD3 */ + J784S4_WKUP_IOPAD(0x018, PIN_OUTPUT, 0) /* (E36) MCU_RGMII1_TXC */ + J784S4_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (C38) MCU_RGMII1_TX_CTL */ >; };
mcu_mdio_pins_default: mcu-mdio-pins-default { pinctrl-single,pins = < - J784S4_WKUP_IOPAD(0x09c, PIN_OUTPUT, 0) /* (A36) MCU_MDIO0_MDC */ - J784S4_WKUP_IOPAD(0x098, PIN_INPUT, 0) /* (B35) MCU_MDIO0_MDIO */ + J784S4_WKUP_IOPAD(0x034, PIN_OUTPUT, 0) /* (A36) MCU_MDIO0_MDC */ + J784S4_WKUP_IOPAD(0x030, PIN_INPUT, 0) /* (B35) MCU_MDIO0_MDIO */ >; }; }; diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi index 64bd3dee14aa6..8a2350f2c82d0 100644 --- a/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi @@ -50,7 +50,34 @@ mcu_ram: sram@41c00000 { wkup_pmx0: pinctrl@4301c000 { compatible = "pinctrl-single"; /* Proxy 0 addressing */ - reg = <0x00 0x4301c000 0x00 0x178>; + reg = <0x00 0x4301c000 0x00 0x034>; + #pinctrl-cells = <1>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xffffffff>; + }; + + wkup_pmx1: pinctrl@4301c038 { + compatible = "pinctrl-single"; + /* Proxy 0 addressing */ + reg = <0x00 0x4301c038 0x00 0x02c>; + #pinctrl-cells = <1>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xffffffff>; + }; + + wkup_pmx2: pinctrl@4301c068 { + compatible = "pinctrl-single"; + /* Proxy 0 addressing */ + reg = <0x00 0x4301c068 0x00 0x120>; + #pinctrl-cells = <1>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xffffffff>; + }; + + wkup_pmx3: pinctrl@4301c190 { + compatible = "pinctrl-single"; + /* Proxy 0 addressing */ + reg = <0x00 0x4301c190 0x00 0x004>; #pinctrl-cells = <1>; pinctrl-single,register-width = <32>; pinctrl-single,function-mask = <0xffffffff>;
From: Nishanth Menon nm@ti.com
[ Upstream commit b38c6ced4ec5b3f6260ff6cc2b71e8a3d8c897d7 ]
main_i2c0 is aliased as i2c0 which creates a problem for u-boot R5 SPL attempting to reuse the same definition in the common board detection logic as it looks for the first i2c instance as the bus on which to detect the eeprom to understand the board variant involved. Switch main_i2c0 to i2c3 alias allowing us to introduce wkup_i2c0 and potentially space for mcu_i2c instances in the gap for follow on patches.
Fixes: 635fb18ba008 ("arch: arm64: dts: Add support for AM69 Starter Kit") Signed-off-by: Nishanth Menon nm@ti.com Reviewed-by: Udit Kumar u-kumar1@ti.com Link: https://lore.kernel.org/r/20230602214937.2349545-5-nm@ti.com Signed-off-by: Vignesh Raghavendra vigneshr@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/ti/k3-am69-sk.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts index bc49ba534790e..f364b7803115d 100644 --- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts +++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts @@ -23,7 +23,7 @@ chosen { aliases { serial2 = &main_uart8; mmc1 = &main_sdhci1; - i2c0 = &main_i2c0; + i2c3 = &main_i2c0; };
memory@80000000 {
From: Su Hui suhui@nfschina.com
[ Upstream commit 79597c8bf64ca99eab385115743131d260339da5 ]
smatch error: sound/pci/ac97/ac97_codec.c:2354 snd_ac97_mixer() error: we previously assumed 'rac97' could be null (see line 2072)
remove redundant assignment, return error if rac97 is NULL.
Fixes: da3cec35dd3c ("ALSA: Kill snd_assert() in sound/pci/*") Signed-off-by: Su Hui suhui@nfschina.com Link: https://lore.kernel.org/r/20230615021732.1972194-1-suhui@nfschina.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/pci/ac97/ac97_codec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 9afc5906d662e..80a65b8ad7b9b 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -2069,8 +2069,8 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, .dev_disconnect = snd_ac97_dev_disconnect, };
- if (rac97) - *rac97 = NULL; + if (!rac97) + return -EINVAL; if (snd_BUG_ON(!bus || !template)) return -EINVAL; if (snd_BUG_ON(template->num >= 4))
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 3bcfc7b90465efd337d39b91b43972162f0d1908 ]
We can not support color management without DSPP blocks being provided in the HW catalog. Do not enable color management for CRTCs if num_dspps is 0.
Fixes: 4259ff7ae509 ("drm/msm/dpu: add support for pcc color block in dpu driver") Reported-by: Yongqin Liu yongqin.liu@linaro.org Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Abhinav Kumar quic_abhinavk@quicinc.com Reviewed-by: Marijn Suijten marijn.suijten@somainline.org Reviewed-by: Sumit Semwal sumit.semwal@linaro.org Tested-by: Yongqin Liu yongqin.liu@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/542141/ Link: https://lore.kernel.org/r/20230612182534.3345805-1-dmitry.baryshkov@linaro.o... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index f29a339a37050..ce188452cd56a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1575,6 +1575,8 @@ static const struct drm_crtc_helper_funcs dpu_crtc_helper_funcs = { struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, struct drm_plane *cursor) { + struct msm_drm_private *priv = dev->dev_private; + struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); struct drm_crtc *crtc = NULL; struct dpu_crtc *dpu_crtc = NULL; int i; @@ -1606,7 +1608,8 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane,
drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs);
- drm_crtc_enable_color_mgmt(crtc, 0, true, 0); + if (dpu_kms->catalog->dspp_count) + drm_crtc_enable_color_mgmt(crtc, 0, true, 0);
/* save user friendly CRTC name for later */ snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", crtc->base.id);
From: Jessica Zhang quic_jesszhan@quicinc.com
[ Upstream commit c223059e6f8340f7eac2319470984cbfc39c433b ]
Correct the math for slice_last_group_size so that it matches the calculations downstream.
Fixes: c110cfd1753e ("drm/msm/disp/dpu1: Add support for DSC") Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Marijn Suijten marijn.suijten@somainline.org Signed-off-by: Jessica Zhang quic_jesszhan@quicinc.com Patchwork: https://patchwork.freedesktop.org/patch/539269/ Link: https://lore.kernel.org/r/20230329-rfc-msm-dsc-helper-v14-7-bafc7be95691@qui... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c index 619926da1441e..68035745b7069 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c @@ -54,9 +54,10 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc, if (is_cmd_mode) initial_lines += 1;
- slice_last_group_size = 3 - (dsc->slice_width % 3); + slice_last_group_size = (dsc->slice_width + 2) % 3; + data = (initial_lines << 20); - data |= ((slice_last_group_size - 1) << 18); + data |= (slice_last_group_size << 18); /* bpp is 6.4 format, 4 LSBs bits are for fractional part */ data |= (dsc->bits_per_pixel << 8); data |= (dsc->block_pred_enable << 7);
From: Jessica Zhang quic_jesszhan@quicinc.com
[ Upstream commit 155fa3a91d64221eb0885fd221cc8085dbef908f ]
Currently, slice_count is being used to calculate word count and pkt_per_line. Instead, these values should be calculated using slice per packet, which is not the same as slice_count.
Slice count represents the number of slices per interface, and its value will not always match that of slice per packet. For example, it is possible to have cases where there are multiple slices per interface but the panel specifies only one slice per packet.
Thus, use the default value of one slice per packet and remove slice_count from the aforementioned calculations.
Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration") Fixes: bc6b6ff8135c ("drm/msm/dsi: Use DSC slice(s) packet size to compute word count") Reviewed-by: Marijn Suijten marijn.suijten@somainline.org Signed-off-by: Jessica Zhang quic_jesszhan@quicinc.com Patchwork: https://patchwork.freedesktop.org/patch/541965/ Link: https://lore.kernel.org/r/20230405-add-dsc-support-v6-5-95eab864d1b6@quicinc... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dsi/dsi_host.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 18fa30e1e8583..3ee770dddc2fd 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -854,18 +854,17 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod */ slice_per_intf = DIV_ROUND_UP(hdisplay, dsc->slice_width);
- /* - * If slice_count is greater than slice_per_intf - * then default to 1. This can happen during partial - * update. - */ - if (dsc->slice_count > slice_per_intf) - dsc->slice_count = 1; - total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
eol_byte_num = total_bytes_per_intf % 3; - pkt_per_line = slice_per_intf / dsc->slice_count; + + /* + * Typically, pkt_per_line = slice_per_intf * slice_per_pkt. + * + * Since the current driver only supports slice_per_pkt = 1, + * pkt_per_line will be equal to slice per intf for now. + */ + pkt_per_line = slice_per_intf;
if (is_cmd_mode) /* packet data type */ reg = DSI_COMMAND_COMPRESSION_MODE_CTRL_STREAM0_DATATYPE(MIPI_DSI_DCS_LONG_WRITE); @@ -989,7 +988,14 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) if (!msm_host->dsc) wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1; else - wc = msm_host->dsc->slice_chunk_size * msm_host->dsc->slice_count + 1; + /* + * When DSC is enabled, WC = slice_chunk_size * slice_per_pkt + 1. + * Currently, the driver only supports default value of slice_per_pkt = 1 + * + * TODO: Expand mipi_dsi_device struct to hold slice_per_pkt info + * and adjust DSC math to account for slice_per_pkt. + */ + wc = msm_host->dsc->slice_chunk_size + 1;
dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL, DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) |
From: Bjorn Andersson quic_bjorande@quicinc.com
[ Upstream commit a7bfb2ad2184a1fba78be35209b6019aa8cc8d4d ]
Using devres to depopulate the aux bus made sure that upon a probe deferral the EDP panel device would be destroyed and recreated upon next attempt.
But the struct device which the devres is tied to is the DPUs (drm_dev->dev), which may be happen after the DP controller is torn down.
Indications of this can be seen in the commonly seen EDID-hexdump full of zeros in the log, or the occasional/rare KASAN fault where the panel's attempt to read the EDID information causes a use after free on DP resources.
It's tempting to move the devres to the DP controller's struct device, but the resources used by the device(s) on the aux bus are explicitly torn down in the error path. The KASAN-reported use-after-free also remains, as the DP aux "module" explicitly frees its devres-allocated memory in this code path.
As such, explicitly depopulate the aux bus in the error path, and in the component unbind path, to avoid these issues.
Fixes: 2b57f726611e ("drm/msm/dp: fix aux-bus EP lifetime") Signed-off-by: Bjorn Andersson quic_bjorande@quicinc.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Douglas Anderson dianders@chromium.org Patchwork: https://patchwork.freedesktop.org/patch/542163/ Link: https://lore.kernel.org/r/20230612220106.1884039-1-quic_bjorande@quicinc.com Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dp/dp_display.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 3f9a18410c0bb..97776f5e12524 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -325,6 +325,8 @@ static void dp_display_unbind(struct device *dev, struct device *master,
kthread_stop(dp->ev_tsk);
+ of_dp_aux_depopulate_bus(dp->aux); + dp_power_client_deinit(dp->power); dp_unregister_audio_driver(dev, dp->audio); dp_aux_unregister(dp->aux); @@ -1538,11 +1540,6 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor) } }
-static void of_dp_aux_depopulate_bus_void(void *data) -{ - of_dp_aux_depopulate_bus(data); -} - static int dp_display_get_next_bridge(struct msm_dp *dp) { int rc; @@ -1571,12 +1568,6 @@ static int dp_display_get_next_bridge(struct msm_dp *dp) of_node_put(aux_bus); if (rc) goto error; - - rc = devm_add_action_or_reset(dp->drm_dev->dev, - of_dp_aux_depopulate_bus_void, - dp_priv->aux); - if (rc) - goto error; } else if (dp->is_edp) { DRM_ERROR("eDP aux_bus not found\n"); return -ENODEV; @@ -1601,6 +1592,7 @@ static int dp_display_get_next_bridge(struct msm_dp *dp) error: if (dp->is_edp) { disable_irq(dp_priv->irq); + of_dp_aux_depopulate_bus(dp_priv->aux); dp_display_host_phy_exit(dp_priv); dp_display_host_deinit(dp_priv); }
From: Bjorn Andersson quic_bjorande@quicinc.com
[ Upstream commit fa0048a4b1fa7a50c8b0e514f5b428abdf69a6f8 ]
The DP component's unbind operation walks through the submodules to unregister and clean things up. But if the unbind happens because the DP controller itself is being removed, all the memory for those submodules has just been freed.
Change the order of these operations to avoid the many use-after-free that otherwise happens in this code path.
Fixes: c943b4948b58 ("drm/msm/dp: add displayPort driver support") Signed-off-by: Bjorn Andersson quic_bjorande@quicinc.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/542166/ Link: https://lore.kernel.org/r/20230612220259.1884381-1-quic_bjorande@quicinc.com Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dp/dp_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 97776f5e12524..22967cf6a79d3 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -1354,9 +1354,9 @@ static int dp_display_remove(struct platform_device *pdev) { struct dp_display_private *dp = dev_get_dp_display_private(&pdev->dev);
+ component_del(&pdev->dev, &dp_display_comp_ops); dp_display_deinit_sub_modules(dp);
- component_del(&pdev->dev, &dp_display_comp_ops); platform_set_drvdata(pdev, NULL);
return 0;
From: Allen-KH Cheng allen-kh.cheng@mediatek.com
[ Upstream commit 9d498cce9298a71e3896e2d1aee24a1a4c531d81 ]
Add the cpufreq nodes for MT8192 SoC.
Signed-off-by: Allen-KH Cheng allen-kh.cheng@mediatek.com Tested-by: Chen-Yu Tsai wenst@chromium.org Reviewed-by: Nícolas F. R. A. Prado nfraprado@collabora.com Tested-by: Nícolas F. R. A. Prado nfraprado@collabora.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Tested-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Link: https://lore.kernel.org/r/20230317061944.15434-1-allen-kh.cheng@mediatek.com Signed-off-by: Matthias Brugger matthias.bgg@gmail.com Stable-dep-of: a4366b5695c9 ("arm64: dts: mediatek: mt8192: Fix CPUs capacity-dmips-mhz") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/mediatek/mt8192.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi index 87b91c8feaf96..ba49f37933d6d 100644 --- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi @@ -70,6 +70,7 @@ cpu0: cpu@0 { d-cache-line-size = <64>; d-cache-sets = <128>; next-level-cache = <&l2_0>; + performance-domains = <&performance 0>; capacity-dmips-mhz = <530>; };
@@ -87,6 +88,7 @@ cpu1: cpu@100 { d-cache-line-size = <64>; d-cache-sets = <128>; next-level-cache = <&l2_0>; + performance-domains = <&performance 0>; capacity-dmips-mhz = <530>; };
@@ -104,6 +106,7 @@ cpu2: cpu@200 { d-cache-line-size = <64>; d-cache-sets = <128>; next-level-cache = <&l2_0>; + performance-domains = <&performance 0>; capacity-dmips-mhz = <530>; };
@@ -121,6 +124,7 @@ cpu3: cpu@300 { d-cache-line-size = <64>; d-cache-sets = <128>; next-level-cache = <&l2_0>; + performance-domains = <&performance 0>; capacity-dmips-mhz = <530>; };
@@ -138,6 +142,7 @@ cpu4: cpu@400 { d-cache-line-size = <64>; d-cache-sets = <256>; next-level-cache = <&l2_1>; + performance-domains = <&performance 1>; capacity-dmips-mhz = <1024>; };
@@ -155,6 +160,7 @@ cpu5: cpu@500 { d-cache-line-size = <64>; d-cache-sets = <256>; next-level-cache = <&l2_1>; + performance-domains = <&performance 1>; capacity-dmips-mhz = <1024>; };
@@ -172,6 +178,7 @@ cpu6: cpu@600 { d-cache-line-size = <64>; d-cache-sets = <256>; next-level-cache = <&l2_1>; + performance-domains = <&performance 1>; capacity-dmips-mhz = <1024>; };
@@ -189,6 +196,7 @@ cpu7: cpu@700 { d-cache-line-size = <64>; d-cache-sets = <256>; next-level-cache = <&l2_1>; + performance-domains = <&performance 1>; capacity-dmips-mhz = <1024>; };
@@ -318,6 +326,12 @@ soc { compatible = "simple-bus"; ranges;
+ performance: performance-controller@11bc10 { + compatible = "mediatek,cpufreq-hw"; + reg = <0 0x0011bc10 0 0x120>, <0 0x0011bd30 0 0x120>; + #performance-domain-cells = <1>; + }; + gic: interrupt-controller@c000000 { compatible = "arm,gic-v3"; #interrupt-cells = <4>;
From: Nícolas F. R. A. Prado nfraprado@collabora.com
[ Upstream commit a4366b5695c984b8a3fc8b31de9e758c8f6d1aed ]
The capacity-dmips-mhz parameter was miscalculated: this SoC runs the first (Cortex-A55) cluster at a maximum of 2000MHz and the second (Cortex-A76) cluster at a maximum of 2200MHz.
In order to calculate the right capacity-dmips-mhz, the following test was performed: 1. CPUFREQ governor was set to 'performance' on both clusters 2. Ran dhrystone with 500000000 iterations for 10 times on each cluster 3. Calculated the mean result for each cluster 4. Calculated DMIPS/MHz: dmips_mhz = dmips_per_second / cpu_mhz 5. Scaled results to 1024: result_c0 = dmips_mhz_c0 / dmips_mhz_c1 * 1024
The mean results for this SoC are: Cluster 0 (LITTLE): 12016411 Dhry/s Cluster 1 (BIG): 31702034 Dhry/s
The calculated scaled results are: Cluster 0: 426.953226899238 (rounded to 427) Cluster 1: 1024
Fixes: 48489980e27e ("arm64: dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile") Signed-off-by: Nícolas F. R. A. Prado nfraprado@collabora.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Link: https://lore.kernel.org/r/20230602183515.3778780-1-nfraprado@collabora.com Signed-off-by: Matthias Brugger matthias.bgg@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/mediatek/mt8192.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi index ba49f37933d6d..a3a2b7de54a7c 100644 --- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi @@ -71,7 +71,7 @@ cpu0: cpu@0 { d-cache-sets = <128>; next-level-cache = <&l2_0>; performance-domains = <&performance 0>; - capacity-dmips-mhz = <530>; + capacity-dmips-mhz = <427>; };
cpu1: cpu@100 { @@ -89,7 +89,7 @@ cpu1: cpu@100 { d-cache-sets = <128>; next-level-cache = <&l2_0>; performance-domains = <&performance 0>; - capacity-dmips-mhz = <530>; + capacity-dmips-mhz = <427>; };
cpu2: cpu@200 { @@ -107,7 +107,7 @@ cpu2: cpu@200 { d-cache-sets = <128>; next-level-cache = <&l2_0>; performance-domains = <&performance 0>; - capacity-dmips-mhz = <530>; + capacity-dmips-mhz = <427>; };
cpu3: cpu@300 { @@ -125,7 +125,7 @@ cpu3: cpu@300 { d-cache-sets = <128>; next-level-cache = <&l2_0>; performance-domains = <&performance 0>; - capacity-dmips-mhz = <530>; + capacity-dmips-mhz = <427>; };
cpu4: cpu@400 {
From: Daniel Golle daniel@makrotopia.org
[ Upstream commit 3bfbff9b461e3506dfb5b2904e8c15a0aea39e07 ]
The bootrom burned into the MT7986 SoC will try multiple locations on the SPI-NAND flash to load bl2 in case the bl2 image located at the the previously attempted offset is corrupt.
Use 0x100000 instead of 0x80000 as partition size for bl2 on SPI-NAND, allowing for up to four redundant copies of bl2 (typically sized a bit less than 0x40000).
Fixes: 8e01fb15b8157 ("arm64: dts: mt7986: add Bananapi R3") Signed-off-by: Daniel Golle daniel@makrotopia.org Link: https://lore.kernel.org/r/ZH9UGF99RgzrHZ88@makrotopia.org Signed-off-by: Matthias Brugger matthias.bgg@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso index 15ee8c568f3c3..543c13385d6e3 100644 --- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso +++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso @@ -29,13 +29,13 @@ partitions {
partition@0 { label = "bl2"; - reg = <0x0 0x80000>; + reg = <0x0 0x100000>; read-only; };
- partition@80000 { + partition@100000 { label = "reserved"; - reg = <0x80000 0x300000>; + reg = <0x100000 0x280000>; };
partition@380000 {
From: Srinivasan Shanmugam srinivasan.shanmugam@amd.com
[ Upstream commit d50dc746ff72b9c48812dac3344fa87fbde940a3 ]
Fixes the following gcc with W=1:
In file included from ./include/linux/string.h:253, from ./include/linux/bitmap.h:11, from ./include/linux/cpumask.h:12, from ./arch/x86/include/asm/cpumask.h:5, from ./arch/x86/include/asm/msr.h:11, from ./arch/x86/include/asm/processor.h:22, from ./arch/x86/include/asm/cpufeature.h:5, from ./arch/x86/include/asm/thread_info.h:53, from ./include/linux/thread_info.h:60, from ./arch/x86/include/asm/preempt.h:7, from ./include/linux/preempt.h:78, from ./include/linux/spinlock.h:56, from ./include/linux/mmzone.h:8, from ./include/linux/gfp.h:7, from ./include/linux/firmware.h:7, from drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu11/sienna_cichlid_ppt.c:26: In function ‘fortify_memcpy_chk’, inlined from ‘sienna_cichlid_append_powerplay_table’ at drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu11/sienna_cichlid_ppt.c:444:2, inlined from ‘sienna_cichlid_setup_pptable’ at drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu11/sienna_cichlid_ppt.c:506:8, inlined from ‘sienna_cichlid_setup_pptable’ at drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu11/sienna_cichlid_ppt.c:494:12: ./include/linux/fortify-string.h:413:4: warning: call to ‘__read_overflow2_field’ declared with attribute warning: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Wattribute-warning] 413 | __read_overflow2_field(q_size_field, size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
the compiler complains about the size calculation in the memcpy() - "sizeof(*smc_dpm_table) - sizeof(smc_dpm_table->table_header)" is much larger than what fits into table_member.
Hence, reuse 'smu_memcpy_trailing' for nv1x
Fixes: 7077b19a38240 ("drm/amd/pm: use macro to get pptable members") Suggested-by: Evan Quan Evan.Quan@amd.com Cc: Evan Quan Evan.Quan@amd.com Cc: Chengming Gui Jack.Gui@amd.com Cc: Christian König christian.koenig@amd.com Cc: Alex Deucher alexander.deucher@amd.com Signed-off-by: Srinivasan Shanmugam srinivasan.shanmugam@amd.com Reviewed-by: Evan Quan evan.quan@amd.com Acked-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index 85d53597eb07a..f7ed3e655e397 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -431,7 +431,13 @@ static int sienna_cichlid_append_powerplay_table(struct smu_context *smu) { struct atom_smc_dpm_info_v4_9 *smc_dpm_table; int index, ret; - I2cControllerConfig_t *table_member; + PPTable_beige_goby_t *ppt_beige_goby; + PPTable_t *ppt; + + if (smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 13)) + ppt_beige_goby = smu->smu_table.driver_pptable; + else + ppt = smu->smu_table.driver_pptable;
index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, smc_dpm_info); @@ -440,9 +446,13 @@ static int sienna_cichlid_append_powerplay_table(struct smu_context *smu) (uint8_t **)&smc_dpm_table); if (ret) return ret; - GET_PPTABLE_MEMBER(I2cControllers, &table_member); - memcpy(table_member, smc_dpm_table->I2cControllers, - sizeof(*smc_dpm_table) - sizeof(smc_dpm_table->table_header)); + + if (smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 13)) + smu_memcpy_trailing(ppt_beige_goby, I2cControllers, BoardReserved, + smc_dpm_table, I2cControllers); + else + smu_memcpy_trailing(ppt, I2cControllers, BoardReserved, + smc_dpm_table, I2cControllers);
return 0; }
From: Luben Tuikov luben.tuikov@amd.com
[ Upstream commit 71344a718a9fda8c551cdc4381d354f9a9907f6f ]
The fixed commit listed in the Fixes tag below, introduced a bug in amdgpu_ras.c::amdgpu_reserve_page_direct(), in that when introducing the new amdgpu_umc_fill_error_record() and internally in that new function the physical address (argument "uint64_t retired_page"--wrong name) is right-shifted by AMDGPU_GPU_PAGE_SHIFT. Thus, in amdgpu_reserve_page_direct() when we pass "address" to that new function, we should NOT right-shift it, since this results, erroneously, in the page address to be 0 for first 2^(2*AMDGPU_GPU_PAGE_SHIFT) memory addresses.
This commit fixes this bug.
Cc: Tao Zhou tao.zhou1@amd.com Cc: Hawking Zhang Hawking.Zhang@amd.com Cc: Alex Deucher Alexander.Deucher@amd.com Fixes: 400013b268cb ("drm/amdgpu: add umc_fill_error_record to make code more simple") Signed-off-by: Luben Tuikov luben.tuikov@amd.com Link: https://lore.kernel.org/r/20230610113536.10621-1-luben.tuikov@amd.com Reviewed-by: Hawking Zhang Hawking.Zhang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 63dfcc98152d5..b3daca6372a90 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -170,8 +170,7 @@ static int amdgpu_reserve_page_direct(struct amdgpu_device *adev, uint64_t addre
memset(&err_rec, 0x0, sizeof(struct eeprom_table_record)); err_data.err_addr = &err_rec; - amdgpu_umc_fill_error_record(&err_data, address, - (address >> AMDGPU_GPU_PAGE_SHIFT), 0, 0); + amdgpu_umc_fill_error_record(&err_data, address, address, 0, 0);
if (amdgpu_bad_page_threshold != 0) { amdgpu_ras_add_bad_pages(adev, err_data.err_addr,
[AMD Official Use Only - General]
Reviewed-by: Tao Zhou tao.zhou1@amd.com
-----Original Message----- From: Greg Kroah-Hartman gregkh@linuxfoundation.org Sent: Sunday, July 9, 2023 7:14 PM To: stable@vger.kernel.org Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org; patches@lists.linux.dev; Zhou1, Tao Tao.Zhou1@amd.com; Zhang, Hawking Hawking.Zhang@amd.com; Deucher, Alexander Alexander.Deucher@amd.com; Tuikov, Luben Luben.Tuikov@amd.com; Deucher, Alexander Alexander.Deucher@amd.com; Sasha Levin sashal@kernel.org Subject: [PATCH 6.3 317/431] drm/amdgpu: Fix usage of UMC fill record in RAS
From: Luben Tuikov luben.tuikov@amd.com
[ Upstream commit 71344a718a9fda8c551cdc4381d354f9a9907f6f ]
The fixed commit listed in the Fixes tag below, introduced a bug in amdgpu_ras.c::amdgpu_reserve_page_direct(), in that when introducing the new amdgpu_umc_fill_error_record() and internally in that new function the physical address (argument "uint64_t retired_page"--wrong name) is right-shifted by AMDGPU_GPU_PAGE_SHIFT. Thus, in amdgpu_reserve_page_direct() when we pass "address" to that new function, we should NOT right-shift it, since this results, erroneously, in the page address to be 0 for first 2^(2*AMDGPU_GPU_PAGE_SHIFT) memory addresses.
This commit fixes this bug.
Cc: Tao Zhou tao.zhou1@amd.com Cc: Hawking Zhang Hawking.Zhang@amd.com Cc: Alex Deucher Alexander.Deucher@amd.com Fixes: 400013b268cb ("drm/amdgpu: add umc_fill_error_record to make code more simple") Signed-off-by: Luben Tuikov luben.tuikov@amd.com Link: https://lore.kernel.org/r/20230610113536.10621-1-luben.tuikov@amd.com Reviewed-by: Hawking Zhang Hawking.Zhang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 63dfcc98152d5..b3daca6372a90 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -170,8 +170,7 @@ static int amdgpu_reserve_page_direct(struct amdgpu_device *adev, uint64_t addre
memset(&err_rec, 0x0, sizeof(struct eeprom_table_record)); err_data.err_addr = &err_rec;
amdgpu_umc_fill_error_record(&err_data, address,
(address >> AMDGPU_GPU_PAGE_SHIFT), 0, 0);
amdgpu_umc_fill_error_record(&err_data, address, address, 0, 0); if (amdgpu_bad_page_threshold != 0) { amdgpu_ras_add_bad_pages(adev, err_data.err_addr,
-- 2.39.2
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 9a6c13b847d61b0c3796820ca6e976789df59cd8 ]
Each MERGE_3D block has just two registers. Correct the block length accordingly.
Fixes: 4369c93cf36b ("drm/msm/dpu: initial support for merge3D hardware block") Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Abhinav Kumar quic_abhinavk@quicinc.com Patchwork: https://patchwork.freedesktop.org/patch/542177/ Reviewed-by: Marijn Suijten marijn.suijten@somainline.org Link: https://lore.kernel.org/r/20230613001004.3426676-3-dmitry.baryshkov@linaro.o... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index f41bbceef70cf..c2462d58b67d6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -1566,7 +1566,7 @@ static struct dpu_pingpong_cfg qcm2290_pp[] = { #define MERGE_3D_BLK(_name, _id, _base) \ {\ .name = _name, .id = _id, \ - .base = _base, .len = 0x100, \ + .base = _base, .len = 0x8, \ .features = MERGE_3D_SM8150_MASK, \ .sblk = NULL \ }
From: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com
[ Upstream commit 3dc265b369ee61db999d6d1588e888eb21dc421e ]
The of_iomap() function returns NULL in case of error so usage of PTR_ERR() is wrong! Change that to return -ENOMEM in case of failure.
Fixes: 41138fbf876c ("clk: mediatek: mt8173: Migrate to platform driver and common probe") Signed-off-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Link: https://lore.kernel.org/r/20230615122051.546985-3-angelogioacchino.delregno@... Reviewed-by: Chen-Yu Tsai wenst@chromium.org Reviewed-by: Markus Schneider-Pargmann msp@baylibre.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/mediatek/clk-mt8173-apmixedsys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/mediatek/clk-mt8173-apmixedsys.c b/drivers/clk/mediatek/clk-mt8173-apmixedsys.c index a56c5845d07a5..a335d076d3f28 100644 --- a/drivers/clk/mediatek/clk-mt8173-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8173-apmixedsys.c @@ -92,7 +92,7 @@ static int clk_mt8173_apmixed_probe(struct platform_device *pdev)
base = of_iomap(node, 0); if (!base) - return PTR_ERR(base); + return -ENOMEM;
clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK); if (IS_ERR_OR_NULL(clk_data))
From: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com
[ Upstream commit b270ae61730e0ebccee39a21dd3311d6896a38ae ]
In case of error after of_ioremap() the resource must be released: call iounmap() where appropriate to fix that.
Fixes: 41138fbf876c ("clk: mediatek: mt8173: Migrate to platform driver and common probe") Signed-off-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Link: https://lore.kernel.org/r/20230615122051.546985-4-angelogioacchino.delregno@... Reviewed-by: Chen-Yu Tsai wenst@chromium.org Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/mediatek/clk-mt8173-apmixedsys.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/mediatek/clk-mt8173-apmixedsys.c b/drivers/clk/mediatek/clk-mt8173-apmixedsys.c index a335d076d3f28..0b95d14c18042 100644 --- a/drivers/clk/mediatek/clk-mt8173-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8173-apmixedsys.c @@ -95,8 +95,10 @@ static int clk_mt8173_apmixed_probe(struct platform_device *pdev) return -ENOMEM;
clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK); - if (IS_ERR_OR_NULL(clk_data)) + if (IS_ERR_OR_NULL(clk_data)) { + iounmap(base); return -ENOMEM; + }
r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); if (r) @@ -127,6 +129,7 @@ static int clk_mt8173_apmixed_probe(struct platform_device *pdev) mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data); free_clk_data: mtk_free_clk_data(clk_data); + iounmap(base); return r; }
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit 144601f6228de5598f03e693822b60a95c367a17 ]
kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script).
Fixes: f491276a5168 ("clk: vc5: Allow Versaclock driver to support multiple instances") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230530093913.1656095-2-claudiu.beznea@microchip.... Reviewed-by: Luca Ceresoli luca.ceresoli@bootlin.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-versaclock5.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c index 5452471b7ba55..e9a7f3c91ae0e 100644 --- a/drivers/clk/clk-versaclock5.c +++ b/drivers/clk/clk-versaclock5.c @@ -1028,6 +1028,11 @@ static int vc5_probe(struct i2c_client *client) }
init.name = kasprintf(GFP_KERNEL, "%pOFn.mux", client->dev.of_node); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } + init.ops = &vc5_mux_ops; init.flags = 0; init.parent_names = parent_names; @@ -1042,6 +1047,10 @@ static int vc5_probe(struct i2c_client *client) memset(&init, 0, sizeof(init)); init.name = kasprintf(GFP_KERNEL, "%pOFn.dbl", client->dev.of_node); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } init.ops = &vc5_dbl_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names; @@ -1057,6 +1066,10 @@ static int vc5_probe(struct i2c_client *client) /* Register PFD */ memset(&init, 0, sizeof(init)); init.name = kasprintf(GFP_KERNEL, "%pOFn.pfd", client->dev.of_node); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } init.ops = &vc5_pfd_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names; @@ -1074,6 +1087,10 @@ static int vc5_probe(struct i2c_client *client) /* Register PLL */ memset(&init, 0, sizeof(init)); init.name = kasprintf(GFP_KERNEL, "%pOFn.pll", client->dev.of_node); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } init.ops = &vc5_pll_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names; @@ -1093,6 +1110,10 @@ static int vc5_probe(struct i2c_client *client) memset(&init, 0, sizeof(init)); init.name = kasprintf(GFP_KERNEL, "%pOFn.fod%d", client->dev.of_node, idx); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } init.ops = &vc5_fod_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names; @@ -1111,6 +1132,10 @@ static int vc5_probe(struct i2c_client *client) memset(&init, 0, sizeof(init)); init.name = kasprintf(GFP_KERNEL, "%pOFn.out0_sel_i2cb", client->dev.of_node); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } init.ops = &vc5_clk_out_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names; @@ -1137,6 +1162,10 @@ static int vc5_probe(struct i2c_client *client) memset(&init, 0, sizeof(init)); init.name = kasprintf(GFP_KERNEL, "%pOFn.out%d", client->dev.of_node, idx + 1); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } init.ops = &vc5_clk_out_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names;
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit bb7d09ddbf361d51eae46f38e7c8a2b85914ea2a ]
kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script).
Fixes: 19fbbbbcd3a3 ("Add TI CDCE925 I2C controlled clock synthesizer driver") Depends-on: e665f029a283 ("clk: Convert to using %pOFn instead of device_node.name") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230530093913.1656095-3-claudiu.beznea@microchip.... Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-cdce925.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/drivers/clk/clk-cdce925.c b/drivers/clk/clk-cdce925.c index 6350682f7e6d2..87890669297d8 100644 --- a/drivers/clk/clk-cdce925.c +++ b/drivers/clk/clk-cdce925.c @@ -701,6 +701,10 @@ static int cdce925_probe(struct i2c_client *client) for (i = 0; i < data->chip_info->num_plls; ++i) { pll_clk_name[i] = kasprintf(GFP_KERNEL, "%pOFn.pll%d", client->dev.of_node, i); + if (!pll_clk_name[i]) { + err = -ENOMEM; + goto error; + } init.name = pll_clk_name[i]; data->pll[i].chip = data; data->pll[i].hw.init = &init; @@ -742,6 +746,10 @@ static int cdce925_probe(struct i2c_client *client) init.num_parents = 1; init.parent_names = &parent_name; /* Mux Y1 to input */ init.name = kasprintf(GFP_KERNEL, "%pOFn.Y1", client->dev.of_node); + if (!init.name) { + err = -ENOMEM; + goto error; + } data->clk[0].chip = data; data->clk[0].hw.init = &init; data->clk[0].index = 0; @@ -760,6 +768,10 @@ static int cdce925_probe(struct i2c_client *client) for (i = 1; i < data->chip_info->num_outputs; ++i) { init.name = kasprintf(GFP_KERNEL, "%pOFn.Y%d", client->dev.of_node, i+1); + if (!init.name) { + err = -ENOMEM; + goto error; + } data->clk[i].chip = data; data->clk[i].hw.init = &init; data->clk[i].index = i;
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit 2560114c06d7a752b3f4639f28cece58fed11267 ]
In case devm_clk_hw_register() fails for one of synth clocks the probe continues. Later on, when registering output clocks which have as parents all the synth clocks, in case there is registration failure for at least one synth clock the information passed to clk core for registering output clock is not right: init.num_parents is fixed but init.parents may contain an array with less parents.
Fixes: 3044a860fd09 ("clk: Add Si5341/Si5340 driver") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230530093913.1656095-4-claudiu.beznea@microchip.... Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-si5341.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c index 0e528d7ba656e..6dca3288c8940 100644 --- a/drivers/clk/clk-si5341.c +++ b/drivers/clk/clk-si5341.c @@ -1553,7 +1553,7 @@ static int si5341_probe(struct i2c_client *client) struct clk_init_data init; struct clk *input; const char *root_clock_name; - const char *synth_clock_names[SI5341_NUM_SYNTH]; + const char *synth_clock_names[SI5341_NUM_SYNTH] = { NULL }; int err; unsigned int i; struct clk_si5341_output_config config[SI5341_MAX_NUM_OUTPUTS]; @@ -1705,6 +1705,7 @@ static int si5341_probe(struct i2c_client *client) if (err) { dev_err(&client->dev, "synth N%u registration failed\n", i); + goto free_clk_names; } }
@@ -1782,16 +1783,17 @@ static int si5341_probe(struct i2c_client *client) goto cleanup; }
+free_clk_names: /* Free the names, clk framework makes copies */ for (i = 0; i < data->num_synth; ++i) devm_kfree(&client->dev, (void *)synth_clock_names[i]);
- return 0; - cleanup: - for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) { - if (data->clk[i].vddo_reg) - regulator_disable(data->clk[i].vddo_reg); + if (err) { + for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) { + if (data->clk[i].vddo_reg) + regulator_disable(data->clk[i].vddo_reg); + } } return err; }
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit 36e4ef82016a2b785cf2317eade77e76699b7bff ]
{devm_}kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script).
Fixes: 3044a860fd09 ("clk: Add Si5341/Si5340 driver") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230530093913.1656095-5-claudiu.beznea@microchip.... Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-si5341.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c index 6dca3288c8940..b2cf7edc8b308 100644 --- a/drivers/clk/clk-si5341.c +++ b/drivers/clk/clk-si5341.c @@ -1697,6 +1697,10 @@ static int si5341_probe(struct i2c_client *client) for (i = 0; i < data->num_synth; ++i) { synth_clock_names[i] = devm_kasprintf(&client->dev, GFP_KERNEL, "%s.N%u", client->dev.of_node->name, i); + if (!synth_clock_names[i]) { + err = -ENOMEM; + goto free_clk_names; + } init.name = synth_clock_names[i]; data->synth[i].index = i; data->synth[i].data = data; @@ -1715,6 +1719,10 @@ static int si5341_probe(struct i2c_client *client) for (i = 0; i < data->num_outputs; ++i) { init.name = kasprintf(GFP_KERNEL, "%s.%d", client->dev.of_node->name, i); + if (!init.name) { + err = -ENOMEM; + goto free_clk_names; + } init.flags = config[i].synth_master ? CLK_SET_RATE_PARENT : 0; data->clk[i].index = i; data->clk[i].data = data;
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit 267ad94b13c53d8c99a336f0841b1fa1595b1d0f ]
Pointers from synth_clock_names[] should be freed at the end of probe either on probe success or failure path.
Fixes: b7bbf6ec4940 ("clk: si5341: Allow different output VDD_SEL values") Fixes: 9b13ff4340df ("clk: si5341: Add sysfs properties to allow checking/resetting device faults") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230530093913.1656095-6-claudiu.beznea@microchip.... Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-si5341.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c index b2cf7edc8b308..c7d8cbd22bacc 100644 --- a/drivers/clk/clk-si5341.c +++ b/drivers/clk/clk-si5341.c @@ -1744,7 +1744,7 @@ static int si5341_probe(struct i2c_client *client) if (err) { dev_err(&client->dev, "output %u registration failed\n", i); - goto cleanup; + goto free_clk_names; } if (config[i].always_on) clk_prepare(data->clk[i].hw.clk); @@ -1754,7 +1754,7 @@ static int si5341_probe(struct i2c_client *client) data); if (err) { dev_err(&client->dev, "unable to add clk provider\n"); - goto cleanup; + goto free_clk_names; }
if (initialization_required) { @@ -1762,11 +1762,11 @@ static int si5341_probe(struct i2c_client *client) regcache_cache_only(data->regmap, false); err = regcache_sync(data->regmap); if (err < 0) - goto cleanup; + goto free_clk_names;
err = si5341_finalize_defaults(data); if (err < 0) - goto cleanup; + goto free_clk_names; }
/* wait for device to report input clock present and PLL lock */ @@ -1775,21 +1775,19 @@ static int si5341_probe(struct i2c_client *client) 10000, 250000); if (err) { dev_err(&client->dev, "Error waiting for input clock or PLL lock\n"); - goto cleanup; + goto free_clk_names; }
/* clear sticky alarm bits from initialization */ err = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0); if (err) { dev_err(&client->dev, "unable to clear sticky status\n"); - goto cleanup; + goto free_clk_names; }
err = sysfs_create_files(&client->dev.kobj, si5341_attributes); - if (err) { + if (err) dev_err(&client->dev, "unable to create sysfs files\n"); - goto cleanup; - }
free_clk_names: /* Free the names, clk framework makes copies */
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit b73ed981da6d25c921aaefa7ca3df85bbd85b7fc ]
kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script).
Fixes: b745c0794e2f ("clk: keystone: Add sci-clk driver support") Depends-on: 96488c09b0f4 ("clk: keystone: sci-clk: cut down the clock name length") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230530093913.1656095-7-claudiu.beznea@microchip.... Reviewed-by: Tony Lindgren tony@atomide.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/keystone/sci-clk.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c index d4b4e74e22da6..254f2cf24be21 100644 --- a/drivers/clk/keystone/sci-clk.c +++ b/drivers/clk/keystone/sci-clk.c @@ -294,6 +294,8 @@ static int _sci_clk_build(struct sci_clk_provider *provider,
name = kasprintf(GFP_KERNEL, "clk:%d:%d", sci_clk->dev_id, sci_clk->clk_id); + if (!name) + return -ENOMEM;
init.name = name;
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit bd46cd0b802d9c9576ca78007aa084ae3e74907b ]
kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script).
Fixes: 852049594b9a ("clk: ti: clkctrl: convert subclocks to use proper names also") Fixes: 6c3090520554 ("clk: ti: clkctrl: Fix hidden dependency to node name") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230530093913.1656095-8-claudiu.beznea@microchip.... Reviewed-by: Tony Lindgren tony@atomide.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/ti/clkctrl.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index f73f402ff7de9..87e5624789ef6 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -258,6 +258,9 @@ static const char * __init clkctrl_get_clock_name(struct device_node *np, if (clkctrl_name && !legacy_naming) { clock_name = kasprintf(GFP_KERNEL, "%s-clkctrl:%04x:%d", clkctrl_name, offset, index); + if (!clock_name) + return NULL; + strreplace(clock_name, '_', '-');
return clock_name; @@ -586,6 +589,10 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) if (clkctrl_name) { provider->clkdm_name = kasprintf(GFP_KERNEL, "%s_clkdm", clkctrl_name); + if (!provider->clkdm_name) { + kfree(provider); + return; + } goto clkdm_found; }
From: Alexey Romanov avromanov@sberdevices.ru
[ Upstream commit 0bb4644d583789c97e74d3e3047189f0c59c4742 ]
Starting from commit e45f243409db ("firmware: meson_sm: populate platform devices from sm device tree data") pwrc is probed successfully and disables unused pwr domains. By A1 SoC family design, any TEE requires DMA pwr domain always enabled.
Fixes: b3dde5013e13 ("soc: amlogic: Add support for Secure power domains controller") Signed-off-by: Alexey Romanov avromanov@sberdevices.ru Acked-by: Neil Armstrong neil.armstrong@linaro.org Link: https://lore.kernel.org/r/20230610090414.90529-1-avromanov@sberdevices.ru [narmstrong: added fixes tag] Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/amlogic/meson-secure-pwrc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soc/amlogic/meson-secure-pwrc.c b/drivers/soc/amlogic/meson-secure-pwrc.c index e935187635267..25b4b71df9b89 100644 --- a/drivers/soc/amlogic/meson-secure-pwrc.c +++ b/drivers/soc/amlogic/meson-secure-pwrc.c @@ -105,7 +105,7 @@ static struct meson_secure_pwrc_domain_desc a1_pwrc_domains[] = { SEC_PD(ACODEC, 0), SEC_PD(AUDIO, 0), SEC_PD(OTP, 0), - SEC_PD(DMA, 0), + SEC_PD(DMA, GENPD_FLAG_ALWAYS_ON | GENPD_FLAG_IRQ_SAFE), SEC_PD(SD_EMMC, 0), SEC_PD(RAMA, 0), /* SRAMB is used as ATF runtime memory, and should be always on */
From: Amir Goldstein amir73il@gmail.com
[ Upstream commit b07d5cc93e1b28df47a72c519d09d0a836043613 ]
After copy up, we may need to update d_flags if upper dentry is on a remote fs and lower dentries are not.
Add helpers to allow incremental update of the revalidate flags.
Fixes: bccece1ead36 ("ovl: allow remote upper") Reviewed-by: Gao Xiang hsiangkao@linux.alibaba.com Signed-off-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/overlayfs/copy_up.c | 2 ++ fs/overlayfs/dir.c | 3 +-- fs/overlayfs/export.c | 3 +-- fs/overlayfs/namei.c | 3 +-- fs/overlayfs/overlayfs.h | 6 ++++-- fs/overlayfs/super.c | 2 +- fs/overlayfs/util.c | 24 ++++++++++++++++++++---- 7 files changed, 30 insertions(+), 13 deletions(-)
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index c14e90764e356..7bf101e756c8c 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -576,6 +576,7 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c) /* Restore timestamps on parent (best effort) */ ovl_set_timestamps(ofs, upperdir, &c->pstat); ovl_dentry_set_upper_alias(c->dentry); + ovl_dentry_update_reval(c->dentry, upper); } } inode_unlock(udir); @@ -895,6 +896,7 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c) inode_unlock(udir);
ovl_dentry_set_upper_alias(c->dentry); + ovl_dentry_update_reval(c->dentry, ovl_dentry_upper(c->dentry)); }
out: diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index fc25fb95d5fc0..9be52d8013c83 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -269,8 +269,7 @@ static int ovl_instantiate(struct dentry *dentry, struct inode *inode,
ovl_dir_modified(dentry->d_parent, false); ovl_dentry_set_upper_alias(dentry); - ovl_dentry_update_reval(dentry, newdentry, - DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE); + ovl_dentry_init_reval(dentry, newdentry);
if (!hardlink) { /* diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c index defd4e231ad2c..5c36fb3a7bab1 100644 --- a/fs/overlayfs/export.c +++ b/fs/overlayfs/export.c @@ -326,8 +326,7 @@ static struct dentry *ovl_obtain_alias(struct super_block *sb, if (upper_alias) ovl_dentry_set_upper_alias(dentry);
- ovl_dentry_update_reval(dentry, upper, - DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE); + ovl_dentry_init_reval(dentry, upper);
return d_instantiate_anon(dentry, inode);
diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index cfb3420b7df0e..100a492d2b2a6 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -1122,8 +1122,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, ovl_set_flag(OVL_UPPERDATA, inode); }
- ovl_dentry_update_reval(dentry, upperdentry, - DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE); + ovl_dentry_init_reval(dentry, upperdentry);
revert_creds(old_cred); if (origin_path) { diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 4d0b278f5630e..e100c55bb924a 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -375,8 +375,10 @@ bool ovl_index_all(struct super_block *sb); bool ovl_verify_lower(struct super_block *sb); struct ovl_entry *ovl_alloc_entry(unsigned int numlower); bool ovl_dentry_remote(struct dentry *dentry); -void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *upperdentry, - unsigned int mask); +void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *realdentry); +void ovl_dentry_init_reval(struct dentry *dentry, struct dentry *upperdentry); +void ovl_dentry_init_flags(struct dentry *dentry, struct dentry *upperdentry, + unsigned int mask); bool ovl_dentry_weird(struct dentry *dentry); enum ovl_path_type ovl_path_type(struct dentry *dentry); void ovl_path_upper(struct dentry *dentry, struct path *path); diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index f1d9f75f8786c..49b6956468f9e 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -1885,7 +1885,7 @@ static struct dentry *ovl_get_root(struct super_block *sb, ovl_dentry_set_flag(OVL_E_CONNECTED, root); ovl_set_upperdata(d_inode(root)); ovl_inode_init(d_inode(root), &oip, ino, fsid); - ovl_dentry_update_reval(root, upperdentry, DCACHE_OP_WEAK_REVALIDATE); + ovl_dentry_init_flags(root, upperdentry, DCACHE_OP_WEAK_REVALIDATE);
return root; } diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 923d66d131c16..6a0652bd51f24 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -94,14 +94,30 @@ struct ovl_entry *ovl_alloc_entry(unsigned int numlower) return oe; }
+#define OVL_D_REVALIDATE (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE) + bool ovl_dentry_remote(struct dentry *dentry) { - return dentry->d_flags & - (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE); + return dentry->d_flags & OVL_D_REVALIDATE; +} + +void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *realdentry) +{ + if (!ovl_dentry_remote(realdentry)) + return; + + spin_lock(&dentry->d_lock); + dentry->d_flags |= realdentry->d_flags & OVL_D_REVALIDATE; + spin_unlock(&dentry->d_lock); +} + +void ovl_dentry_init_reval(struct dentry *dentry, struct dentry *upperdentry) +{ + return ovl_dentry_init_flags(dentry, upperdentry, OVL_D_REVALIDATE); }
-void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *upperdentry, - unsigned int mask) +void ovl_dentry_init_flags(struct dentry *dentry, struct dentry *upperdentry, + unsigned int mask) { struct ovl_entry *oe = OVL_E(dentry); unsigned int i, flags = 0;
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit 2f76e1d6ca524a888d29aafe29f2ad2003857971 ]
devm_kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script).
Fixes: b86ef5367761 ("ASoC: fsl: Add Audio Mixer machine driver") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230614121509.443926-1-claudiu.beznea@microchip.c... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/imx-audmix.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c index 1292a845c4244..d8e99b263ab21 100644 --- a/sound/soc/fsl/imx-audmix.c +++ b/sound/soc/fsl/imx-audmix.c @@ -228,6 +228,8 @@ static int imx_audmix_probe(struct platform_device *pdev)
dai_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%s", fe_name_pref, args.np->full_name + 1); + if (!dai_name) + return -ENOMEM;
dev_info(pdev->dev.parent, "DAI FE name:%s\n", dai_name);
@@ -236,6 +238,8 @@ static int imx_audmix_probe(struct platform_device *pdev) capture_dai_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s", dai_name, "CPU-Capture"); + if (!capture_dai_name) + return -ENOMEM; }
priv->dai[i].cpus = &dlc[0]; @@ -266,6 +270,8 @@ static int imx_audmix_probe(struct platform_device *pdev) "AUDMIX-Playback-%d", i); be_cp = devm_kasprintf(&pdev->dev, GFP_KERNEL, "AUDMIX-Capture-%d", i); + if (!be_name || !be_pb || !be_cp) + return -ENOMEM;
priv->dai[num_dai + i].cpus = &dlc[3]; priv->dai[num_dai + i].codecs = &dlc[4]; @@ -293,6 +299,9 @@ static int imx_audmix_probe(struct platform_device *pdev) priv->dapm_routes[i].source = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s", dai_name, "CPU-Playback"); + if (!priv->dapm_routes[i].source) + return -ENOMEM; + priv->dapm_routes[i].sink = be_pb; priv->dapm_routes[num_dai + i].source = be_pb; priv->dapm_routes[num_dai + i].sink = be_cp;
From: Fei Shao fshao@chromium.org
[ Upstream commit 7fb933e56f77a57ef7cfc59fc34cbbf1b1fa31ff ]
devm_clk_notifier_register() allocates a devres resource for clk notifier but didn't register that to the device, so the notifier didn't get unregistered on device detach and the allocated resource was leaked.
Fix the issue by registering the resource through devres_add().
This issue was found with kmemleak on a Chromebook.
Fixes: 6d30d50d037d ("clk: add devm variant of clk_notifier_register") Signed-off-by: Fei Shao fshao@chromium.org Link: https://lore.kernel.org/r/20230619112253.v2.1.I13f060c10549ef181603e921291bd... Reviewed-by: Dan Carpenter dan.carpenter@linaro.org Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 657b27743c4dd..15a405a5582bb 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -4694,6 +4694,7 @@ int devm_clk_notifier_register(struct device *dev, struct clk *clk, if (!ret) { devres->clk = clk; devres->nb = nb; + devres_add(dev, devres); } else { devres_free(devres); }
From: Michael Walle mwalle@kernel.org
[ Upstream commit bfcd5714f6424c03e385e0e9296dcd69855cfea7 ]
The pinctrl node was missing which change the pin mux to GPIO mode. Add it.
Fixes: 79d83b3a458e ("ARM: dts: lan966x: add basic Kontron KSwitch D10 support") Signed-off-by: Michael Walle mwalle@kernel.org [claudiu.beznea: moved pinctrl-* bindings after compatible] Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230616-feature-d10-dt-cleanups-v1-1-50dd0452b8fe... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi b/arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi index 0097e72e3fb22..42be207509a46 100644 --- a/arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi +++ b/arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi @@ -18,6 +18,8 @@ chosen {
gpio-restart { compatible = "gpio-restart"; + pinctrl-0 = <&reset_pins>; + pinctrl-names = "default"; gpios = <&gpio 56 GPIO_ACTIVE_LOW>; priority = <200>; }; @@ -59,6 +61,12 @@ miim_c_pins: miim-c-pins { function = "miim_c"; };
+ reset_pins: reset-pins { + /* SYS_RST# */ + pins = "GPIO_56"; + function = "gpio"; + }; + sgpio_a_pins: sgpio-a-pins { /* SCK, D0, D1 */ pins = "GPIO_32", "GPIO_33", "GPIO_34";
From: Michael Walle mwalle@kernel.org
[ Upstream commit fcb79ee3f0b15ed15f35eca5f24e952fdced9c61 ]
The pinctrl node was missing which change the pin mux to GPIO mode. Add it so we don't have to rely on the bootloader to set the correct mode.
Fixes: 79d83b3a458e ("ARM: dts: lan966x: add basic Kontron KSwitch D10 support") Signed-off-by: Michael Walle mwalle@kernel.org Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230616-feature-d10-dt-cleanups-v1-2-50dd0452b8fe... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi b/arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi index 42be207509a46..f4df4cc1dfa5e 100644 --- a/arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi +++ b/arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi @@ -41,7 +41,7 @@ &flx3 { status = "okay";
spi3: spi@400 { - pinctrl-0 = <&fc3_b_pins>; + pinctrl-0 = <&fc3_b_pins>, <&spi3_cs_pins>; pinctrl-names = "default"; status = "okay"; cs-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; @@ -79,6 +79,12 @@ sgpio_b_pins: sgpio-b-pins { function = "sgpio_b"; };
+ spi3_cs_pins: spi3-cs-pins { + /* CS# */ + pins = "GPIO_46"; + function = "gpio"; + }; + usart0_pins: usart0-pins { /* RXD, TXD */ pins = "GPIO_25", "GPIO_26";
From: Syed Saba Kareem Syed.SabaKareem@amd.com
[ Upstream commit ad60672394bd1f95c58d3d9336902f47e05126fc ]
Clear pdm dma interrupt mask in acp_dmic_shutdown().
'Fixes: c32bd332ce5c9 ("ASoC: amd: acp: Add generic support for PDM controller on ACP")'
Signed-off-by: Syed Saba Kareem Syed.SabaKareem@amd.com Link: https://lore.kernel.org/r/Message-Id: 20230622152406.3709231-1-Syed.SabaKareem@amd.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/amd/acp/acp-pdm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/amd/acp/acp-pdm.c b/sound/soc/amd/acp/acp-pdm.c index 66ec6b6a59723..f8030b79ac17c 100644 --- a/sound/soc/amd/acp/acp-pdm.c +++ b/sound/soc/amd/acp/acp-pdm.c @@ -176,7 +176,7 @@ static void acp_dmic_dai_shutdown(struct snd_pcm_substream *substream,
/* Disable DMIC interrupts */ ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0)); - ext_int_ctrl |= ~PDM_DMA_INTR_MASK; + ext_int_ctrl &= ~PDM_DMA_INTR_MASK; writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0)); }
From: Paul Cercueil paul@crapouillou.net
[ Upstream commit fbf1e42093f8d6346baf17079585fbcebb2ff284 ]
Provide parent regulators to the ACT8600 regulators that need one.
Signed-off-by: Paul Cercueil paul@crapouillou.net Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Stable-dep-of: 944520f85d5b ("MIPS: DTS: CI20: Raise VDDCORE voltage to 1.125 volts") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/boot/dts/ingenic/ci20.dts | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts index 2b1284c6c64a6..eac6b3411b5f7 100644 --- a/arch/mips/boot/dts/ingenic/ci20.dts +++ b/arch/mips/boot/dts/ingenic/ci20.dts @@ -242,16 +242,19 @@ regulators { vddcore: DCDC1 { regulator-min-microvolt = <1100000>; regulator-max-microvolt = <1100000>; + vp1-supply = <&vcc_33v>; regulator-always-on; }; vddmem: DCDC2 { regulator-min-microvolt = <1500000>; regulator-max-microvolt = <1500000>; + vp2-supply = <&vcc_33v>; regulator-always-on; }; vcc_33: DCDC3 { regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; + vp3-supply = <&vcc_33v>; regulator-always-on; }; vcc_50: SUDCDC_REG4 { @@ -262,21 +265,25 @@ vcc_50: SUDCDC_REG4 { vcc_25: LDO5 { regulator-min-microvolt = <2500000>; regulator-max-microvolt = <2500000>; + inl-supply = <&vcc_33v>; regulator-always-on; }; wifi_io: LDO6 { regulator-min-microvolt = <2500000>; regulator-max-microvolt = <2500000>; + inl-supply = <&vcc_33v>; regulator-always-on; }; cim_io_28: LDO7 { regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; + inl-supply = <&vcc_33v>; regulator-always-on; }; cim_io_15: LDO8 { regulator-min-microvolt = <1500000>; regulator-max-microvolt = <1500000>; + inl-supply = <&vcc_33v>; regulator-always-on; }; vrtc_18: LDO_REG9 {
From: Paul Cercueil paul@crapouillou.net
[ Upstream commit 944520f85d5b1fb2f9ea243be41f9c9af3d4cef3 ]
Commit 08384e80a70f ("MIPS: DTS: CI20: Fix ACT8600 regulator node names") caused the VDDCORE power supply (regulated by the ACT8600's DCDC1 output) to drop from a voltage of 1.2V configured by the bootloader, to the 1.1V set in the Device Tree.
According to the documentation, the VDDCORE supply should be between 0.99V and 1.21V; both values are therefore within the supported range.
However, VDDCORE being 1.1V results in the CI20 being very unstable, with corrupted memory, failures to boot, or reboots at random. The reason might be succint drops of the voltage below the minimum required.
Raising the minimum voltage to 1.125 volts seems to be enough to address this issue, while still keeping a relatively low core voltage which helps for power consumption and thermals.
Fixes: 08384e80a70f ("MIPS: DTS: CI20: Fix ACT8600 regulator node names") Signed-off-by: Paul Cercueil paul@crapouillou.net Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/boot/dts/ingenic/ci20.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts index eac6b3411b5f7..c0f6c4d3618e1 100644 --- a/arch/mips/boot/dts/ingenic/ci20.dts +++ b/arch/mips/boot/dts/ingenic/ci20.dts @@ -240,8 +240,8 @@ act8600: act8600@5a {
regulators { vddcore: DCDC1 { - regulator-min-microvolt = <1100000>; - regulator-max-microvolt = <1100000>; + regulator-min-microvolt = <1125000>; + regulator-max-microvolt = <1125000>; vp1-supply = <&vcc_33v>; regulator-always-on; };
From: Jason Gunthorpe jgg@nvidia.com
[ Upstream commit 804ca14d04df09bf7924bacc5ad22a4bed80c94f ]
A concurrent unmap can trigger freeing of the area pointers while we are generating an unmapping notification for accesses.
syzkaller reports:
BUG: KASAN: slab-use-after-free in iopt_unmap_iova_range+0x5ba/0x5f0 Read of size 4 at addr ffff888075996184 by task syz-executor.2/31160
CPU: 1 PID: 31160 Comm: syz-executor.2 Not tainted 6.4.0-rc5-syzkaller-00313-g4c605260bc60 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/25/2023 Call Trace: <TASK> dump_stack_lvl+0xd9/0x150 print_address_description.constprop.0+0x2c/0x3c0 kasan_report+0x11c/0x130 iopt_unmap_iova_range+0x5ba/0x5f0 iopt_unmap_all+0x27/0x50 iommufd_ioas_unmap+0x3d0/0x490 iommufd_fops_ioctl+0x317/0x4b0 __x64_sys_ioctl+0x197/0x210 do_syscall_64+0x39/0xb0 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f0812c8c169 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 f1 19 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f0813914168 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007f0812dabf80 RCX: 00007f0812c8c169 RDX: 0000000020000100 RSI: 0000000000003b86 RDI: 0000000000000005 RBP: 00007f0812ce7ca1 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007f0812ecfb1f R14: 00007f0813914300 R15: 0000000000022000 </TASK>
Allocated by task 31160: kasan_save_stack+0x22/0x40 kasan_set_track+0x25/0x30 __kasan_kmalloc+0xa2/0xb0 iopt_alloc_area_pages+0x94/0x560 iopt_map_user_pages+0x205/0x4e0 iommufd_ioas_map+0x329/0x5f0 iommufd_fops_ioctl+0x317/0x4b0 __x64_sys_ioctl+0x197/0x210 do_syscall_64+0x39/0xb0 entry_SYSCALL_64_after_hwframe+0x63/0xcd
Freed by task 31161: kasan_save_stack+0x22/0x40 kasan_set_track+0x25/0x30 kasan_save_free_info+0x2e/0x40 ____kasan_slab_free+0x160/0x1c0 slab_free_freelist_hook+0x8b/0x1c0 __kmem_cache_free+0xaf/0x2d0 iopt_unmap_iova_range+0x288/0x5f0 iopt_unmap_all+0x27/0x50 iommufd_ioas_unmap+0x3d0/0x490 iommufd_fops_ioctl+0x317/0x4b0 __x64_sys_ioctl+0x197/0x210 do_syscall_64+0x39/0xb0 entry_SYSCALL_64_after_hwframe+0x63/0xcd
The buggy address belongs to the object at ffff888075996100 which belongs to the cache kmalloc-cg-192 of size 192 The buggy address is located 132 bytes inside of freed 192-byte region [ffff888075996100, ffff8880759961c0)
The buggy address belongs to the physical page: page:ffffea0001d66580 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x75996 memcg:ffff88801f1c2701 flags: 0xfff00000000200(slab|node=0|zone=1|lastcpupid=0x7ff) page_type: 0xffffffff() raw: 00fff00000000200 ffff88801244ddc0 dead000000000122 0000000000000000 raw: 0000000000000000 0000000080100010 00000001ffffffff ffff88801f1c2701 page dumped because: kasan: bad access detected page_owner tracks the page as allocated page last allocated via order 0, migratetype Unmovable, gfp_mask 0x112cc0(GFP_USER|__GFP_NOWARN|__GFP_NORETRY), pid 31157, tgid 31154 (syz-executor.0), ts 1984547323469, free_ts 1983933451331 post_alloc_hook+0x2db/0x350 get_page_from_freelist+0xf41/0x2c00 __alloc_pages+0x1cb/0x4a0 alloc_pages+0x1aa/0x270 allocate_slab+0x25f/0x390 ___slab_alloc+0xa91/0x1400 __slab_alloc.constprop.0+0x56/0xa0 __kmem_cache_alloc_node+0x136/0x320 kmalloc_trace+0x26/0xe0 iommufd_test+0x1328/0x2c20 iommufd_fops_ioctl+0x317/0x4b0 __x64_sys_ioctl+0x197/0x210 do_syscall_64+0x39/0xb0 entry_SYSCALL_64_after_hwframe+0x63/0xcd page last free stack trace: free_unref_page_prepare+0x62e/0xcb0 free_unref_page_list+0xe3/0xa70 release_pages+0xcd8/0x1380 tlb_batch_pages_flush+0xa8/0x1a0 tlb_finish_mmu+0x14b/0x7e0 exit_mmap+0x2b2/0x930 __mmput+0x128/0x4c0 mmput+0x60/0x70 do_exit+0x9b0/0x29b0 do_group_exit+0xd4/0x2a0 get_signal+0x2318/0x25b0 arch_do_signal_or_restart+0x79/0x5c0 exit_to_user_mode_prepare+0x11f/0x240 syscall_exit_to_user_mode+0x1d/0x50 do_syscall_64+0x46/0xb0 entry_SYSCALL_64_after_hwframe+0x63/0xcd
Precompute what is needed to call the access function and do not check the area's num_accesses again as the pointer may not be valid anymore. Use a counter instead.
Fixes: 51fe6141f0f6 ("iommufd: Data structure to provide IOVA to PFN mapping") Link: https://lore.kernel.org/r/1-v2-9a03761d445d+54-iommufd_syz2_jgg@nvidia.com Reviewed-by: Kevin Tian kevin.tian@intel.com Reported-by: syzbot+1ad12d16afca0e7d2dde@syzkaller.appspotmail.com Closes: https://lore.kernel.org/r/0000000000001d40fc05fe385332@google.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/iommufd/io_pagetable.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/iommu/iommufd/io_pagetable.c b/drivers/iommu/iommufd/io_pagetable.c index e0ae72b9e67f8..724c4c5742417 100644 --- a/drivers/iommu/iommufd/io_pagetable.c +++ b/drivers/iommu/iommufd/io_pagetable.c @@ -458,6 +458,7 @@ static int iopt_unmap_iova_range(struct io_pagetable *iopt, unsigned long start, { struct iopt_area *area; unsigned long unmapped_bytes = 0; + unsigned int tries = 0; int rc = -ENOENT;
/* @@ -484,19 +485,26 @@ static int iopt_unmap_iova_range(struct io_pagetable *iopt, unsigned long start, goto out_unlock_iova; }
+ if (area_first != start) + tries = 0; + /* * num_accesses writers must hold the iova_rwsem too, so we can * safely read it under the write side of the iovam_rwsem * without the pages->mutex. */ if (area->num_accesses) { + size_t length = iopt_area_length(area); + start = area_first; area->prevent_access = true; up_write(&iopt->iova_rwsem); up_read(&iopt->domains_rwsem); - iommufd_access_notify_unmap(iopt, area_first, - iopt_area_length(area)); - if (WARN_ON(READ_ONCE(area->num_accesses))) + + iommufd_access_notify_unmap(iopt, area_first, length); + /* Something is not responding to unmap requests. */ + tries++; + if (WARN_ON(tries > 100)) return -EDEADLOCK; goto again; }
From: Jason Gunthorpe jgg@nvidia.com
[ Upstream commit dbe245cdf5189e88d680379ed13901356628b650 ]
The iter internally holds a pointer to the area and iopt_area_contig_done() will dereference it. The pointer is not valid outside the iova_rwsem.
syzkaller reports:
BUG: KASAN: slab-use-after-free in iommufd_access_unpin_pages+0x363/0x370 Read of size 8 at addr ffff888022286e20 by task syz-executor669/5771
CPU: 0 PID: 5771 Comm: syz-executor669 Not tainted 6.4.0-rc5-syzkaller-00313-g4c605260bc60 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/25/2023 Call Trace: <TASK> dump_stack_lvl+0xd9/0x150 print_address_description.constprop.0+0x2c/0x3c0 kasan_report+0x11c/0x130 iommufd_access_unpin_pages+0x363/0x370 iommufd_test_access_unmap+0x24b/0x390 iommufd_access_notify_unmap+0x24c/0x3a0 iopt_unmap_iova_range+0x4c4/0x5f0 iopt_unmap_all+0x27/0x50 iommufd_ioas_unmap+0x3d0/0x490 iommufd_fops_ioctl+0x317/0x4b0 __x64_sys_ioctl+0x197/0x210 do_syscall_64+0x39/0xb0 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7fec1dae3b19 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 11 15 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fec1da74308 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007fec1db6b438 RCX: 00007fec1dae3b19 RDX: 0000000020000100 RSI: 0000000000003b86 RDI: 0000000000000003 RBP: 00007fec1db6b430 R08: 00007fec1da74700 R09: 0000000000000000 R10: 00007fec1da74700 R11: 0000000000000246 R12: 00007fec1db6b43c R13: 00007fec1db39074 R14: 6d6f692f7665642f R15: 0000000000022000 </TASK>
Allocated by task 5770: kasan_save_stack+0x22/0x40 kasan_set_track+0x25/0x30 __kasan_kmalloc+0xa2/0xb0 iopt_alloc_area_pages+0x94/0x560 iopt_map_user_pages+0x205/0x4e0 iommufd_ioas_map+0x329/0x5f0 iommufd_fops_ioctl+0x317/0x4b0 __x64_sys_ioctl+0x197/0x210 do_syscall_64+0x39/0xb0 entry_SYSCALL_64_after_hwframe+0x63/0xcd
Freed by task 5770: kasan_save_stack+0x22/0x40 kasan_set_track+0x25/0x30 kasan_save_free_info+0x2e/0x40 ____kasan_slab_free+0x160/0x1c0 slab_free_freelist_hook+0x8b/0x1c0 __kmem_cache_free+0xaf/0x2d0 iopt_unmap_iova_range+0x288/0x5f0 iopt_unmap_all+0x27/0x50 iommufd_ioas_unmap+0x3d0/0x490 iommufd_fops_ioctl+0x317/0x4b0 __x64_sys_ioctl+0x197/0x210 do_syscall_64+0x39/0xb0 entry_SYSCALL_64_after_hwframe+0x63/0xcd
The parallel unmap free'd iter->area the instant the lock was released.
Fixes: 51fe6141f0f6 ("iommufd: Data structure to provide IOVA to PFN mapping") Link: https://lore.kernel.org/r/2-v2-9a03761d445d+54-iommufd_syz2_jgg@nvidia.com Reviewed-by: Kevin Tian kevin.tian@intel.com Reported-by: syzbot+6c8d756f238a75fc3eb8@syzkaller.appspotmail.com Closes: https://lore.kernel.org/r/000000000000905eba05fe38e9f2@google.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/iommufd/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c index a0c66f47a65ad..532e12ea23efe 100644 --- a/drivers/iommu/iommufd/device.c +++ b/drivers/iommu/iommufd/device.c @@ -560,8 +560,8 @@ void iommufd_access_unpin_pages(struct iommufd_access *access, iopt_area_iova_to_index( area, min(last_iova, iopt_area_last_iova(area)))); - up_read(&iopt->iova_rwsem); WARN_ON(!iopt_area_contig_done(&iter)); + up_read(&iopt->iova_rwsem); } EXPORT_SYMBOL_NS_GPL(iommufd_access_unpin_pages, IOMMUFD);
From: Siddharth Vadapalli s-vadapalli@ti.com
[ Upstream commit 0e12f830236928b6fadf40d917a7527f0a048d2f ]
The Link Retraining process is initiated to account for the Gen2 defect in the Cadence PCIe controller in J721E SoC. The errata corresponding to this is i2085, documented at: https://www.ti.com/lit/er/sprz455c/sprz455c.pdf
The existing workaround implemented for the errata waits for the Data Link initialization to complete and assumes that the link retraining process at the Physical Layer has completed. However, it is possible that the Physical Layer training might be ongoing as indicated by the PCI_EXP_LNKSTA_LT bit in the PCI_EXP_LNKSTA register.
Fix the existing workaround, to ensure that the Physical Layer training has also completed, in addition to the Data Link initialization.
Link: https://lore.kernel.org/r/20230315070800.1615527-1-s-vadapalli@ti.com Fixes: 4740b969aaf5 ("PCI: cadence: Retrain Link to work around Gen2 training defect") Signed-off-by: Siddharth Vadapalli s-vadapalli@ti.com Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Reviewed-by: Vignesh Raghavendra vigneshr@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../controller/cadence/pcie-cadence-host.c | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c index 940c7dd701d68..5b14f7ee3c798 100644 --- a/drivers/pci/controller/cadence/pcie-cadence-host.c +++ b/drivers/pci/controller/cadence/pcie-cadence-host.c @@ -12,6 +12,8 @@
#include "pcie-cadence.h"
+#define LINK_RETRAIN_TIMEOUT HZ + static u64 bar_max_size[] = { [RP_BAR0] = _ULL(128 * SZ_2G), [RP_BAR1] = SZ_2G, @@ -77,6 +79,27 @@ static struct pci_ops cdns_pcie_host_ops = { .write = pci_generic_config_write, };
+static int cdns_pcie_host_training_complete(struct cdns_pcie *pcie) +{ + u32 pcie_cap_off = CDNS_PCIE_RP_CAP_OFFSET; + unsigned long end_jiffies; + u16 lnk_stat; + + /* Wait for link training to complete. Exit after timeout. */ + end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT; + do { + lnk_stat = cdns_pcie_rp_readw(pcie, pcie_cap_off + PCI_EXP_LNKSTA); + if (!(lnk_stat & PCI_EXP_LNKSTA_LT)) + break; + usleep_range(0, 1000); + } while (time_before(jiffies, end_jiffies)); + + if (!(lnk_stat & PCI_EXP_LNKSTA_LT)) + return 0; + + return -ETIMEDOUT; +} + static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie) { struct device *dev = pcie->dev; @@ -118,6 +141,10 @@ static int cdns_pcie_retrain(struct cdns_pcie *pcie) cdns_pcie_rp_writew(pcie, pcie_cap_off + PCI_EXP_LNKCTL, lnk_ctl);
+ ret = cdns_pcie_host_training_complete(pcie); + if (ret) + return ret; + ret = cdns_pcie_host_wait_for_link(pcie); } return ret;
From: Nirmal Patel nirmal.patel@linux.intel.com
[ Upstream commit b61cf04c49c3dfa70a0d6725d3eb40bf9b35cf71 ]
VMD driver can disable or enable MSI remapping by changing VMCONFIG_MSI_REMAP register. This register needs to be set to the default value during soft reboots. Drives failed to enumerate when Windows boots after performing a soft reboot from Linux. Windows doesn't support MSI remapping disable feature and stale register value hinders Windows VMD driver initialization process. Adding vmd_shutdown function to make sure to set the VMCONFIG register to the default value.
Link: https://lore.kernel.org/r/20230224202811.644370-1-nirmal.patel@linux.intel.c... Fixes: ee81ee84f873 ("PCI: vmd: Disable MSI-X remapping when possible") Signed-off-by: Nirmal Patel nirmal.patel@linux.intel.com Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Reviewed-by: Jon Derrick jonathan.derrick@linux.dev Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/vmd.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c index 990630ec57c6a..30ec18283aaf4 100644 --- a/drivers/pci/controller/vmd.c +++ b/drivers/pci/controller/vmd.c @@ -1036,6 +1036,13 @@ static void vmd_remove(struct pci_dev *dev) ida_simple_remove(&vmd_instance_ida, vmd->instance); }
+static void vmd_shutdown(struct pci_dev *dev) +{ + struct vmd_dev *vmd = pci_get_drvdata(dev); + + vmd_remove_irq_domain(vmd); +} + #ifdef CONFIG_PM_SLEEP static int vmd_suspend(struct device *dev) { @@ -1101,6 +1108,7 @@ static struct pci_driver vmd_drv = { .id_table = vmd_ids, .probe = vmd_probe, .remove = vmd_remove, + .shutdown = vmd_shutdown, .driver = { .pm = &vmd_dev_pm_ops, },
From: Jinhong Zhu jinhongzhu@hust.edu.cn
[ Upstream commit f025312b089474a54e4859f3453771314d9e3d4f ]
Smatch reported:
drivers/scsi/qedf/qedf_main.c:3056 qedf_alloc_global_queues() warn: missing unwind goto?
At this point in the function, nothing has been allocated so we can return directly. In particular the "qedf->global_queues" have not been allocated so calling qedf_free_global_queues() will lead to a NULL dereference when we check if (!gl[i]) and "gl" is NULL.
Fixes: 61d8658b4a43 ("scsi: qedf: Add QLogic FastLinQ offload FCoE driver framework.") Signed-off-by: Jinhong Zhu jinhongzhu@hust.edu.cn Link: https://lore.kernel.org/r/20230502140022.2852-1-jinhongzhu@hust.edu.cn Reviewed-by: Dan Carpenter error27@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qedf/qedf_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index 35e16600fc637..f2c7dd4db9c64 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -3043,9 +3043,8 @@ static int qedf_alloc_global_queues(struct qedf_ctx *qedf) * addresses of our queues */ if (!qedf->p_cpuq) { - status = -EINVAL; QEDF_ERR(&qedf->dbg_ctx, "p_cpuq is NULL.\n"); - goto mem_alloc_failure; + return -EINVAL; }
qedf->global_queues = kzalloc((sizeof(struct global_queue *)
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit cdf7e616120065007687fe1df0412154f259daec ]
gpiochip_add_pin_range() can fail, so better return its error code than a hard coded '0'.
Fixes: d2b67744fd99 ("pinctrl: bcm2835: implement hook for missing gpio-ranges") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Link: https://lore.kernel.org/r/98c3b5890bb72415145c9fe4e1d974711edae376.168168140... Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index 7435173e10f43..1489191a213fe 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -376,10 +376,8 @@ static int bcm2835_add_pin_ranges_fallback(struct gpio_chip *gc) if (!pctldev) return 0;
- gpiochip_add_pin_range(gc, pinctrl_dev_get_devname(pctldev), 0, 0, - gc->ngpio); - - return 0; + return gpiochip_add_pin_range(gc, pinctrl_dev_get_devname(pctldev), 0, 0, + gc->ngpio); }
static const struct gpio_chip bcm2835_gpio_chip = {
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 9148cd2eb4450a8e9c49c8a14201fb82f651128f ]
When yogabook_wmi_remove() runs yogabook_wmi_work might still be running and using the devices which yogabook_wmi_remove() puts.
To avoid this move to explicitly cancelling the work rather then using devm_work_autocancel().
This requires also making the yogabook_backside_hall_irq handler non devm managed, so that it cannot re-queue the work while yogabook_wmi_remove() runs.
Fixes: c0549b72d99d ("platform/x86: lenovo-yogabook-wmi: Add driver for Lenovo Yoga Book") Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20230430165807.472798-3-hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/lenovo-yogabook-wmi.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/platform/x86/lenovo-yogabook-wmi.c b/drivers/platform/x86/lenovo-yogabook-wmi.c index 5f4bd1eec38a9..3a6de4ab74a41 100644 --- a/drivers/platform/x86/lenovo-yogabook-wmi.c +++ b/drivers/platform/x86/lenovo-yogabook-wmi.c @@ -2,7 +2,6 @@ /* WMI driver for Lenovo Yoga Book YB1-X90* / -X91* tablets */
#include <linux/acpi.h> -#include <linux/devm-helpers.h> #include <linux/gpio/consumer.h> #include <linux/gpio/machine.h> #include <linux/interrupt.h> @@ -248,10 +247,7 @@ static int yogabook_wmi_probe(struct wmi_device *wdev, const void *context) data->brightness = YB_KBD_BL_DEFAULT; set_bit(YB_KBD_IS_ON, &data->flags); set_bit(YB_DIGITIZER_IS_ON, &data->flags); - - r = devm_work_autocancel(&wdev->dev, &data->work, yogabook_wmi_work); - if (r) - return r; + INIT_WORK(&data->work, yogabook_wmi_work);
data->kbd_adev = acpi_dev_get_first_match_dev("GDIX1001", NULL, -1); if (!data->kbd_adev) { @@ -299,10 +295,9 @@ static int yogabook_wmi_probe(struct wmi_device *wdev, const void *context) } data->backside_hall_irq = r;
- r = devm_request_irq(&wdev->dev, data->backside_hall_irq, - yogabook_backside_hall_irq, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "backside_hall_sw", data); + r = request_irq(data->backside_hall_irq, yogabook_backside_hall_irq, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + "backside_hall_sw", data); if (r) { dev_err_probe(&wdev->dev, r, "Requesting backside_hall_sw IRQ\n"); goto error_put_devs; @@ -318,11 +313,14 @@ static int yogabook_wmi_probe(struct wmi_device *wdev, const void *context) r = devm_led_classdev_register(&wdev->dev, &data->kbd_bl_led); if (r < 0) { dev_err_probe(&wdev->dev, r, "Registering backlight LED device\n"); - goto error_put_devs; + goto error_free_irq; }
return 0;
+error_free_irq: + free_irq(data->backside_hall_irq, data); + cancel_work_sync(&data->work); error_put_devs: put_device(data->dig_dev); put_device(data->kbd_dev); @@ -335,6 +333,8 @@ static void yogabook_wmi_remove(struct wmi_device *wdev) { struct yogabook_wmi *data = dev_get_drvdata(&wdev->dev);
+ free_irq(data->backside_hall_irq, data); + cancel_work_sync(&data->work); put_device(data->dig_dev); put_device(data->kbd_dev); acpi_dev_put(data->dig_adev);
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 711bcc0cb34e96a60e88d7b0260862781de3e530 ]
Ensure that both the keyboard touchscreen and the digitizer have their driver bound after remove(). Without this modprobing lenovo-yogabook-wmi after a rmmod fails because lenovo-yogabook-wmi defers probing until both devices have their driver bound.
Fixes: c0549b72d99d ("platform/x86: lenovo-yogabook-wmi: Add driver for Lenovo Yoga Book") Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20230430165807.472798-4-hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/lenovo-yogabook-wmi.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/platform/x86/lenovo-yogabook-wmi.c b/drivers/platform/x86/lenovo-yogabook-wmi.c index 3a6de4ab74a41..5948ffa74acd5 100644 --- a/drivers/platform/x86/lenovo-yogabook-wmi.c +++ b/drivers/platform/x86/lenovo-yogabook-wmi.c @@ -332,9 +332,20 @@ static int yogabook_wmi_probe(struct wmi_device *wdev, const void *context) static void yogabook_wmi_remove(struct wmi_device *wdev) { struct yogabook_wmi *data = dev_get_drvdata(&wdev->dev); + int r = 0;
free_irq(data->backside_hall_irq, data); cancel_work_sync(&data->work); + + if (!test_bit(YB_KBD_IS_ON, &data->flags)) + r |= device_reprobe(data->kbd_dev); + + if (!test_bit(YB_DIGITIZER_IS_ON, &data->flags)) + r |= device_reprobe(data->dig_dev); + + if (r) + dev_warn(&wdev->dev, "Reprobe of devices failed\n"); + put_device(data->dig_dev); put_device(data->kbd_dev); acpi_dev_put(data->dig_adev);
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 9e6380d6573181c555ca1b5019b08d19a9ee581c ]
Set default keyboard backlight brightness on probe(), this fixes the backlight being off after a rmmod + modprobe.
Fixes: c0549b72d99d ("platform/x86: lenovo-yogabook-wmi: Add driver for Lenovo Yoga Book") Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20230430165807.472798-5-hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/lenovo-yogabook-wmi.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/platform/x86/lenovo-yogabook-wmi.c b/drivers/platform/x86/lenovo-yogabook-wmi.c index 5948ffa74acd5..d57fcc8388519 100644 --- a/drivers/platform/x86/lenovo-yogabook-wmi.c +++ b/drivers/platform/x86/lenovo-yogabook-wmi.c @@ -295,6 +295,9 @@ static int yogabook_wmi_probe(struct wmi_device *wdev, const void *context) } data->backside_hall_irq = r;
+ /* Set default brightness before enabling the IRQ */ + yogabook_wmi_set_kbd_backlight(data->wdev, YB_KBD_BL_DEFAULT); + r = request_irq(data->backside_hall_irq, yogabook_backside_hall_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "backside_hall_sw", data);
From: Ding Hui dinghui@sangfor.com.cn
[ Upstream commit 456d8aa37d0f56fc9e985e812496e861dcd6f2f2 ]
Struct pcie_link_state->downstream is a pointer to the pci_dev of function 0. Previously we retained that pointer when removing function 0, and subsequent ASPM policy changes dereferenced it, resulting in a use-after-free warning from KASAN, e.g.:
# echo 1 > /sys/bus/pci/devices/0000:03:00.0/remove # echo powersave > /sys/module/pcie_aspm/parameters/policy
BUG: KASAN: slab-use-after-free in pcie_config_aspm_link+0x42d/0x500 Call Trace: kasan_report+0xae/0xe0 pcie_config_aspm_link+0x42d/0x500 pcie_aspm_set_policy+0x8e/0x1a0 param_attr_store+0x162/0x2c0 module_attr_store+0x3e/0x80
PCIe spec r6.0, sec 7.5.3.7, recommends that software program the same ASPM Control value in all functions of multi-function devices.
Disable ASPM and free the pcie_link_state when any child function is removed so we can discard the dangling pcie_link_state->downstream pointer and maintain the same ASPM Control configuration for all functions.
[bhelgaas: commit log and comment] Debugged-by: Zongquan Qin qinzongquan@sangfor.com.cn Suggested-by: Bjorn Helgaas bhelgaas@google.com Fixes: b5a0a9b59c81 ("PCI/ASPM: Read and set up L1 substate capabilities") Link: https://lore.kernel.org/r/20230507034057.20970-1-dinghui@sangfor.com.cn Signed-off-by: Ding Hui dinghui@sangfor.com.cn Signed-off-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/pcie/aspm.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 66d7514ca111b..db32335039d61 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -1010,21 +1010,24 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
down_read(&pci_bus_sem); mutex_lock(&aspm_lock); - /* - * All PCIe functions are in one slot, remove one function will remove - * the whole slot, so just wait until we are the last function left. - */ - if (!list_empty(&parent->subordinate->devices)) - goto out;
link = parent->link_state; root = link->root; parent_link = link->parent;
- /* All functions are removed, so just disable ASPM for the link */ + /* + * link->downstream is a pointer to the pci_dev of function 0. If + * we remove that function, the pci_dev is about to be deallocated, + * so we can't use link->downstream again. Free the link state to + * avoid this. + * + * If we're removing a non-0 function, it's possible we could + * retain the link state, but PCIe r6.0, sec 7.5.3.7, recommends + * programming the same ASPM Control value for all functions of + * multi-function devices, so disable ASPM for all of them. + */ pcie_config_aspm_link(link, 0); list_del(&link->sibling); - /* Clock PM is for endpoint device */ free_link_state(link);
/* Recheck latencies and configure upstream links */ @@ -1032,7 +1035,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) pcie_update_aspm_capable(root); pcie_config_aspm_path(parent_link); } -out: + mutex_unlock(&aspm_lock); up_read(&pci_bus_sem); }
From: Yuchen Yang u202114568@hust.edu.cn
[ Upstream commit 2e2fe5ac695a00ab03cab4db1f4d6be07168ed9d ]
Smatch complains that:
tw_probe() warn: missing error code 'retval'
This patch adds error checking to tw_probe() to handle initialization failure. If tw_reset_sequence() function returns a non-zero value, the function will return -EINVAL to indicate initialization failure.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Yuchen Yang u202114568@hust.edu.cn Link: https://lore.kernel.org/r/20230505141259.7730-1-u202114568@hust.edu.cn Reviewed-by: Dan Carpenter dan.carpenter@linaro.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/3w-xxxx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index ffdecb12d654c..9bd70e4618d52 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -2305,8 +2305,10 @@ static int tw_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id) TW_DISABLE_INTERRUPTS(tw_dev);
/* Initialize the card */ - if (tw_reset_sequence(tw_dev)) + if (tw_reset_sequence(tw_dev)) { + retval = -EINVAL; goto out_release_mem_region; + }
/* Set host specific parameters */ host->max_id = TW_MAX_UNITS;
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 415a099ea55ae716b69beefdcaa654b96087c016 ]
Replace devm_clk_get() by devm_clk_get_enabled() and drop unneeded code pieces. This will make sure we keep the ordering of the resource allocation correct.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Reviewed-by: Claudiu Beznea claudiu.beznea@microchip.com Tested-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230215134242.37618-3-andriy.shevchenko@linux.int... Signed-off-by: Linus Walleij linus.walleij@linaro.org Stable-dep-of: 35216718c9ac ("pinctrl: at91: fix a couple NULL vs IS_ERR() checks") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/pinctrl-at91.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 9fa68ca4a412d..f0b139a1cc3ed 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -1849,19 +1849,13 @@ static int at91_gpio_probe(struct platform_device *pdev) at91_chip->pioc_virq = irq; at91_chip->pioc_idx = alias_idx;
- at91_chip->clock = devm_clk_get(&pdev->dev, NULL); + at91_chip->clock = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(at91_chip->clock)) { dev_err(&pdev->dev, "failed to get clock, ignoring.\n"); ret = PTR_ERR(at91_chip->clock); goto err; }
- ret = clk_prepare_enable(at91_chip->clock); - if (ret) { - dev_err(&pdev->dev, "failed to prepare and enable clock, ignoring.\n"); - goto clk_enable_err; - } - at91_chip->chip = at91_gpio_template; at91_chip->id = alias_idx;
@@ -1882,7 +1876,7 @@ static int at91_gpio_probe(struct platform_device *pdev) names = devm_kasprintf_strarray(dev, "pio", chip->ngpio); if (!names) { ret = -ENOMEM; - goto clk_enable_err; + goto err; }
for (i = 0; i < chip->ngpio; i++) @@ -1915,8 +1909,6 @@ static int at91_gpio_probe(struct platform_device *pdev) return 0;
gpiochip_add_err: -clk_enable_err: - clk_disable_unprepare(at91_chip->clock); err: dev_err(&pdev->dev, "Failure %i for GPIO %i\n", ret, alias_idx);
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 472bbb2cfd6384fe4c4b956af2170c1225fe2a92 ]
The custom message has no value except printing the error code, the same does dev_err_probe(). Let's use the latter for the sake of unification.
Note that some APIs already have messaging in them and some simply do not require the current noise.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Reviewed-by: Claudiu Beznea claudiu.beznea@microchip.com Tested-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230215134242.37618-5-andriy.shevchenko@linux.int... Signed-off-by: Linus Walleij linus.walleij@linaro.org Stable-dep-of: 35216718c9ac ("pinctrl: at91: fix a couple NULL vs IS_ERR() checks") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/pinctrl-at91.c | 64 +++++++++++----------------------- 1 file changed, 21 insertions(+), 43 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index f0b139a1cc3ed..e3664aafccef9 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -1294,10 +1294,11 @@ static const struct of_device_id at91_pinctrl_of_match[] = { static int at91_pinctrl_probe_dt(struct platform_device *pdev, struct at91_pinctrl *info) { + struct device *dev = &pdev->dev; int ret = 0; int i, j, ngpio_chips_enabled = 0; uint32_t *tmp; - struct device_node *np = pdev->dev.of_node; + struct device_node *np = dev->of_node; struct device_node *child;
if (!np) @@ -1361,9 +1362,8 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev, continue; ret = at91_pinctrl_parse_functions(child, info, i++); if (ret) { - dev_err(&pdev->dev, "failed to parse function\n"); of_node_put(child); - return ret; + return dev_err_probe(dev, ret, "failed to parse function\n"); } }
@@ -1416,11 +1416,8 @@ static int at91_pinctrl_probe(struct platform_device *pdev) platform_set_drvdata(pdev, info); info->pctl = devm_pinctrl_register(&pdev->dev, &at91_pinctrl_desc, info); - - if (IS_ERR(info->pctl)) { - dev_err(&pdev->dev, "could not register AT91 pinctrl driver\n"); - return PTR_ERR(info->pctl); - } + if (IS_ERR(info->pctl)) + return dev_err_probe(dev, PTR_ERR(info->pctl), "could not register AT91 pinctrl driver\n");
/* We will handle a range of GPIO pins */ for (i = 0; i < gpio_banks; i++) @@ -1821,28 +1818,20 @@ static int at91_gpio_probe(struct platform_device *pdev) char **names;
BUG_ON(alias_idx >= ARRAY_SIZE(gpio_chips)); - if (gpio_chips[alias_idx]) { - ret = -EBUSY; - goto err; - } + if (gpio_chips[alias_idx]) + return dev_err_probe(dev, -EBUSY, "%d slot is occupied.\n", alias_idx);
irq = platform_get_irq(pdev, 0); - if (irq < 0) { - ret = irq; - goto err; - } + if (irq < 0) + return irq;
at91_chip = devm_kzalloc(&pdev->dev, sizeof(*at91_chip), GFP_KERNEL); - if (!at91_chip) { - ret = -ENOMEM; - goto err; - } + if (!at91_chip) + return -ENOMEM;
at91_chip->regbase = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(at91_chip->regbase)) { - ret = PTR_ERR(at91_chip->regbase); - goto err; - } + if (IS_ERR(at91_chip->regbase)) + return PTR_ERR(at91_chip->regbase);
at91_chip->ops = (const struct at91_pinctrl_mux_ops *) of_match_device(at91_gpio_of_match, &pdev->dev)->data; @@ -1850,11 +1839,8 @@ static int at91_gpio_probe(struct platform_device *pdev) at91_chip->pioc_idx = alias_idx;
at91_chip->clock = devm_clk_get_enabled(&pdev->dev, NULL); - if (IS_ERR(at91_chip->clock)) { - dev_err(&pdev->dev, "failed to get clock, ignoring.\n"); - ret = PTR_ERR(at91_chip->clock); - goto err; - } + if (IS_ERR(at91_chip->clock)) + return dev_err_probe(dev, PTR_ERR(at91_chip->clock), "failed to get clock, ignoring.\n");
at91_chip->chip = at91_gpio_template; at91_chip->id = alias_idx; @@ -1867,17 +1853,15 @@ static int at91_gpio_probe(struct platform_device *pdev)
if (!of_property_read_u32(np, "#gpio-lines", &ngpio)) { if (ngpio >= MAX_NB_GPIO_PER_BANK) - pr_err("at91_gpio.%d, gpio-nb >= %d failback to %d\n", - alias_idx, MAX_NB_GPIO_PER_BANK, MAX_NB_GPIO_PER_BANK); + dev_err(dev, "at91_gpio.%d, gpio-nb >= %d failback to %d\n", + alias_idx, MAX_NB_GPIO_PER_BANK, MAX_NB_GPIO_PER_BANK); else chip->ngpio = ngpio; }
names = devm_kasprintf_strarray(dev, "pio", chip->ngpio); - if (!names) { - ret = -ENOMEM; - goto err; - } + if (!names) + return -ENOMEM;
for (i = 0; i < chip->ngpio; i++) strreplace(names[i], '-', alias_idx + 'A'); @@ -1894,11 +1878,11 @@ static int at91_gpio_probe(struct platform_device *pdev)
ret = at91_gpio_of_irq_setup(pdev, at91_chip); if (ret) - goto gpiochip_add_err; + return ret;
ret = gpiochip_add_data(chip, at91_chip); if (ret) - goto gpiochip_add_err; + return ret;
gpio_chips[alias_idx] = at91_chip; platform_set_drvdata(pdev, at91_chip); @@ -1907,12 +1891,6 @@ static int at91_gpio_probe(struct platform_device *pdev) dev_info(&pdev->dev, "at address %p\n", at91_chip->regbase);
return 0; - -gpiochip_add_err: -err: - dev_err(&pdev->dev, "Failure %i for GPIO %i\n", ret, alias_idx); - - return ret; }
static const struct dev_pm_ops at91_gpio_pm_ops = {
From: Dan Carpenter dan.carpenter@linaro.org
[ Upstream commit 35216718c9ac2aef934ea9cd229572d4996807b2 ]
The devm_kasprintf_strarray() function doesn't return NULL on error, it returns error pointers. Update the checks accordingly.
Fixes: f494c1913cbb ("pinctrl: at91: use devm_kasprintf() to avoid potential leaks (part 2)") Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Reviewed-by: Claudiu Beznea claudiu.beznea@microchip.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Acked-by: Ryan Wanner ryan.wanner@microchip.com Link: https://lore.kernel.org/r/5697980e-f687-47a7-9db8-2af34ae464bd@kili.mountain Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/pinctrl-at91.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index e3664aafccef9..9184d457edf8d 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -1399,8 +1399,8 @@ static int at91_pinctrl_probe(struct platform_device *pdev) char **names;
names = devm_kasprintf_strarray(dev, "pio", MAX_NB_GPIO_PER_BANK); - if (!names) - return -ENOMEM; + if (IS_ERR(names)) + return PTR_ERR(names);
for (j = 0; j < MAX_NB_GPIO_PER_BANK; j++, k++) { char *name = names[j]; @@ -1860,8 +1860,8 @@ static int at91_gpio_probe(struct platform_device *pdev) }
names = devm_kasprintf_strarray(dev, "pio", chip->ngpio); - if (!names) - return -ENOMEM; + if (IS_ERR(names)) + return PTR_ERR(names);
for (i = 0; i < chip->ngpio; i++) strreplace(names[i], '-', alias_idx + 'A');
From: Rongguang Wei weirongguang@kylinos.cn
[ Upstream commit e8afd0d9fccc27c8ad263db5cf5952cfcf72d6fe ]
If a PCIe hotplug slot has an Attention Button, the normal hot-add flow is:
- Slot is empty and slot power is off - User inserts card in slot and presses Attention Button - OS blinks Power Indicator for 5 seconds - After 5 seconds, OS turns on Power Indicator, turns on slot power, and enumerates the device
Previously, if a user pressed the Attention Button on an *empty* slot, pciehp logged the following messages and blinked the Power Indicator until a second button press:
[0.000] pciehp: Button press: will power on in 5 sec [0.001] # Power Indicator starts blinking [5.001] # 5 second timeout; slot is empty, so we should cancel the request to power on and turn off Power Indicator
[7.000] # Power Indicator still blinking [8.000] # possible card insertion [9.000] pciehp: Button press: canceling request to power on
The first button press incorrectly left the slot in BLINKINGON_STATE, so the second was interpreted as a "cancel power on" event regardless of whether a card was present.
If the slot is empty, turn off the Power Indicator and return from BLINKINGON_STATE to OFF_STATE after 5 seconds, effectively canceling the request to power on. Putting the slot in OFF_STATE also means the second button press will correctly request a slot power on if the slot is occupied.
[bhelgaas: commit log] Link: https://lore.kernel.org/r/20230512021518.336460-1-clementwei90@163.com Fixes: d331710ea78f ("PCI: pciehp: Become resilient to missed events") Suggested-by: Lukas Wunner lukas@wunner.de Signed-off-by: Rongguang Wei weirongguang@kylinos.cn Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Lukas Wunner lukas@wunner.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/hotplug/pciehp_ctrl.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 529c348084401..32baba1b7f131 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -256,6 +256,14 @@ void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events) present = pciehp_card_present(ctrl); link_active = pciehp_check_link_active(ctrl); if (present <= 0 && link_active <= 0) { + if (ctrl->state == BLINKINGON_STATE) { + ctrl->state = OFF_STATE; + cancel_delayed_work(&ctrl->button_work); + pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF, + INDICATOR_NOOP); + ctrl_info(ctrl, "Slot(%s): Card not present\n", + slot_name(ctrl)); + } mutex_unlock(&ctrl->state_lock); return; }
From: Ian Rogers irogers@google.com
[ Upstream commit 797b9ec8c4bc9ec89f633a9b2c710b7b64753ca4 ]
Address/memory sanitizer was reporting issues in evsel__group_pmu_name because the for_each_group_evsel loop didn't terminate when the head was reached, the head would then be cast and accessed as an evsel leading to invalid memory accesses.
Fix for_each_group_member and for_each_group_evsel to terminate at the list head. Note, evsel__group_pmu_name no longer iterates the group, but the problem is present regardless.
Fixes: 717e263fc354d53d ("perf report: Show group description when event group is enabled") Signed-off-by: Ian Rogers irogers@google.com Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Changbin Du changbin.du@huawei.com Cc: Dmitrii Dolgov 9erthalion6@gmail.com Cc: Ingo Molnar mingo@redhat.com Cc: James Clark james.clark@arm.com Cc: Jiri Olsa jolsa@kernel.org Cc: Kan Liang kan.liang@linux.intel.com Cc: Mark Rutland mark.rutland@arm.com Cc: Namhyung Kim namhyung.kim@lge.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Rob Herring robh@kernel.org Cc: Sandipan Das sandipan.das@amd.com Cc: Xing Zhengjun zhengjun.xing@linux.intel.com Link: https://lore.kernel.org/r/20230526194442.2355872-3-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/evsel.h | 24 ++++++++++++++++-------- tools/perf/util/evsel_fprintf.c | 1 + 2 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 1a7358b46ad4e..72549fd79992b 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -457,16 +457,24 @@ static inline int evsel__group_idx(struct evsel *evsel) }
/* Iterates group WITHOUT the leader. */ -#define for_each_group_member(_evsel, _leader) \ -for ((_evsel) = list_entry((_leader)->core.node.next, struct evsel, core.node); \ - (_evsel) && (_evsel)->core.leader == (&_leader->core); \ - (_evsel) = list_entry((_evsel)->core.node.next, struct evsel, core.node)) +#define for_each_group_member_head(_evsel, _leader, _head) \ +for ((_evsel) = list_entry((_leader)->core.node.next, struct evsel, core.node); \ + (_evsel) && &(_evsel)->core.node != (_head) && \ + (_evsel)->core.leader == &(_leader)->core; \ + (_evsel) = list_entry((_evsel)->core.node.next, struct evsel, core.node)) + +#define for_each_group_member(_evsel, _leader) \ + for_each_group_member_head(_evsel, _leader, &(_leader)->evlist->core.entries)
/* Iterates group WITH the leader. */ -#define for_each_group_evsel(_evsel, _leader) \ -for ((_evsel) = _leader; \ - (_evsel) && (_evsel)->core.leader == (&_leader->core); \ - (_evsel) = list_entry((_evsel)->core.node.next, struct evsel, core.node)) +#define for_each_group_evsel_head(_evsel, _leader, _head) \ +for ((_evsel) = _leader; \ + (_evsel) && &(_evsel)->core.node != (_head) && \ + (_evsel)->core.leader == &(_leader)->core; \ + (_evsel) = list_entry((_evsel)->core.node.next, struct evsel, core.node)) + +#define for_each_group_evsel(_evsel, _leader) \ + for_each_group_evsel_head(_evsel, _leader, &(_leader)->evlist->core.entries)
static inline bool evsel__has_branch_callstack(const struct evsel *evsel) { diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c index bd22c4932d10e..6fa3a306f301d 100644 --- a/tools/perf/util/evsel_fprintf.c +++ b/tools/perf/util/evsel_fprintf.c @@ -2,6 +2,7 @@ #include <inttypes.h> #include <stdio.h> #include <stdbool.h> +#include "util/evlist.h" #include "evsel.h" #include "util/evsel_fprintf.h" #include "util/event.h"
From: Junyan Ye yejunyan@hust.edu.cn
[ Upstream commit c60738de85f40b0b9f5cb23c21f9246e5a47908c ]
Smatch reported: 1. drivers/pci/controller/pci-ftpci100.c:526 faraday_pci_probe() warn: 'clk' from clk_prepare_enable() not released on lines: 442,451,462,478,512,517. 2. drivers/pci/controller/pci-ftpci100.c:526 faraday_pci_probe() warn: 'p->bus_clk' from clk_prepare_enable() not released on lines: 451,462,478,512,517.
The clock resource is obtained by devm_clk_get(), and then clk_prepare_enable() makes the clock resource ready for use. After that, clk_disable_unprepare() should be called to release the clock resource when it is no longer needed. However, while doing some error handling in faraday_pci_probe(), clk_disable_unprepare() is not called to release clk and p->bus_clk before returning. These return lines are exactly 442, 451, 462, 478, 512, 517.
Fix this warning by replacing devm_clk_get() with devm_clk_get_enabled(), which is equivalent to devm_clk_get() + clk_prepare_enable(). And with devm_clk_get_enabled(), the clock will automatically be disabled, unprepared and freed when the device is unbound from the bus.
Link: https://lore.kernel.org/r/20230508043641.23807-1-yejunyan@hust.edu.cn Fixes: b3c433efb8a3 ("PCI: faraday: Fix wrong pointer passed to PTR_ERR()") Fixes: 2eeb02b28579 ("PCI: faraday: Add clock handling") Fixes: 783a862563f7 ("PCI: faraday: Use pci_parse_request_of_pci_ranges()") Fixes: d3c68e0a7e34 ("PCI: faraday: Add Faraday Technology FTPCI100 PCI Host Bridge driver") Fixes: f1e8bd21e39e ("PCI: faraday: Convert IRQ masking to raw PCI config accessors") Signed-off-by: Junyan Ye yejunyan@hust.edu.cn Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Reviewed-by: Dongliang Mu dzm91@hust.edu.cn Reviewed-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pci-ftpci100.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-)
diff --git a/drivers/pci/controller/pci-ftpci100.c b/drivers/pci/controller/pci-ftpci100.c index ecd3009df586d..6e7981d2ed5e1 100644 --- a/drivers/pci/controller/pci-ftpci100.c +++ b/drivers/pci/controller/pci-ftpci100.c @@ -429,22 +429,12 @@ static int faraday_pci_probe(struct platform_device *pdev) p->dev = dev;
/* Retrieve and enable optional clocks */ - clk = devm_clk_get(dev, "PCLK"); + clk = devm_clk_get_enabled(dev, "PCLK"); if (IS_ERR(clk)) return PTR_ERR(clk); - ret = clk_prepare_enable(clk); - if (ret) { - dev_err(dev, "could not prepare PCLK\n"); - return ret; - } - p->bus_clk = devm_clk_get(dev, "PCICLK"); + p->bus_clk = devm_clk_get_enabled(dev, "PCICLK"); if (IS_ERR(p->bus_clk)) return PTR_ERR(p->bus_clk); - ret = clk_prepare_enable(p->bus_clk); - if (ret) { - dev_err(dev, "could not prepare PCICLK\n"); - return ret; - }
p->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(p->base))
From: Wells Lu wellslutw@gmail.com
[ Upstream commit a5961bed5429cf1134d7f539b4ed60317012f84d ]
Fix Smatch static checker warning: potential null dereference 'configs'. (kmalloc returns null)
Fixes: aa74c44be19c ("pinctrl: Add driver for Sunplus SP7021") Signed-off-by: Wells Lu wellslutw@gmail.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Link: https://lore.kernel.org/r/1685277277-12209-1-git-send-email-wellslutw@gmail.... Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/sunplus/sppctl.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/drivers/pinctrl/sunplus/sppctl.c b/drivers/pinctrl/sunplus/sppctl.c index 6bbbab3a6fdf3..e91ce5b5d5598 100644 --- a/drivers/pinctrl/sunplus/sppctl.c +++ b/drivers/pinctrl/sunplus/sppctl.c @@ -834,11 +834,6 @@ static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node int i, size = 0;
list = of_get_property(np_config, "sunplus,pins", &size); - - if (nmG <= 0) - nmG = 0; - - parent = of_get_parent(np_config); *num_maps = size / sizeof(*list);
/* @@ -866,10 +861,14 @@ static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node } }
+ if (nmG <= 0) + nmG = 0; + *map = kcalloc(*num_maps + nmG, sizeof(**map), GFP_KERNEL); - if (*map == NULL) + if (!(*map)) return -ENOMEM;
+ parent = of_get_parent(np_config); for (i = 0; i < (*num_maps); i++) { dt_pin = be32_to_cpu(list[i]); pin_num = FIELD_GET(GENMASK(31, 24), dt_pin); @@ -883,6 +882,8 @@ static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node (*map)[i].data.configs.num_configs = 1; (*map)[i].data.configs.group_or_pin = pin_get_name(pctldev, pin_num); configs = kmalloc(sizeof(*configs), GFP_KERNEL); + if (!configs) + goto sppctl_map_err; *configs = FIELD_GET(GENMASK(7, 0), dt_pin); (*map)[i].data.configs.configs = configs;
@@ -896,6 +897,8 @@ static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node (*map)[i].data.configs.num_configs = 1; (*map)[i].data.configs.group_or_pin = pin_get_name(pctldev, pin_num); configs = kmalloc(sizeof(*configs), GFP_KERNEL); + if (!configs) + goto sppctl_map_err; *configs = SPPCTL_IOP_CONFIGS; (*map)[i].data.configs.configs = configs;
@@ -965,6 +968,15 @@ static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node of_node_put(parent); dev_dbg(pctldev->dev, "%d pins mapped\n", *num_maps); return 0; + +sppctl_map_err: + for (i = 0; i < (*num_maps); i++) + if (((*map)[i].type == PIN_MAP_TYPE_CONFIGS_PIN) && + (*map)[i].data.configs.configs) + kfree((*map)[i].data.configs.configs); + kfree(*map); + of_node_put(parent); + return -ENOMEM; }
static const struct pinctrl_ops sppctl_pctl_ops = {
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit 4b68b7f9c46d90c541d39c8b397a86ac0ca4c765 ]
ufshcd_hold() and ufshcd_release are declared twice: once in drivers/ufs/core/ufshcd-priv.h and a second time in include/ufs/ufshcd.h. Remove the declarations from ufshcd-priv.h.
Fixes: dd11376b9f1b ("scsi: ufs: Split the drivers/scsi/ufs directory") Signed-off-by: Bart Van Assche bvanassche@acm.org Link: https://lore.kernel.org/r/20230529202640.11883-5-bvanassche@acm.org Reviewed-by: Adrian Hunter adrian.hunter@intel.com Reviewed-by: Keoseong Park keosung.park@samsung.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ufs/core/ufshcd-priv.h | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h index 529f8507a5e4c..7d8ff743a1b28 100644 --- a/drivers/ufs/core/ufshcd-priv.h +++ b/drivers/ufs/core/ufshcd-priv.h @@ -84,9 +84,6 @@ unsigned long ufshcd_mcq_poll_cqe_lock(struct ufs_hba *hba, int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, u8 **buf, bool ascii);
-int ufshcd_hold(struct ufs_hba *hba, bool async); -void ufshcd_release(struct ufs_hba *hba); - int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd);
int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba,
From: Sui Jingfeng suijingfeng@loongson.cn
[ Upstream commit 2aa5ac633259843f656eb6ecff4cf01e8e810c5e ]
Add a pci_clear_master() stub when CONFIG_PCI is not set so drivers that support both PCI and platform devices don't need #ifdefs or extra Kconfig symbols for the PCI parts.
[bhelgaas: commit log] Fixes: 6a479079c072 ("PCI: Add pci_clear_master() as opposite of pci_set_master()") Link: https://lore.kernel.org/r/20230531102744.2354313-1-suijingfeng@loongson.cn Signed-off-by: Sui Jingfeng suijingfeng@loongson.cn Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Geert Uytterhoeven geert@linux-m68k.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/pci.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/include/linux/pci.h b/include/linux/pci.h index a5dda515fcd1d..87d499ca7e176 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1866,6 +1866,7 @@ static inline int pci_dev_present(const struct pci_device_id *ids) #define pci_dev_put(dev) do { } while (0)
static inline void pci_set_master(struct pci_dev *dev) { } +static inline void pci_clear_master(struct pci_dev *dev) { } static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; } static inline void pci_disable_device(struct pci_dev *dev) { } static inline int pcim_enable_device(struct pci_dev *pdev) { return -EIO; }
From: Justin Tee justin.tee@broadcom.com
[ Upstream commit 9914a3d033d3e1d836a43e93e9738e7dd44a096a ]
When NPIV ports are zoned to devices that support both initiator and target mode, a remote device's initiated PRLI results in unintended final kref clean up of the device's ndlp structure. This disrupts NPIV ports' discovery for target devices that support both initiator and target mode.
Modify the NPIV lpfc_drop_node clause such that we allow the ndlp to live so long as it was in NLP_STE_PLOGI_ISSUE, NLP_STE_REG_LOGIN_ISSUE, or NLP_STE_PRLI_ISSUE nlp_state. This allows lpfc's issued PRLI completion routine to determine if the final kref clean up should execute rather than a remote device's issued PRLI.
Fixes: db651ec22524 ("scsi: lpfc: Correct used_rpi count when devloss tmo fires with no recovery") Signed-off-by: Justin Tee justin.tee@broadcom.com Link: https://lore.kernel.org/r/20230523183206.7728-5-justintee8345@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_els.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 62d2ca688cd14..e07242ac0f014 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -5466,9 +5466,19 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ndlp->nlp_flag &= ~NLP_RELEASE_RPI; spin_unlock_irq(&ndlp->lock); } + lpfc_drop_node(vport, ndlp); + } else if (ndlp->nlp_state != NLP_STE_PLOGI_ISSUE && + ndlp->nlp_state != NLP_STE_REG_LOGIN_ISSUE && + ndlp->nlp_state != NLP_STE_PRLI_ISSUE) { + /* Drop ndlp if there is no planned or outstanding + * issued PRLI. + * + * In cases when the ndlp is acting as both an initiator + * and target function, let our issued PRLI determine + * the final ndlp kref drop. + */ + lpfc_drop_node(vport, ndlp); } - - lpfc_drop_node(vport, ndlp); }
/* Release the originating I/O reference. */
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit fe8637f7708c16765ecf4035813efbfdd2c9be10 ]
One UFS vendor asked to increase the UFS timeout from 1 s to 3 s. Another UFS vendor asked to increase the UFS timeout from 1 s to 10 s. Hence this patch that increases the UFS timeout to 10 s. This patch can cause the total timeout to exceed 20 s, the Android shutdown timeout. This is fine since the loop around ufshcd_execute_start_stop() exists to deal with unit attentions and because unit attentions are reported quickly.
Fixes: dcd5b7637c6d ("scsi: ufs: Reduce the START STOP UNIT timeout") Fixes: 8f2c96420c6e ("scsi: ufs: core: Reduce the power mode change timeout") Acked-by: Adrian Hunter adrian.hunter@intel.com Reviewed-by: Stanley Chu stanley.chu@mediatek.com Reviewed-by: Bean Huo beanhuo@micron.com Signed-off-by: Bart Van Assche bvanassche@acm.org Link: https://lore.kernel.org/r/20230524203659.1394307-2-bvanassche@acm.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ufs/core/ufshcd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index aec74987cb4e0..8bf39a83ecd7f 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -9153,7 +9153,8 @@ static int ufshcd_execute_start_stop(struct scsi_device *sdev, };
return scsi_execute_cmd(sdev, cdb, REQ_OP_DRV_IN, /*buffer=*/NULL, - /*bufflen=*/0, /*timeout=*/HZ, /*retries=*/0, &args); + /*bufflen=*/0, /*timeout=*/10 * HZ, /*retries=*/0, + &args); }
/**
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit 549e91a9bbaa0ee480f59357868421a61d369770 ]
ufshcd_queuecommand() may be called two times in a row for a SCSI command before it is completed. Hence make the following changes:
- In the functions that submit a command, do not check the old value of lrbp->cmd nor clear lrbp->cmd in error paths.
- In ufshcd_release_scsi_cmd(), do not clear lrbp->cmd.
See also scsi_send_eh_cmnd().
This commit prevents that the following appears if a command times out:
WARNING: at drivers/ufs/core/ufshcd.c:2965 ufshcd_queuecommand+0x6f8/0x9a8 Call trace: ufshcd_queuecommand+0x6f8/0x9a8 scsi_send_eh_cmnd+0x2c0/0x960 scsi_eh_test_devices+0x100/0x314 scsi_eh_ready_devs+0xd90/0x114c scsi_error_handler+0x2b4/0xb70 kthread+0x16c/0x1e0
Fixes: 5a0b0cb9bee7 ("[SCSI] ufs: Add support for sending NOP OUT UPIU") Signed-off-by: Bart Van Assche bvanassche@acm.org Link: https://lore.kernel.org/r/20230524203659.1394307-3-bvanassche@acm.org Acked-by: Adrian Hunter adrian.hunter@intel.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ufs/core/ufshcd.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 8bf39a83ecd7f..dc63bd60db77d 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -2917,7 +2917,6 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) (hba->clk_gating.state != CLKS_ON));
lrbp = &hba->lrb[tag]; - WARN_ON(lrbp->cmd); lrbp->cmd = cmd; lrbp->task_tag = tag; lrbp->lun = ufshcd_scsi_to_upiu_lun(cmd->device->lun); @@ -2933,7 +2932,6 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
err = ufshcd_map_sg(hba, lrbp); if (err) { - lrbp->cmd = NULL; ufshcd_release(hba); goto out; } @@ -3152,7 +3150,7 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, down_read(&hba->clk_scaling_lock);
lrbp = &hba->lrb[tag]; - WARN_ON(lrbp->cmd); + lrbp->cmd = NULL; err = ufshcd_compose_dev_cmd(hba, lrbp, cmd_type, tag); if (unlikely(err)) goto out; @@ -5391,7 +5389,6 @@ static void ufshcd_release_scsi_cmd(struct ufs_hba *hba, struct scsi_cmnd *cmd = lrbp->cmd;
scsi_dma_unmap(cmd); - lrbp->cmd = NULL; /* Mark the command as completed. */ ufshcd_release(hba); ufshcd_clk_scaling_update_busy(hba); } @@ -7006,7 +7003,6 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, down_read(&hba->clk_scaling_lock);
lrbp = &hba->lrb[tag]; - WARN_ON(lrbp->cmd); lrbp->cmd = NULL; lrbp->task_tag = tag; lrbp->lun = 0; @@ -7178,7 +7174,6 @@ int ufshcd_advanced_rpmb_req_handler(struct ufs_hba *hba, struct utp_upiu_req *r down_read(&hba->clk_scaling_lock);
lrbp = &hba->lrb[tag]; - WARN_ON(lrbp->cmd); lrbp->cmd = NULL; lrbp->task_tag = tag; lrbp->lun = UFS_UPIU_RPMB_WLUN;
From: Thierry Reding treding@nvidia.com
[ Upstream commit fad57233501beb5bd25f037cb9128a533e710600 ]
The function table is filled with group information based on other instance-specific data at runtime. However, the function table can be shared between multiple instances, causing the ->probe() function for one instance to overwrite the table of a previously probed instance.
Fix this by sharing only the function names and allocating a separate function table for each instance.
Fixes: 5a0047360743 ("pinctrl: tegra: Separate Tegra194 instances") Signed-off-by: Thierry Reding treding@nvidia.com Link: https://lore.kernel.org/r/20230530105308.1292852-1-thierry.reding@gmail.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/tegra/pinctrl-tegra.c | 15 +++++++++++---- drivers/pinctrl/tegra/pinctrl-tegra.h | 3 ++- drivers/pinctrl/tegra/pinctrl-tegra114.c | 7 ++----- drivers/pinctrl/tegra/pinctrl-tegra124.c | 7 ++----- drivers/pinctrl/tegra/pinctrl-tegra194.c | 7 ++----- drivers/pinctrl/tegra/pinctrl-tegra20.c | 7 ++----- drivers/pinctrl/tegra/pinctrl-tegra210.c | 7 ++----- drivers/pinctrl/tegra/pinctrl-tegra30.c | 7 ++----- 8 files changed, 25 insertions(+), 35 deletions(-)
diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.c b/drivers/pinctrl/tegra/pinctrl-tegra.c index 1729b7ddfa946..21e08fbd1df0e 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra.c @@ -232,7 +232,7 @@ static const char *tegra_pinctrl_get_func_name(struct pinctrl_dev *pctldev, { struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
- return pmx->soc->functions[function].name; + return pmx->functions[function].name; }
static int tegra_pinctrl_get_func_groups(struct pinctrl_dev *pctldev, @@ -242,8 +242,8 @@ static int tegra_pinctrl_get_func_groups(struct pinctrl_dev *pctldev, { struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
- *groups = pmx->soc->functions[function].groups; - *num_groups = pmx->soc->functions[function].ngroups; + *groups = pmx->functions[function].groups; + *num_groups = pmx->functions[function].ngroups;
return 0; } @@ -795,10 +795,17 @@ int tegra_pinctrl_probe(struct platform_device *pdev, if (!pmx->group_pins) return -ENOMEM;
+ pmx->functions = devm_kcalloc(&pdev->dev, pmx->soc->nfunctions, + sizeof(*pmx->functions), GFP_KERNEL); + if (!pmx->functions) + return -ENOMEM; + group_pins = pmx->group_pins; + for (fn = 0; fn < soc_data->nfunctions; fn++) { - struct tegra_function *func = &soc_data->functions[fn]; + struct tegra_function *func = &pmx->functions[fn];
+ func->name = pmx->soc->functions[fn]; func->groups = group_pins;
for (gn = 0; gn < soc_data->ngroups; gn++) { diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.h b/drivers/pinctrl/tegra/pinctrl-tegra.h index 6130cba7cce54..b3289bdf727d8 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra.h +++ b/drivers/pinctrl/tegra/pinctrl-tegra.h @@ -13,6 +13,7 @@ struct tegra_pmx { struct pinctrl_dev *pctl;
const struct tegra_pinctrl_soc_data *soc; + struct tegra_function *functions; const char **group_pins;
struct pinctrl_gpio_range gpio_range; @@ -191,7 +192,7 @@ struct tegra_pinctrl_soc_data { const char *gpio_compatible; const struct pinctrl_pin_desc *pins; unsigned npins; - struct tegra_function *functions; + const char * const *functions; unsigned nfunctions; const struct tegra_pingroup *groups; unsigned ngroups; diff --git a/drivers/pinctrl/tegra/pinctrl-tegra114.c b/drivers/pinctrl/tegra/pinctrl-tegra114.c index e72ab1eb23983..3d425b2018e78 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra114.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra114.c @@ -1452,12 +1452,9 @@ enum tegra_mux { TEGRA_MUX_VI_ALT3, };
-#define FUNCTION(fname) \ - { \ - .name = #fname, \ - } +#define FUNCTION(fname) #fname
-static struct tegra_function tegra114_functions[] = { +static const char * const tegra114_functions[] = { FUNCTION(blink), FUNCTION(cec), FUNCTION(cldvfs), diff --git a/drivers/pinctrl/tegra/pinctrl-tegra124.c b/drivers/pinctrl/tegra/pinctrl-tegra124.c index 26096c6b967e2..2a50c5c7516c3 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra124.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra124.c @@ -1611,12 +1611,9 @@ enum tegra_mux { TEGRA_MUX_VIMCLK2_ALT, };
-#define FUNCTION(fname) \ - { \ - .name = #fname, \ - } +#define FUNCTION(fname) #fname
-static struct tegra_function tegra124_functions[] = { +static const char * const tegra124_functions[] = { FUNCTION(blink), FUNCTION(ccla), FUNCTION(cec), diff --git a/drivers/pinctrl/tegra/pinctrl-tegra194.c b/drivers/pinctrl/tegra/pinctrl-tegra194.c index 277973c884344..69f58df628977 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra194.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra194.c @@ -1189,12 +1189,9 @@ enum tegra_mux_dt { };
/* Make list of each function name */ -#define TEGRA_PIN_FUNCTION(lid) \ - { \ - .name = #lid, \ - } +#define TEGRA_PIN_FUNCTION(lid) #lid
-static struct tegra_function tegra194_functions[] = { +static const char * const tegra194_functions[] = { TEGRA_PIN_FUNCTION(rsvd0), TEGRA_PIN_FUNCTION(rsvd1), TEGRA_PIN_FUNCTION(rsvd2), diff --git a/drivers/pinctrl/tegra/pinctrl-tegra20.c b/drivers/pinctrl/tegra/pinctrl-tegra20.c index 0dc2cf0d05b1e..737fc2000f66b 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra20.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra20.c @@ -1889,12 +1889,9 @@ enum tegra_mux { TEGRA_MUX_XIO, };
-#define FUNCTION(fname) \ - { \ - .name = #fname, \ - } +#define FUNCTION(fname) #fname
-static struct tegra_function tegra20_functions[] = { +static const char * const tegra20_functions[] = { FUNCTION(ahb_clk), FUNCTION(apb_clk), FUNCTION(audio_sync), diff --git a/drivers/pinctrl/tegra/pinctrl-tegra210.c b/drivers/pinctrl/tegra/pinctrl-tegra210.c index b480f607fa16f..9bb29146dfff7 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra210.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra210.c @@ -1185,12 +1185,9 @@ enum tegra_mux { TEGRA_MUX_VIMCLK2, };
-#define FUNCTION(fname) \ - { \ - .name = #fname, \ - } +#define FUNCTION(fname) #fname
-static struct tegra_function tegra210_functions[] = { +static const char * const tegra210_functions[] = { FUNCTION(aud), FUNCTION(bcl), FUNCTION(blink), diff --git a/drivers/pinctrl/tegra/pinctrl-tegra30.c b/drivers/pinctrl/tegra/pinctrl-tegra30.c index 7299a371827f1..de5aa2d4d28d3 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra30.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra30.c @@ -2010,12 +2010,9 @@ enum tegra_mux { TEGRA_MUX_VI_ALT3, };
-#define FUNCTION(fname) \ - { \ - .name = #fname, \ - } +#define FUNCTION(fname) #fname
-static struct tegra_function tegra30_functions[] = { +static const char * const tegra30_functions[] = { FUNCTION(blink), FUNCTION(cec), FUNCTION(clk_12m_out),
From: Arnaldo Carvalho de Melo acme@redhat.com
[ Upstream commit 16203e9cd01896b4244100a8e3fb9f6e612ab2b1 ]
Without this we were not getting the thousands separator for big numbers.
Noticed while developing 'perf bench uprobe', but the use of %' predates that, for instance 'perf bench syscall' uses it.
Before:
# perf bench uprobe all # Running uprobe/baseline benchmark... # Executed 1000 usleep(1000) calls Total time: 1054082243ns
1054082.243000 nsecs/op
#
After:
# perf bench uprobe all # Running uprobe/baseline benchmark... # Executed 1,000 usleep(1000) calls Total time: 1,053,715,144ns
1,053,715.144000 nsecs/op
#
Fixes: c2a08203052f8975 ("perf bench: Add basic syscall benchmark") Cc: Adrian Hunter adrian.hunter@intel.com Cc: Andre Fredette anfredet@redhat.com Cc: Clark Williams williams@redhat.com Cc: Dave Tucker datucker@redhat.com Cc: Davidlohr Bueso dave@stgolabs.net Cc: Derek Barbosa debarbos@redhat.com Cc: Ian Rogers irogers@google.com Cc: Jiri Olsa jolsa@kernel.org Cc: Namhyung Kim namhyung@kernel.org Cc: Tiezhu Yang yangtiezhu@loongson.cn Link: https://lore.kernel.org/lkml/ZH3lcepZ4tBYr1jv@kernel.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/builtin-bench.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c index 814e9afc86f6e..5efb29a7564af 100644 --- a/tools/perf/builtin-bench.c +++ b/tools/perf/builtin-bench.c @@ -21,6 +21,7 @@ #include "builtin.h" #include "bench/bench.h"
+#include <locale.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -258,6 +259,7 @@ int cmd_bench(int argc, const char **argv)
/* Unbuffered output */ setvbuf(stdout, NULL, _IONBF, 0); + setlocale(LC_ALL, "");
if (argc < 2) { /* No collection specified. */
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 5835196a17be5cfdcad0b617f90cf4abe16951a4 ]
Currently the getter returns ENOTSUPP on pin configured in the push-pull mode. Fix this by adding the missed switch case.
Fixes: ccdf81d08dbe ("pinctrl: cherryview: add option to set open-drain pin config") Fixes: 6e08d6bbebeb ("pinctrl: Add Intel Cherryview/Braswell pin controller support") Acked-by: Mika Westerberg mika.westerberg@linux.intel.com Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/intel/pinctrl-cherryview.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 722990e278361..87cf1e7403979 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -949,11 +949,6 @@ static int chv_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
break;
- case PIN_CONFIG_DRIVE_OPEN_DRAIN: - if (!(ctrl1 & CHV_PADCTRL1_ODEN)) - return -EINVAL; - break; - case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: { u32 cfg;
@@ -963,6 +958,16 @@ static int chv_config_get(struct pinctrl_dev *pctldev, unsigned int pin, return -EINVAL;
break; + + case PIN_CONFIG_DRIVE_PUSH_PULL: + if (ctrl1 & CHV_PADCTRL1_ODEN) + return -EINVAL; + break; + + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + if (!(ctrl1 & CHV_PADCTRL1_ODEN)) + return -EINVAL; + break; }
default:
From: Xi Pardee xi.pardee@intel.com
[ Upstream commit 416a87c972b978d71ab828442d1d48e3bd194855 ]
commit c5ad454a12c6 ("platform/x86: intel/pmc/core: Add Meteor Lake support to pmc core driver") was supposed to add support for Meter Lake P/M and mistakenly added support for Meteor Lake S instead. Meteor Lake P/M support was added later and MTL-S support needs to be removed since its currently assigned to the wrong register maps.
Fixes: c5ad454a12c6 ("platform/x86: intel/pmc/core: Add Meteor Lake support to pmc core driver") Signed-off-by: Xi Pardee xi.pardee@intel.com Signed-off-by: David E. Box david.e.box@linux.intel.com Link: https://lore.kernel.org/r/20230601004706.871528-1-xi.pardee@intel.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/intel/pmc/core.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c index b9591969e0fa1..bed083525fbe7 100644 --- a/drivers/platform/x86/intel/pmc/core.c +++ b/drivers/platform/x86/intel/pmc/core.c @@ -1039,7 +1039,6 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = { X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, tgl_core_init), X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, adl_core_init), X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, adl_core_init), - X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE, mtl_core_init), X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE_L, mtl_core_init), {} };
From: Mark Pearson mpearson-lenovo@squebb.ca
[ Upstream commit c41e0121a1221894a1a9c4666156db9e1def4d6c ]
When an attribute is being changed if the Admin account is enabled, or if a password is being updated then multiple WMI calls are needed. Add mutex protection to ensure no race conditions are introduced.
Fixes: b49f72e7f96d ("platform/x86: think-lmi: Certificate authentication support") Signed-off-by: Mark Pearson mpearson-lenovo@squebb.ca Reviewed-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Reviewed-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20230601200552.4396-1-mpearson-lenovo@squebb.ca Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/think-lmi.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index 78dc82bda4dde..7a145f578ef49 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -14,6 +14,7 @@ #include <linux/acpi.h> #include <linux/errno.h> #include <linux/fs.h> +#include <linux/mutex.h> #include <linux/string.h> #include <linux/types.h> #include <linux/dmi.h> @@ -195,6 +196,7 @@ static const char * const level_options[] = { }; static struct think_lmi tlmi_priv; static struct class *fw_attr_class; +static DEFINE_MUTEX(tlmi_mutex);
/* ------ Utility functions ------------*/ /* Strip out CR if one is present */ @@ -437,6 +439,9 @@ static ssize_t new_password_store(struct kobject *kobj, /* Strip out CR if one is present, setting password won't work if it is present */ strip_cr(new_pwd);
+ /* Use lock in case multiple WMI operations needed */ + mutex_lock(&tlmi_mutex); + pwdlen = strlen(new_pwd); /* pwdlen == 0 is allowed to clear the password */ if (pwdlen && ((pwdlen < setting->minlen) || (pwdlen > setting->maxlen))) { @@ -493,6 +498,7 @@ static ssize_t new_password_store(struct kobject *kobj, kfree(auth_str); } out: + mutex_unlock(&tlmi_mutex); kfree(new_pwd); return ret ?: count; } @@ -982,6 +988,9 @@ static ssize_t current_value_store(struct kobject *kobj, /* Strip out CR if one is present */ strip_cr(new_setting);
+ /* Use lock in case multiple WMI operations needed */ + mutex_lock(&tlmi_mutex); + /* Check if certificate authentication is enabled and active */ if (tlmi_priv.certificate_support && tlmi_priv.pwd_admin->cert_installed) { if (!tlmi_priv.pwd_admin->signature || !tlmi_priv.pwd_admin->save_signature) { @@ -1040,6 +1049,7 @@ static ssize_t current_value_store(struct kobject *kobj, kobject_uevent(&tlmi_priv.class_dev->kobj, KOBJ_CHANGE); } out: + mutex_unlock(&tlmi_mutex); kfree(auth_str); kfree(set_str); kfree(new_setting);
From: Mark Pearson mpearson-lenovo@squebb.ca
[ Upstream commit 97eef5983372d7aee6549d644d788fd0c10d2b6e ]
The system password identification was incorrect. This means that if the password was enabled it wouldn't be detected correctly; and setting it would not work. Also updated code to use TLMI_SMP_PWD instead of TLMI_SYS_PWD to be in sync with Lenovo documentation.
Fixes: 640a5fa50a42 ("platform/x86: think-lmi: Opcode support") Signed-off-by: Mark Pearson mpearson-lenovo@squebb.ca Reviewed-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Reviewed-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20230601200552.4396-3-mpearson-lenovo@squebb.ca Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/think-lmi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index 7a145f578ef49..cd755ef48ce40 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -172,7 +172,7 @@ MODULE_PARM_DESC(debug_support, "Enable debug command support"); #define TLMI_POP_PWD (1 << 0) #define TLMI_PAP_PWD (1 << 1) #define TLMI_HDD_PWD (1 << 2) -#define TLMI_SYS_PWD (1 << 3) +#define TLMI_SMP_PWD (1 << 6) /* System Management */ #define TLMI_CERT (1 << 7)
#define to_tlmi_pwd_setting(kobj) container_of(kobj, struct tlmi_pwd_setting, kobj) @@ -1522,11 +1522,11 @@ static int tlmi_analyze(void) tlmi_priv.pwd_power->valid = true;
if (tlmi_priv.opcode_support) { - tlmi_priv.pwd_system = tlmi_create_auth("sys", "system"); + tlmi_priv.pwd_system = tlmi_create_auth("smp", "system"); if (!tlmi_priv.pwd_system) goto fail_clear_attr;
- if (tlmi_priv.pwdcfg.core.password_state & TLMI_SYS_PWD) + if (tlmi_priv.pwdcfg.core.password_state & TLMI_SMP_PWD) tlmi_priv.pwd_system->valid = true;
tlmi_priv.pwd_hdd = tlmi_create_auth("hdd", "hdd");
From: Mark Pearson mpearson-lenovo@squebb.ca
[ Upstream commit 4cebb42412248d28df6de01420cfac5654428d41 ]
NVME passwords identifier have been standardised across the Lenovo systems and now use udrp and adrp (user and admin level) instead of unvp and mnvp.
This should apparently be backwards compatible.
Fixes: 640a5fa50a42 ("platform/x86: think-lmi: Opcode support") Signed-off-by: Mark Pearson mpearson-lenovo@squebb.ca Reviewed-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Reviewed-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20230601200552.4396-6-mpearson-lenovo@squebb.ca Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/think-lmi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index cd755ef48ce40..4b7f2a969dfec 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -461,9 +461,9 @@ static ssize_t new_password_store(struct kobject *kobj, sprintf(pwd_type, "mhdp%d", setting->index); } else if (setting == tlmi_priv.pwd_nvme) { if (setting->level == TLMI_LEVEL_USER) - sprintf(pwd_type, "unvp%d", setting->index); + sprintf(pwd_type, "udrp%d", setting->index); else - sprintf(pwd_type, "mnvp%d", setting->index); + sprintf(pwd_type, "adrp%d", setting->index); } else { sprintf(pwd_type, "%s", setting->pwd_type); }
From: Wells Lu wellslutw@gmail.com
[ Upstream commit 73f8ce7f961afcb3be49352efeb7c26cc1c00cc4 ]
Fix Smatch static checker warning: potential null dereference 'configs'. (kmalloc returns null)
Changes in v2: 1. Add free allocated memory before returned -ENOMEM. 2. Add call of_node_put() before returned -ENOMEM.
Fixes: aa74c44be19c ("pinctrl: Add driver for Sunplus SP7021") Signed-off-by: Wells Lu wellslutw@gmail.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Link: https://lore.kernel.org/r/1685277277-12209-1-git-send-email-wellslutw@gmail.... [Rebased on the patch from Lu Hongfei] Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/sunplus/sppctl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/pinctrl/sunplus/sppctl.c b/drivers/pinctrl/sunplus/sppctl.c index e91ce5b5d5598..150996949ede7 100644 --- a/drivers/pinctrl/sunplus/sppctl.c +++ b/drivers/pinctrl/sunplus/sppctl.c @@ -971,8 +971,7 @@ static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node
sppctl_map_err: for (i = 0; i < (*num_maps); i++) - if (((*map)[i].type == PIN_MAP_TYPE_CONFIGS_PIN) && - (*map)[i].data.configs.configs) + if ((*map)[i].type == PIN_MAP_TYPE_CONFIGS_PIN) kfree((*map)[i].data.configs.configs); kfree(*map); of_node_put(parent);
From: Jiasheng Jiang jiasheng@iscas.ac.cn
[ Upstream commit ad64639417161e90b30dda00486570eb150aeee5 ]
Add check for ioremap() and return the error if it fails in order to guarantee the success of ioremap().
Fixes: 3b588e43ee5c ("pinctrl: nuvoton: add NPCM7xx pinctrl and GPIO driver") Signed-off-by: Jiasheng Jiang jiasheng@iscas.ac.cn Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Link: https://lore.kernel.org/r/20230607095829.1345-1-jiasheng@iscas.ac.cn Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c index ff5bcea172e84..071bdfd570f94 100644 --- a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c +++ b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c @@ -1881,6 +1881,8 @@ static int npcm7xx_gpio_of(struct npcm7xx_pinctrl *pctrl) }
pctrl->gpio_bank[id].base = ioremap(res.start, resource_size(&res)); + if (!pctrl->gpio_bank[id].base) + return -EINVAL;
ret = bgpio_init(&pctrl->gpio_bank[id].gc, dev, 4, pctrl->gpio_bank[id].base + NPCM7XX_GP_N_DIN,
From: Christophe Leroy christophe.leroy@csgroup.eu
[ Upstream commit 353e7300a1db928e427462f2745f9a2cd1625b3d ]
Activating KCSAN on a 32 bits architecture leads to the following link-time failure:
LD .tmp_vmlinux.kallsyms1 powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_load': kernel/kcsan/core.c:1273: undefined reference to `__atomic_load_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_store': kernel/kcsan/core.c:1273: undefined reference to `__atomic_store_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_exchange': kernel/kcsan/core.c:1273: undefined reference to `__atomic_exchange_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_fetch_add': kernel/kcsan/core.c:1273: undefined reference to `__atomic_fetch_add_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_fetch_sub': kernel/kcsan/core.c:1273: undefined reference to `__atomic_fetch_sub_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_fetch_and': kernel/kcsan/core.c:1273: undefined reference to `__atomic_fetch_and_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_fetch_or': kernel/kcsan/core.c:1273: undefined reference to `__atomic_fetch_or_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_fetch_xor': kernel/kcsan/core.c:1273: undefined reference to `__atomic_fetch_xor_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_fetch_nand': kernel/kcsan/core.c:1273: undefined reference to `__atomic_fetch_nand_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_compare_exchange_strong': kernel/kcsan/core.c:1273: undefined reference to `__atomic_compare_exchange_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_compare_exchange_weak': kernel/kcsan/core.c:1273: undefined reference to `__atomic_compare_exchange_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_compare_exchange_val': kernel/kcsan/core.c:1273: undefined reference to `__atomic_compare_exchange_8'
32 bits architectures don't have 64 bits atomic builtins. Only include DEFINE_TSAN_ATOMIC_OPS(64) on 64 bits architectures.
Fixes: 0f8ad5f2e934 ("kcsan: Add support for atomic builtins") Suggested-by: Marco Elver elver@google.com Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Reviewed-by: Marco Elver elver@google.com Acked-by: Marco Elver elver@google.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/d9c6afc28d0855240171a4e0ad9ffcdb9d07fceb.1683892665.git.c... Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/kcsan/core.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/kernel/kcsan/core.c b/kernel/kcsan/core.c index 5a60cc52adc0c..8a7baf4e332e3 100644 --- a/kernel/kcsan/core.c +++ b/kernel/kcsan/core.c @@ -1270,7 +1270,9 @@ static __always_inline void kcsan_atomic_builtin_memorder(int memorder) DEFINE_TSAN_ATOMIC_OPS(8); DEFINE_TSAN_ATOMIC_OPS(16); DEFINE_TSAN_ATOMIC_OPS(32); +#ifdef CONFIG_64BIT DEFINE_TSAN_ATOMIC_OPS(64); +#endif
void __tsan_atomic_thread_fence(int memorder); void __tsan_atomic_thread_fence(int memorder)
From: Christophe Leroy christophe.leroy@csgroup.eu
[ Upstream commit 0eb089a72fda3f7969e6277804bde75dc1474a14 ]
A disassembly of interrupt_exit_kernel_prepare() shows a useless read of MSR register. This is shown by r9 being re-used immediately without doing anything with the value read.
c000e0e0: 60 00 00 00 nop c000e0e4: 7d 3a c2 a6 mfmd_ap r9 c000e0e8: 7d 20 00 a6 mfmsr r9 c000e0ec: 7c 51 13 a6 mtspr 81,r2 c000e0f0: 81 3f 00 84 lwz r9,132(r31) c000e0f4: 71 29 80 00 andi. r9,r9,32768
This is due to the use of local_irq_save(). The flags read by local_irq_save() are never used, use local_irq_disable() instead.
Fixes: 13799748b957 ("powerpc/64: use interrupt restart table to speed up return from interrupt") Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Reviewed-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/df36c6205ab64326fb1b991993c82057e92ace2f.1685955214.git.c... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/interrupt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c index 0ec1581619db5..cf770d86c03c6 100644 --- a/arch/powerpc/kernel/interrupt.c +++ b/arch/powerpc/kernel/interrupt.c @@ -368,7 +368,6 @@ void preempt_schedule_irq(void);
notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs) { - unsigned long flags; unsigned long ret = 0; unsigned long kuap; bool stack_store = read_thread_flags() & _TIF_EMULATE_STACK_STORE; @@ -392,7 +391,7 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)
kuap = kuap_get_and_assert_locked();
- local_irq_save(flags); + local_irq_disable();
if (!arch_irq_disabled_regs(regs)) { /* Returning to a kernel context with local irqs enabled. */
From: Christophe Leroy christophe.leroy@csgroup.eu
[ Upstream commit a03b1a0b19398a47489fdcef02ec19c2ba05a15d ]
Looking at generated code for handle_signal32() shows calls to a function called __unsafe_save_user_regs.constprop.0 while user access is open.
And that __unsafe_save_user_regs.constprop.0 function has two nops at the begining, allowing it to be traced, which is unexpected during user access open window.
The solution could be to mark __unsafe_save_user_regs() no trace, but to be on the safe side the most efficient is to flag it __always_inline as already done for function __unsafe_restore_general_regs(). The function is relatively small and only called twice, so the size increase will remain in the noise.
Do the same with save_tm_user_regs_unsafe() as it may suffer the same issue.
Fixes: ef75e7318294 ("powerpc/signal32: Transform save_user_regs() and save_tm_user_regs() in 'unsafe' version") Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/7e469c8f01860a69c1ada3ca6a5e2aa65f0f74b2.1685955220.git.c... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/signal_32.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index c114c7f25645c..7a718ed32b277 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -264,8 +264,9 @@ static void prepare_save_user_regs(int ctx_has_vsx_region) #endif }
-static int __unsafe_save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, - struct mcontext __user *tm_frame, int ctx_has_vsx_region) +static __always_inline int +__unsafe_save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, + struct mcontext __user *tm_frame, int ctx_has_vsx_region) { unsigned long msr = regs->msr;
@@ -364,8 +365,9 @@ static void prepare_save_tm_user_regs(void) current->thread.ckvrsave = mfspr(SPRN_VRSAVE); }
-static int save_tm_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame, - struct mcontext __user *tm_frame, unsigned long msr) +static __always_inline int +save_tm_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame, + struct mcontext __user *tm_frame, unsigned long msr) { /* Save both sets of general registers */ unsafe_save_general_regs(¤t->thread.ckpt_regs, frame, failed); @@ -444,8 +446,9 @@ static int save_tm_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user #else static void prepare_save_tm_user_regs(void) { }
-static int save_tm_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame, - struct mcontext __user *tm_frame, unsigned long msr) +static __always_inline int +save_tm_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame, + struct mcontext __user *tm_frame, unsigned long msr) { return 0; }
From: Arnaldo Carvalho de Melo acme@redhat.com
[ Upstream commit 36d3e4138e1b6cc9ab179f3f397b5548f8b1eaae ]
When printing output we may want to generate per event files, where the --per-event-dump option should be used, creating perf.data.EVENT.dump files instead of printing to stdout.
The callback thar processes event thus expects that evsel->priv->fp should point to either the per-event FILE descriptor or to stdout.
The a3af66f51bd0bca7 ("perf script: Fix crash because of missing evsel->priv") changeset fixed a case where evsel->priv wasn't setup, thus set to NULL, causing a segfault when trying to access evsel->priv->fp.
But it did it for the non --per-event-dump case by allocating a 'struct perf_evsel_script' just to set its ->fp to stdout.
Since evsel->priv is only freed when --per-event-dump is used, we ended up with a memory leak, detected using ASAN.
Fix it by using the same method as perf_script__setup_per_event_dump(), and reuse that static 'struct perf_evsel_script'.
Also check if evsel_script__new() failed.
Fixes: a3af66f51bd0bca7 ("perf script: Fix crash because of missing evsel->priv") Reported-by: Ian Rogers irogers@google.com Tested-by: Ian Rogers irogers@google.com Cc: Adrian Hunter adrian.hunter@intel.com Cc: Jiri Olsa jolsa@kernel.org Cc: Namhyung Kim namhyung@kernel.org Cc: Ravi Bangoria ravi.bangoria@linux.ibm.com Link: https://lore.kernel.org/lkml/ZH+F0wGAWV14zvMP@kernel.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/builtin-script.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index d8c174a719383..72a3faa28c394 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -2425,6 +2425,9 @@ static int process_sample_event(struct perf_tool *tool, return ret; }
+// Used when scr->per_event_dump is not set +static struct evsel_script es_stdout; + static int process_attr(struct perf_tool *tool, union perf_event *event, struct evlist **pevlist) { @@ -2433,7 +2436,6 @@ static int process_attr(struct perf_tool *tool, union perf_event *event, struct evsel *evsel, *pos; u64 sample_type; int err; - static struct evsel_script *es;
err = perf_event__process_attr(tool, event, pevlist); if (err) @@ -2443,14 +2445,13 @@ static int process_attr(struct perf_tool *tool, union perf_event *event, evsel = evlist__last(*pevlist);
if (!evsel->priv) { - if (scr->per_event_dump) { + if (scr->per_event_dump) { evsel->priv = evsel_script__new(evsel, scr->session->data); - } else { - es = zalloc(sizeof(*es)); - if (!es) + if (!evsel->priv) return -ENOMEM; - es->fp = stdout; - evsel->priv = es; + } else { // Replicate what is done in perf_script__setup_per_event_dump() + es_stdout.fp = stdout; + evsel->priv = &es_stdout; } }
@@ -2756,7 +2757,6 @@ static int perf_script__fopen_per_event_dump(struct perf_script *script) static int perf_script__setup_per_event_dump(struct perf_script *script) { struct evsel *evsel; - static struct evsel_script es_stdout;
if (script->per_event_dump) return perf_script__fopen_per_event_dump(script);
From: Mark Pearson mpearson-lenovo@squebb.ca
[ Upstream commit f999e23ce66c1555d7b653fba171a88ecee53704 ]
Fix issues identified in dytc_profile_refresh identified by lkp-tests. drivers/platform/x86/thinkpad_acpi.c:10538 dytc_profile_refresh() error: uninitialized symbol 'funcmode'. drivers/platform/x86/thinkpad_acpi.c:10531 dytc_profile_refresh() error: uninitialized symbol 'output'. drivers/platform/x86/thinkpad_acpi.c:10537 dytc_profile_refresh() error: uninitialized symbol 'output'.
These issues should not lead to real problems in the field as the refresh function should only be called if MMC or PSC mode enabled. But good to fix.
Thanks to Dan Carpenter and the lkp-tests project for flagging these.
Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter error27@gmail.com Closes: https://lore.kernel.org/r/202306011202.1hbgLRD4-lkp@intel.com/ Fixes: 1bc5d819f0b9 ("platform/x86: thinkpad_acpi: Fix profile modes on Intel platforms") Signed-off-by: Mark Pearson mpearson-lenovo@squebb.ca Link: https://lore.kernel.org/r/20230606151804.8819-1-mpearson-lenovo@squebb.ca Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/thinkpad_acpi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index e40cbe81b12c1..97c6ec12d0829 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -10524,8 +10524,8 @@ static int dytc_profile_set(struct platform_profile_handler *pprof, static void dytc_profile_refresh(void) { enum platform_profile_option profile; - int output, err = 0; - int perfmode, funcmode; + int output = 0, err = 0; + int perfmode, funcmode = 0;
mutex_lock(&dytc_mutex); if (dytc_capabilities & BIT(DYTC_FC_MMC)) { @@ -10538,6 +10538,8 @@ static void dytc_profile_refresh(void) err = dytc_command(DYTC_CMD_GET, &output); /* Check if we are PSC mode, or have AMT enabled */ funcmode = (output >> DYTC_GET_FUNCTION_BIT) & 0xF; + } else { /* Unknown profile mode */ + err = -ENODEV; } mutex_unlock(&dytc_mutex); if (err)
From: Namhyung Kim namhyung@kernel.org
[ Upstream commit 3abfcfd847717d232e36963f31a361747c388fe7 ]
The die_get_varname() returns "(unknown_type)" string if it failed to find a type for the variable. But it had a space before the opening parenthesis and it made the closing parenthesis cut off due to the off-by-one in the string length (14).
Signed-off-by: Namhyung Kim namhyung@kernel.org Fixes: 88fd633cdfa19060 ("perf probe: No need to use formatting strbuf method") Cc: Adrian Hunter adrian.hunter@intel.com Cc: Ian Rogers irogers@google.com Cc: Ingo Molnar mingo@kernel.org Cc: Jiri Olsa jolsa@kernel.org Cc: Masami Hiramatsu mhiramat@kernel.org Cc: Peter Zijlstra peterz@infradead.org Link: https://lore.kernel.org/r/20230612234102.3909116-1-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/dwarf-aux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index b074144097710..3bff678745635 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -1103,7 +1103,7 @@ int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf) ret = die_get_typename(vr_die, buf); if (ret < 0) { pr_debug("Failed to get type, make it unknown.\n"); - ret = strbuf_add(buf, " (unknown_type)", 14); + ret = strbuf_add(buf, "(unknown_type)", 14); }
return ret < 0 ? ret : strbuf_addf(buf, "\t%s", dwarf_diename(vr_die));
From: Aditya Gupta adityag@linux.ibm.com
[ Upstream commit 5c4396efb53ef07d046a2e9456b240880e0c3076 ]
${$1} gives bad substitution error on sh, bash, and zsh. This seems like a typo, and this patch modifies it to $1, since that is what it's usage looks like from wherever `check_exec_0` is called.
This issue due to ${$1} caused all function calls to give error in `find_str_or_fail` line, and so no test runs completely. But 'perf test "perf script task-analyzer tests"' wrongly reports that tests passed with the status OK, which is wrong considering the tests didn't even run completely
Fixes: e8478b84d6ba9ccf ("perf test: add new task-analyzer tests") Signed-off-by: Aditya Gupta adityag@linux.ibm.com Signed-off-by: Athira Rajeev atrajeev@linux.vnet.ibm.com Signed-off-by: Kajol Jain kjain@linux.ibm.com Cc: Disha Goel disgoel@linux.vnet.ibm.com Cc: Hagen Paul Pfeifer hagen@jauu.net Cc: Ian Rogers irogers@google.com Cc: Jiri Olsa jolsa@kernel.org Cc: John Garry john.g.garry@oracle.com Cc: Madhavan Srinivasan maddy@linux.ibm.com Cc: Namhyung Kim namhyung@kernel.org Cc: Petar Gligoric petar.gligoric@rohde-schwarz.com Cc: Ravi Bangoria ravi.bangoria@amd.com Cc: linuxppc-dev@lists.ozlabs.org Link: https://lore.kernel.org/r/20230613164145.50488-16-atrajeev@linux.vnet.ibm.co... Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/tests/shell/test_task_analyzer.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/tests/shell/test_task_analyzer.sh b/tools/perf/tests/shell/test_task_analyzer.sh index a98e4ab66040e..6b3343234a6b2 100755 --- a/tools/perf/tests/shell/test_task_analyzer.sh +++ b/tools/perf/tests/shell/test_task_analyzer.sh @@ -31,7 +31,7 @@ report() {
check_exec_0() { if [ $? != 0 ]; then - report 1 "invokation of ${$1} command failed" + report 1 "invocation of $1 command failed" fi }
From: Aditya Gupta adityag@linux.ibm.com
[ Upstream commit c3ac3b0779770acd3ad7eecb5099ab4419ef2e2e ]
Test "perf script task-analyzer tests" fails in environment with missing libtraceevent support, as perf record fails to create the perf.data file, which further tests depend on.
Instead, when perf is not compiled with libtraceevent support, skip those tests instead of failing them, by checking the output of `perf record --dry-run` to see if it prints the error "libtraceevent is necessary for tracepoint support"
For the following output, perf compiled with: `make NO_LIBTRACEEVENT=1`
Before the patch:
108: perf script task-analyzer tests : test child forked, pid 24105 failed to open perf.data: No such file or directory (try 'perf record' first) FAIL: "invokation of perf script report task-analyzer command failed" Error message: "" FAIL: "test_basic" Error message: "Failed to find required string:'Comm'." failed to open perf.data: No such file or directory (try 'perf record' first) FAIL: "invokation of perf script report task-analyzer --ns --rename-comms-by-tids 0:random command failed" Error message: "" FAIL: "test_ns_rename" Error message: "Failed to find required string:'Comm'." failed to open perf.data: No such file or directory (try 'perf record' first) <...> perf script task-analyzer tests: FAILED!
With this patch, the script instead returns 2 signifying SKIP, and after the patch:
108: perf script task-analyzer tests : test child forked, pid 26010 libtraceevent is necessary for tracepoint support WARN: Skipping tests. No libtraceevent support test child finished with -2 perf script task-analyzer tests: Skip
Fixes: e8478b84d6ba9ccf ("perf test: Add new task-analyzer tests") Signed-off-by: Aditya Gupta adityag@linux.ibm.com Cc: Disha Goel disgoel@linux.vnet.ibm.com Cc: Ian Rogers irogers@google.com Cc: Jiri Olsa jolsa@kernel.org Cc: John Garry john.g.garry@oracle.com Cc: Madhavan Srinivasan maddy@linux.ibm.com Cc: Namhyung Kim namhyung@kernel.org Cc: Petar Gligoric petar.gligoric@rohde-schwarz.com Cc: Ravi Bangoria ravi.bangoria@amd.com Cc: linuxppc-dev@lists.ozlabs.org Link: https://lore.kernel.org/r/20230613164145.50488-18-atrajeev@linux.vnet.ibm.co... Signed-off-by: Athira Rajeev atrajeev@linux.vnet.ibm.com Signed-off-by: Kajol Jain kjain@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/tests/shell/test_task_analyzer.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/tools/perf/tests/shell/test_task_analyzer.sh b/tools/perf/tests/shell/test_task_analyzer.sh index 6b3343234a6b2..1b7f3c1ec218b 100755 --- a/tools/perf/tests/shell/test_task_analyzer.sh +++ b/tools/perf/tests/shell/test_task_analyzer.sh @@ -44,9 +44,20 @@ find_str_or_fail() { fi }
+# check if perf is compiled with libtraceevent support +skip_no_probe_record_support() { + perf record -e "sched:sched_switch" -a -- sleep 1 2>&1 | grep "libtraceevent is necessary for tracepoint support" && return 2 + return 0 +} + prepare_perf_data() { # 1s should be sufficient to catch at least some switches perf record -e sched:sched_switch -a -- sleep 1 > /dev/null 2>&1 + # check if perf data file got created in above step. + if [ ! -e "perf.data" ]; then + printf "FAIL: perf record failed to create "perf.data" \n" + return 1 + fi }
# check standard inkvokation with no arguments @@ -134,6 +145,13 @@ test_csvsummary_extended() { find_str_or_fail "Out-Out;" csvsummary ${FUNCNAME[0]} }
+skip_no_probe_record_support +err=$? +if [ $err -ne 0 ]; then + echo "WARN: Skipping tests. No libtraceevent support" + cleanup + exit $err +fi prepare_perf_data test_basic test_ns_rename
From: Michal Wilczynski michal.wilczynski@intel.com
[ Upstream commit 966cca72ab20289083521a385fa56035d85a222d ]
Currently rbtn_add() in case of failure is leaking resources. Fix this by adding a proper rollback. Move devm_kzalloc() before rbtn_acquire(), so it doesn't require rollback in case of failure. While at it, remove unnecessary assignment of NULL to device->driver_data and unnecessary whitespace, plus add a break for the default case in a switch.
Suggested-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Suggested-by: Pali Rohár pali@kernel.org Fixes: 817a5cdb40c8 ("dell-rbtn: Dell Airplane Mode Switch driver") Signed-off-by: Michal Wilczynski michal.wilczynski@intel.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Acked-by: Rafael J. Wysocki rafael@kernel.org Reviewed-by: Pali Rohár pali@kernel.org Link: https://lore.kernel.org/r/20230613084310.2775896-1-michal.wilczynski@intel.c... Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/dell/dell-rbtn.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/platform/x86/dell/dell-rbtn.c b/drivers/platform/x86/dell/dell-rbtn.c index aa0e6c9074942..c8fcb537fd65d 100644 --- a/drivers/platform/x86/dell/dell-rbtn.c +++ b/drivers/platform/x86/dell/dell-rbtn.c @@ -395,16 +395,16 @@ static int rbtn_add(struct acpi_device *device) return -EINVAL; }
+ rbtn_data = devm_kzalloc(&device->dev, sizeof(*rbtn_data), GFP_KERNEL); + if (!rbtn_data) + return -ENOMEM; + ret = rbtn_acquire(device, true); if (ret < 0) { dev_err(&device->dev, "Cannot enable device\n"); return ret; }
- rbtn_data = devm_kzalloc(&device->dev, sizeof(*rbtn_data), GFP_KERNEL); - if (!rbtn_data) - return -ENOMEM; - rbtn_data->type = type; device->driver_data = rbtn_data;
@@ -420,10 +420,12 @@ static int rbtn_add(struct acpi_device *device) break; default: ret = -EINVAL; + break; } + if (ret) + rbtn_acquire(device, false);
return ret; - }
static void rbtn_remove(struct acpi_device *device) @@ -442,7 +444,6 @@ static void rbtn_remove(struct acpi_device *device) }
rbtn_acquire(device, false); - device->driver_data = NULL; }
static void rbtn_notify(struct acpi_device *device, u32 event)
From: Ravi Bangoria ravi.bangoria@amd.com
[ Upstream commit 0cd1ca4650c9cf5f318110f67d39cbebae3693b3 ]
There are multiple places where x86 specific code determines AMD vs Intel arch and acts based on that. Consolidate those checks into a single function.
Signed-off-by: Ravi Bangoria ravi.bangoria@amd.com Acked-by: Ian Rogers irogers@google.com Cc: Adrian Hunter adrian.hunter@intel.com Cc: Ali Saidi alisaidi@amazon.com Cc: Ananth Narayan ananth.narayan@amd.com Cc: James Clark james.clark@arm.com Cc: Jiri Olsa jolsa@kernel.org Cc: Kan Liang kan.liang@linux.intel.com Cc: Leo Yan leo.yan@linaro.org Cc: Madhavan Srinivasan maddy@linux.ibm.com Cc: Mark Rutland mark.rutland@arm.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Sandipan Das sandipan.das@amd.com Cc: Santosh Shukla santosh.shukla@amd.com Link: https://lore.kernel.org/r/20230613095506.547-3-ravi.bangoria@amd.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Stable-dep-of: 99d4850062a8 ("perf tool x86: Fix perf_env memory leak") Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/arch/x86/util/Build | 1 + tools/perf/arch/x86/util/env.c | 19 +++++++++++++++++++ tools/perf/arch/x86/util/env.h | 7 +++++++ tools/perf/arch/x86/util/evsel.c | 16 ++-------------- tools/perf/arch/x86/util/mem-events.c | 19 ++----------------- 5 files changed, 31 insertions(+), 31 deletions(-) create mode 100644 tools/perf/arch/x86/util/env.c create mode 100644 tools/perf/arch/x86/util/env.h
diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build index 195ccfdef7aa1..005907cb97d8c 100644 --- a/tools/perf/arch/x86/util/Build +++ b/tools/perf/arch/x86/util/Build @@ -10,6 +10,7 @@ perf-y += evlist.o perf-y += mem-events.o perf-y += evsel.o perf-y += iostat.o +perf-y += env.o
perf-$(CONFIG_DWARF) += dwarf-regs.o perf-$(CONFIG_BPF_PROLOGUE) += dwarf-regs.o diff --git a/tools/perf/arch/x86/util/env.c b/tools/perf/arch/x86/util/env.c new file mode 100644 index 0000000000000..33b87f8ac1cc1 --- /dev/null +++ b/tools/perf/arch/x86/util/env.c @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "linux/string.h" +#include "util/env.h" +#include "env.h" + +bool x86__is_amd_cpu(void) +{ + struct perf_env env = { .total_mem = 0, }; + static int is_amd; /* 0: Uninitialized, 1: Yes, -1: No */ + + if (is_amd) + goto ret; + + perf_env__cpuid(&env); + is_amd = env.cpuid && strstarts(env.cpuid, "AuthenticAMD") ? 1 : -1; + +ret: + return is_amd >= 1 ? true : false; +} diff --git a/tools/perf/arch/x86/util/env.h b/tools/perf/arch/x86/util/env.h new file mode 100644 index 0000000000000..d78f080b6b3f8 --- /dev/null +++ b/tools/perf/arch/x86/util/env.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _X86_ENV_H +#define _X86_ENV_H + +bool x86__is_amd_cpu(void); + +#endif /* _X86_ENV_H */ diff --git a/tools/perf/arch/x86/util/evsel.c b/tools/perf/arch/x86/util/evsel.c index ea3972d785d10..d72390cdf391d 100644 --- a/tools/perf/arch/x86/util/evsel.c +++ b/tools/perf/arch/x86/util/evsel.c @@ -7,6 +7,7 @@ #include "linux/string.h" #include "evsel.h" #include "util/debug.h" +#include "env.h"
#define IBS_FETCH_L3MISSONLY (1ULL << 59) #define IBS_OP_L3MISSONLY (1ULL << 16) @@ -97,23 +98,10 @@ void arch__post_evsel_config(struct evsel *evsel, struct perf_event_attr *attr) { struct perf_pmu *evsel_pmu, *ibs_fetch_pmu, *ibs_op_pmu; static int warned_once; - /* 0: Uninitialized, 1: Yes, -1: No */ - static int is_amd;
- if (warned_once || is_amd == -1) + if (warned_once || !x86__is_amd_cpu()) return;
- if (!is_amd) { - struct perf_env *env = evsel__env(evsel); - - if (!perf_env__cpuid(env) || !env->cpuid || - !strstarts(env->cpuid, "AuthenticAMD")) { - is_amd = -1; - return; - } - is_amd = 1; - } - evsel_pmu = evsel__find_pmu(evsel); if (!evsel_pmu) return; diff --git a/tools/perf/arch/x86/util/mem-events.c b/tools/perf/arch/x86/util/mem-events.c index f683ac702247c..efc0fae9ed0a7 100644 --- a/tools/perf/arch/x86/util/mem-events.c +++ b/tools/perf/arch/x86/util/mem-events.c @@ -4,6 +4,7 @@ #include "map_symbol.h" #include "mem-events.h" #include "linux/string.h" +#include "env.h"
static char mem_loads_name[100]; static bool mem_loads_name__init; @@ -26,28 +27,12 @@ static struct perf_mem_event perf_mem_events_amd[PERF_MEM_EVENTS__MAX] = { E("mem-ldst", "ibs_op//", "ibs_op"), };
-static int perf_mem_is_amd_cpu(void) -{ - struct perf_env env = { .total_mem = 0, }; - - perf_env__cpuid(&env); - if (env.cpuid && strstarts(env.cpuid, "AuthenticAMD")) - return 1; - return -1; -} - struct perf_mem_event *perf_mem_events__ptr(int i) { - /* 0: Uninitialized, 1: Yes, -1: No */ - static int is_amd; - if (i >= PERF_MEM_EVENTS__MAX) return NULL;
- if (!is_amd) - is_amd = perf_mem_is_amd_cpu(); - - if (is_amd == 1) + if (x86__is_amd_cpu()) return &perf_mem_events_amd[i];
return &perf_mem_events_intel[i];
From: Ian Rogers irogers@google.com
[ Upstream commit 99d4850062a84564f36923764bb93935ef2ed108 ]
Found by leak sanitizer: ``` ==1632594==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 21 byte(s) in 1 object(s) allocated from: #0 0x7f2953a7077b in __interceptor_strdup ../../../../src/libsanitizer/asan/asan_interceptors.cpp:439 #1 0x556701d6fbbf in perf_env__read_cpuid util/env.c:369 #2 0x556701d70589 in perf_env__cpuid util/env.c:465 #3 0x55670204bba2 in x86__is_amd_cpu arch/x86/util/env.c:14 #4 0x5567020487a2 in arch__post_evsel_config arch/x86/util/evsel.c:83 #5 0x556701d8f78b in evsel__config util/evsel.c:1366 #6 0x556701ef5872 in evlist__config util/record.c:108 #7 0x556701cd6bcd in test__PERF_RECORD tests/perf-record.c:112 #8 0x556701cacd07 in run_test tests/builtin-test.c:236 #9 0x556701cacfac in test_and_print tests/builtin-test.c:265 #10 0x556701cadddb in __cmd_test tests/builtin-test.c:402 #11 0x556701caf2aa in cmd_test tests/builtin-test.c:559 #12 0x556701d3b557 in run_builtin tools/perf/perf.c:323 #13 0x556701d3bac8 in handle_internal_command tools/perf/perf.c:377 #14 0x556701d3be90 in run_argv tools/perf/perf.c:421 #15 0x556701d3c3f8 in main tools/perf/perf.c:537 #16 0x7f2952a46189 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
SUMMARY: AddressSanitizer: 21 byte(s) leaked in 1 allocation(s). ```
Fixes: f7b58cbdb3ff36eb ("perf mem/c2c: Add load store event mappings for AMD") Signed-off-by: Ian Rogers irogers@google.com Acked-by: Ravi Bangoria ravi.bangoria@amd.com Tested-by: Arnaldo Carvalho de Melo acme@redhat.com Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Ingo Molnar mingo@redhat.com Cc: Jiri Olsa jolsa@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Ravi Bangoria ravi.bangoria@amd.com Link: https://lore.kernel.org/r/20230613235416.1650755-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/arch/x86/util/env.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/arch/x86/util/env.c b/tools/perf/arch/x86/util/env.c index 33b87f8ac1cc1..3e537ffb1353a 100644 --- a/tools/perf/arch/x86/util/env.c +++ b/tools/perf/arch/x86/util/env.c @@ -13,7 +13,7 @@ bool x86__is_amd_cpu(void)
perf_env__cpuid(&env); is_amd = env.cpuid && strstarts(env.cpuid, "AuthenticAMD") ? 1 : -1; - + perf_env__exit(&env); ret: return is_amd >= 1 ? true : false; }
From: Nicholas Piggin npiggin@gmail.com
[ Upstream commit b4bda59b47879cce38a6ec5a01cd3cac702b5331 ]
The refcount on mm is dropped before the coprocessor is detached.
Reported-by: Sachin Sant sachinp@linux.ibm.com Fixes: 7bc6f71bdff5f ("powerpc/vas: Define and use common vas_window struct") Fixes: b22f2d88e435c ("powerpc/pseries/vas: Integrate API with open/close windows") Signed-off-by: Nicholas Piggin npiggin@gmail.com Tested-by: Sachin Sant sachinp@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20230607101024.14559-1-npiggin@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/powernv/vas-window.c | 2 +- arch/powerpc/platforms/pseries/vas.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index 0072682531d80..b664838008c12 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -1310,8 +1310,8 @@ int vas_win_close(struct vas_window *vwin) /* if send window, drop reference to matching receive window */ if (window->tx_win) { if (window->user_win) { - put_vas_user_win_ref(&vwin->task_ref); mm_context_remove_vas_window(vwin->task_ref.mm); + put_vas_user_win_ref(&vwin->task_ref); } put_rx_win(window->rxwin); } diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c index 513180467562b..9a44a98ba3420 100644 --- a/arch/powerpc/platforms/pseries/vas.c +++ b/arch/powerpc/platforms/pseries/vas.c @@ -507,8 +507,8 @@ static int vas_deallocate_window(struct vas_window *vwin) vascaps[win->win_type].nr_open_windows--; mutex_unlock(&vas_pseries_mutex);
- put_vas_user_win_ref(&vwin->task_ref); mm_context_remove_vas_window(vwin->task_ref.mm); + put_vas_user_win_ref(&vwin->task_ref);
kfree(win); return 0;
From: Xiaolei Wang xiaolei.wang@windriver.com
[ Upstream commit 9063777ca1e2e895c5fdd493ee0c3f18fa710ed4 ]
The config passed in by pad wakeup is 1, when num_configs is 1, Configuration [1] should not be fetched, which will be detected by KASAN as a memory out of bounds condition. Modify to get configs[1] when num_configs is 2.
Fixes: f60c9eac54af ("gpio: mxc: enable pad wakeup on i.MX8x platforms") Signed-off-by: Xiaolei Wang xiaolei.wang@windriver.com Reviewed-by: Peng Fan peng.fan@nxp.com Link: https://lore.kernel.org/r/20230504233736.3766296-1-xiaolei.wang@windriver.co... Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/freescale/pinctrl-scu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/pinctrl/freescale/pinctrl-scu.c b/drivers/pinctrl/freescale/pinctrl-scu.c index ea261b6e74581..3b252d684d723 100644 --- a/drivers/pinctrl/freescale/pinctrl-scu.c +++ b/drivers/pinctrl/freescale/pinctrl-scu.c @@ -90,7 +90,7 @@ int imx_pinconf_set_scu(struct pinctrl_dev *pctldev, unsigned pin_id, struct imx_sc_msg_req_pad_set msg; struct imx_sc_rpc_msg *hdr = &msg.hdr; unsigned int mux = configs[0]; - unsigned int conf = configs[1]; + unsigned int conf; unsigned int val; int ret;
@@ -115,6 +115,7 @@ int imx_pinconf_set_scu(struct pinctrl_dev *pctldev, unsigned pin_id, * Set mux and conf together in one IPC call */ WARN_ON(num_configs != 2); + conf = configs[1];
val = conf | BM_PAD_CTL_IFMUX_ENABLE | BM_PAD_CTL_GP_ENABLE; val |= mux << BP_PAD_CTL_IFMUX;
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit 310cd4c206cd04696ccbfd1927b5ab6973e8cc8e ]
devm_kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script).
Fixes: 7e5ea974e61c ("pinctrl: pinctrl-microchip-sgpio: Add pinctrl driver for Microsemi Serial GPIO") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Link: https://lore.kernel.org/r/20230615105333.585304-3-claudiu.beznea@microchip.c... Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/pinctrl-microchip-sgpio.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/pinctrl/pinctrl-microchip-sgpio.c b/drivers/pinctrl/pinctrl-microchip-sgpio.c index 4794602316e7d..666d8b7cdbad3 100644 --- a/drivers/pinctrl/pinctrl-microchip-sgpio.c +++ b/drivers/pinctrl/pinctrl-microchip-sgpio.c @@ -818,6 +818,9 @@ static int microchip_sgpio_register_bank(struct device *dev, pctl_desc->name = devm_kasprintf(dev, GFP_KERNEL, "%s-%sput", dev_name(dev), bank->is_input ? "in" : "out"); + if (!pctl_desc->name) + return -ENOMEM; + pctl_desc->pctlops = &sgpio_pctl_ops; pctl_desc->pmxops = &sgpio_pmx_ops; pctl_desc->confops = &sgpio_confops;
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit f6fd5d4ff8ca0b24cee1af4130bcb1fa96b61aa0 ]
devm_kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script).
Fixes: 776180848b57 ("pinctrl: introduce driver for Atmel PIO4 controller") Depends-on: 1c4e5c470a56 ("pinctrl: at91: use devm_kasprintf() to avoid potential leaks") Depends-on: 5a8f9cf269e8 ("pinctrl: at91-pio4: use proper format specifier for unsigned int") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Link: https://lore.kernel.org/r/20230615105333.585304-4-claudiu.beznea@microchip.c... Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/pinctrl-at91-pio4.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c index c775d239444a6..20433c1745805 100644 --- a/drivers/pinctrl/pinctrl-at91-pio4.c +++ b/drivers/pinctrl/pinctrl-at91-pio4.c @@ -1151,6 +1151,8 @@ static int atmel_pinctrl_probe(struct platform_device *pdev) /* Pin naming convention: P(bank_name)(bank_pin_number). */ pin_desc[i].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "P%c%d", bank + 'A', line); + if (!pin_desc[i].name) + return -ENOMEM;
group->name = group_names[i] = pin_desc[i].name; group->pin = pin_desc[i].number;
From: Namhyung Kim namhyung@kernel.org
[ Upstream commit ed4090a22c123b9b33368741253edddc6ff8d18f ]
When it runs multiple times with -r option, it missed to reset the aggregation counters and the values were added up. The aggregation count has the values to be printed in the end. It should reset the counters at the beginning of each run. But the current code does that only when -I/--interval-print option is given.
Fixes: 91f85f98da7ab8c3 ("perf stat: Display event stats using aggr counts") Reported-by: Jiri Olsa jolsa@kernel.org Signed-off-by: Namhyung Kim namhyung@kernel.org Cc: Adrian Hunter adrian.hunter@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Ian Rogers irogers@google.com Cc: Ingo Molnar mingo@kernel.org Cc: Kan Liang kan.liang@linux.intel.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Link: https://lore.kernel.org/r/20230616073211.1057936-1-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/builtin-stat.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index eeba93ae3b584..f5a6d08cf07f6 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -777,6 +777,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) all_counters_use_bpf = false; }
+ evlist__reset_aggr_stats(evsel_list); + evlist__for_each_cpu(evlist_cpu_itr, evsel_list, affinity) { counter = evlist_cpu_itr.evsel;
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit 72554035b9797e00e68cd866e6cefa7f0b2c6f76 ]
ufshcd_add_command_trace() traces SCSI commands. Remove a ufshcd_add_command_trace() call from a code path that is not related to SCSI commands.
Signed-off-by: Bart Van Assche bvanassche@acm.org Link: https://lore.kernel.org/r/20230531224050.25554-1-bvanassche@acm.org Reviewed-by: Avri Altman avri.altman@wdc.com Reviewed-by: Bean Huo beanhuo@micron.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Stable-dep-of: 0fef6bb730c4 ("scsi: ufs: core: mcq: Fix the incorrect OCS value for the device command") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ufs/core/ufshcd.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index dc63bd60db77d..b788bd0053330 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -5420,7 +5420,6 @@ void ufshcd_compl_one_cqe(struct ufs_hba *hba, int task_tag, lrbp->command_type == UTP_CMD_TYPE_UFS_STORAGE) { if (hba->dev_cmd.complete) { hba->dev_cmd.cqe = cqe; - ufshcd_add_command_trace(hba, task_tag, UFS_DEV_COMP); complete(hba->dev_cmd.complete); ufshcd_clk_scaling_update_busy(hba); }
From: Stanley Chu stanley.chu@mediatek.com
[ Upstream commit 0fef6bb730c490fcdc4347dbd21646d3ffe62cf5 ]
In MCQ mode, when a device command uses a hardware queue shared with other commands, a race condition may occur in the following scenario:
1. A device command is completed in CQx with CQE entry "e".
2. The interrupt handler copies the "cqe" pointer to "hba->dev_cmd.cqe" and completes "hba->dev_cmd.complete".
3. The "ufshcd_wait_for_dev_cmd()" function is awakened and retrieves the OCS value from "hba->dev_cmd.cqe".
However, there is a possibility that the CQE entry "e" will be overwritten by newly completed commands in CQx, resulting in an incorrect OCS value being received by "ufshcd_wait_for_dev_cmd()".
To avoid this race condition, the OCS value should be immediately copied to the struct "lrb" of the device command. Then "ufshcd_wait_for_dev_cmd()" can retrieve the OCS value from the struct "lrb".
Fixes: 57b1c0ef89ac ("scsi: ufs: core: mcq: Add support to allocate multiple queues") Suggested-by: Can Guo quic_cang@quicinc.com Signed-off-by: Stanley Chu stanley.chu@mediatek.com Link: https://lore.kernel.org/r/20230610021553.1213-2-powen.kao@mediatek.com Tested-by: Po-Wen Kao powen.kao@mediatek.com Reviewed-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ufs/core/ufshcd.c | 10 +++++++--- include/ufs/ufshcd.h | 1 - 2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index b788bd0053330..e67981317dcbf 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -3069,7 +3069,7 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba, * not trigger any race conditions. */ hba->dev_cmd.complete = NULL; - err = ufshcd_get_tr_ocs(lrbp, hba->dev_cmd.cqe); + err = ufshcd_get_tr_ocs(lrbp, NULL); if (!err) err = ufshcd_dev_cmd_completion(hba, lrbp); } else { @@ -3156,7 +3156,6 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, goto out;
hba->dev_cmd.complete = &wait; - hba->dev_cmd.cqe = NULL;
ufshcd_add_query_upiu_trace(hba, UFS_QUERY_SEND, lrbp->ucd_req_ptr);
@@ -5404,6 +5403,7 @@ void ufshcd_compl_one_cqe(struct ufs_hba *hba, int task_tag, { struct ufshcd_lrb *lrbp; struct scsi_cmnd *cmd; + enum utp_ocs ocs;
lrbp = &hba->lrb[task_tag]; lrbp->compl_time_stamp = ktime_get(); @@ -5419,7 +5419,11 @@ void ufshcd_compl_one_cqe(struct ufs_hba *hba, int task_tag, } else if (lrbp->command_type == UTP_CMD_TYPE_DEV_MANAGE || lrbp->command_type == UTP_CMD_TYPE_UFS_STORAGE) { if (hba->dev_cmd.complete) { - hba->dev_cmd.cqe = cqe; + if (cqe) { + ocs = le32_to_cpu(cqe->status) & MASK_OCS; + lrbp->utr_descriptor_ptr->header.dword_2 = + cpu_to_le32(ocs); + } complete(hba->dev_cmd.complete); ufshcd_clk_scaling_update_busy(hba); } diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index db70944c681aa..91803587691a6 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -225,7 +225,6 @@ struct ufs_dev_cmd { struct mutex lock; struct completion *complete; struct ufs_query query; - struct cq_entry *cqe; };
/**
From: Colin Ian King colin.i.king@gmail.com
[ Upstream commit f4f913c980bc6abe0ccfe88fe3909c125afe4a2d ]
Currently pointer iov is being dereferenced before the null check of iov which can lead to null pointer dereference errors. Fix this by moving the iov null check before the dereferencing.
Detected using cppcheck static analysis: linux/arch/powerpc/platforms/powernv/pci-sriov.c:597:12: warning: Either the condition '!iov' is redundant or there is possible null pointer dereference: iov. [nullPointerRedundantCheck] num_vfs = iov->num_vfs; ^
Fixes: 052da31d45fc ("powerpc/powernv/sriov: De-indent setup and teardown") Signed-off-by: Colin Ian King colin.i.king@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20230608095849.1147969-1-colin.i.king@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/powernv/pci-sriov.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/pci-sriov.c b/arch/powerpc/platforms/powernv/pci-sriov.c index 7195133b26bb9..59882da3e7425 100644 --- a/arch/powerpc/platforms/powernv/pci-sriov.c +++ b/arch/powerpc/platforms/powernv/pci-sriov.c @@ -594,12 +594,12 @@ static void pnv_pci_sriov_disable(struct pci_dev *pdev) struct pnv_iov_data *iov;
iov = pnv_iov_get(pdev); - num_vfs = iov->num_vfs; - base_pe = iov->vf_pe_arr[0].pe_number; - if (WARN_ON(!iov)) return;
+ num_vfs = iov->num_vfs; + base_pe = iov->vf_pe_arr[0].pe_number; + /* Release VF PEs */ pnv_ioda_release_vf_PE(pdev);
From: Aditya Gupta adityag@linux.ibm.com
[ Upstream commit b684c09f09e7a6af3794d4233ef785819e72db79 ]
ppc_save_regs() skips one stack frame while saving the CPU register states. Instead of saving current R1, it pulls the previous stack frame pointer.
When vmcores caused by direct panic call (such as `echo c > /proc/sysrq-trigger`), are debugged with gdb, gdb fails to show the backtrace correctly. On further analysis, it was found that it was because of mismatch between r1 and NIP.
GDB uses NIP to get current function symbol and uses corresponding debug info of that function to unwind previous frames, but due to the mismatching r1 and NIP, the unwinding does not work, and it fails to unwind to the 2nd frame and hence does not show the backtrace.
GDB backtrace with vmcore of kernel without this patch:
--------- (gdb) bt #0 0xc0000000002a53e8 in crash_setup_regs (oldregs=<optimized out>, newregs=0xc000000004f8f8d8) at ./arch/powerpc/include/asm/kexec.h:69 #1 __crash_kexec (regs=<optimized out>) at kernel/kexec_core.c:974 #2 0x0000000000000063 in ?? () #3 0xc000000003579320 in ?? () ---------
Further analysis revealed that the mismatch occurred because "ppc_save_regs" was saving the previous stack's SP instead of the current r1. This patch fixes this by storing current r1 in the saved pt_regs.
GDB backtrace with vmcore of patched kernel:
-------- (gdb) bt #0 0xc0000000002a53e8 in crash_setup_regs (oldregs=0x0, newregs=0xc00000000670b8d8) at ./arch/powerpc/include/asm/kexec.h:69 #1 __crash_kexec (regs=regs@entry=0x0) at kernel/kexec_core.c:974 #2 0xc000000000168918 in panic (fmt=fmt@entry=0xc000000001654a60 "sysrq triggered crash\n") at kernel/panic.c:358 #3 0xc000000000b735f8 in sysrq_handle_crash (key=<optimized out>) at drivers/tty/sysrq.c:155 #4 0xc000000000b742cc in __handle_sysrq (key=key@entry=99, check_mask=check_mask@entry=false) at drivers/tty/sysrq.c:602 #5 0xc000000000b7506c in write_sysrq_trigger (file=<optimized out>, buf=<optimized out>, count=2, ppos=<optimized out>) at drivers/tty/sysrq.c:1163 #6 0xc00000000069a7bc in pde_write (ppos=<optimized out>, count=<optimized out>, buf=<optimized out>, file=<optimized out>, pde=0xc00000000362cb40) at fs/proc/inode.c:340 #7 proc_reg_write (file=<optimized out>, buf=<optimized out>, count=<optimized out>, ppos=<optimized out>) at fs/proc/inode.c:352 #8 0xc0000000005b3bbc in vfs_write (file=file@entry=0xc000000006aa6b00, buf=buf@entry=0x61f498b4f60 <error: Cannot access memory at address 0x61f498b4f60>, count=count@entry=2, pos=pos@entry=0xc00000000670bda0) at fs/read_write.c:582 #9 0xc0000000005b4264 in ksys_write (fd=<optimized out>, buf=0x61f498b4f60 <error: Cannot access memory at address 0x61f498b4f60>, count=2) at fs/read_write.c:637 #10 0xc00000000002ea2c in system_call_exception (regs=0xc00000000670be80, r0=<optimized out>) at arch/powerpc/kernel/syscall.c:171 #11 0xc00000000000c270 in system_call_vectored_common () at arch/powerpc/kernel/interrupt_64.S:192 --------
Nick adds: So this now saves regs as though it was an interrupt taken in the caller, at the instruction after the call to ppc_save_regs, whereas previously the NIP was there, but R1 came from the caller's caller and that mismatch is what causes gdb's dwarf unwinder to go haywire.
Signed-off-by: Aditya Gupta adityag@linux.ibm.com Fixes: d16a58f8854b1 ("powerpc: Improve ppc_save_regs()") Reivewed-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20230615091047.90433-1-adityag@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/ppc_save_regs.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/ppc_save_regs.S b/arch/powerpc/kernel/ppc_save_regs.S index 49813f9824681..a9b9c32d0c1ff 100644 --- a/arch/powerpc/kernel/ppc_save_regs.S +++ b/arch/powerpc/kernel/ppc_save_regs.S @@ -31,10 +31,10 @@ _GLOBAL(ppc_save_regs) lbz r0,PACAIRQSOFTMASK(r13) PPC_STL r0,SOFTE(r3) #endif - /* go up one stack frame for SP */ - PPC_LL r4,0(r1) - PPC_STL r4,GPR1(r3) + /* store current SP */ + PPC_STL r1,GPR1(r3) /* get caller's LR */ + PPC_LL r4,0(r1) PPC_LL r0,LRSAVE(r4) PPC_STL r0,_LINK(r3) mflr r0
From: Xi Pardee xi.pardee@intel.com
[ Upstream commit 9682cfd1973d01e43c2764c662e6d3291ddf770d ]
Fix the IP name errors in the register maps used by the following debugfs attributes in the Meteor Lake SOC-M PMC.
pfear_sts lpm_sts ltr_show
Fixes: c5ad454a12c6 ("platform/x86: intel/pmc/core: Add Meteor Lake support to pmc core driver") Signed-off-by: Xi Pardee xi.pardee@intel.com Signed-off-by: Rajvi Jingar rajvi.jingar@linux.intel.com Reviewed-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Link: https://lore.kernel.org/r/20230613225347.2720665-2-rajvi.jingar@linux.intel.... Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/intel/pmc/core.h | 28 +- drivers/platform/x86/intel/pmc/mtl.c | 448 +++++++++++++++++++++++++- 2 files changed, 466 insertions(+), 10 deletions(-)
diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h index 810204d758ab3..d1c29fcd07ae9 100644 --- a/drivers/platform/x86/intel/pmc/core.h +++ b/drivers/platform/x86/intel/pmc/core.h @@ -247,6 +247,14 @@ enum ppfear_regs { #define MTL_LPM_STATUS_LATCH_EN_OFFSET 0x16F8 #define MTL_LPM_STATUS_OFFSET 0x1700 #define MTL_LPM_LIVE_STATUS_OFFSET 0x175C +#define MTL_PMC_LTR_IOE_PMC 0x1C0C +#define MTL_PMC_LTR_ESE 0x1BAC +#define MTL_SOCM_NUM_IP_IGN_ALLOWED 25 +#define MTL_SOC_PMC_MMIO_REG_LEN 0x2708 +#define MTL_PMC_LTR_SPG 0x1B74 + +/* Meteor Lake PGD PFET Enable Ack Status */ +#define MTL_SOCM_PPFEAR_NUM_ENTRIES 8
extern const char *pmc_lpm_modes[];
@@ -393,7 +401,25 @@ extern const struct pmc_bit_map adl_vnn_req_status_3_map[]; extern const struct pmc_bit_map adl_vnn_misc_status_map[]; extern const struct pmc_bit_map *adl_lpm_maps[]; extern const struct pmc_reg_map adl_reg_map; -extern const struct pmc_reg_map mtl_reg_map; +extern const struct pmc_bit_map mtl_socm_pfear_map[]; +extern const struct pmc_bit_map *ext_mtl_socm_pfear_map[]; +extern const struct pmc_bit_map mtl_socm_ltr_show_map[]; +extern const struct pmc_bit_map mtl_socm_clocksource_status_map[]; +extern const struct pmc_bit_map mtl_socm_power_gating_status_0_map[]; +extern const struct pmc_bit_map mtl_socm_power_gating_status_1_map[]; +extern const struct pmc_bit_map mtl_socm_power_gating_status_2_map[]; +extern const struct pmc_bit_map mtl_socm_d3_status_0_map[]; +extern const struct pmc_bit_map mtl_socm_d3_status_1_map[]; +extern const struct pmc_bit_map mtl_socm_d3_status_2_map[]; +extern const struct pmc_bit_map mtl_socm_d3_status_3_map[]; +extern const struct pmc_bit_map mtl_socm_vnn_req_status_0_map[]; +extern const struct pmc_bit_map mtl_socm_vnn_req_status_1_map[]; +extern const struct pmc_bit_map mtl_socm_vnn_req_status_2_map[]; +extern const struct pmc_bit_map mtl_socm_vnn_req_status_3_map[]; +extern const struct pmc_bit_map mtl_socm_vnn_misc_status_map[]; +extern const struct pmc_bit_map mtl_socm_signal_status_map[]; +extern const struct pmc_bit_map *mtl_socm_lpm_maps[]; +extern const struct pmc_reg_map mtl_socm_reg_map;
extern void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev); extern int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value); diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c index eeb3bd8c2502d..de9348e031003 100644 --- a/drivers/platform/x86/intel/pmc/mtl.c +++ b/drivers/platform/x86/intel/pmc/mtl.c @@ -10,28 +10,458 @@
#include "core.h"
-const struct pmc_reg_map mtl_reg_map = { - .pfear_sts = ext_tgl_pfear_map, +/* + * Die Mapping to Product. + * Product SOCDie IOEDie PCHDie + * MTL-M SOC-M IOE-M None + * MTL-P SOC-M IOE-P None + * MTL-S SOC-S IOE-P PCH-S + */ + +const struct pmc_bit_map mtl_socm_pfear_map[] = { + {"PMC", BIT(0)}, + {"OPI", BIT(1)}, + {"SPI", BIT(2)}, + {"XHCI", BIT(3)}, + {"SPA", BIT(4)}, + {"SPB", BIT(5)}, + {"SPC", BIT(6)}, + {"GBE", BIT(7)}, + + {"SATA", BIT(0)}, + {"DSP0", BIT(1)}, + {"DSP1", BIT(2)}, + {"DSP2", BIT(3)}, + {"DSP3", BIT(4)}, + {"SPD", BIT(5)}, + {"LPSS", BIT(6)}, + {"LPC", BIT(7)}, + + {"SMB", BIT(0)}, + {"ISH", BIT(1)}, + {"P2SB", BIT(2)}, + {"NPK_VNN", BIT(3)}, + {"SDX", BIT(4)}, + {"SPE", BIT(5)}, + {"FUSE", BIT(6)}, + {"SBR8", BIT(7)}, + + {"RSVD24", BIT(0)}, + {"OTG", BIT(1)}, + {"EXI", BIT(2)}, + {"CSE", BIT(3)}, + {"CSME_KVM", BIT(4)}, + {"CSME_PMT", BIT(5)}, + {"CSME_CLINK", BIT(6)}, + {"CSME_PTIO", BIT(7)}, + + {"CSME_USBR", BIT(0)}, + {"CSME_SUSRAM", BIT(1)}, + {"CSME_SMT1", BIT(2)}, + {"RSVD35", BIT(3)}, + {"CSME_SMS2", BIT(4)}, + {"CSME_SMS", BIT(5)}, + {"CSME_RTC", BIT(6)}, + {"CSME_PSF", BIT(7)}, + + {"SBR0", BIT(0)}, + {"SBR1", BIT(1)}, + {"SBR2", BIT(2)}, + {"SBR3", BIT(3)}, + {"SBR4", BIT(4)}, + {"SBR5", BIT(5)}, + {"RSVD46", BIT(6)}, + {"PSF1", BIT(7)}, + + {"PSF2", BIT(0)}, + {"PSF3", BIT(1)}, + {"PSF4", BIT(2)}, + {"CNVI", BIT(3)}, + {"UFSX2", BIT(4)}, + {"EMMC", BIT(5)}, + {"SPF", BIT(6)}, + {"SBR6", BIT(7)}, + + {"SBR7", BIT(0)}, + {"NPK_AON", BIT(1)}, + {"HDA4", BIT(2)}, + {"HDA5", BIT(3)}, + {"HDA6", BIT(4)}, + {"PSF6", BIT(5)}, + {"RSVD62", BIT(6)}, + {"RSVD63", BIT(7)}, + {} +}; + +const struct pmc_bit_map *ext_mtl_socm_pfear_map[] = { + mtl_socm_pfear_map, + NULL +}; + +const struct pmc_bit_map mtl_socm_ltr_show_map[] = { + {"SOUTHPORT_A", CNP_PMC_LTR_SPA}, + {"SOUTHPORT_B", CNP_PMC_LTR_SPB}, + {"SATA", CNP_PMC_LTR_SATA}, + {"GIGABIT_ETHERNET", CNP_PMC_LTR_GBE}, + {"XHCI", CNP_PMC_LTR_XHCI}, + {"SOUTHPORT_F", ADL_PMC_LTR_SPF}, + {"ME", CNP_PMC_LTR_ME}, + {"SATA1", CNP_PMC_LTR_EVA}, + {"SOUTHPORT_C", CNP_PMC_LTR_SPC}, + {"HD_AUDIO", CNP_PMC_LTR_AZ}, + {"CNV", CNP_PMC_LTR_CNV}, + {"LPSS", CNP_PMC_LTR_LPSS}, + {"SOUTHPORT_D", CNP_PMC_LTR_SPD}, + {"SOUTHPORT_E", CNP_PMC_LTR_SPE}, + {"SATA2", CNP_PMC_LTR_CAM}, + {"ESPI", CNP_PMC_LTR_ESPI}, + {"SCC", CNP_PMC_LTR_SCC}, + {"ISH", CNP_PMC_LTR_ISH}, + {"UFSX2", CNP_PMC_LTR_UFSX2}, + {"EMMC", CNP_PMC_LTR_EMMC}, + {"WIGIG", ICL_PMC_LTR_WIGIG}, + {"THC0", TGL_PMC_LTR_THC0}, + {"THC1", TGL_PMC_LTR_THC1}, + {"SOUTHPORT_G", MTL_PMC_LTR_SPG}, + {"ESE", MTL_PMC_LTR_ESE}, + {"IOE_PMC", MTL_PMC_LTR_IOE_PMC}, + + /* Below two cannot be used for LTR_IGNORE */ + {"CURRENT_PLATFORM", CNP_PMC_LTR_CUR_PLT}, + {"AGGREGATED_SYSTEM", CNP_PMC_LTR_CUR_ASLT}, + {} +}; + +const struct pmc_bit_map mtl_socm_clocksource_status_map[] = { + {"AON2_OFF_STS", BIT(0)}, + {"AON3_OFF_STS", BIT(1)}, + {"AON4_OFF_STS", BIT(2)}, + {"AON5_OFF_STS", BIT(3)}, + {"AON1_OFF_STS", BIT(4)}, + {"XTAL_LVM_OFF_STS", BIT(5)}, + {"MPFPW1_0_PLL_OFF_STS", BIT(6)}, + {"MPFPW1_1_PLL_OFF_STS", BIT(7)}, + {"USB3_PLL_OFF_STS", BIT(8)}, + {"AON3_SPL_OFF_STS", BIT(9)}, + {"MPFPW2_0_PLL_OFF_STS", BIT(12)}, + {"MPFPW3_0_PLL_OFF_STS", BIT(13)}, + {"XTAL_AGGR_OFF_STS", BIT(17)}, + {"USB2_PLL_OFF_STS", BIT(18)}, + {"FILTER_PLL_OFF_STS", BIT(22)}, + {"ACE_PLL_OFF_STS", BIT(24)}, + {"FABRIC_PLL_OFF_STS", BIT(25)}, + {"SOC_PLL_OFF_STS", BIT(26)}, + {"PCIFAB_PLL_OFF_STS", BIT(27)}, + {"REF_PLL_OFF_STS", BIT(28)}, + {"IMG_PLL_OFF_STS", BIT(29)}, + {"RTC_PLL_OFF_STS", BIT(31)}, + {} +}; + +const struct pmc_bit_map mtl_socm_power_gating_status_0_map[] = { + {"PMC_PGD0_PG_STS", BIT(0)}, + {"DMI_PGD0_PG_STS", BIT(1)}, + {"ESPISPI_PGD0_PG_STS", BIT(2)}, + {"XHCI_PGD0_PG_STS", BIT(3)}, + {"SPA_PGD0_PG_STS", BIT(4)}, + {"SPB_PGD0_PG_STS", BIT(5)}, + {"SPC_PGD0_PG_STS", BIT(6)}, + {"GBE_PGD0_PG_STS", BIT(7)}, + {"SATA_PGD0_PG_STS", BIT(8)}, + {"PSF13_PGD0_PG_STS", BIT(9)}, + {"SOC_D2D_PGD3_PG_STS", BIT(10)}, + {"MPFPW3_PGD0_PG_STS", BIT(11)}, + {"ESE_PGD0_PG_STS", BIT(12)}, + {"SPD_PGD0_PG_STS", BIT(13)}, + {"LPSS_PGD0_PG_STS", BIT(14)}, + {"LPC_PGD0_PG_STS", BIT(15)}, + {"SMB_PGD0_PG_STS", BIT(16)}, + {"ISH_PGD0_PG_STS", BIT(17)}, + {"P2S_PGD0_PG_STS", BIT(18)}, + {"NPK_PGD0_PG_STS", BIT(19)}, + {"DBG_SBR_PGD0_PG_STS", BIT(20)}, + {"SBRG_PGD0_PG_STS", BIT(21)}, + {"FUSE_PGD0_PG_STS", BIT(22)}, + {"SBR8_PGD0_PG_STS", BIT(23)}, + {"SOC_D2D_PGD2_PG_STS", BIT(24)}, + {"XDCI_PGD0_PG_STS", BIT(25)}, + {"EXI_PGD0_PG_STS", BIT(26)}, + {"CSE_PGD0_PG_STS", BIT(27)}, + {"KVMCC_PGD0_PG_STS", BIT(28)}, + {"PMT_PGD0_PG_STS", BIT(29)}, + {"CLINK_PGD0_PG_STS", BIT(30)}, + {"PTIO_PGD0_PG_STS", BIT(31)}, + {} +}; + +const struct pmc_bit_map mtl_socm_power_gating_status_1_map[] = { + {"USBR0_PGD0_PG_STS", BIT(0)}, + {"SUSRAM_PGD0_PG_STS", BIT(1)}, + {"SMT1_PGD0_PG_STS", BIT(2)}, + {"FIACPCB_U_PGD0_PG_STS", BIT(3)}, + {"SMS2_PGD0_PG_STS", BIT(4)}, + {"SMS1_PGD0_PG_STS", BIT(5)}, + {"CSMERTC_PGD0_PG_STS", BIT(6)}, + {"CSMEPSF_PGD0_PG_STS", BIT(7)}, + {"SBR0_PGD0_PG_STS", BIT(8)}, + {"SBR1_PGD0_PG_STS", BIT(9)}, + {"SBR2_PGD0_PG_STS", BIT(10)}, + {"SBR3_PGD0_PG_STS", BIT(11)}, + {"U3FPW1_PGD0_PG_STS", BIT(12)}, + {"SBR5_PGD0_PG_STS", BIT(13)}, + {"MPFPW1_PGD0_PG_STS", BIT(14)}, + {"UFSPW1_PGD0_PG_STS", BIT(15)}, + {"FIA_X_PGD0_PG_STS", BIT(16)}, + {"SOC_D2D_PGD0_PG_STS", BIT(17)}, + {"MPFPW2_PGD0_PG_STS", BIT(18)}, + {"CNVI_PGD0_PG_STS", BIT(19)}, + {"UFSX2_PGD0_PG_STS", BIT(20)}, + {"ENDBG_PGD0_PG_STS", BIT(21)}, + {"DBG_PSF_PGD0_PG_STS", BIT(22)}, + {"SBR6_PGD0_PG_STS", BIT(23)}, + {"SBR7_PGD0_PG_STS", BIT(24)}, + {"NPK_PGD1_PG_STS", BIT(25)}, + {"FIACPCB_X_PGD0_PG_STS", BIT(26)}, + {"DBC_PGD0_PG_STS", BIT(27)}, + {"FUSEGPSB_PGD0_PG_STS", BIT(28)}, + {"PSF6_PGD0_PG_STS", BIT(29)}, + {"PSF7_PGD0_PG_STS", BIT(30)}, + {"GBETSN1_PGD0_PG_STS", BIT(31)}, + {} +}; + +const struct pmc_bit_map mtl_socm_power_gating_status_2_map[] = { + {"PSF8_PGD0_PG_STS", BIT(0)}, + {"FIA_PGD0_PG_STS", BIT(1)}, + {"SOC_D2D_PGD1_PG_STS", BIT(2)}, + {"FIA_U_PGD0_PG_STS", BIT(3)}, + {"TAM_PGD0_PG_STS", BIT(4)}, + {"GBETSN_PGD0_PG_STS", BIT(5)}, + {"TBTLSX_PGD0_PG_STS", BIT(6)}, + {"THC0_PGD0_PG_STS", BIT(7)}, + {"THC1_PGD0_PG_STS", BIT(8)}, + {"PMC_PGD1_PG_STS", BIT(9)}, + {"GNA_PGD0_PG_STS", BIT(10)}, + {"ACE_PGD0_PG_STS", BIT(11)}, + {"ACE_PGD1_PG_STS", BIT(12)}, + {"ACE_PGD2_PG_STS", BIT(13)}, + {"ACE_PGD3_PG_STS", BIT(14)}, + {"ACE_PGD4_PG_STS", BIT(15)}, + {"ACE_PGD5_PG_STS", BIT(16)}, + {"ACE_PGD6_PG_STS", BIT(17)}, + {"ACE_PGD7_PG_STS", BIT(18)}, + {"ACE_PGD8_PG_STS", BIT(19)}, + {"FIA_PGS_PGD0_PG_STS", BIT(20)}, + {"FIACPCB_PGS_PGD0_PG_STS", BIT(21)}, + {"FUSEPMSB_PGD0_PG_STS", BIT(22)}, + {} +}; + +const struct pmc_bit_map mtl_socm_d3_status_0_map[] = { + {"LPSS_D3_STS", BIT(3)}, + {"XDCI_D3_STS", BIT(4)}, + {"XHCI_D3_STS", BIT(5)}, + {"SPA_D3_STS", BIT(12)}, + {"SPB_D3_STS", BIT(13)}, + {"SPC_D3_STS", BIT(14)}, + {"SPD_D3_STS", BIT(15)}, + {"ESPISPI_D3_STS", BIT(18)}, + {"SATA_D3_STS", BIT(20)}, + {"PSTH_D3_STS", BIT(21)}, + {"DMI_D3_STS", BIT(22)}, + {} +}; + +const struct pmc_bit_map mtl_socm_d3_status_1_map[] = { + {"GBETSN1_D3_STS", BIT(14)}, + {"GBE_D3_STS", BIT(19)}, + {"ITSS_D3_STS", BIT(23)}, + {"P2S_D3_STS", BIT(24)}, + {"CNVI_D3_STS", BIT(27)}, + {"UFSX2_D3_STS", BIT(28)}, + {} +}; + +const struct pmc_bit_map mtl_socm_d3_status_2_map[] = { + {"GNA_D3_STS", BIT(0)}, + {"CSMERTC_D3_STS", BIT(1)}, + {"SUSRAM_D3_STS", BIT(2)}, + {"CSE_D3_STS", BIT(4)}, + {"KVMCC_D3_STS", BIT(5)}, + {"USBR0_D3_STS", BIT(6)}, + {"ISH_D3_STS", BIT(7)}, + {"SMT1_D3_STS", BIT(8)}, + {"SMT2_D3_STS", BIT(9)}, + {"SMT3_D3_STS", BIT(10)}, + {"CLINK_D3_STS", BIT(14)}, + {"PTIO_D3_STS", BIT(16)}, + {"PMT_D3_STS", BIT(17)}, + {"SMS1_D3_STS", BIT(18)}, + {"SMS2_D3_STS", BIT(19)}, + {} +}; + +const struct pmc_bit_map mtl_socm_d3_status_3_map[] = { + {"ESE_D3_STS", BIT(2)}, + {"GBETSN_D3_STS", BIT(13)}, + {"THC0_D3_STS", BIT(14)}, + {"THC1_D3_STS", BIT(15)}, + {"ACE_D3_STS", BIT(23)}, + {} +}; + +const struct pmc_bit_map mtl_socm_vnn_req_status_0_map[] = { + {"LPSS_VNN_REQ_STS", BIT(3)}, + {"FIA_VNN_REQ_STS", BIT(17)}, + {"ESPISPI_VNN_REQ_STS", BIT(18)}, + {} +}; + +const struct pmc_bit_map mtl_socm_vnn_req_status_1_map[] = { + {"NPK_VNN_REQ_STS", BIT(4)}, + {"DFXAGG_VNN_REQ_STS", BIT(8)}, + {"EXI_VNN_REQ_STS", BIT(9)}, + {"P2D_VNN_REQ_STS", BIT(18)}, + {"GBE_VNN_REQ_STS", BIT(19)}, + {"SMB_VNN_REQ_STS", BIT(25)}, + {"LPC_VNN_REQ_STS", BIT(26)}, + {} +}; + +const struct pmc_bit_map mtl_socm_vnn_req_status_2_map[] = { + {"CSMERTC_VNN_REQ_STS", BIT(1)}, + {"CSE_VNN_REQ_STS", BIT(4)}, + {"ISH_VNN_REQ_STS", BIT(7)}, + {"SMT1_VNN_REQ_STS", BIT(8)}, + {"CLINK_VNN_REQ_STS", BIT(14)}, + {"SMS1_VNN_REQ_STS", BIT(18)}, + {"SMS2_VNN_REQ_STS", BIT(19)}, + {"GPIOCOM4_VNN_REQ_STS", BIT(20)}, + {"GPIOCOM3_VNN_REQ_STS", BIT(21)}, + {"GPIOCOM2_VNN_REQ_STS", BIT(22)}, + {"GPIOCOM1_VNN_REQ_STS", BIT(23)}, + {"GPIOCOM0_VNN_REQ_STS", BIT(24)}, + {} +}; + +const struct pmc_bit_map mtl_socm_vnn_req_status_3_map[] = { + {"ESE_VNN_REQ_STS", BIT(2)}, + {"DTS0_VNN_REQ_STS", BIT(7)}, + {"GPIOCOM5_VNN_REQ_STS", BIT(11)}, + {} +}; + +const struct pmc_bit_map mtl_socm_vnn_misc_status_map[] = { + {"CPU_C10_REQ_STS", BIT(0)}, + {"TS_OFF_REQ_STS", BIT(1)}, + {"PNDE_MET_REQ_STS", BIT(2)}, + {"PCIE_DEEP_PM_REQ_STS", BIT(3)}, + {"PMC_CLK_THROTTLE_EN_REQ_STS", BIT(4)}, + {"NPK_VNNAON_REQ_STS", BIT(5)}, + {"VNN_SOC_REQ_STS", BIT(6)}, + {"ISH_VNNAON_REQ_STS", BIT(7)}, + {"IOE_COND_MET_S02I2_0_REQ_STS", BIT(8)}, + {"IOE_COND_MET_S02I2_1_REQ_STS", BIT(9)}, + {"IOE_COND_MET_S02I2_2_REQ_STS", BIT(10)}, + {"PLT_GREATER_REQ_STS", BIT(11)}, + {"PCIE_CLKREQ_REQ_STS", BIT(12)}, + {"PMC_IDLE_FB_OCP_REQ_STS", BIT(13)}, + {"PM_SYNC_STATES_REQ_STS", BIT(14)}, + {"EA_REQ_STS", BIT(15)}, + {"MPHY_CORE_OFF_REQ_STS", BIT(16)}, + {"BRK_EV_EN_REQ_STS", BIT(17)}, + {"AUTO_DEMO_EN_REQ_STS", BIT(18)}, + {"ITSS_CLK_SRC_REQ_STS", BIT(19)}, + {"LPC_CLK_SRC_REQ_STS", BIT(20)}, + {"ARC_IDLE_REQ_STS", BIT(21)}, + {"MPHY_SUS_REQ_STS", BIT(22)}, + {"FIA_DEEP_PM_REQ_STS", BIT(23)}, + {"UXD_CONNECTED_REQ_STS", BIT(24)}, + {"ARC_INTERRUPT_WAKE_REQ_STS", BIT(25)}, + {"USB2_VNNAON_ACT_REQ_STS", BIT(26)}, + {"PRE_WAKE0_REQ_STS", BIT(27)}, + {"PRE_WAKE1_REQ_STS", BIT(28)}, + {"PRE_WAKE2_EN_REQ_STS", BIT(29)}, + {"WOV_REQ_STS", BIT(30)}, + {"CNVI_V1P05_REQ_STS", BIT(31)}, + {} +}; + +const struct pmc_bit_map mtl_socm_signal_status_map[] = { + {"LSX_Wake0_En_STS", BIT(0)}, + {"LSX_Wake0_Pol_STS", BIT(1)}, + {"LSX_Wake1_En_STS", BIT(2)}, + {"LSX_Wake1_Pol_STS", BIT(3)}, + {"LSX_Wake2_En_STS", BIT(4)}, + {"LSX_Wake2_Pol_STS", BIT(5)}, + {"LSX_Wake3_En_STS", BIT(6)}, + {"LSX_Wake3_Pol_STS", BIT(7)}, + {"LSX_Wake4_En_STS", BIT(8)}, + {"LSX_Wake4_Pol_STS", BIT(9)}, + {"LSX_Wake5_En_STS", BIT(10)}, + {"LSX_Wake5_Pol_STS", BIT(11)}, + {"LSX_Wake6_En_STS", BIT(12)}, + {"LSX_Wake6_Pol_STS", BIT(13)}, + {"LSX_Wake7_En_STS", BIT(14)}, + {"LSX_Wake7_Pol_STS", BIT(15)}, + {"LPSS_Wake0_En_STS", BIT(16)}, + {"LPSS_Wake0_Pol_STS", BIT(17)}, + {"LPSS_Wake1_En_STS", BIT(18)}, + {"LPSS_Wake1_Pol_STS", BIT(19)}, + {"Int_Timer_SS_Wake0_En_STS", BIT(20)}, + {"Int_Timer_SS_Wake0_Pol_STS", BIT(21)}, + {"Int_Timer_SS_Wake1_En_STS", BIT(22)}, + {"Int_Timer_SS_Wake1_Pol_STS", BIT(23)}, + {"Int_Timer_SS_Wake2_En_STS", BIT(24)}, + {"Int_Timer_SS_Wake2_Pol_STS", BIT(25)}, + {"Int_Timer_SS_Wake3_En_STS", BIT(26)}, + {"Int_Timer_SS_Wake3_Pol_STS", BIT(27)}, + {"Int_Timer_SS_Wake4_En_STS", BIT(28)}, + {"Int_Timer_SS_Wake4_Pol_STS", BIT(29)}, + {"Int_Timer_SS_Wake5_En_STS", BIT(30)}, + {"Int_Timer_SS_Wake5_Pol_STS", BIT(31)}, + {} +}; + +const struct pmc_bit_map *mtl_socm_lpm_maps[] = { + mtl_socm_clocksource_status_map, + mtl_socm_power_gating_status_0_map, + mtl_socm_power_gating_status_1_map, + mtl_socm_power_gating_status_2_map, + mtl_socm_d3_status_0_map, + mtl_socm_d3_status_1_map, + mtl_socm_d3_status_2_map, + mtl_socm_d3_status_3_map, + mtl_socm_vnn_req_status_0_map, + mtl_socm_vnn_req_status_1_map, + mtl_socm_vnn_req_status_2_map, + mtl_socm_vnn_req_status_3_map, + mtl_socm_vnn_misc_status_map, + mtl_socm_signal_status_map, + NULL +}; + +const struct pmc_reg_map mtl_socm_reg_map = { + .pfear_sts = ext_mtl_socm_pfear_map, .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET, .slp_s0_res_counter_step = TGL_PMC_SLP_S0_RES_COUNTER_STEP, - .ltr_show_sts = adl_ltr_show_map, + .ltr_show_sts = mtl_socm_ltr_show_map, .msr_sts = msr_map, .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET, - .regmap_length = CNP_PMC_MMIO_REG_LEN, + .regmap_length = MTL_SOC_PMC_MMIO_REG_LEN, .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A, - .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES, + .ppfear_buckets = MTL_SOCM_PPFEAR_NUM_ENTRIES, .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, - .ltr_ignore_max = ADL_NUM_IP_IGN_ALLOWED, - .lpm_num_modes = ADL_LPM_NUM_MODES, .lpm_num_maps = ADL_LPM_NUM_MAPS, + .ltr_ignore_max = MTL_SOCM_NUM_IP_IGN_ALLOWED, .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2, .etr3_offset = ETR3_OFFSET, .lpm_sts_latch_en_offset = MTL_LPM_STATUS_LATCH_EN_OFFSET, .lpm_priority_offset = MTL_LPM_PRI_OFFSET, .lpm_en_offset = MTL_LPM_EN_OFFSET, .lpm_residency_offset = MTL_LPM_RESIDENCY_OFFSET, - .lpm_sts = adl_lpm_maps, + .lpm_sts = mtl_socm_lpm_maps, .lpm_status_offset = MTL_LPM_STATUS_OFFSET, .lpm_live_status_offset = MTL_LPM_LIVE_STATUS_OFFSET, }; @@ -47,6 +477,6 @@ void mtl_core_configure(struct pmc_dev *pmcdev)
void mtl_core_init(struct pmc_dev *pmcdev) { - pmcdev->map = &mtl_reg_map; + pmcdev->map = &mtl_socm_reg_map; pmcdev->core_configure = mtl_core_configure; }
From: Tiezhu Yang yangtiezhu@loongson.cn
[ Upstream commit 58b1294dd1d65bb62f08dddbf418f954210c2057 ]
thread.bad_cause is saved in arch_uprobe_pre_xol(), it should be restored in arch_uprobe_{post,abort}_xol() accordingly, otherwise the save operation is meaningless, this change is similar with x86 and powerpc.
Signed-off-by: Tiezhu Yang yangtiezhu@loongson.cn Acked-by: Oleg Nesterov oleg@redhat.com Reviewed-by: Guo Ren guoren@kernel.org Fixes: 74784081aac8 ("riscv: Add uprobes supported") Link: https://lore.kernel.org/r/1682214146-3756-1-git-send-email-yangtiezhu@loongs... Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/kernel/probes/uprobes.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/riscv/kernel/probes/uprobes.c b/arch/riscv/kernel/probes/uprobes.c index c976a21cd4bd5..194f166b2cc40 100644 --- a/arch/riscv/kernel/probes/uprobes.c +++ b/arch/riscv/kernel/probes/uprobes.c @@ -67,6 +67,7 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) struct uprobe_task *utask = current->utask;
WARN_ON_ONCE(current->thread.bad_cause != UPROBE_TRAP_NR); + current->thread.bad_cause = utask->autask.saved_cause;
instruction_pointer_set(regs, utask->vaddr + auprobe->insn_size);
@@ -102,6 +103,7 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) { struct uprobe_task *utask = current->utask;
+ current->thread.bad_cause = utask->autask.saved_cause; /* * Task has received a fatal signal, so reset back to probbed * address.
From: Namhyung Kim namhyung@kernel.org
[ Upstream commit e4ef3ef1bc0a3d2535427da78b8095ef657eb474 ]
The task-analyzer.py script (actually every other scripts too) requires PERF_EXEC_PATH env to find dependent libraries and scripts. For scripts test to run correctly, it needs to set PERF_EXEC_PATH to the perf tool source directory.
Instead of blindly update the env, let's check the directory structure to make sure it points to the correct location.
Fixes: e8478b84d6ba ("perf test: add new task-analyzer tests") Cc: Petar Gligoric petar.gligoric@rohde-schwarz.com Cc: Hagen Paul Pfeifer hagen@jauu.net Cc: Aditya Gupta adityag@linux.ibm.com Cc: Peter Zijlstra peterz@infradead.org Cc: Adrian Hunter adrian.hunter@intel.com Cc: Arnaldo Carvalho de Melo acme@kernel.org Cc: Jiri Olsa jolsa@kernel.org Cc: Ingo Molnar mingo@kernel.org Acked-by: Ian Rogers irogers@google.com Signed-off-by: Namhyung Kim namhyung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/tests/shell/test_task_analyzer.sh | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/tools/perf/tests/shell/test_task_analyzer.sh b/tools/perf/tests/shell/test_task_analyzer.sh index 1b7f3c1ec218b..365b61aea519a 100755 --- a/tools/perf/tests/shell/test_task_analyzer.sh +++ b/tools/perf/tests/shell/test_task_analyzer.sh @@ -5,6 +5,12 @@ tmpdir=$(mktemp -d /tmp/perf-script-task-analyzer-XXXXX) err=0
+# set PERF_EXEC_PATH to find scripts in the source directory +perfdir=$(dirname "$0")/../.. +if [ -e "$perfdir/scripts/python/Perf-Trace-Util" ]; then + export PERF_EXEC_PATH=$perfdir +fi + cleanup() { rm -f perf.data rm -f perf.data.old
From: Shunsuke Mie mie@igel.co.jp
[ Upstream commit 37587673cda963ec950e4983db5023802f9b5ff2 ]
vNTB driver and NTB driver have same Kconfig prompt. Changed to make it distinguishable.
Link: https://lore.kernel.org/r/20230202103832.2038286-1-mie@igel.co.jp Fixes: e35f56bb0330 ("PCI: endpoint: Support NTB transfer between RC and EP") Signed-off-by: Shunsuke Mie mie@igel.co.jp Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Manivannan Sadhasivam mani@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/endpoint/functions/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/endpoint/functions/Kconfig b/drivers/pci/endpoint/functions/Kconfig index 9fd5608868718..8efb6a869e7ce 100644 --- a/drivers/pci/endpoint/functions/Kconfig +++ b/drivers/pci/endpoint/functions/Kconfig @@ -27,7 +27,7 @@ config PCI_EPF_NTB If in doubt, say "N" to disable Endpoint NTB driver.
config PCI_EPF_VNTB - tristate "PCI Endpoint NTB driver" + tristate "PCI Endpoint Virtual NTB driver" depends on PCI_ENDPOINT depends on NTB select CONFIGFS_FS
From: Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com
[ Upstream commit 880d51c729a3fa944794feb19f605eefe55916fc ]
In pci_epf_test_init_dma_chan() epf_test->dma_chan_rx is assigned from dma_request_channel() with DMA_DEV_TO_MEM as filter.dma_mask.
However, in pci_epf_test_data_transfer() if the dir is DMA_DEV_TO_MEM, epf->dma_chan_rx should be used but instead we are using epf_test->dma_chan_tx.
Fix it.
Link: https://lore.kernel.org/r/20230412063447.2841177-1-yoshihiro.shimoda.uh@rene... Fixes: 8353813c88ef ("PCI: endpoint: Enable DMA tests for endpoints with DMA capabilities") Tested-by: Kunihiko Hayashi hayashi.kunihiko@socionext.com Signed-off-by: Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Frank Li Frank.Li@nxp.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/endpoint/functions/pci-epf-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index 0f9d2ec822ac6..172e5ac0bd96c 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c @@ -112,7 +112,7 @@ static int pci_epf_test_data_transfer(struct pci_epf_test *epf_test, size_t len, dma_addr_t dma_remote, enum dma_transfer_direction dir) { - struct dma_chan *chan = (dir == DMA_DEV_TO_MEM) ? + struct dma_chan *chan = (dir == DMA_MEM_TO_DEV) ? epf_test->dma_chan_tx : epf_test->dma_chan_rx; dma_addr_t dma_local = (dir == DMA_MEM_TO_DEV) ? dma_src : dma_dst; enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
From: Xinghui Li korantli@tencent.com
[ Upstream commit 0c0206dc4f5ba2d18b15e24d2047487d6f73916b ]
The ret variable in the vmd_enable_domain() function was used uninitialized when printing a warning message upon failure of the pci_reset_bus() function.
Thus, fix the issue by assigning ret with the value returned from pci_reset_bus() before referencing it in the warning message.
This was detected by Smatch:
drivers/pci/controller/vmd.c:931 vmd_enable_domain() error: uninitialized symbol 'ret'.
[kwilczynski: drop the second patch from the series, add missing reported by tag, commit log] Fixes: 0a584655ef89 ("PCI: vmd: Fix secondary bus reset for Intel bridges") Link: https://lore.kernel.org/all/202305270219.B96IiIfv-lkp@intel.com Link: https://lore.kernel.org/linux-pci/20230420094332.1507900-2-korantwork@gmail.... Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter error27@gmail.com Signed-off-by: Xinghui Li korantli@tencent.com Signed-off-by: Krzysztof Wilczyński kwilczynski@kernel.org Reviewed-by: Nirmal Patel nirmal.patel@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/vmd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c index 30ec18283aaf4..e718a816d4814 100644 --- a/drivers/pci/controller/vmd.c +++ b/drivers/pci/controller/vmd.c @@ -927,7 +927,8 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) if (!list_empty(&child->devices)) { dev = list_first_entry(&child->devices, struct pci_dev, bus_list); - if (pci_reset_bus(dev)) + ret = pci_reset_bus(dev); + if (ret) pci_warn(dev, "can't reset device: %d\n", ret);
break;
From: Eric Farman farman@linux.ibm.com
[ Upstream commit ff598081e5b9d0bdd6874bfe340811bbb75b35e4 ]
The pointer to mdev_bus_compat_class is statically defined at the top of mdev_core, and was originally (commit 7b96953bc640 ("vfio: Mediated device Core driver") serialized by the parent_list_lock. The blamed commit removed this mutex, leaving the pointer initialization unserialized. As a result, the creation of multiple MDEVs in parallel (such as during boot) can encounter errors during the creation of the sysfs entries, such as:
[ 8.337509] sysfs: cannot create duplicate filename '/class/mdev_bus' [ 8.337514] vfio_ccw 0.0.01d8: MDEV: Registered [ 8.337516] CPU: 13 PID: 946 Comm: driverctl Not tainted 6.4.0-rc7 #20 [ 8.337522] Hardware name: IBM 3906 M05 780 (LPAR) [ 8.337525] Call Trace: [ 8.337528] [<0000000162b0145a>] dump_stack_lvl+0x62/0x80 [ 8.337540] [<00000001622aeb30>] sysfs_warn_dup+0x78/0x88 [ 8.337549] [<00000001622aeca6>] sysfs_create_dir_ns+0xe6/0xf8 [ 8.337552] [<0000000162b04504>] kobject_add_internal+0xf4/0x340 [ 8.337557] [<0000000162b04d48>] kobject_add+0x78/0xd0 [ 8.337561] [<0000000162b04e0a>] kobject_create_and_add+0x6a/0xb8 [ 8.337565] [<00000001627a110e>] class_compat_register+0x5e/0x90 [ 8.337572] [<000003ff7fd815da>] mdev_register_parent+0x102/0x130 [mdev] [ 8.337581] [<000003ff7fdc7f2c>] vfio_ccw_sch_probe+0xe4/0x178 [vfio_ccw] [ 8.337588] [<0000000162a7833c>] css_probe+0x44/0x80 [ 8.337599] [<000000016279f4da>] really_probe+0xd2/0x460 [ 8.337603] [<000000016279fa08>] driver_probe_device+0x40/0xf0 [ 8.337606] [<000000016279fb78>] __device_attach_driver+0xc0/0x140 [ 8.337610] [<000000016279cbe0>] bus_for_each_drv+0x90/0xd8 [ 8.337618] [<00000001627a00b0>] __device_attach+0x110/0x190 [ 8.337621] [<000000016279c7c8>] bus_rescan_devices_helper+0x60/0xb0 [ 8.337626] [<000000016279cd48>] drivers_probe_store+0x48/0x80 [ 8.337632] [<00000001622ac9b0>] kernfs_fop_write_iter+0x138/0x1f0 [ 8.337635] [<00000001621e5e14>] vfs_write+0x1ac/0x2f8 [ 8.337645] [<00000001621e61d8>] ksys_write+0x70/0x100 [ 8.337650] [<0000000162b2bdc4>] __do_syscall+0x1d4/0x200 [ 8.337656] [<0000000162b3c828>] system_call+0x70/0x98 [ 8.337664] kobject: kobject_add_internal failed for mdev_bus with -EEXIST, don't try to register things with the same name in the same directory. [ 8.337668] kobject: kobject_create_and_add: kobject_add error: -17 [ 8.337674] vfio_ccw: probe of 0.0.01d9 failed with error -12 [ 8.342941] vfio_ccw_mdev aeb9ca91-10c6-42bc-a168-320023570aea: Adding to iommu group 2
Move the initialization of the mdev_bus_compat_class pointer to the init path, to match the cleanup in module exit. This way the code in mdev_register_parent() can simply link the new parent to it, rather than determining whether initialization is required first.
Fixes: 89345d5177aa ("vfio/mdev: embedd struct mdev_parent in the parent data structure") Reported-by: Alexander Egorenkov egorenar@linux.ibm.com Signed-off-by: Eric Farman farman@linux.ibm.com Reviewed-by: Kevin Tian kevin.tian@intel.com Reviewed-by: Christoph Hellwig hch@lst.de Reviewed-by: Tony Krowiak akrowiak@linux.ibm.com Reviewed-by: Jason Gunthorpe jgg@nvidia.com Link: https://lore.kernel.org/r/20230626133642.2939168-1-farman@linux.ibm.com Signed-off-by: Alex Williamson alex.williamson@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/vfio/mdev/mdev_core.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c index 58f91b3bd670c..ed4737de45289 100644 --- a/drivers/vfio/mdev/mdev_core.c +++ b/drivers/vfio/mdev/mdev_core.c @@ -72,12 +72,6 @@ int mdev_register_parent(struct mdev_parent *parent, struct device *dev, parent->nr_types = nr_types; atomic_set(&parent->available_instances, mdev_driver->max_instances);
- if (!mdev_bus_compat_class) { - mdev_bus_compat_class = class_compat_register("mdev_bus"); - if (!mdev_bus_compat_class) - return -ENOMEM; - } - ret = parent_create_sysfs_files(parent); if (ret) return ret; @@ -251,13 +245,24 @@ int mdev_device_remove(struct mdev_device *mdev)
static int __init mdev_init(void) { - return bus_register(&mdev_bus_type); + int ret; + + ret = bus_register(&mdev_bus_type); + if (ret) + return ret; + + mdev_bus_compat_class = class_compat_register("mdev_bus"); + if (!mdev_bus_compat_class) { + bus_unregister(&mdev_bus_type); + return -ENOMEM; + } + + return 0; }
static void __exit mdev_exit(void) { - if (mdev_bus_compat_class) - class_compat_unregister(mdev_bus_compat_class); + class_compat_unregister(mdev_bus_compat_class); bus_unregister(&mdev_bus_type); }
From: Herbert Xu herbert@gondor.apana.org.au
[ Upstream commit ac52578d6e8d300dd50f790f29a24169b1edd26c ]
The virtio rng device kicks off a new entropy request whenever the data available reaches zero. When a new request occurs at the end of a read operation, that is, when the result of that request is only needed by the next reader, then there is a race between the writing of the new data and the next reader.
This is because there is no synchronisation whatsoever between the writer and the reader.
Fix this by writing data_avail with smp_store_release and reading it with smp_load_acquire when we first enter read. The subsequent reads are safe because they're either protected by the first load acquire, or by the completion mechanism.
Also remove the redundant zeroing of data_idx in random_recv_done (data_idx must already be zero at this point) and data_avail in request_entropy (ditto).
Reported-by: syzbot+726dc8c62c3536431ceb@syzkaller.appspotmail.com Fixes: f7f510ec1957 ("virtio: An entropy device, as suggested by hpa.") Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Acked-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/hw_random/virtio-rng.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index f7690e0f92ede..e41a84e6b4b56 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -4,6 +4,7 @@ * Copyright (C) 2007, 2008 Rusty Russell IBM Corporation */
+#include <asm/barrier.h> #include <linux/err.h> #include <linux/hw_random.h> #include <linux/scatterlist.h> @@ -37,13 +38,13 @@ struct virtrng_info { static void random_recv_done(struct virtqueue *vq) { struct virtrng_info *vi = vq->vdev->priv; + unsigned int len;
/* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */ - if (!virtqueue_get_buf(vi->vq, &vi->data_avail)) + if (!virtqueue_get_buf(vi->vq, &len)) return;
- vi->data_idx = 0; - + smp_store_release(&vi->data_avail, len); complete(&vi->have_data); }
@@ -52,7 +53,6 @@ static void request_entropy(struct virtrng_info *vi) struct scatterlist sg;
reinit_completion(&vi->have_data); - vi->data_avail = 0; vi->data_idx = 0;
sg_init_one(&sg, vi->data, sizeof(vi->data)); @@ -88,7 +88,7 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) read = 0;
/* copy available data */ - if (vi->data_avail) { + if (smp_load_acquire(&vi->data_avail)) { chunk = copy_data(vi, buf, size); size -= chunk; read += chunk;
From: Masahiro Yamada masahiroy@kernel.org
[ Upstream commit d0acc76a49aa917c1a455d11d32d34a01e8b2835 ]
find_extable_entry_size() is completely broken. It has awesome comments about how to calculate sizeof(struct exception_table_entry).
It was based on these assumptions:
- struct exception_table_entry has two fields - both of the fields have the same size
Then, we came up with this equation:
(offset of the second field) * 2 == (size of struct)
It was true for all architectures when commit 52dc0595d540 ("modpost: handle relocations mismatch in __ex_table.") was applied.
Our mathematics broke when commit 548acf19234d ("x86/mm: Expand the exception table logic to allow new handling options") introduced the third field.
Now, the definition of exception_table_entry is highly arch-dependent.
For x86, sizeof(struct exception_table_entry) is apparently 12, but find_extable_entry_size() sets extable_entry_size to 8.
I could fix it, but I do not see much value in this code.
extable_entry_size is used just for selecting a slightly different error message.
If the first field ("insn") references to a non-executable section,
The relocation at %s+0x%lx references section "%s" which is not executable, IOW it is not possible for the kernel to fault at that address. Something is seriously wrong and should be fixed.
If the second field ("fixup") references to a non-executable section,
The relocation at %s+0x%lx references section "%s" which is not executable, IOW the kernel will fault if it ever tries to jump to it. Something is seriously wrong and should be fixed.
Merge the two error messages rather than adding even more complexity.
Change fatal() to error() to make it continue running and catch more possible errors.
Fixes: 548acf19234d ("x86/mm: Expand the exception table logic to allow new handling options") Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/mod/modpost.c | 60 +++---------------------------------------- 1 file changed, 3 insertions(+), 57 deletions(-)
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 5b3964b39709f..934e9d90de540 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1298,43 +1298,6 @@ static int is_executable_section(struct elf_info* elf, unsigned int section_inde return ((elf->sechdrs[section_index].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR); }
-/* - * We rely on a gross hack in section_rel[a]() calling find_extable_entry_size() - * to know the sizeof(struct exception_table_entry) for the target architecture. - */ -static unsigned int extable_entry_size = 0; -static void find_extable_entry_size(const char* const sec, const Elf_Rela* r) -{ - /* - * If we're currently checking the second relocation within __ex_table, - * that relocation offset tells us the offsetof(struct - * exception_table_entry, fixup) which is equal to sizeof(struct - * exception_table_entry) divided by two. We use that to our advantage - * since there's no portable way to get that size as every architecture - * seems to go with different sized types. Not pretty but better than - * hard-coding the size for every architecture.. - */ - if (!extable_entry_size) - extable_entry_size = r->r_offset * 2; -} - -static inline bool is_extable_fault_address(Elf_Rela *r) -{ - /* - * extable_entry_size is only discovered after we've handled the - * _second_ relocation in __ex_table, so only abort when we're not - * handling the first reloc and extable_entry_size is zero. - */ - if (r->r_offset && extable_entry_size == 0) - fatal("extable_entry size hasn't been discovered!\n"); - - return ((r->r_offset == 0) || - (r->r_offset % extable_entry_size == 0)); -} - -#define is_second_extable_reloc(Start, Cur, Sec) \ - (((Cur) == (Start) + 1) && (strcmp("__ex_table", (Sec)) == 0)) - static void report_extable_warnings(const char* modname, struct elf_info* elf, const struct sectioncheck* const mismatch, Elf_Rela* r, Elf_Sym* sym, @@ -1390,22 +1353,9 @@ static void extable_mismatch_handler(const char* modname, struct elf_info *elf, "You might get more information about where this is\n" "coming from by using scripts/check_extable.sh %s\n", fromsec, (long)r->r_offset, tosec, modname); - else if (!is_executable_section(elf, get_secindex(elf, sym))) { - if (is_extable_fault_address(r)) - fatal("The relocation at %s+0x%lx references\n" - "section "%s" which is not executable, IOW\n" - "it is not possible for the kernel to fault\n" - "at that address. Something is seriously wrong\n" - "and should be fixed.\n", - fromsec, (long)r->r_offset, tosec); - else - fatal("The relocation at %s+0x%lx references\n" - "section "%s" which is not executable, IOW\n" - "the kernel will fault if it ever tries to\n" - "jump to it. Something is seriously wrong\n" - "and should be fixed.\n", - fromsec, (long)r->r_offset, tosec); - } + else if (!is_executable_section(elf, get_secindex(elf, sym))) + error("%s+0x%lx references non-executable section '%s'\n", + fromsec, (long)r->r_offset, tosec); }
static void check_section_mismatch(const char *modname, struct elf_info *elf, @@ -1580,8 +1530,6 @@ static void section_rela(const char *modname, struct elf_info *elf, /* Skip special sections */ if (is_shndx_special(sym->st_shndx)) continue; - if (is_second_extable_reloc(start, rela, fromsec)) - find_extable_entry_size(fromsec, &r); check_section_mismatch(modname, elf, &r, sym, fromsec); } } @@ -1639,8 +1587,6 @@ static void section_rel(const char *modname, struct elf_info *elf, /* Skip special sections */ if (is_shndx_special(sym->st_shndx)) continue; - if (is_second_extable_reloc(start, rel, fromsec)) - find_extable_entry_size(fromsec, &r); check_section_mismatch(modname, elf, &r, sym, fromsec); } }
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit b04b076fb56560b39d695ac3744db457e12278fd ]
Fix build warnings when DEBUG_FS is not enabled by using an empty do-while loop instead of a value:
In file included from ../drivers/crypto/nx/nx.c:27: ../drivers/crypto/nx/nx.c: In function 'nx_register_algs': ../drivers/crypto/nx/nx.h:173:33: warning: statement with no effect [-Wunused-value] 173 | #define NX_DEBUGFS_INIT(drv) (0) ../drivers/crypto/nx/nx.c:573:9: note: in expansion of macro 'NX_DEBUGFS_INIT' 573 | NX_DEBUGFS_INIT(&nx_driver); ../drivers/crypto/nx/nx.c: In function 'nx_remove': ../drivers/crypto/nx/nx.h:174:33: warning: statement with no effect [-Wunused-value] 174 | #define NX_DEBUGFS_FINI(drv) (0) ../drivers/crypto/nx/nx.c:793:17: note: in expansion of macro 'NX_DEBUGFS_FINI' 793 | NX_DEBUGFS_FINI(&nx_driver);
Also, there is no need to build nx_debugfs.o when DEBUG_FS is not enabled, so change the Makefile to accommodate that.
Fixes: ae0222b7289d ("powerpc/crypto: nx driver code supporting nx encryption") Fixes: aef7b31c8833 ("powerpc/crypto: Build files for the nx device driver") Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: Breno Leitão leitao@debian.org Cc: Nayna Jain nayna@linux.ibm.com Cc: Paulo Flabiano Smorigo pfsmorigo@gmail.com Cc: Herbert Xu herbert@gondor.apana.org.au Cc: "David S. Miller" davem@davemloft.net Cc: linux-crypto@vger.kernel.org Cc: Michael Ellerman mpe@ellerman.id.au Cc: Nicholas Piggin npiggin@gmail.com Cc: Christophe Leroy christophe.leroy@csgroup.eu Cc: linuxppc-dev@lists.ozlabs.org Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/nx/Makefile | 2 +- drivers/crypto/nx/nx.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/crypto/nx/Makefile b/drivers/crypto/nx/Makefile index d00181a26dd65..483cef62acee8 100644 --- a/drivers/crypto/nx/Makefile +++ b/drivers/crypto/nx/Makefile @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_CRYPTO_DEV_NX_ENCRYPT) += nx-crypto.o nx-crypto-objs := nx.o \ - nx_debugfs.o \ nx-aes-cbc.o \ nx-aes-ecb.o \ nx-aes-gcm.o \ @@ -11,6 +10,7 @@ nx-crypto-objs := nx.o \ nx-sha256.o \ nx-sha512.o
+nx-crypto-$(CONFIG_DEBUG_FS) += nx_debugfs.o obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_PSERIES) += nx-compress-pseries.o nx-compress.o obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_POWERNV) += nx-compress-powernv.o nx-compress.o nx-compress-objs := nx-842.o diff --git a/drivers/crypto/nx/nx.h b/drivers/crypto/nx/nx.h index c6233173c612e..2697baebb6a35 100644 --- a/drivers/crypto/nx/nx.h +++ b/drivers/crypto/nx/nx.h @@ -170,8 +170,8 @@ struct nx_sg *nx_walk_and_build(struct nx_sg *, unsigned int, void nx_debugfs_init(struct nx_crypto_driver *); void nx_debugfs_fini(struct nx_crypto_driver *); #else -#define NX_DEBUGFS_INIT(drv) (0) -#define NX_DEBUGFS_FINI(drv) (0) +#define NX_DEBUGFS_INIT(drv) do {} while (0) +#define NX_DEBUGFS_FINI(drv) do {} while (0) #endif
#define NX_PAGE_NUM(x) ((u64)(x) & 0xfffffffffffff000ULL)
From: Masahiro Yamada masahiroy@kernel.org
[ Upstream commit b7c63520f6703a25eebb4f8138fed764fcae1c6f ]
addend_arm_rel() processes R_ARM_ABS32 in a wrong way.
Here, test code.
[test code 1]
#include <linux/init.h>
int __initdata foo; int get_foo(void) { return foo; }
If you compile it with ARM versatile_defconfig, modpost will show the symbol name, (unknown).
WARNING: modpost: vmlinux.o: section mismatch in reference: get_foo (section: .text) -> (unknown) (section: .init.data)
(You need to use GNU linker instead of LLD to reproduce it.)
If you compile it for other architectures, modpost will show the correct symbol name.
WARNING: modpost: vmlinux.o: section mismatch in reference: get_foo (section: .text) -> foo (section: .init.data)
For R_ARM_ABS32, addend_arm_rel() sets r->r_addend to a wrong value.
I just mimicked the code in arch/arm/kernel/module.c.
However, there is more difficulty for ARM.
Here, test code.
[test code 2]
#include <linux/init.h>
int __initdata foo; int get_foo(void) { return foo; }
int __initdata bar; int get_bar(void) { return bar; }
With this commit applied, modpost will show the following messages for ARM versatile_defconfig:
WARNING: modpost: vmlinux.o: section mismatch in reference: get_foo (section: .text) -> foo (section: .init.data) WARNING: modpost: vmlinux.o: section mismatch in reference: get_bar (section: .text) -> foo (section: .init.data)
The reference from 'get_bar' to 'foo' seems wrong.
I have no solution for this because it is true in assembly level.
In the following output, relocation at 0x1c is no longer associated with 'bar'. The two relocation entries point to the same symbol, and the offset to 'bar' is encoded in the instruction 'r0, [r3, #4]'.
Disassembly of section .text:
00000000 <get_foo>: 0: e59f3004 ldr r3, [pc, #4] @ c <get_foo+0xc> 4: e5930000 ldr r0, [r3] 8: e12fff1e bx lr c: 00000000 .word 0x00000000
00000010 <get_bar>: 10: e59f3004 ldr r3, [pc, #4] @ 1c <get_bar+0xc> 14: e5930004 ldr r0, [r3, #4] 18: e12fff1e bx lr 1c: 00000000 .word 0x00000000
Relocation section '.rel.text' at offset 0x244 contains 2 entries: Offset Info Type Sym.Value Sym. Name 0000000c 00000c02 R_ARM_ABS32 00000000 .init.data 0000001c 00000c02 R_ARM_ABS32 00000000 .init.data
When find_elf_symbol() gets into a situation where relsym->st_name is zero, there is no guarantee to get the symbol name as written in C.
I am keeping the current logic because it is useful in many architectures, but the symbol name is not always correct depending on the optimization. I left some comments in find_tosym().
Fixes: 56a974fa2d59 ("kbuild: make better section mismatch reports on arm") Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/mod/modpost.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 934e9d90de540..ff7a8df9e54cd 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1156,6 +1156,10 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr, if (relsym->st_name != 0) return relsym;
+ /* + * Strive to find a better symbol name, but the resulting name may not + * match the symbol referenced in the original code. + */ relsym_secindex = get_secindex(elf, relsym); for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { if (get_secindex(elf, sym) != relsym_secindex) @@ -1416,12 +1420,14 @@ static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) { unsigned int r_typ = ELF_R_TYPE(r->r_info); + Elf_Sym *sym = elf->symtab_start + ELF_R_SYM(r->r_info); + void *loc = reloc_location(elf, sechdr, r); + uint32_t inst;
switch (r_typ) { case R_ARM_ABS32: - /* From ARM ABI: (S + A) | T */ - r->r_addend = (int)(long) - (elf->symtab_start + ELF_R_SYM(r->r_info)); + inst = TO_NATIVE(*(uint32_t *)loc); + r->r_addend = inst + sym->st_value; break; case R_ARM_PC24: case R_ARM_CALL:
From: Masahiro Yamada masahiroy@kernel.org
[ Upstream commit 56a24b8ce6a7f9c4a21b2276a8644f6f3d8fc14d ]
addend_arm_rel() processes R_ARM_PC24, R_ARM_CALL, R_ARM_JUMP24 in a wrong way.
Here, test code.
[test code for R_ARM_JUMP24]
.section .init.text,"ax" bar: bx lr
.section .text,"ax" .globl foo foo: b bar
[test code for R_ARM_CALL]
.section .init.text,"ax" bar: bx lr
.section .text,"ax" .globl foo foo: push {lr} bl bar pop {pc}
If you compile it with ARM multi_v7_defconfig, modpost will show the symbol name, (unknown).
WARNING: modpost: vmlinux.o: section mismatch in reference: foo (section: .text) -> (unknown) (section: .init.text)
(You need to use GNU linker instead of LLD to reproduce it.)
Fix the code to make modpost show the correct symbol name.
I imported (with adjustment) sign_extend32() from include/linux/bitops.h.
The '+8' is the compensation for pc-relative instruction. It is documented in "ELF for the Arm Architecture" [1].
"If the relocation is pc-relative then compensation for the PC bias (the PC value is 8 bytes ahead of the executing instruction in Arm state and 4 bytes in Thumb state) must be encoded in the relocation by the object producer."
[1]: https://github.com/ARM-software/abi-aa/blob/main/aaelf32/aaelf32.rst
Fixes: 56a974fa2d59 ("kbuild: make better section mismatch reports on arm") Fixes: 6e2e340b59d2 ("ARM: 7324/1: modpost: Fix section warnings for ARM for many compilers") Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/mod/modpost.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index ff7a8df9e54cd..30d2ebc391f4a 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1417,12 +1417,20 @@ static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) #define R_ARM_THM_JUMP19 51 #endif
+static int32_t sign_extend32(int32_t value, int index) +{ + uint8_t shift = 31 - index; + + return (int32_t)(value << shift) >> shift; +} + static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) { unsigned int r_typ = ELF_R_TYPE(r->r_info); Elf_Sym *sym = elf->symtab_start + ELF_R_SYM(r->r_info); void *loc = reloc_location(elf, sechdr, r); uint32_t inst; + int32_t offset;
switch (r_typ) { case R_ARM_ABS32: @@ -1432,6 +1440,10 @@ static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) case R_ARM_PC24: case R_ARM_CALL: case R_ARM_JUMP24: + inst = TO_NATIVE(*(uint32_t *)loc); + offset = sign_extend32((inst & 0x00ffffff) << 2, 25); + r->r_addend = offset + sym->st_value + 8; + break; case R_ARM_THM_CALL: case R_ARM_THM_JUMP24: case R_ARM_THM_JUMP19:
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit efbc7764c4446566edb76ca05e903b5905673d2e ]
Commit df8fc4e934c1 ("kbuild: Enable -fstrict-flex-arrays=3") uncovered a type mismatch in cesa 3des support that leads to a memcpy beyond the end of a structure:
In function 'fortify_memcpy_chk', inlined from 'mv_cesa_des3_ede_setkey' at drivers/crypto/marvell/cesa/cipher.c:307:2: include/linux/fortify-string.h:583:25: error: call to '__write_overflow_field' declared with attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror=attribute-warning] 583 | __write_overflow_field(p_size_field, size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is probably harmless as the actual data that is copied has the correct type, but clearly worth fixing nonetheless.
Fixes: 4ada48397823 ("crypto: marvell/cesa - add Triple-DES support") Cc: Kees Cook keescook@chromium.org Cc: Gustavo A. R. Silva gustavoars@kernel.org Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Kees Cook keescook@chromium.org Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/marvell/cesa/cipher.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/marvell/cesa/cipher.c b/drivers/crypto/marvell/cesa/cipher.c index c6f2fa753b7c0..0f37dfd42d850 100644 --- a/drivers/crypto/marvell/cesa/cipher.c +++ b/drivers/crypto/marvell/cesa/cipher.c @@ -297,7 +297,7 @@ static int mv_cesa_des_setkey(struct crypto_skcipher *cipher, const u8 *key, static int mv_cesa_des3_ede_setkey(struct crypto_skcipher *cipher, const u8 *key, unsigned int len) { - struct mv_cesa_des_ctx *ctx = crypto_skcipher_ctx(cipher); + struct mv_cesa_des3_ctx *ctx = crypto_skcipher_ctx(cipher); int err;
err = verify_skcipher_des3_key(cipher, key);
From: Stephan Müller smueller@chronox.de
[ Upstream commit d23659769ad1bf2cbafaa0efcbae20ef1a74f77e ]
With the update of the permanent and intermittent health errors, the actual indicator for the health test indicates a potential error only for the one offending time stamp gathered in the current iteration round. The next iteration round will "overwrite" the health test result.
Thus, the entropy collection loop in jent_gen_entropy checks for the health test failure upon each loop iteration. However, the initialization operation checked for the APT health test once for an APT window which implies it would not catch most errors.
Thus, the check for all health errors is now invoked unconditionally during each loop iteration for the startup test.
With the change, the error JENT_ERCT becomes unused as all health errors are only reported with the JENT_HEALTH return code. This allows the removal of the error indicator.
Fixes: 3fde2fe99aa6 ("crypto: jitter - permanent and intermittent health errors" ) Reported-by: Joachim Vandersmissen git@jvdsn.com Signed-off-by: Stephan Mueller smueller@chronox.de Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- crypto/jitterentropy.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c index 22f48bf4c6f57..227cedfa4f0ae 100644 --- a/crypto/jitterentropy.c +++ b/crypto/jitterentropy.c @@ -117,7 +117,6 @@ struct rand_data { * zero). */ #define JENT_ESTUCK 8 /* Too many stuck results during init. */ #define JENT_EHEALTH 9 /* Health test failed during initialization */ -#define JENT_ERCT 10 /* RCT failed during initialization */
/* * The output n bits can receive more than n bits of min entropy, of course, @@ -762,14 +761,12 @@ int jent_entropy_init(void) if ((nonstuck % JENT_APT_WINDOW_SIZE) == 0) { jent_apt_reset(&ec, delta & JENT_APT_WORD_MASK); - if (jent_health_failure(&ec)) - return JENT_EHEALTH; } }
- /* Validate RCT */ - if (jent_rct_failure(&ec)) - return JENT_ERCT; + /* Validate health test result */ + if (jent_health_failure(&ec)) + return JENT_EHEALTH;
/* test whether we have an increasing timer */ if (!(time2 > time))
From: Dan Carpenter dan.carpenter@linaro.org
[ Upstream commit 3a3f1e573a105328a2cca45a7cfbebabbf5e3192 ]
The > comparison should be >= to prevent an out of bounds array access.
Fixes: 52dc0595d540 ("modpost: handle relocations mismatch in __ex_table.") Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/mod/modpost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 30d2ebc391f4a..b1163bad652aa 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1296,7 +1296,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf,
static int is_executable_section(struct elf_info* elf, unsigned int section_index) { - if (section_index > elf->num_sections) + if (section_index >= elf->num_sections) fatal("section_index is outside elf->num_sections!\n");
return ((elf->sechdrs[section_index].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR);
From: Masahiro Yamada masahiroy@kernel.org
[ Upstream commit 92e2921eeafdfca9acd9b83f07d2b7ca099bac24 ]
ASM_NL is useful not only in *.S files but also in .c files for using inline assembler in C code.
On ARC, however, ASM_NL is evaluated inconsistently. It is expanded to a backquote (`) in *.S files, but a semicolon (;) in *.c files because arch/arc/include/asm/linkage.h defines it inside #ifdef __ASSEMBLY__, so the definition for C code falls back to the default value defined in include/linux/linkage.h.
If ASM_NL is used in inline assembler in .c files, it will result in wrong assembly code because a semicolon is not an instruction separator, but the start of a comment for ARC.
Move ASM_NL (also __ALIGN and __ALIGN_STR) out of the #ifdef.
Fixes: 9df62f054406 ("arch: use ASM_NL instead of ';' for assembler new line character in the macro") Fixes: 8d92e992a785 ("ARC: define __ALIGN_STR and __ALIGN symbols for ARC") Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arc/include/asm/linkage.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arc/include/asm/linkage.h b/arch/arc/include/asm/linkage.h index c9434ff3aa4ce..8a3fb71e9cfad 100644 --- a/arch/arc/include/asm/linkage.h +++ b/arch/arc/include/asm/linkage.h @@ -8,6 +8,10 @@
#include <asm/dwarf.h>
+#define ASM_NL ` /* use '`' to mark new line in macro */ +#define __ALIGN .align 4 +#define __ALIGN_STR __stringify(__ALIGN) + #ifdef __ASSEMBLY__
.macro ST2 e, o, off @@ -28,10 +32,6 @@ #endif .endm
-#define ASM_NL ` /* use '`' to mark new line in macro */ -#define __ALIGN .align 4 -#define __ALIGN_STR __stringify(__ALIGN) - /* annotation for data we want in DCCM - if enabled in .config */ .macro ARCFP_DATA nm #ifdef CONFIG_ARC_HAS_DCCM
From: Hareshx Sankar Raj hareshx.sankar.raj@intel.com
[ Upstream commit eb7713f5ca97697b92f225127440d1525119b8de ]
The callback function for DH frees the memory allocated for the destination buffer before unmapping it. This sequence is wrong.
Change the cleanup sequence to unmap the buffer before freeing it.
Fixes: 029aa4624a7f ("crypto: qat - remove dma_free_coherent() for DH") Signed-off-by: Hareshx Sankar Raj hareshx.sankar.raj@intel.com Co-developed-by: Bolemx Sivanagaleela bolemx.sivanagaleela@intel.com Signed-off-by: Bolemx Sivanagaleela bolemx.sivanagaleela@intel.com Reviewed-by: Giovanni Cabiddu giovanni.cabiddu@intel.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Giovanni Cabiddu giovanni.cabiddu@intel.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/qat/qat_common/qat_asym_algs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c b/drivers/crypto/qat/qat_common/qat_asym_algs.c index 935a7e012946e..8806242469a06 100644 --- a/drivers/crypto/qat/qat_common/qat_asym_algs.c +++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c @@ -170,15 +170,14 @@ static void qat_dh_cb(struct icp_qat_fw_pke_resp *resp) }
areq->dst_len = req->ctx.dh->p_size; + dma_unmap_single(dev, req->out.dh.r, req->ctx.dh->p_size, + DMA_FROM_DEVICE); if (req->dst_align) { scatterwalk_map_and_copy(req->dst_align, areq->dst, 0, areq->dst_len, 1); kfree_sensitive(req->dst_align); }
- dma_unmap_single(dev, req->out.dh.r, req->ctx.dh->p_size, - DMA_FROM_DEVICE); - dma_unmap_single(dev, req->phy_in, sizeof(struct qat_dh_input_params), DMA_TO_DEVICE); dma_unmap_single(dev, req->phy_out,
From: Hareshx Sankar Raj hareshx.sankar.raj@intel.com
[ Upstream commit d776b25495f2c71b9dbf1f5e53b642215ba72f3c ]
The callback function for RSA frees the memory allocated for the source and destination buffers before unmapping them. This sequence is wrong.
Change the cleanup sequence to unmap the buffers before freeing them.
Fixes: 3dfaf0071ed7 ("crypto: qat - remove dma_free_coherent() for RSA") Signed-off-by: Hareshx Sankar Raj hareshx.sankar.raj@intel.com Co-developed-by: Bolemx Sivanagaleela bolemx.sivanagaleela@intel.com Signed-off-by: Bolemx Sivanagaleela bolemx.sivanagaleela@intel.com Reviewed-by: Giovanni Cabiddu giovanni.cabiddu@intel.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Giovanni Cabiddu giovanni.cabiddu@intel.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/qat/qat_common/qat_asym_algs.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c b/drivers/crypto/qat/qat_common/qat_asym_algs.c index 8806242469a06..4128200a90329 100644 --- a/drivers/crypto/qat/qat_common/qat_asym_algs.c +++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c @@ -520,12 +520,14 @@ static void qat_rsa_cb(struct icp_qat_fw_pke_resp *resp)
err = (err == ICP_QAT_FW_COMN_STATUS_FLAG_OK) ? 0 : -EINVAL;
- kfree_sensitive(req->src_align); - dma_unmap_single(dev, req->in.rsa.enc.m, req->ctx.rsa->key_sz, DMA_TO_DEVICE);
+ kfree_sensitive(req->src_align); + areq->dst_len = req->ctx.rsa->key_sz; + dma_unmap_single(dev, req->out.rsa.enc.c, req->ctx.rsa->key_sz, + DMA_FROM_DEVICE); if (req->dst_align) { scatterwalk_map_and_copy(req->dst_align, areq->dst, 0, areq->dst_len, 1); @@ -533,9 +535,6 @@ static void qat_rsa_cb(struct icp_qat_fw_pke_resp *resp) kfree_sensitive(req->dst_align); }
- dma_unmap_single(dev, req->out.rsa.enc.c, req->ctx.rsa->key_sz, - DMA_FROM_DEVICE); - dma_unmap_single(dev, req->phy_in, sizeof(struct qat_rsa_input_params), DMA_TO_DEVICE); dma_unmap_single(dev, req->phy_out,
From: Qi Zheng zhengqi.arch@bytedance.com
[ Upstream commit 7f7ab336898f281e58540ef781a8fb375acc32a9 ]
Currently, the list_lru::shrinker_id corresponding to the nfs4_xattr shrinkers is wrong:
prog["nfs4_xattr_cache_lru"].shrinker_id
(int)0
prog["nfs4_xattr_entry_lru"].shrinker_id
(int)0
prog["nfs4_xattr_large_entry_lru"].shrinker_id
(int)0
prog["nfs4_xattr_cache_shrinker"].id
(int)18
prog["nfs4_xattr_entry_shrinker"].id
(int)19
prog["nfs4_xattr_large_entry_shrinker"].id
(int)20
This is not what we expect, which will cause these shrinkers not to be found in shrink_slab_memcg().
We should assign shrinker::id before calling list_lru_init_memcg(), so that the corresponding list_lru::shrinker_id will be assigned the correct value like below:
prog["nfs4_xattr_cache_lru"].shrinker_id
(int)16
prog["nfs4_xattr_entry_lru"].shrinker_id
(int)17
prog["nfs4_xattr_large_entry_lru"].shrinker_id
(int)18
prog["nfs4_xattr_cache_shrinker"].id
(int)16
prog["nfs4_xattr_entry_shrinker"].id
(int)17
prog["nfs4_xattr_large_entry_shrinker"].id
(int)18
So just do it.
Fixes: 95ad37f90c33 ("NFSv4.2: add client side xattr caching.") Signed-off-by: Qi Zheng zhengqi.arch@bytedance.com Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/nfs42xattr.c | 79 +++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 35 deletions(-)
diff --git a/fs/nfs/nfs42xattr.c b/fs/nfs/nfs42xattr.c index 76ae118342066..911f634ba3da7 100644 --- a/fs/nfs/nfs42xattr.c +++ b/fs/nfs/nfs42xattr.c @@ -991,6 +991,29 @@ static void nfs4_xattr_cache_init_once(void *p) INIT_LIST_HEAD(&cache->dispose); }
+static int nfs4_xattr_shrinker_init(struct shrinker *shrinker, + struct list_lru *lru, const char *name) +{ + int ret = 0; + + ret = register_shrinker(shrinker, name); + if (ret) + return ret; + + ret = list_lru_init_memcg(lru, shrinker); + if (ret) + unregister_shrinker(shrinker); + + return ret; +} + +static void nfs4_xattr_shrinker_destroy(struct shrinker *shrinker, + struct list_lru *lru) +{ + unregister_shrinker(shrinker); + list_lru_destroy(lru); +} + int __init nfs4_xattr_cache_init(void) { int ret = 0; @@ -1002,44 +1025,30 @@ int __init nfs4_xattr_cache_init(void) if (nfs4_xattr_cache_cachep == NULL) return -ENOMEM;
- ret = list_lru_init_memcg(&nfs4_xattr_large_entry_lru, - &nfs4_xattr_large_entry_shrinker); - if (ret) - goto out4; - - ret = list_lru_init_memcg(&nfs4_xattr_entry_lru, - &nfs4_xattr_entry_shrinker); - if (ret) - goto out3; - - ret = list_lru_init_memcg(&nfs4_xattr_cache_lru, - &nfs4_xattr_cache_shrinker); - if (ret) - goto out2; - - ret = register_shrinker(&nfs4_xattr_cache_shrinker, "nfs-xattr_cache"); + ret = nfs4_xattr_shrinker_init(&nfs4_xattr_cache_shrinker, + &nfs4_xattr_cache_lru, + "nfs-xattr_cache"); if (ret) goto out1;
- ret = register_shrinker(&nfs4_xattr_entry_shrinker, "nfs-xattr_entry"); + ret = nfs4_xattr_shrinker_init(&nfs4_xattr_entry_shrinker, + &nfs4_xattr_entry_lru, + "nfs-xattr_entry"); if (ret) - goto out; + goto out2;
- ret = register_shrinker(&nfs4_xattr_large_entry_shrinker, - "nfs-xattr_large_entry"); + ret = nfs4_xattr_shrinker_init(&nfs4_xattr_large_entry_shrinker, + &nfs4_xattr_large_entry_lru, + "nfs-xattr_large_entry"); if (!ret) return 0;
- unregister_shrinker(&nfs4_xattr_entry_shrinker); -out: - unregister_shrinker(&nfs4_xattr_cache_shrinker); -out1: - list_lru_destroy(&nfs4_xattr_cache_lru); + nfs4_xattr_shrinker_destroy(&nfs4_xattr_entry_shrinker, + &nfs4_xattr_entry_lru); out2: - list_lru_destroy(&nfs4_xattr_entry_lru); -out3: - list_lru_destroy(&nfs4_xattr_large_entry_lru); -out4: + nfs4_xattr_shrinker_destroy(&nfs4_xattr_cache_shrinker, + &nfs4_xattr_cache_lru); +out1: kmem_cache_destroy(nfs4_xattr_cache_cachep);
return ret; @@ -1047,11 +1056,11 @@ int __init nfs4_xattr_cache_init(void)
void nfs4_xattr_cache_exit(void) { - unregister_shrinker(&nfs4_xattr_large_entry_shrinker); - unregister_shrinker(&nfs4_xattr_entry_shrinker); - unregister_shrinker(&nfs4_xattr_cache_shrinker); - list_lru_destroy(&nfs4_xattr_large_entry_lru); - list_lru_destroy(&nfs4_xattr_entry_lru); - list_lru_destroy(&nfs4_xattr_cache_lru); + nfs4_xattr_shrinker_destroy(&nfs4_xattr_large_entry_shrinker, + &nfs4_xattr_large_entry_lru); + nfs4_xattr_shrinker_destroy(&nfs4_xattr_entry_shrinker, + &nfs4_xattr_entry_lru); + nfs4_xattr_shrinker_destroy(&nfs4_xattr_cache_shrinker, + &nfs4_xattr_cache_lru); kmem_cache_destroy(nfs4_xattr_cache_cachep); }
From: Olga Kornievskaia kolga@netapp.com
[ Upstream commit c907e72f58ed979a24a9fdcadfbc447c51d5e509 ]
When the client received NFS4ERR_BADSESSION, it schedules recovery and start the state manager thread which in turn freezes the session table and does not allow for any new requests to use the no-longer valid session. However, it is possible that before the state manager thread runs, a new operation would use the released slot that received BADSESSION and was therefore not updated its sequence number. Such re-use of the slot can lead the application errors.
Fixes: 5c441544f045 ("NFSv4.x: Handle bad/dead sessions correctly in nfs41_sequence_process()") Signed-off-by: Olga Kornievskaia kolga@netapp.com Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/nfs4proc.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 5607b1e2b8212..23a23387211ba 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -921,6 +921,7 @@ static int nfs41_sequence_process(struct rpc_task *task, out_noaction: return ret; session_recover: + set_bit(NFS4_SLOT_TBL_DRAINING, &session->fc_slot_table.slot_tbl_state); nfs4_schedule_session_recovery(session, status); dprintk("%s ERROR: %d Reset session\n", __func__, status); nfs41_sequence_free_slot(res);
From: Bharath SM bharathsm@microsoft.com
[ Upstream commit da787d5b74983f7525d1eb4b9c0b4aff2821511a ]
In case if all existing file handles are deferred handles and if all of them gets closed due to handle lease break then we dont need to send lease break acknowledgment to server, because last handle close will be considered as lease break ack. After closing deferred handels, we check for openfile list of inode, if its empty then we skip sending lease break ack.
Fixes: 59a556aebc43 ("SMB3: drop reference to cfile before sending oplock break") Reviewed-by: Tom Talpey tom@talpey.com Signed-off-by: Bharath SM bharathsm@microsoft.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/cifs/file.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 051283386e229..1a854dc204823 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -4936,20 +4936,19 @@ void cifs_oplock_break(struct work_struct *work)
_cifsFileInfo_put(cfile, false /* do not wait for ourself */, false); /* - * releasing stale oplock after recent reconnect of smb session using - * a now incorrect file handle is not a data integrity issue but do - * not bother sending an oplock release if session to server still is - * disconnected since oplock already released by the server + * MS-SMB2 3.2.5.19.1 and 3.2.5.19.2 (and MS-CIFS 3.2.5.42) do not require + * an acknowledgment to be sent when the file has already been closed. + * check for server null, since can race with kill_sb calling tree disconnect. */ - if (!oplock_break_cancelled) { - /* check for server null since can race with kill_sb calling tree disconnect */ - if (tcon->ses && tcon->ses->server) { - rc = tcon->ses->server->ops->oplock_response(tcon, persistent_fid, - volatile_fid, net_fid, cinode); - cifs_dbg(FYI, "Oplock release rc = %d\n", rc); - } else - pr_warn_once("lease break not sent for unmounted share\n"); - } + spin_lock(&cinode->open_file_lock); + if (tcon->ses && tcon->ses->server && !oplock_break_cancelled && + !list_empty(&cinode->openFileList)) { + spin_unlock(&cinode->open_file_lock); + rc = tcon->ses->server->ops->oplock_response(tcon, persistent_fid, + volatile_fid, net_fid, cinode); + cifs_dbg(FYI, "Oplock release rc = %d\n", rc); + } else + spin_unlock(&cinode->open_file_lock);
cifs_done_oplock_break(cinode); }
From: Dan Williams dan.j.williams@intel.com
[ Upstream commit 6d24b170a9db0456f577b1ab01226a2254c016a8 ]
A CONFIG_DEBUG_KOBJECT_RELEASE test of removing a device-dax region provider (like modprobe -r dax_hmem) yields:
kobject: 'mapping0' (ffff93eb460e8800): kobject_release, parent 0000000000000000 (delayed 2000) [..] DEBUG_LOCKS_WARN_ON(1) WARNING: CPU: 23 PID: 282 at kernel/locking/lockdep.c:232 __lock_acquire+0x9fc/0x2260 [..] RIP: 0010:__lock_acquire+0x9fc/0x2260 [..] Call Trace: <TASK> [..] lock_acquire+0xd4/0x2c0 ? ida_free+0x62/0x130 _raw_spin_lock_irqsave+0x47/0x70 ? ida_free+0x62/0x130 ida_free+0x62/0x130 dax_mapping_release+0x1f/0x30 device_release+0x36/0x90 kobject_delayed_cleanup+0x46/0x150
Due to attempting ida_free() on an ida object that has already been freed. Devices typically only hold a reference on their parent while registered. If a child needs a parent object to complete its release it needs to hold a reference that it drops from its release callback. Arrange for a dax_mapping to pin its parent dev_dax instance until dax_mapping_release().
Fixes: 0b07ce872a9e ("device-dax: introduce 'mapping' devices") Signed-off-by: Dan Williams dan.j.williams@intel.com Link: https://lore.kernel.org/r/168577283412.1672036.16111545266174261446.stgit@dw... Reviewed-by: Dave Jiang dave.jiang@intel.com Reviewed-by: Fan Ni fan.ni@samsung.com Reviewed-by: Ira Weiny ira.weiny@intel.com Signed-off-by: Vishal Verma vishal.l.verma@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dax/bus.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c index 227800053309f..aee695f86b445 100644 --- a/drivers/dax/bus.c +++ b/drivers/dax/bus.c @@ -635,10 +635,12 @@ EXPORT_SYMBOL_GPL(alloc_dax_region); static void dax_mapping_release(struct device *dev) { struct dax_mapping *mapping = to_dax_mapping(dev); - struct dev_dax *dev_dax = to_dev_dax(dev->parent); + struct device *parent = dev->parent; + struct dev_dax *dev_dax = to_dev_dax(parent);
ida_free(&dev_dax->ida, mapping->id); kfree(mapping); + put_device(parent); }
static void unregister_dax_mapping(void *data) @@ -778,6 +780,7 @@ static int devm_register_dax_mapping(struct dev_dax *dev_dax, int range_id) dev = &mapping->dev; device_initialize(dev); dev->parent = &dev_dax->dev; + get_device(dev->parent); dev->type = &dax_mapping_type; dev_set_name(dev, "mapping%d", mapping->id); rc = device_add(dev);
From: Dan Williams dan.j.williams@intel.com
[ Upstream commit 70aab281e18c68a1284bc387de127c2fc0bed3f8 ]
The reference counting of dax_region objects is needlessly complicated, has lead to confusion [1], and has hidden a bug [2]. Towards cleaning up that mess introduce alloc_dev_dax_id() to minimize the holding of a dax_region reference to only what dev_dax_release() needs, the dax_region->ida.
Part of the reason for the mess was the design to dereference a dax_region in all cases in free_dev_dax_id() even if the id was statically assigned by the upper level dax_region driver. Remove the need to call "is_static(dax_region)" by tracking whether the id is dynamic directly in the dev_dax instance itself.
With that flag the dax_region pinning and release per dev_dax instance can move to alloc_dev_dax_id() and free_dev_dax_id() respectively.
A follow-on cleanup address the unnecessary references in the dax_region setup and drivers.
Fixes: 0f3da14a4f05 ("device-dax: introduce 'seed' devices") Link: http://lore.kernel.org/r/20221203095858.612027-1-liuyongqiang13@huawei.com [1] Link: http://lore.kernel.org/r/3cf0890b-4eb0-e70e-cd9c-2ecc3d496263@hpe.com [2] Reported-by: Yongqiang Liu liuyongqiang13@huawei.com Reported-by: Paul Cassella cassella@hpe.com Reported-by: Ira Weiny ira.weiny@intel.com Signed-off-by: Dan Williams dan.j.williams@intel.com Link: https://lore.kernel.org/r/168577284563.1672036.13493034988900989554.stgit@dw... Reviewed-by: Ira Weiny ira.weiny@intel.com Signed-off-by: Vishal Verma vishal.l.verma@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dax/bus.c | 56 ++++++++++++++++++++++++--------------- drivers/dax/dax-private.h | 4 ++- 2 files changed, 37 insertions(+), 23 deletions(-)
diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c index aee695f86b445..e7c61358564e1 100644 --- a/drivers/dax/bus.c +++ b/drivers/dax/bus.c @@ -446,18 +446,34 @@ static void unregister_dev_dax(void *dev) put_device(dev); }
+static void dax_region_free(struct kref *kref) +{ + struct dax_region *dax_region; + + dax_region = container_of(kref, struct dax_region, kref); + kfree(dax_region); +} + +void dax_region_put(struct dax_region *dax_region) +{ + kref_put(&dax_region->kref, dax_region_free); +} +EXPORT_SYMBOL_GPL(dax_region_put); + /* a return value >= 0 indicates this invocation invalidated the id */ static int __free_dev_dax_id(struct dev_dax *dev_dax) { - struct dax_region *dax_region = dev_dax->region; struct device *dev = &dev_dax->dev; + struct dax_region *dax_region; int rc = dev_dax->id;
device_lock_assert(dev);
- if (is_static(dax_region) || dev_dax->id < 0) + if (!dev_dax->dyn_id || dev_dax->id < 0) return -1; + dax_region = dev_dax->region; ida_free(&dax_region->ida, dev_dax->id); + dax_region_put(dax_region); dev_dax->id = -1; return rc; } @@ -473,6 +489,20 @@ static int free_dev_dax_id(struct dev_dax *dev_dax) return rc; }
+static int alloc_dev_dax_id(struct dev_dax *dev_dax) +{ + struct dax_region *dax_region = dev_dax->region; + int id; + + id = ida_alloc(&dax_region->ida, GFP_KERNEL); + if (id < 0) + return id; + kref_get(&dax_region->kref); + dev_dax->dyn_id = true; + dev_dax->id = id; + return id; +} + static ssize_t delete_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { @@ -560,20 +590,6 @@ static const struct attribute_group *dax_region_attribute_groups[] = { NULL, };
-static void dax_region_free(struct kref *kref) -{ - struct dax_region *dax_region; - - dax_region = container_of(kref, struct dax_region, kref); - kfree(dax_region); -} - -void dax_region_put(struct dax_region *dax_region) -{ - kref_put(&dax_region->kref, dax_region_free); -} -EXPORT_SYMBOL_GPL(dax_region_put); - static void dax_region_unregister(void *region) { struct dax_region *dax_region = region; @@ -1298,12 +1314,10 @@ static const struct attribute_group *dax_attribute_groups[] = { static void dev_dax_release(struct device *dev) { struct dev_dax *dev_dax = to_dev_dax(dev); - struct dax_region *dax_region = dev_dax->region; struct dax_device *dax_dev = dev_dax->dax_dev;
put_dax(dax_dev); free_dev_dax_id(dev_dax); - dax_region_put(dax_region); kfree(dev_dax->pgmap); kfree(dev_dax); } @@ -1327,6 +1341,7 @@ struct dev_dax *devm_create_dev_dax(struct dev_dax_data *data) if (!dev_dax) return ERR_PTR(-ENOMEM);
+ dev_dax->region = dax_region; if (is_static(dax_region)) { if (dev_WARN_ONCE(parent, data->id < 0, "dynamic id specified to static region\n")) { @@ -1342,13 +1357,11 @@ struct dev_dax *devm_create_dev_dax(struct dev_dax_data *data) goto err_id; }
- rc = ida_alloc(&dax_region->ida, GFP_KERNEL); + rc = alloc_dev_dax_id(dev_dax); if (rc < 0) goto err_id; - dev_dax->id = rc; }
- dev_dax->region = dax_region; dev = &dev_dax->dev; device_initialize(dev); dev_set_name(dev, "dax%d.%d", dax_region->id, dev_dax->id); @@ -1389,7 +1402,6 @@ struct dev_dax *devm_create_dev_dax(struct dev_dax_data *data) dev_dax->target_node = dax_region->target_node; dev_dax->align = dax_region->align; ida_init(&dev_dax->ida); - kref_get(&dax_region->kref);
inode = dax_inode(dax_dev); dev->devt = inode->i_rdev; diff --git a/drivers/dax/dax-private.h b/drivers/dax/dax-private.h index 1c974b7caae6e..afcada6fd2eda 100644 --- a/drivers/dax/dax-private.h +++ b/drivers/dax/dax-private.h @@ -52,7 +52,8 @@ struct dax_mapping { * @region - parent region * @dax_dev - core dax functionality * @target_node: effective numa node if dev_dax memory range is onlined - * @id: ida allocated id + * @dyn_id: is this a dynamic or statically created instance + * @id: ida allocated id when the dax_region is not static * @ida: mapping id allocator * @dev - device core * @pgmap - pgmap for memmap setup / lifetime (driver owned) @@ -64,6 +65,7 @@ struct dev_dax { struct dax_device *dax_dev; unsigned int align; int target_node; + bool dyn_id; int id; struct ida ida; struct device dev;
From: Tarun Sahu tsahu@linux.ibm.com
[ Upstream commit 46e66dab8565f742374e9cc4ff7d35f344d774e2 ]
memory_group_register_static takes maximum number of pages as the argument while dev_dax_kmem_probe passes total_len (in bytes) as the argument.
IIUC, I don't see any crash/panic impact as such. As, memory_group_register_static just set the max_pages limit which is used in auto_movable_zone_for_pfn to determine the zone.
which might cause these condition to behave differently,
This will be true always so jump will happen to kernel_zone ... if (!auto_movable_can_online_movable(NUMA_NO_NODE, group, nr_pages)) goto kernel_zone;
... kernel_zone: return default_kernel_zone_for_pfn(nid, pfn, nr_pages);
Here, In below, zone_intersects compare range will be larger as nr_pages will be higher (derived from total_len passed in dev_dax_kmem_probe).
... static struct zone *default_kernel_zone_for_pfn(int nid, unsigned long start_pfn, unsigned long nr_pages) { struct pglist_data *pgdat = NODE_DATA(nid); int zid;
for (zid = 0; zid < ZONE_NORMAL; zid++) { struct zone *zone = &pgdat->node_zones[zid];
if (zone_intersects(zone, start_pfn, nr_pages)) return zone; }
return &pgdat->node_zones[ZONE_NORMAL]; }
Incorrect zone will be returned here, which in later time might cause bigger problem.
Fixes: eedf634aac3b ("dax/kmem: use a single static memory group for a single probed unit") Signed-off-by: Tarun Sahu tsahu@linux.ibm.com Link: https://lore.kernel.org/r/20230621155025.370672-1-tsahu@linux.ibm.com Reviewed-by: Vishal Verma vishal.l.verma@intel.com Signed-off-by: Vishal Verma vishal.l.verma@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dax/kmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dax/kmem.c b/drivers/dax/kmem.c index 7b36db6f1cbdc..898ca95057547 100644 --- a/drivers/dax/kmem.c +++ b/drivers/dax/kmem.c @@ -99,7 +99,7 @@ static int dev_dax_kmem_probe(struct dev_dax *dev_dax) if (!data->res_name) goto err_res_name;
- rc = memory_group_register_static(numa_node, total_len); + rc = memory_group_register_static(numa_node, PFN_UP(total_len)); if (rc < 0) goto err_reg_mgid; data->mgid = rc;
From: Martin Kaiser martin@kaiser.cx
[ Upstream commit 501e197a02d4aef157f53ba3a0b9049c3e52fedc ]
The st-rng driver uses devres to register itself with the hwrng core, the driver will be unregistered from hwrng when its device goes out of scope. This happens after the driver's remove function is called.
However, st-rng's clock is disabled in the remove function. There's a short timeframe where st-rng is still registered with the hwrng core although its clock is disabled. I suppose the clock must be active to access the hardware and serve requests from the hwrng core.
Switch to devm_clk_get_enabled and let devres disable the clock and unregister the hwrng. This avoids the race condition.
Fixes: 3e75241be808 ("hwrng: drivers - Use device-managed registration API") Signed-off-by: Martin Kaiser martin@kaiser.cx Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/hw_random/st-rng.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-)
diff --git a/drivers/char/hw_random/st-rng.c b/drivers/char/hw_random/st-rng.c index 15ba1e6fae4d2..6e9dfac9fc9f4 100644 --- a/drivers/char/hw_random/st-rng.c +++ b/drivers/char/hw_random/st-rng.c @@ -42,7 +42,6 @@
struct st_rng_data { void __iomem *base; - struct clk *clk; struct hwrng ops; };
@@ -85,26 +84,18 @@ static int st_rng_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base);
- clk = devm_clk_get(&pdev->dev, NULL); + clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(clk)) return PTR_ERR(clk);
- ret = clk_prepare_enable(clk); - if (ret) - return ret; - ddata->ops.priv = (unsigned long)ddata; ddata->ops.read = st_rng_read; ddata->ops.name = pdev->name; ddata->base = base; - ddata->clk = clk; - - dev_set_drvdata(&pdev->dev, ddata);
ret = devm_hwrng_register(&pdev->dev, &ddata->ops); if (ret) { dev_err(&pdev->dev, "Failed to register HW RNG\n"); - clk_disable_unprepare(clk); return ret; }
@@ -113,15 +104,6 @@ static int st_rng_probe(struct platform_device *pdev) return 0; }
-static int st_rng_remove(struct platform_device *pdev) -{ - struct st_rng_data *ddata = dev_get_drvdata(&pdev->dev); - - clk_disable_unprepare(ddata->clk); - - return 0; -} - static const struct of_device_id st_rng_match[] __maybe_unused = { { .compatible = "st,rng" }, {}, @@ -134,7 +116,6 @@ static struct platform_driver st_rng_driver = { .of_match_table = of_match_ptr(st_rng_match), }, .probe = st_rng_probe, - .remove = st_rng_remove };
module_platform_driver(st_rng_driver);
From: Sami Tolvanen samitolvanen@google.com
[ Upstream commit ddf56288eebd1fe82c46fc9f693b5b18045cddb6 ]
With GCOV_PROFILE_ALL, Clang injects __llvm_gcov_* functions to each object file, and the functions are indirectly called during boot. However, when code is injected to object files that are not part of vmlinux.o, it's also not processed by objtool, which breaks CFI hash randomization as the hashes in these files won't be included in the .cfi_sites section and thus won't be randomized.
Similarly to commit 42633ed852de ("kbuild: Fix CFI hash randomization with KASAN"), disable GCOV for .vmlinux.export.o and init/version-timestamp.o to avoid emitting unnecessary functions to object files that don't otherwise have executable code.
Fixes: 0c3e806ec0f9 ("x86/cfi: Add boot time hash randomization") Reported-by: Joe Fradley joefradley@google.com Signed-off-by: Sami Tolvanen samitolvanen@google.com Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Kees Cook keescook@chromium.org Reviewed-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- init/Makefile | 1 + scripts/Makefile.vmlinux | 1 + 2 files changed, 2 insertions(+)
diff --git a/init/Makefile b/init/Makefile index 26de459006c4e..ec557ada3c12e 100644 --- a/init/Makefile +++ b/init/Makefile @@ -60,3 +60,4 @@ include/generated/utsversion.h: FORCE $(obj)/version-timestamp.o: include/generated/utsversion.h CFLAGS_version-timestamp.o := -include include/generated/utsversion.h KASAN_SANITIZE_version-timestamp.o := n +GCOV_PROFILE_version-timestamp.o := n diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index 10176dec97eac..3cd6ca15f390d 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -19,6 +19,7 @@ quiet_cmd_cc_o_c = CC $@
ifdef CONFIG_MODULES KASAN_SANITIZE_.vmlinux.export.o := n +GCOV_PROFILE_.vmlinux.export.o := n targets += .vmlinux.export.o vmlinux: .vmlinux.export.o endif
From: Sami Tolvanen samitolvanen@google.com
[ Upstream commit 25a21fbb934a0d989e1858f83c2ddf4cfb2ebe30 ]
With GCOV_PROFILE_ALL, Clang injects __llvm_gcov_* functions to each object file, including the *.mod.o. As we filter out CC_FLAGS_CFI for *.mod.o, the compiler won't generate type hashes for the injected functions, and therefore indirectly calling them during module loading trips indirect call checking.
Enabling CFI for *.mod.o isn't sufficient to fix this issue after commit 0c3e806ec0f9 ("x86/cfi: Add boot time hash randomization"), as *.mod.o aren't processed by objtool, which means any hashes emitted there won't be randomized. Therefore, in addition to disabling CFI for *.mod.o, also disable GCOV, as the object files don't otherwise contain any executable code.
Fixes: cf68fffb66d6 ("add support for Clang CFI") Reported-by: Joe Fradley joefradley@google.com Signed-off-by: Sami Tolvanen samitolvanen@google.com Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Kees Cook keescook@chromium.org Reviewed-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/Makefile.modfinal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 4703f652c0098..fc19f67039bda 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -23,7 +23,7 @@ modname = $(notdir $(@:.mod.o=)) part-of-module = y
quiet_cmd_cc_o_c = CC [M] $@ - cmd_cc_o_c = $(CC) $(filter-out $(CC_FLAGS_CFI), $(c_flags)) -c -o $@ $< + cmd_cc_o_c = $(CC) $(filter-out $(CC_FLAGS_CFI) $(CFLAGS_GCOV), $(c_flags)) -c -o $@ $<
%.mod.o: %.mod.c FORCE $(call if_changed_dep,cc_o_c)
From: Dan Williams dan.j.williams@intel.com
[ Upstream commit d1257d098a5a38753a0736a50db0a26a62377ad7 ]
Vikram raised a concern with the theoretical case of a CPU sending MemClnEvict to a device that is not prepared to receive. MemClnEvict is a message that is sent after a CPU has taken ownership of a cacheline from accelerator memory (HDM-DB). In the case of hotplug or HDM decoder reconfiguration it is possible that the CPU is holding old contents for a new device that has taken over the physical address range being cached by the CPU.
To avoid this scenario, invalidate caches prior to tearing down an HDM decoder configuration.
Now, this poses another problem that it is possible for something to speculate into that space while the decode configuration is still up, so to close that gap also invalidate prior to establish new contents behind a given physical address range.
With this change the cache invalidation is now explicit and need not be checked in cxl_region_probe(), and that obviates the need for CXL_REGION_F_INCOHERENT.
Cc: Jonathan Cameron Jonathan.Cameron@Huawei.com Fixes: d18bc74aced6 ("cxl/region: Manage CPU caches relative to DPA invalidation events") Reported-by: Vikram Sethi vsethi@nvidia.com Closes: http://lore.kernel.org/r/BYAPR12MB33364B5EB908BF7239BB996BBD53A@BYAPR12MB333... Reviewed-by: Jonathan Cameron Jonathan.Cameron@huawei.com Reviewed-by: Dave Jiang dave.jiang@intel.com Link: https://lore.kernel.org/r/168696506886.3590522.4597053660991916591.stgit@dwi... Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cxl/core/region.c | 66 ++++++++++++++++++++++----------------- drivers/cxl/cxl.h | 8 +---- 2 files changed, 38 insertions(+), 36 deletions(-)
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index b2fd67fcebfb5..3b3bbd98e99d5 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -125,10 +125,38 @@ static struct cxl_region_ref *cxl_rr_load(struct cxl_port *port, return xa_load(&port->regions, (unsigned long)cxlr); }
+static int cxl_region_invalidate_memregion(struct cxl_region *cxlr) +{ + if (!cpu_cache_has_invalidate_memregion()) { + if (IS_ENABLED(CONFIG_CXL_REGION_INVALIDATION_TEST)) { + dev_warn_once( + &cxlr->dev, + "Bypassing cpu_cache_invalidate_memregion() for testing!\n"); + return 0; + } else { + dev_err(&cxlr->dev, + "Failed to synchronize CPU cache state\n"); + return -ENXIO; + } + } + + cpu_cache_invalidate_memregion(IORES_DESC_CXL); + return 0; +} + static int cxl_region_decode_reset(struct cxl_region *cxlr, int count) { struct cxl_region_params *p = &cxlr->params; - int i; + int i, rc = 0; + + /* + * Before region teardown attempt to flush, and if the flush + * fails cancel the region teardown for data consistency + * concerns + */ + rc = cxl_region_invalidate_memregion(cxlr); + if (rc) + return rc;
for (i = count - 1; i >= 0; i--) { struct cxl_endpoint_decoder *cxled = p->targets[i]; @@ -136,7 +164,6 @@ static int cxl_region_decode_reset(struct cxl_region *cxlr, int count) struct cxl_port *iter = cxled_to_port(cxled); struct cxl_dev_state *cxlds = cxlmd->cxlds; struct cxl_ep *ep; - int rc = 0;
if (cxlds->rcd) goto endpoint_reset; @@ -256,6 +283,14 @@ static ssize_t commit_store(struct device *dev, struct device_attribute *attr, goto out; }
+ /* + * Invalidate caches before region setup to drop any speculative + * consumption of this address space + */ + rc = cxl_region_invalidate_memregion(cxlr); + if (rc) + return rc; + if (commit) rc = cxl_region_decode_commit(cxlr); else { @@ -1674,7 +1709,6 @@ static int cxl_region_attach(struct cxl_region *cxlr, if (rc) goto err_decrement; p->state = CXL_CONFIG_ACTIVE; - set_bit(CXL_REGION_F_INCOHERENT, &cxlr->flags); }
cxled->cxld.interleave_ways = p->interleave_ways; @@ -2679,30 +2713,6 @@ int cxl_add_to_region(struct cxl_port *root, struct cxl_endpoint_decoder *cxled) } EXPORT_SYMBOL_NS_GPL(cxl_add_to_region, CXL);
-static int cxl_region_invalidate_memregion(struct cxl_region *cxlr) -{ - if (!test_bit(CXL_REGION_F_INCOHERENT, &cxlr->flags)) - return 0; - - if (!cpu_cache_has_invalidate_memregion()) { - if (IS_ENABLED(CONFIG_CXL_REGION_INVALIDATION_TEST)) { - dev_warn_once( - &cxlr->dev, - "Bypassing cpu_cache_invalidate_memregion() for testing!\n"); - clear_bit(CXL_REGION_F_INCOHERENT, &cxlr->flags); - return 0; - } else { - dev_err(&cxlr->dev, - "Failed to synchronize CPU cache state\n"); - return -ENXIO; - } - } - - cpu_cache_invalidate_memregion(IORES_DESC_CXL); - clear_bit(CXL_REGION_F_INCOHERENT, &cxlr->flags); - return 0; -} - static int is_system_ram(struct resource *res, void *arg) { struct cxl_region *cxlr = arg; @@ -2730,8 +2740,6 @@ static int cxl_region_probe(struct device *dev) goto out; }
- rc = cxl_region_invalidate_memregion(cxlr); - /* * From this point on any path that changes the region's state away from * CXL_CONFIG_COMMIT is also responsible for releasing the driver. diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index 044a92d9813e2..70ab8fcd0377c 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -462,18 +462,12 @@ struct cxl_region_params { int nr_targets; };
-/* - * Flag whether this region needs to have its HPA span synchronized with - * CPU cache state at region activation time. - */ -#define CXL_REGION_F_INCOHERENT 0 - /* * Indicate whether this region has been assembled by autodetection or * userspace assembly. Prevent endpoint decoders outside of automatic * detection from being added to the region. */ -#define CXL_REGION_F_AUTO 1 +#define CXL_REGION_F_AUTO 0
/** * struct cxl_region - CXL region
From: Dan Williams dan.j.williams@intel.com
[ Upstream commit 2ab47045ac96a605e3037d479a7d5854570ee5bf ]
cxl_region_decode_reset() walks all the decoders associated with a given region and disables them. Due to decoder ordering rules it is possible that a switch in the topology notices that a given decoder can not be shutdown before another region with a higher HPA is shutdown first. That can leave the region in a partially committed state.
Capture that state in a new CXL_REGION_F_NEEDS_RESET flag and require that a successful cxl_region_decode_reset() attempt must be completed before cxl_region_probe() accepts the region.
This is a corollary for the bug that Jonathan identified in "CXL/region : commit reset of out of order region appears to succeed." [1].
Cc: Jonathan Cameron Jonathan.Cameron@Huawei.com Link: http://lore.kernel.org/r/20230316171441.0000205b@Huawei.com [1] Fixes: 176baefb2eb5 ("cxl/hdm: Commit decoder state to hardware") Reviewed-by: Dave Jiang dave.jiang@intel.com Link: https://lore.kernel.org/r/168696507423.3590522.16254212607926684429.stgit@dw... Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cxl/core/region.c | 12 ++++++++++++ drivers/cxl/cxl.h | 8 ++++++++ 2 files changed, 20 insertions(+)
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index 3b3bbd98e99d5..c1422167ab02b 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -182,14 +182,19 @@ static int cxl_region_decode_reset(struct cxl_region *cxlr, int count) rc = cxld->reset(cxld); if (rc) return rc; + set_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags); }
endpoint_reset: rc = cxled->cxld.reset(&cxled->cxld); if (rc) return rc; + set_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags); }
+ /* all decoders associated with this region have been torn down */ + clear_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags); + return 0; }
@@ -2740,6 +2745,13 @@ static int cxl_region_probe(struct device *dev) goto out; }
+ if (test_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags)) { + dev_err(&cxlr->dev, + "failed to activate, re-commit region and retry\n"); + rc = -ENXIO; + goto out; + } + /* * From this point on any path that changes the region's state away from * CXL_CONFIG_COMMIT is also responsible for releasing the driver. diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index 70ab8fcd0377c..dcebe48bb5bb5 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -469,6 +469,14 @@ struct cxl_region_params { */ #define CXL_REGION_F_AUTO 0
+/* + * Require that a committed region successfully complete a teardown once + * any of its associated decoders have been torn down. This maintains + * the commit state for the region since there are committed decoders, + * but blocks cxl_region_probe(). + */ +#define CXL_REGION_F_NEEDS_RESET 1 + /** * struct cxl_region - CXL region * @dev: This region's device
From: Dan Williams dan.j.williams@intel.com
[ Upstream commit adfe19738b71a893da62cb2e30bd6bdb4299ea67 ]
Jonathan reports that failed attempts to reset a region (teardown its HDM decoder configuration) mistakenly advance the state of the region to "not committed". Revert to the previous state of the region on reset failure so that the reset can be re-attempted.
Reported-by: Jonathan Cameron Jonathan.Cameron@Huawei.com Closes: http://lore.kernel.org/r/20230316171441.0000205b@Huawei.com Fixes: 176baefb2eb5 ("cxl/hdm: Commit decoder state to hardware") Reviewed-by: Jonathan Cameron Jonathan.Cameron@huawei.com Reviewed-by: Dave Jiang dave.jiang@intel.com Link: https://lore.kernel.org/r/168696507968.3590522.14484000711718573626.stgit@dw... Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cxl/core/region.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index c1422167ab02b..1997bc1bf64aa 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -296,9 +296,11 @@ static ssize_t commit_store(struct device *dev, struct device_attribute *attr, if (rc) return rc;
- if (commit) + if (commit) { rc = cxl_region_decode_commit(cxlr); - else { + if (rc == 0) + p->state = CXL_CONFIG_COMMIT; + } else { p->state = CXL_CONFIG_RESET_PENDING; up_write(&cxl_region_rwsem); device_release_driver(&cxlr->dev); @@ -308,18 +310,20 @@ static ssize_t commit_store(struct device *dev, struct device_attribute *attr, * The lock was dropped, so need to revalidate that the reset is * still pending. */ - if (p->state == CXL_CONFIG_RESET_PENDING) + if (p->state == CXL_CONFIG_RESET_PENDING) { rc = cxl_region_decode_reset(cxlr, p->interleave_ways); + /* + * Revert to committed since there may still be active + * decoders associated with this region, or move forward + * to active to mark the reset successful + */ + if (rc) + p->state = CXL_CONFIG_COMMIT; + else + p->state = CXL_CONFIG_ACTIVE; + } }
- if (rc) - goto out; - - if (commit) - p->state = CXL_CONFIG_COMMIT; - else if (p->state == CXL_CONFIG_RESET_PENDING) - p->state = CXL_CONFIG_ACTIVE; - out: up_write(&cxl_region_rwsem);
From: Josh Triplett josh@joshtriplett.org
[ Upstream commit 4243afdb932677a03770753be8c54b3190a512e8 ]
Even for a non-modular kernel, the kernel builds modules.builtin and modules.builtin.modinfo, with information about the built-in modules. Tools such as initramfs-tools need these files to build a working initramfs on some systems, such as those requiring firmware.
Now that `make modules_install` works even in non-modular kernels and installs these files, unconditionally invoke it when building a Debian package.
Signed-off-by: Josh Triplett josh@joshtriplett.org Reviewed-by: Nicolas Schier nicolas@fjasle.eu Signed-off-by: Masahiro Yamada masahiroy@kernel.org Stable-dep-of: 1240dabe8d58 ("kbuild: deb-pkg: remove the CONFIG_MODULES check in buildeb") Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/package/builddeb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 7b23f52c70c5f..07087ca68fe4b 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -62,8 +62,8 @@ install_linux_image () { ${MAKE} -f ${srctree}/Makefile INSTALL_DTBS_PATH="${pdir}/usr/lib/linux-image-${KERNELRELEASE}" dtbs_install fi
+ ${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${pdir}" modules_install if is_enabled CONFIG_MODULES; then - ${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${pdir}" modules_install rm -f "${pdir}/lib/modules/${KERNELRELEASE}/build" rm -f "${pdir}/lib/modules/${KERNELRELEASE}/source" if [ "${SRCARCH}" = um ] ; then
From: Masahiro Yamada masahiroy@kernel.org
[ Upstream commit 1240dabe8d58b4eff09e7edf1560da0360f997aa ]
When CONFIG_MODULES is disabled for ARCH=um, 'make (bin)deb-pkg' fails with an error like follows:
cp: cannot create regular file 'debian/linux-image/usr/lib/uml/modules/6.4.0-rc2+/System.map': No such file or directory
Remove the CONFIG_MODULES check completely so ${pdir}/usr/lib/uml/modules will always be created and modules.builtin.(modinfo) will be installed under it for ARCH=um.
Fixes: b611daae5efc ("kbuild: deb-pkg: split image and debug objects staging out into functions") Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/package/builddeb | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 07087ca68fe4b..a0af4c0f971ca 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -63,17 +63,13 @@ install_linux_image () { fi
${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${pdir}" modules_install - if is_enabled CONFIG_MODULES; then - rm -f "${pdir}/lib/modules/${KERNELRELEASE}/build" - rm -f "${pdir}/lib/modules/${KERNELRELEASE}/source" - if [ "${SRCARCH}" = um ] ; then - mkdir -p "${pdir}/usr/lib/uml/modules" - mv "${pdir}/lib/modules/${KERNELRELEASE}" "${pdir}/usr/lib/uml/modules/${KERNELRELEASE}" - fi - fi + rm -f "${pdir}/lib/modules/${KERNELRELEASE}/build" + rm -f "${pdir}/lib/modules/${KERNELRELEASE}/source"
# Install the kernel if [ "${ARCH}" = um ] ; then + mkdir -p "${pdir}/usr/lib/uml/modules" + mv "${pdir}/lib/modules/${KERNELRELEASE}" "${pdir}/usr/lib/uml/modules/${KERNELRELEASE}" mkdir -p "${pdir}/usr/bin" "${pdir}/usr/share/doc/${pname}" cp System.map "${pdir}/usr/lib/uml/modules/${KERNELRELEASE}/System.map" cp ${KCONFIG_CONFIG} "${pdir}/usr/share/doc/${pname}/config"
From: Ard Biesheuvel ardb@kernel.org
[ Upstream commit 2e28a798c3092ea42b968fa16ac835969d124898 ]
Currently, the EFI stub will disable PCI DMA as the very last thing it does before calling ExitBootServices(), to avoid interfering with the firmware's normal operation as much as possible.
However, the stub will invoke DisconnectController() on all endpoints downstream of the PCI bridges it disables, and this may affect the layout of the EFI memory map, making it substantially more likely that ExitBootServices() will fail the first time around, and that the EFI memory map needs to be reloaded.
This, in turn, increases the likelihood that the slack space we allocated is insufficient (and we can no longer allocate memory via boot services after having called ExitBootServices() once), causing the second call to GetMemoryMap (and therefore the boot) to fail. This makes the PCI DMA disable feature a bit more fragile than it already is, so let's make it more robust, by allocating the space for the EFI memory map after disabling PCI DMA.
Fixes: 4444f8541dad16fe ("efi: Allow disabling PCI busmastering on bridges during boot") Reported-by: Glenn Washburn development@efficientek.com Acked-by: Matthew Garrett mjg59@srcf.ucam.org Signed-off-by: Ard Biesheuvel ardb@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firmware/efi/libstub/efi-stub-helper.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index 1e0203d74691f..732984295295f 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -378,6 +378,9 @@ efi_status_t efi_exit_boot_services(void *handle, void *priv, struct efi_boot_memmap *map; efi_status_t status;
+ if (efi_disable_pci_dma) + efi_pci_disable_bridge_busmaster(); + status = efi_get_memory_map(&map, true); if (status != EFI_SUCCESS) return status; @@ -388,9 +391,6 @@ efi_status_t efi_exit_boot_services(void *handle, void *priv, return status; }
- if (efi_disable_pci_dma) - efi_pci_disable_bridge_busmaster(); - status = efi_bs_call(exit_boot_services, handle, map->map_key);
if (status == EFI_INVALID_PARAMETER) {
From: Shyam Prasad N sprasad@microsoft.com
[ Upstream commit 33f736187d08f6bc822117629f263b97d3df4165 ]
In smb2_compound_op we have a possible use-after-free which can cause hard to debug problems later on.
This was revealed during stress testing with KASAN enabled kernel. Fixing it by moving the cfile free call to a few lines below, after the usage.
Fixes: 76894f3e2f71 ("cifs: improve symlink handling for smb2+") Reviewed-by: Paulo Alcantara (SUSE) pc@manguebit.com Signed-off-by: Shyam Prasad N sprasad@microsoft.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/cifs/smb2inode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c index 163a03298430d..7e3ac4cb4efa6 100644 --- a/fs/cifs/smb2inode.c +++ b/fs/cifs/smb2inode.c @@ -398,9 +398,6 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, rsp_iov);
finished: - if (cfile) - cifsFileInfo_put(cfile); - SMB2_open_free(&rqst[0]); if (rc == -EREMCHG) { pr_warn_once("server share %s deleted\n", tcon->tree_name); @@ -529,6 +526,9 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, break; }
+ if (cfile) + cifsFileInfo_put(cfile); + if (rc && err_iov && err_buftype) { memcpy(err_iov, rsp_iov, 3 * sizeof(*err_iov)); memcpy(err_buftype, resp_buftype, 3 * sizeof(*err_buftype));
From: Shyam Prasad N sprasad@microsoft.com
[ Upstream commit 326a8d04f147e2bf393f6f9cdb74126ee6900607 ]
All the server credits and in-flight info is protected by req_lock. Once the req_lock is held, and we've determined that we have enough credits to continue, this lock cannot be dropped till we've made the changes to credits and in-flight count.
However, we used to drop the lock in order to avoid deadlock with the recent srv_lock. This could cause the checks already made to be invalidated.
Fixed it by moving the server status check to before locking req_lock.
Fixes: d7d7a66aacd6 ("cifs: avoid use of global locks for high contention data") Signed-off-by: Shyam Prasad N sprasad@microsoft.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/cifs/smb2ops.c | 19 ++++++++++--------- fs/cifs/transport.c | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 19 deletions(-)
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 5065398665f11..bb41b9bae262d 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -208,6 +208,16 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
spin_lock(&server->req_lock); while (1) { + spin_unlock(&server->req_lock); + + spin_lock(&server->srv_lock); + if (server->tcpStatus == CifsExiting) { + spin_unlock(&server->srv_lock); + return -ENOENT; + } + spin_unlock(&server->srv_lock); + + spin_lock(&server->req_lock); if (server->credits <= 0) { spin_unlock(&server->req_lock); cifs_num_waiters_inc(server); @@ -218,15 +228,6 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size, return rc; spin_lock(&server->req_lock); } else { - spin_unlock(&server->req_lock); - spin_lock(&server->srv_lock); - if (server->tcpStatus == CifsExiting) { - spin_unlock(&server->srv_lock); - return -ENOENT; - } - spin_unlock(&server->srv_lock); - - spin_lock(&server->req_lock); scredits = server->credits; /* can deadlock with reopen */ if (scredits <= 8) { diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 24bdd5f4d3bcc..968bfd029b8eb 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -522,6 +522,16 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits, }
while (1) { + spin_unlock(&server->req_lock); + + spin_lock(&server->srv_lock); + if (server->tcpStatus == CifsExiting) { + spin_unlock(&server->srv_lock); + return -ENOENT; + } + spin_unlock(&server->srv_lock); + + spin_lock(&server->req_lock); if (*credits < num_credits) { scredits = *credits; spin_unlock(&server->req_lock); @@ -547,15 +557,6 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits, return -ERESTARTSYS; spin_lock(&server->req_lock); } else { - spin_unlock(&server->req_lock); - - spin_lock(&server->srv_lock); - if (server->tcpStatus == CifsExiting) { - spin_unlock(&server->srv_lock); - return -ENOENT; - } - spin_unlock(&server->srv_lock); - /* * For normal commands, reserve the last MAX_COMPOUND * credits to compound requests. @@ -569,7 +570,6 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits, * for servers that are slow to hand out credits on * new sessions. */ - spin_lock(&server->req_lock); if (!optype && num_credits == 1 && server->in_flight > 2 * MAX_COMPOUND && *credits <= MAX_COMPOUND) {
From: Paulo Alcantara pc@manguebit.com
[ Upstream commit d439b29057e26464120fc6c18f97433aa003b5fe ]
*_get_inode_info() functions expect -EREMOTE when query path info calls find a DFS link, regardless whether !CONFIG_CIFS_DFS_UPCALL or 'nodfs' mount option. Otherwise, those files will miss the fake DFS file attributes.
Before patch
$ mount.cifs //srv/dfs /mnt/1 -o ...,nodfs $ ls -l /mnt/1 ls: cannot access '/mnt/1/link': Operation not supported total 0 -rwxr-xr-x 1 root root 0 Jul 26 2022 dfstest2_file1.txt drwxr-xr-x 2 root root 0 Aug 8 2022 dir1 d????????? ? ? ? ? ? link
After patch
$ mount.cifs //srv/dfs /mnt/1 -o ...,nodfs $ ls -l /mnt/1 total 0 -rwxr-xr-x 1 root root 0 Jul 26 2022 dfstest2_file1.txt drwxr-xr-x 2 root root 0 Aug 8 2022 dir1 drwx--x--x 2 root root 0 Jun 26 20:29 link
Fixes: c877ce47e137 ("cifs: reduce roundtrips on create/qinfo requests") Signed-off-by: Paulo Alcantara (SUSE) pc@manguebit.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/cifs/smb2inode.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c index 7e3ac4cb4efa6..8e696fbd72fa8 100644 --- a/fs/cifs/smb2inode.c +++ b/fs/cifs/smb2inode.c @@ -609,9 +609,6 @@ int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, if (islink) rc = -EREMOTE; } - if (rc == -EREMOTE && IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) && cifs_sb && - (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS)) - rc = -EOPNOTSUPP; }
out:
From: Paulo Alcantara pc@manguebit.com
[ Upstream commit 3ae872de410751fe5e629e04da491a632d95201c ]
When having two DFS root mounts that are connected to same namespace, same mount options but different prefix paths, we can't really use the shared @server->origin_fullpath when chasing DFS links in them.
Move the origin_fullpath field to cifs_tcon structure so when having shared DFS root mounts with different prefix paths, and we need to chase any DFS links, dfs_get_automount_devname() will pick up the correct full path out of the @tcon that will be used for the new mount.
Before patch
mount.cifs //dom/dfs/dir /mnt/1 -o ... mount.cifs //dom/dfs /mnt/2 -o ... # shared server, ses, tcon # server: origin_fullpath=//dom/dfs/dir
# @server->origin_fullpath + '/dir/link1' $ ls /mnt/2/dir/link1 ls: cannot open directory '/mnt/2/dir/link1': No such file or directory
After patch
mount.cifs //dom/dfs/dir /mnt/1 -o ... mount.cifs //dom/dfs /mnt/2 -o ... # shared server & ses # tcon_1: origin_fullpath=//dom/dfs/dir # tcon_2: origin_fullpath=//dom/dfs
# @tcon_2->origin_fullpath + '/dir/link1' $ ls /mnt/2/dir/link1 dir0 dir1 dir10 dir3 dir5 dir6 dir7 dir9 target2_file.txt tsub
Fixes: 8e3554150d6c ("cifs: fix sharing of DFS connections") Signed-off-by: Paulo Alcantara (SUSE) pc@manguebit.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/cifs/cifs_debug.c | 16 +++++----- fs/cifs/cifsglob.h | 10 +++---- fs/cifs/cifsproto.h | 2 +- fs/cifs/connect.c | 70 +++++++++++++++++++++++++------------------- fs/cifs/dfs.c | 55 +++++++++++++--------------------- fs/cifs/dfs.h | 19 ++++++------ fs/cifs/dfs_cache.c | 8 +++-- fs/cifs/misc.c | 38 ++++++++++++++++++------ 8 files changed, 118 insertions(+), 100 deletions(-)
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index d4ed200a94714..7e0667bdfba07 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -121,6 +121,12 @@ static void cifs_debug_tcon(struct seq_file *m, struct cifs_tcon *tcon) seq_puts(m, " nosparse"); if (tcon->need_reconnect) seq_puts(m, "\tDISCONNECTED "); + spin_lock(&tcon->tc_lock); + if (tcon->origin_fullpath) { + seq_printf(m, "\n\tDFS origin fullpath: %s", + tcon->origin_fullpath); + } + spin_unlock(&tcon->tc_lock); seq_putc(m, '\n'); }
@@ -377,13 +383,9 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) seq_printf(m, "\nIn Send: %d In MaxReq Wait: %d", atomic_read(&server->in_send), atomic_read(&server->num_waiters)); - if (IS_ENABLED(CONFIG_CIFS_DFS_UPCALL)) { - if (server->origin_fullpath) - seq_printf(m, "\nDFS origin full path: %s", - server->origin_fullpath); - if (server->leaf_fullpath) - seq_printf(m, "\nDFS leaf full path: %s", - server->leaf_fullpath); + if (server->leaf_fullpath) { + seq_printf(m, "\nDFS leaf full path: %s", + server->leaf_fullpath); }
seq_printf(m, "\n\n\tSessions: "); diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 5f8fd20951af3..56d440772e029 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -736,23 +736,20 @@ struct TCP_Server_Info { #endif struct mutex refpath_lock; /* protects leaf_fullpath */ /* - * origin_fullpath: Canonical copy of smb3_fs_context::source. - * It is used for matching existing DFS tcons. - * * leaf_fullpath: Canonical DFS referral path related to this * connection. * It is used in DFS cache refresher, reconnect and may * change due to nested DFS links. * - * Both protected by @refpath_lock and @srv_lock. The @refpath_lock is - * mosly used for not requiring a copy of @leaf_fullpath when getting + * Protected by @refpath_lock and @srv_lock. The @refpath_lock is + * mostly used for not requiring a copy of @leaf_fullpath when getting * cached or new DFS referrals (which might also sleep during I/O). * While @srv_lock is held for making string and NULL comparions against * both fields as in mount(2) and cache refresh. * * format: \HOST\SHARE[\OPTIONAL PATH] */ - char *origin_fullpath, *leaf_fullpath; + char *leaf_fullpath; };
static inline bool is_smb1(struct TCP_Server_Info *server) @@ -1242,6 +1239,7 @@ struct cifs_tcon { struct delayed_work dfs_cache_work; #endif struct delayed_work query_interfaces; /* query interfaces workqueue job */ + char *origin_fullpath; /* canonical copy of smb3_fs_context::source */ };
/* diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index c1c704990b986..16eac67fd48ac 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -649,7 +649,7 @@ int smb2_parse_query_directory(struct cifs_tcon *tcon, struct kvec *rsp_iov, int resp_buftype, struct cifs_search_info *srch_inf);
-struct super_block *cifs_get_tcp_super(struct TCP_Server_Info *server); +struct super_block *cifs_get_dfs_tcon_super(struct cifs_tcon *tcon); void cifs_put_tcp_super(struct super_block *sb); int cifs_update_super_prepath(struct cifs_sb_info *cifs_sb, char *prefix); char *extract_hostname(const char *unc); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 1250d156619b7..f0189afd940cf 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -996,7 +996,6 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server) */ }
- kfree(server->origin_fullpath); kfree(server->leaf_fullpath); kfree(server);
@@ -1386,7 +1385,9 @@ match_security(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) }
/* this function must be called with srv_lock held */ -static int match_server(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) +static int match_server(struct TCP_Server_Info *server, + struct smb3_fs_context *ctx, + bool match_super) { struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr;
@@ -1417,36 +1418,38 @@ static int match_server(struct TCP_Server_Info *server, struct smb3_fs_context * (struct sockaddr *)&server->srcaddr)) return 0; /* - * - Match for an DFS tcon (@server->origin_fullpath). - * - Match for an DFS root server connection (@server->leaf_fullpath). - * - If none of the above and @ctx->leaf_fullpath is set, then - * it is a new DFS connection. - * - If 'nodfs' mount option was passed, then match only connections - * that have no DFS referrals set - * (e.g. can't failover to other targets). + * When matching cifs.ko superblocks (@match_super == true), we can't + * really match either @server->leaf_fullpath or @server->dstaddr + * directly since this @server might belong to a completely different + * server -- in case of domain-based DFS referrals or DFS links -- as + * provided earlier by mount(2) through 'source' and 'ip' options. + * + * Otherwise, match the DFS referral in @server->leaf_fullpath or the + * destination address in @server->dstaddr. + * + * When using 'nodfs' mount option, we avoid sharing it with DFS + * connections as they might failover. */ - if (!ctx->nodfs) { - if (ctx->source && server->origin_fullpath) { - if (!dfs_src_pathname_equal(ctx->source, - server->origin_fullpath)) + if (!match_super) { + if (!ctx->nodfs) { + if (server->leaf_fullpath) { + if (!ctx->leaf_fullpath || + strcasecmp(server->leaf_fullpath, + ctx->leaf_fullpath)) + return 0; + } else if (ctx->leaf_fullpath) { return 0; + } } else if (server->leaf_fullpath) { - if (!ctx->leaf_fullpath || - strcasecmp(server->leaf_fullpath, - ctx->leaf_fullpath)) - return 0; - } else if (ctx->leaf_fullpath) { return 0; } - } else if (server->origin_fullpath || server->leaf_fullpath) { - return 0; }
/* * Match for a regular connection (address/hostname/port) which has no * DFS referrals set. */ - if (!server->origin_fullpath && !server->leaf_fullpath && + if (!server->leaf_fullpath && (strcasecmp(server->hostname, ctx->server_hostname) || !match_server_address(server, addr) || !match_port(server, addr))) @@ -1482,7 +1485,8 @@ cifs_find_tcp_session(struct smb3_fs_context *ctx) * Skip ses channels since they're only handled in lower layers * (e.g. cifs_send_recv). */ - if (CIFS_SERVER_IS_CHAN(server) || !match_server(server, ctx)) { + if (CIFS_SERVER_IS_CHAN(server) || + !match_server(server, ctx, false)) { spin_unlock(&server->srv_lock); continue; } @@ -2270,10 +2274,16 @@ static int match_tcon(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
if (tcon->status == TID_EXITING) return 0; - /* Skip UNC validation when matching DFS connections or superblocks */ - if (!server->origin_fullpath && !server->leaf_fullpath && - strncmp(tcon->tree_name, ctx->UNC, MAX_TREE_SIZE)) + + if (tcon->origin_fullpath) { + if (!ctx->source || + !dfs_src_pathname_equal(ctx->source, + tcon->origin_fullpath)) + return 0; + } else if (!server->leaf_fullpath && + strncmp(tcon->tree_name, ctx->UNC, MAX_TREE_SIZE)) { return 0; + } if (tcon->seal != ctx->seal) return 0; if (tcon->snapshot_time != ctx->snapshot_time) @@ -2672,7 +2682,7 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data) }
static int match_prepath(struct super_block *sb, - struct TCP_Server_Info *server, + struct cifs_tcon *tcon, struct cifs_mnt_data *mnt_data) { struct smb3_fs_context *ctx = mnt_data->ctx; @@ -2683,8 +2693,8 @@ static int match_prepath(struct super_block *sb, bool new_set = (new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) && new->prepath;
- if (server->origin_fullpath && - dfs_src_pathname_equal(server->origin_fullpath, ctx->source)) + if (tcon->origin_fullpath && + dfs_src_pathname_equal(tcon->origin_fullpath, ctx->source)) return 1;
if (old_set && new_set && !strcmp(new->prepath, old->prepath)) @@ -2732,10 +2742,10 @@ cifs_match_super(struct super_block *sb, void *data) spin_lock(&ses->ses_lock); spin_lock(&ses->chan_lock); spin_lock(&tcon->tc_lock); - if (!match_server(tcp_srv, ctx) || + if (!match_server(tcp_srv, ctx, true) || !match_session(ses, ctx) || !match_tcon(tcon, ctx) || - !match_prepath(sb, tcp_srv, mnt_data)) { + !match_prepath(sb, tcon, mnt_data)) { rc = 0; goto out; } diff --git a/fs/cifs/dfs.c b/fs/cifs/dfs.c index 2390b2fedd6a3..267536a7531df 100644 --- a/fs/cifs/dfs.c +++ b/fs/cifs/dfs.c @@ -249,14 +249,12 @@ static int __dfs_mount_share(struct cifs_mount_ctx *mnt_ctx) server = mnt_ctx->server; tcon = mnt_ctx->tcon;
- mutex_lock(&server->refpath_lock); - spin_lock(&server->srv_lock); - if (!server->origin_fullpath) { - server->origin_fullpath = origin_fullpath; + spin_lock(&tcon->tc_lock); + if (!tcon->origin_fullpath) { + tcon->origin_fullpath = origin_fullpath; origin_fullpath = NULL; } - spin_unlock(&server->srv_lock); - mutex_unlock(&server->refpath_lock); + spin_unlock(&tcon->tc_lock);
if (list_empty(&tcon->dfs_ses_list)) { list_replace_init(&mnt_ctx->dfs_ses_list, @@ -279,18 +277,13 @@ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs) { struct smb3_fs_context *ctx = mnt_ctx->fs_ctx; struct cifs_ses *ses; - char *source = ctx->source; bool nodfs = ctx->nodfs; int rc;
*isdfs = false; - /* Temporarily set @ctx->source to NULL as we're not matching DFS - * superblocks yet. See cifs_match_super() and match_server(). - */ - ctx->source = NULL; rc = get_session(mnt_ctx, NULL); if (rc) - goto out; + return rc;
ctx->dfs_root_ses = mnt_ctx->ses; /* @@ -304,7 +297,7 @@ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs) rc = dfs_get_referral(mnt_ctx, ctx->UNC + 1, NULL, NULL); if (rc) { if (rc != -ENOENT && rc != -EOPNOTSUPP && rc != -EIO) - goto out; + return rc; nodfs = true; } } @@ -312,7 +305,7 @@ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs) rc = cifs_mount_get_tcon(mnt_ctx); if (!rc) rc = cifs_is_path_remote(mnt_ctx); - goto out; + return rc; }
*isdfs = true; @@ -328,12 +321,7 @@ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs) rc = __dfs_mount_share(mnt_ctx); if (ses == ctx->dfs_root_ses) cifs_put_smb_ses(ses); -out: - /* - * Restore previous value of @ctx->source so DFS superblock can be - * matched in cifs_match_super(). - */ - ctx->source = source; + return rc; }
@@ -567,11 +555,11 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru int rc; struct TCP_Server_Info *server = tcon->ses->server; const struct smb_version_operations *ops = server->ops; - struct super_block *sb = NULL; - struct cifs_sb_info *cifs_sb; struct dfs_cache_tgt_list tl = DFS_CACHE_TGT_LIST_INIT(tl); - char *tree; + struct cifs_sb_info *cifs_sb = NULL; + struct super_block *sb = NULL; struct dfs_info3_param ref = {0}; + char *tree;
/* only send once per connect */ spin_lock(&tcon->tc_lock); @@ -603,19 +591,18 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru goto out; }
- sb = cifs_get_tcp_super(server); - if (IS_ERR(sb)) { - rc = PTR_ERR(sb); - cifs_dbg(VFS, "%s: could not find superblock: %d\n", __func__, rc); - goto out; - } - - cifs_sb = CIFS_SB(sb); + sb = cifs_get_dfs_tcon_super(tcon); + if (!IS_ERR(sb)) + cifs_sb = CIFS_SB(sb);
- /* If it is not dfs or there was no cached dfs referral, then reconnect to same share */ - if (!server->leaf_fullpath || + /* + * Tree connect to last share in @tcon->tree_name whether dfs super or + * cached dfs referral was not found. + */ + if (!cifs_sb || !server->leaf_fullpath || dfs_cache_noreq_find(server->leaf_fullpath + 1, &ref, &tl)) { - rc = ops->tree_connect(xid, tcon->ses, tcon->tree_name, tcon, cifs_sb->local_nls); + rc = ops->tree_connect(xid, tcon->ses, tcon->tree_name, tcon, + cifs_sb ? cifs_sb->local_nls : nlsc); goto out; }
diff --git a/fs/cifs/dfs.h b/fs/cifs/dfs.h index 1c90df5ecfbda..98e9d2aca6a7a 100644 --- a/fs/cifs/dfs.h +++ b/fs/cifs/dfs.h @@ -39,16 +39,15 @@ static inline char *dfs_get_automount_devname(struct dentry *dentry, void *page) { struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); - struct TCP_Server_Info *server = tcon->ses->server; size_t len; char *s;
- spin_lock(&server->srv_lock); - if (unlikely(!server->origin_fullpath)) { - spin_unlock(&server->srv_lock); + spin_lock(&tcon->tc_lock); + if (unlikely(!tcon->origin_fullpath)) { + spin_unlock(&tcon->tc_lock); return ERR_PTR(-EREMOTE); } - spin_unlock(&server->srv_lock); + spin_unlock(&tcon->tc_lock);
s = dentry_path_raw(dentry, page, PATH_MAX); if (IS_ERR(s)) @@ -57,16 +56,16 @@ static inline char *dfs_get_automount_devname(struct dentry *dentry, void *page) if (!s[1]) s++;
- spin_lock(&server->srv_lock); - len = strlen(server->origin_fullpath); + spin_lock(&tcon->tc_lock); + len = strlen(tcon->origin_fullpath); if (s < (char *)page + len) { - spin_unlock(&server->srv_lock); + spin_unlock(&tcon->tc_lock); return ERR_PTR(-ENAMETOOLONG); }
s -= len; - memcpy(s, server->origin_fullpath, len); - spin_unlock(&server->srv_lock); + memcpy(s, tcon->origin_fullpath, len); + spin_unlock(&tcon->tc_lock); convert_delimiter(s, '/');
return s; diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c index 1513b2709889b..33adf43a01f1d 100644 --- a/fs/cifs/dfs_cache.c +++ b/fs/cifs/dfs_cache.c @@ -1248,18 +1248,20 @@ static int refresh_tcon(struct cifs_tcon *tcon, bool force_refresh) int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb) { struct cifs_tcon *tcon; - struct TCP_Server_Info *server;
if (!cifs_sb || !cifs_sb->master_tlink) return -EINVAL;
tcon = cifs_sb_master_tcon(cifs_sb); - server = tcon->ses->server;
- if (!server->origin_fullpath) { + spin_lock(&tcon->tc_lock); + if (!tcon->origin_fullpath) { + spin_unlock(&tcon->tc_lock); cifs_dbg(FYI, "%s: not a dfs mount\n", __func__); return 0; } + spin_unlock(&tcon->tc_lock); + /* * After reconnecting to a different server, unique ids won't match anymore, so we disable * serverino. This prevents dentry revalidation to think the dentry are stale (ESTALE). diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index cd914be905b24..b0dedc26643b6 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -156,6 +156,7 @@ tconInfoFree(struct cifs_tcon *tcon) #ifdef CONFIG_CIFS_DFS_UPCALL dfs_put_root_smb_sessions(&tcon->dfs_ses_list); #endif + kfree(tcon->origin_fullpath); kfree(tcon); }
@@ -1106,20 +1107,25 @@ struct super_cb_data { struct super_block *sb; };
-static void tcp_super_cb(struct super_block *sb, void *arg) +static void tcon_super_cb(struct super_block *sb, void *arg) { struct super_cb_data *sd = arg; - struct TCP_Server_Info *server = sd->data; struct cifs_sb_info *cifs_sb; - struct cifs_tcon *tcon; + struct cifs_tcon *t1 = sd->data, *t2;
if (sd->sb) return;
cifs_sb = CIFS_SB(sb); - tcon = cifs_sb_master_tcon(cifs_sb); - if (tcon->ses->server == server) + t2 = cifs_sb_master_tcon(cifs_sb); + + spin_lock(&t2->tc_lock); + if (t1->ses == t2->ses && + t1->ses->server == t2->ses->server && + t2->origin_fullpath && + dfs_src_pathname_equal(t2->origin_fullpath, t1->origin_fullpath)) sd->sb = sb; + spin_unlock(&t2->tc_lock); }
static struct super_block *__cifs_get_super(void (*f)(struct super_block *, void *), @@ -1145,6 +1151,7 @@ static struct super_block *__cifs_get_super(void (*f)(struct super_block *, void return sd.sb; } } + pr_warn_once("%s: could not find dfs superblock\n", __func__); return ERR_PTR(-EINVAL); }
@@ -1154,9 +1161,15 @@ static void __cifs_put_super(struct super_block *sb) cifs_sb_deactive(sb); }
-struct super_block *cifs_get_tcp_super(struct TCP_Server_Info *server) +struct super_block *cifs_get_dfs_tcon_super(struct cifs_tcon *tcon) { - return __cifs_get_super(tcp_super_cb, server); + spin_lock(&tcon->tc_lock); + if (!tcon->origin_fullpath) { + spin_unlock(&tcon->tc_lock); + return ERR_PTR(-ENOENT); + } + spin_unlock(&tcon->tc_lock); + return __cifs_get_super(tcon_super_cb, tcon); }
void cifs_put_tcp_super(struct super_block *sb) @@ -1238,9 +1251,16 @@ int cifs_inval_name_dfs_link_error(const unsigned int xid, */ if (strlen(full_path) < 2 || !cifs_sb || (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS) || - !is_tcon_dfs(tcon) || !ses->server->origin_fullpath) + !is_tcon_dfs(tcon)) return 0;
+ spin_lock(&tcon->tc_lock); + if (!tcon->origin_fullpath) { + spin_unlock(&tcon->tc_lock); + return 0; + } + spin_unlock(&tcon->tc_lock); + /* * Slow path - tcon is DFS and @full_path has prefix path, so attempt * to get a referral to figure out whether it is an DFS link. @@ -1264,7 +1284,7 @@ int cifs_inval_name_dfs_link_error(const unsigned int xid,
/* * XXX: we are not using dfs_cache_find() here because we might - * end filling all the DFS cache and thus potentially + * end up filling all the DFS cache and thus potentially * removing cached DFS targets that the client would eventually * need during failover. */
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 9cedc58bdbe9fff9aacd0ca19ee5777659f28fd7 ]
clang warns about a possible field overflow in a memcpy:
In file included from fs/smb/server/smb_common.c:7: include/linux/fortify-string.h:583:4: error: call to '__write_overflow_field' declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror,-Wattribute-warning] __write_overflow_field(p_size_field, size);
It appears to interpret the "&out[baselen + 4]" as referring to a single byte of the character array, while the equivalen "out + baselen + 4" is seen as an offset into the array.
I don't see that kind of warning elsewhere, so just go with the simple rework.
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Signed-off-by: Arnd Bergmann arnd@arndb.de Acked-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ksmbd/smb_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ksmbd/smb_common.c b/fs/ksmbd/smb_common.c index 569e5eecdf3db..3e391a7d5a3ab 100644 --- a/fs/ksmbd/smb_common.c +++ b/fs/ksmbd/smb_common.c @@ -536,7 +536,7 @@ int ksmbd_extract_shortname(struct ksmbd_conn *conn, const char *longname, out[baselen + 3] = PERIOD;
if (dot_present) - memcpy(&out[baselen + 4], extension, 4); + memcpy(out + baselen + 4, extension, 4); else out[baselen + 4] = '\0'; smbConvertToUTF16((__le16 *)shortname, out, PATH_MAX,
From: Will Deacon will@kernel.org
[ Upstream commit 893b24181b4c4bf1fa2841b1ed192e5413a97cb1 ]
The FFR is a predicate register which can vary between 16 and 256 bits in size depending upon the configured vector length. When saving the SVE state in streaming SVE mode, the FFR register is inaccessible and so commit 9f5848665788 ("arm64/sve: Make access to FFR optional") simply clears the FFR field of the in-memory context structure. Unfortunately, it achieves this using an unconditional 8-byte store and so if the SME vector length is anything other than 64 bytes in size we will either fail to clear the entire field or, worse, we will corrupt memory immediately following the structure. This has led to intermittent kfence splats in CI [1] and can trigger kmalloc Redzone corruption messages when running the 'fp-stress' kselftest:
| ============================================================================= | BUG kmalloc-1k (Not tainted): kmalloc Redzone overwritten | ----------------------------------------------------------------------------- | | 0xffff000809bf1e22-0xffff000809bf1e27 @offset=7714. First byte 0x0 instead of 0xcc | Allocated in do_sme_acc+0x9c/0x220 age=2613 cpu=1 pid=531 | __kmalloc+0x8c/0xcc | do_sme_acc+0x9c/0x220 | ...
Replace the 8-byte store with a store of a predicate register which has been zero-initialised with PFALSE, ensuring that the entire field is cleared in memory.
[1] https://lore.kernel.org/r/CA+G9fYtU7HsV0R0dp4XEH5xXHSJFw8KyDf5VQrLLfMxWfxQka...
Cc: Mark Brown broonie@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Naresh Kamboju naresh.kamboju@linaro.org Fixes: 9f5848665788 ("arm64/sve: Make access to FFR optional") Reported-by: Linux Kernel Functional Testing lkft@linaro.org Signed-off-by: Will Deacon will@kernel.org Reviewed-by: Mark Brown broonie@kernel.org Tested-by: Anders Roxell anders.roxell@linaro.org Link: https://lore.kernel.org/r/20230628155605.22296-1-will@kernel.org Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/include/asm/fpsimdmacros.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h index cd03819a3b686..cdf6a35e39944 100644 --- a/arch/arm64/include/asm/fpsimdmacros.h +++ b/arch/arm64/include/asm/fpsimdmacros.h @@ -316,12 +316,12 @@ _for n, 0, 15, _sve_str_p \n, \nxbase, \n - 16 cbz \save_ffr, 921f _sve_rdffr 0 - _sve_str_p 0, \nxbase - _sve_ldr_p 0, \nxbase, -16 b 922f 921: - str xzr, [x\nxbase] // Zero out FFR + _sve_pfalse 0 // Zero out FFR 922: + _sve_str_p 0, \nxbase + _sve_ldr_p 0, \nxbase, -16 mrs x\nxtmp, fpsr str w\nxtmp, [\xpfpsr] mrs x\nxtmp, fpcr
From: Thomas Gleixner tglx@linutronix.de
[ Upstream commit 0303c9729afc4094ef53e552b7b8cff7436028d6 ]
Niklāvs reported a boot regression on an Alderlake machine and bisected it to commit 9df9d2f0471b ("init: Invoke arch_cpu_finalize_init() earlier").
By moving the invocation of arch_cpu_finalize_init() further down he identified that efi_enter_virtual_mode() is the function which causes the boot hang.
The main difference of the earlier invocation is that the boot CPU is already fully initialized and mitigations and alternatives are applied.
But the only really interesting change turned out to be IBT, which is now enabled before efi_enter_virtual_mode(). "ibt=off" on the kernel command line cured the problem.
Inspection of the involved calls in efi_enter_virtual_mode() unearthed that efi_set_virtual_address_map() is the only place in the kernel which invokes an EFI call without the IBT safe wrapper. This went obviously unnoticed so far as IBT was enabled later.
Use arch_efi_call_virt() instead of efi_call() to cure that.
Fixes: fe379fa4d199 ("x86/ibt: Disable IBT around firmware") Fixes: 9df9d2f0471b ("init: Invoke arch_cpu_finalize_init() earlier") Reported-by: Niklāvs Koļesņikovs pinkflames.linux@gmail.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Ard Biesheuvel ardb@kernel.org Link: https://bugzilla.kernel.org/show_bug.cgi?id=217602 Link: https://lore.kernel.org/r/87jzvm12q0.ffs@tglx Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/platform/efi/efi_64.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 232acf418cfbe..77f7ac3668cb4 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -853,9 +853,9 @@ efi_set_virtual_address_map(unsigned long memory_map_size,
/* Disable interrupts around EFI calls: */ local_irq_save(flags); - status = efi_call(efi.runtime->set_virtual_address_map, - memory_map_size, descriptor_size, - descriptor_version, virtual_map); + status = arch_efi_call_virt(efi.runtime, set_virtual_address_map, + memory_map_size, descriptor_size, + descriptor_version, virtual_map); local_irq_restore(flags);
efi_fpu_end();
From: Yu Kuai yukuai3@huawei.com
commit b5a99602b74bbfa655be509c615181dd95b0719e upstream.
Following build error triggered while build with clang version 17.0.0 with W=1(this can't be reporduced with gcc 13.1.0):
drivers/md/raid1-10.c:117:25: error: casting from randomized structure pointer type 'struct block_device *' to 'struct md_rdev *' 117 | struct md_rdev *rdev = (struct md_rdev *)bio->bi_bdev; | ^
Fix this by casting 'bio->bi_bdev' to 'void *', as it used to be.
Reported-by: kernel test robot lkp@intel.com Closes: https://lore.kernel.org/oe-kbuild-all/202306142042.fmjfmTF8-lkp@intel.com/ Fixes: 8295efbe68c0 ("md/raid1-10: factor out a helper to submit normal write") Signed-off-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230616012136.3047071-1-yukuai1@huaweicloud.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/raid1-10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/md/raid1-10.c +++ b/drivers/md/raid1-10.c @@ -113,7 +113,7 @@ static void md_bio_reset_resync_pages(st
static inline void raid1_submit_write(struct bio *bio) { - struct md_rdev *rdev = (struct md_rdev *)bio->bi_bdev; + struct md_rdev *rdev = (void *)bio->bi_bdev;
bio->bi_next = NULL; bio_set_dev(bio, rdev->bdev);
Hello!
On Sun, 9 Jul 2023 at 05:18, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
Note, this is the LAST release for the 6.3.y kernel series. After this is released, it will be end-of-life. Please move to the 6.4.y kernel series at this point in time, OR let us know what is preventing that from happening for you.
This is the start of the stable review cycle for the 6.3.13 release. There are 431 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue, 11 Jul 2023 11:14:03 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.3.13-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.3.y and the diffstat can be found below.
thanks,
greg k-h
There build regressions on Arm 32-bits, specifically omap1_defconfig:
-----8<----- /builds/linux/arch/arm/mach-omap1/irq.c: In function 'omap1_init_irq': /builds/linux/arch/arm/mach-omap1/irq.c:221:11: error: implicit declaration of function 'irq_domain_add_legacy' [-Werror=implicit-function-declaration] domain = irq_domain_add_legacy(NULL, nr_irqs, irq_base, 0, ^~~~~~~~~~~~~~~~~~~~~ /builds/linux/arch/arm/mach-omap1/irq.c:222:13: error: 'irq_domain_simple_ops' undeclared (first use in this function); did you mean 'irq_domain_chip_generic'? &irq_domain_simple_ops, NULL); ^~~~~~~~~~~~~~~~~~~~~ irq_domain_chip_generic /builds/linux/arch/arm/mach-omap1/irq.c:222:13: note: each undeclared identifier is reported only once for each function it appears in /builds/linux/arch/arm/mach-omap1/irq.c:250:23: error: implicit declaration of function 'irq_find_mapping'; did you mean 'iomem_get_mapping'? [-Werror=implicit-function-declaration] d = irq_get_irq_data(irq_find_mapping(domain, omap_l2_irq)); ^~~~~~~~~~~~~~~~ iomem_get_mapping cc1: some warnings being treated as errors make[3]: *** [/builds/linux/scripts/Makefile.build:252: arch/arm/mach-omap1/irq.o] Error 1 ----->8-----
Greetings!
Daniel Díaz daniel.diaz@linaro.org
On Sun, Jul 09, 2023 at 02:06:05PM -0600, Daniel Díaz wrote:
Hello!
On Sun, 9 Jul 2023 at 05:18, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
Note, this is the LAST release for the 6.3.y kernel series. After this is released, it will be end-of-life. Please move to the 6.4.y kernel series at this point in time, OR let us know what is preventing that from happening for you.
This is the start of the stable review cycle for the 6.3.13 release. There are 431 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue, 11 Jul 2023 11:14:03 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.3.13-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.3.y and the diffstat can be found below.
thanks,
greg k-h
There build regressions on Arm 32-bits, specifically omap1_defconfig:
-----8<----- /builds/linux/arch/arm/mach-omap1/irq.c: In function 'omap1_init_irq': /builds/linux/arch/arm/mach-omap1/irq.c:221:11: error: implicit declaration of function 'irq_domain_add_legacy' [-Werror=implicit-function-declaration] domain = irq_domain_add_legacy(NULL, nr_irqs, irq_base, 0, ^~~~~~~~~~~~~~~~~~~~~ /builds/linux/arch/arm/mach-omap1/irq.c:222:13: error: 'irq_domain_simple_ops' undeclared (first use in this function); did you mean 'irq_domain_chip_generic'? &irq_domain_simple_ops, NULL); ^~~~~~~~~~~~~~~~~~~~~ irq_domain_chip_generic /builds/linux/arch/arm/mach-omap1/irq.c:222:13: note: each undeclared identifier is reported only once for each function it appears in /builds/linux/arch/arm/mach-omap1/irq.c:250:23: error: implicit declaration of function 'irq_find_mapping'; did you mean 'iomem_get_mapping'? [-Werror=implicit-function-declaration] d = irq_get_irq_data(irq_find_mapping(domain, omap_l2_irq)); ^~~~~~~~~~~~~~~~ iomem_get_mapping cc1: some warnings being treated as errors make[3]: *** [/builds/linux/scripts/Makefile.build:252: arch/arm/mach-omap1/irq.o] Error 1 ----->8-----
Ick, sorry, let me go drop some patches and push out a -rc2.
thanks,
greg k-h
linux-stable-mirror@lists.linaro.org