I'm announcing the release of the 6.13.3 kernel.
All users of the 6.13 kernel series must upgrade.
The updated 6.13.y git tree can be found at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux-6.13.y and can be browsed at the normal kernel.org git web browser: https://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git%3Ba=summa...
thanks,
greg k-h
------------
Documentation/arch/arm64/elf_hwcaps.rst | 39 Documentation/driver-api/media/tx-rx.rst | 2 Documentation/gpu/drm-kms-helpers.rst | 3 Makefile | 2 arch/arm/boot/dts/ti/omap/dra7-l4.dtsi | 2 arch/arm/boot/dts/ti/omap/omap3-gta04.dtsi | 10 arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 5 arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts | 4 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 2 arch/arm64/boot/dts/nvidia/tegra234.dtsi | 6 arch/arm64/boot/dts/qcom/sdx75.dtsi | 2 arch/arm64/boot/dts/qcom/sm6115.dtsi | 8 arch/arm64/boot/dts/qcom/sm6350.dtsi | 6 arch/arm64/boot/dts/qcom/sm6375.dtsi | 10 arch/arm64/boot/dts/qcom/sm8350.dtsi | 492 +++++----- arch/arm64/boot/dts/qcom/sm8450.dtsi | 216 ++-- arch/arm64/boot/dts/qcom/sm8550.dtsi | 271 ++--- arch/arm64/boot/dts/qcom/sm8650.dtsi | 305 +++--- arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts | 4 arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dts | 4 arch/arm64/boot/dts/qcom/x1e80100-crd.dts | 6 arch/arm64/boot/dts/qcom/x1e80100-dell-xps13-9345.dts | 4 arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts | 6 arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus.dtsi | 4 arch/arm64/boot/dts/qcom/x1e80100-qcp.dts | 6 arch/arm64/boot/dts/qcom/x1e80100.dtsi | 280 ++--- arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 2 arch/arm64/include/asm/assembler.h | 5 arch/arm64/include/asm/pgtable-hwdef.h | 6 arch/arm64/include/asm/pgtable-prot.h | 7 arch/arm64/include/asm/sparsemem.h | 5 arch/arm64/kernel/cpufeature.c | 55 - arch/arm64/kernel/cpuinfo.c | 10 arch/arm64/kernel/pi/idreg-override.c | 9 arch/arm64/kernel/pi/map_kernel.c | 6 arch/arm64/kvm/arch_timer.c | 4 arch/arm64/kvm/arm.c | 8 arch/arm64/mm/hugetlbpage.c | 12 arch/arm64/mm/init.c | 7 arch/loongarch/include/uapi/asm/ptrace.h | 10 arch/loongarch/kernel/ptrace.c | 6 arch/m68k/include/asm/vga.h | 8 arch/mips/Kconfig | 1 arch/mips/kernel/ftrace.c | 2 arch/mips/loongson64/boardinfo.c | 2 arch/mips/math-emu/cp1emu.c | 2 arch/mips/pci/pci-legacy.c | 8 arch/parisc/Kconfig | 4 arch/powerpc/platforms/pseries/eeh_pseries.c | 6 arch/s390/include/asm/asm-extable.h | 4 arch/s390/include/asm/fpu-insn.h | 17 arch/s390/include/asm/futex.h | 2 arch/s390/include/asm/processor.h | 3 arch/s390/kernel/vmlinux.lds.S | 1 arch/s390/kvm/vsie.c | 25 arch/s390/mm/extable.c | 9 arch/s390/pci/pci_bus.c | 1 arch/x86/boot/compressed/Makefile | 1 arch/x86/include/asm/kexec.h | 18 arch/x86/include/asm/kvm_host.h | 2 arch/x86/kernel/acpi/boot.c | 50 - arch/x86/kernel/amd_nb.c | 4 arch/x86/kernel/machine_kexec_64.c | 45 arch/x86/kernel/process.c | 2 arch/x86/kernel/reboot.c | 2 arch/x86/kvm/lapic.c | 11 arch/x86/kvm/lapic.h | 1 arch/x86/kvm/mmu/mmu.c | 45 arch/x86/kvm/svm/sev.c | 2 arch/x86/kvm/vmx/nested.c | 5 arch/x86/kvm/vmx/vmx.c | 21 arch/x86/kvm/vmx/vmx.h | 1 arch/x86/kvm/x86.c | 7 arch/x86/mm/fault.c | 2 arch/x86/pci/fixup.c | 30 arch/x86/platform/efi/quirks.c | 5 arch/x86/xen/xen-head.S | 5 block/blk-cgroup.c | 1 block/blk-sysfs.c | 3 block/fops.c | 5 drivers/accel/ivpu/ivpu_drv.c | 8 drivers/accel/ivpu/ivpu_pm.c | 86 - drivers/acpi/apei/ghes.c | 10 drivers/acpi/prmt.c | 4 drivers/acpi/property.c | 10 drivers/ata/libata-sff.c | 18 drivers/bluetooth/btusb.c | 6 drivers/char/misc.c | 39 drivers/char/tpm/eventlog/acpi.c | 15 drivers/clk/clk-loongson2.c | 5 drivers/clk/mediatek/clk-mt2701-aud.c | 10 drivers/clk/mediatek/clk-mt2701-bdp.c | 1 drivers/clk/mediatek/clk-mt2701-img.c | 1 drivers/clk/mediatek/clk-mt2701-mm.c | 1 drivers/clk/mediatek/clk-mt2701-vdec.c | 1 drivers/clk/mmp/pwr-island.c | 2 drivers/clk/qcom/Kconfig | 1 drivers/clk/qcom/clk-alpha-pll.c | 2 drivers/clk/qcom/clk-rpmh.c | 2 drivers/clk/qcom/dispcc-sm6350.c | 7 drivers/clk/qcom/gcc-mdm9607.c | 2 drivers/clk/qcom/gcc-sm6350.c | 22 drivers/clk/qcom/gcc-sm8550.c | 8 drivers/clk/qcom/gcc-sm8650.c | 8 drivers/clk/sunxi-ng/ccu-sun50i-a100.c | 6 drivers/cpufreq/Kconfig | 2 drivers/cpufreq/cpufreq-dt-platdev.c | 2 drivers/cpufreq/s3c64xx-cpufreq.c | 11 drivers/crypto/qce/aead.c | 2 drivers/crypto/qce/core.c | 13 drivers/crypto/qce/sha.c | 2 drivers/crypto/qce/skcipher.c | 2 drivers/firmware/Kconfig | 2 drivers/firmware/efi/libstub/Makefile | 2 drivers/firmware/qcom/qcom_scm.c | 10 drivers/gpio/Kconfig | 1 drivers/gpio/gpio-pca953x.c | 19 drivers/gpio/gpio-sim.c | 13 drivers/gpu/drm/Kconfig | 4 drivers/gpu/drm/Makefile | 1 drivers/gpu/drm/amd/amdgpu/Kconfig | 1 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 8 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 2 drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 11 drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c | 8 drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c | 5 drivers/gpu/drm/amd/amdkfd/kfd_device.c | 25 drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 4 drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c | 25 drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 3 drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 7 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 20 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 6 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 22 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h | 3 drivers/gpu/drm/amd/display/dc/core/dc.c | 2 drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c | 3 drivers/gpu/drm/amd/display/dc/dml2/Makefile | 4 drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c | 35 drivers/gpu/drm/amd/display/dc/dml2/display_mode_core_structs.h | 6 drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c | 35 drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp.c | 7 drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c | 6 drivers/gpu/drm/amd/display/dc/hubbub/dcn30/dcn30_hubbub.c | 3 drivers/gpu/drm/amd/display/dc/hubbub/dcn31/dcn31_hubbub.c | 3 drivers/gpu/drm/amd/display/dc/hubbub/dcn32/dcn32_hubbub.c | 3 drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c | 3 drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c | 8 drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c | 2 drivers/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c | 2 drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c | 10 drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 3 drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c | 8 drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c | 1 drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c | 4 drivers/gpu/drm/ast/ast_dp.c | 2 drivers/gpu/drm/bridge/analogix/anx7625.c | 2 drivers/gpu/drm/bridge/ite-it6505.c | 83 - drivers/gpu/drm/bridge/ite-it66121.c | 2 drivers/gpu/drm/display/drm_dp_cec.c | 14 drivers/gpu/drm/drm_client_modeset.c | 9 drivers/gpu/drm/drm_connector.c | 1 drivers/gpu/drm/drm_edid.c | 6 drivers/gpu/drm/drm_fb_helper.c | 14 drivers/gpu/drm/drm_panel_backlight_quirks.c | 94 + drivers/gpu/drm/exynos/exynos_hdmi.c | 2 drivers/gpu/drm/i915/display/intel_dp.c | 10 drivers/gpu/drm/i915/display/intel_hdcp.c | 13 drivers/gpu/drm/i915/display/skl_universal_plane.c | 4 drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 6 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 20 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 13 drivers/gpu/drm/msm/dp/dp_audio.c | 2 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c | 16 drivers/gpu/drm/radeon/radeon_audio.c | 2 drivers/gpu/drm/rockchip/cdn-dp-core.c | 9 drivers/gpu/drm/sti/sti_hdmi.c | 2 drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 33 drivers/gpu/drm/vc4/vc4_hdmi.c | 4 drivers/gpu/drm/virtio/virtgpu_drv.h | 7 drivers/gpu/drm/virtio/virtgpu_plane.c | 58 - drivers/gpu/drm/xe/regs/xe_oa_regs.h | 6 drivers/gpu/drm/xe/xe_devcoredump.c | 40 drivers/gpu/drm/xe/xe_devcoredump.h | 2 drivers/gpu/drm/xe/xe_gt.c | 4 drivers/gpu/drm/xe/xe_gt_sriov_pf.c | 14 drivers/gpu/drm/xe/xe_gt_sriov_pf.h | 6 drivers/gpu/drm/xe/xe_guc_ct.c | 3 drivers/gpu/drm/xe/xe_guc_log.c | 4 drivers/gpu/drm/xe/xe_oa.c | 12 drivers/hid/hid-asus.c | 26 drivers/hid/hid-multitouch.c | 5 drivers/hid/hid-sensor-hub.c | 21 drivers/hid/wacom_wac.c | 5 drivers/i2c/i2c-core-acpi.c | 22 drivers/i3c/master.c | 2 drivers/iio/chemical/bme680_core.c | 4 drivers/iio/dac/ad3552r-common.c | 5 drivers/iio/dac/ad3552r-hs.c | 6 drivers/iio/dac/ad3552r.h | 8 drivers/iio/light/as73211.c | 24 drivers/infiniband/hw/mlx5/mr.c | 17 drivers/infiniband/hw/mlx5/odp.c | 2 drivers/input/misc/nxp-bbnsm-pwrkey.c | 8 drivers/input/mouse/synaptics.c | 56 - drivers/input/mouse/synaptics.h | 1 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 17 drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c | 8 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 1 drivers/iommu/intel/iommu.c | 7 drivers/iommu/iommufd/fault.c | 44 drivers/iommu/iommufd/iommufd_private.h | 29 drivers/irqchip/Kconfig | 1 drivers/irqchip/irq-apple-aic.c | 3 drivers/irqchip/irq-mvebu-icu.c | 3 drivers/leds/leds-lp8860.c | 2 drivers/mailbox/tegra-hsp.c | 6 drivers/mailbox/zynqmp-ipi-mailbox.c | 2 drivers/md/Kconfig | 13 drivers/md/Makefile | 2 drivers/md/dm-crypt.c | 27 drivers/md/md-autodetect.c | 8 drivers/md/md-linear.c | 352 +++++++ drivers/md/md.c | 2 drivers/media/i2c/ccs/ccs-core.c | 6 drivers/media/i2c/ccs/ccs-data.c | 14 drivers/media/i2c/ds90ub913.c | 1 drivers/media/i2c/ds90ub953.c | 1 drivers/media/i2c/ds90ub960.c | 123 +- drivers/media/i2c/imx296.c | 2 drivers/media/i2c/ov5640.c | 1 drivers/media/pci/intel/ipu6/ipu6-isys.c | 1 drivers/media/platform/marvell/mmp-driver.c | 21 drivers/media/platform/nuvoton/npcm-video.c | 4 drivers/media/platform/qcom/venus/core.c | 8 drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c | 2 drivers/media/usb/uvc/uvc_ctrl.c | 83 + drivers/media/usb/uvc/uvc_driver.c | 98 - drivers/media/usb/uvc/uvc_v4l2.c | 2 drivers/media/usb/uvc/uvc_video.c | 21 drivers/media/usb/uvc/uvcvideo.h | 10 drivers/media/v4l2-core/v4l2-mc.c | 2 drivers/mfd/axp20x.c | 2 drivers/mfd/lpc_ich.c | 3 drivers/misc/fastrpc.c | 8 drivers/mmc/core/sdio.c | 2 drivers/mmc/host/sdhci-esdhc-imx.c | 1 drivers/mmc/host/sdhci-msm.c | 53 + drivers/mtd/nand/onenand/onenand_base.c | 1 drivers/mtd/ubi/build.c | 2 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 4 drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 16 drivers/net/ethernet/broadcom/tg3.c | 58 + drivers/net/ethernet/intel/ice/devlink/devlink.c | 3 drivers/net/ethernet/intel/ice/ice_txrx.c | 150 ++- drivers/net/ethernet/intel/ice/ice_txrx.h | 1 drivers/net/ethernet/intel/ice/ice_txrx_lib.h | 43 drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c | 41 drivers/net/ethernet/marvell/octeon_ep/octep_main.c | 19 drivers/net/ethernet/marvell/octeon_ep/octep_main.h | 6 drivers/net/ethernet/marvell/octeon_ep/octep_rx.c | 11 drivers/net/ethernet/marvell/octeon_ep/octep_rx.h | 4 drivers/net/ethernet/marvell/octeon_ep/octep_tx.c | 7 drivers/net/ethernet/marvell/octeon_ep/octep_tx.h | 4 drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_ethtool.c | 29 drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c | 17 drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.h | 6 drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c | 9 drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.h | 2 drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_tx.c | 7 drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_tx.h | 2 drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c | 24 drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c | 17 drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.h | 2 drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c | 24 drivers/net/ethernet/ti/am65-cpsw-nuss.c | 67 - drivers/net/phy/nxp-c45-tja11xx.c | 2 drivers/net/tun.c | 2 drivers/net/usb/ipheth.c | 69 - drivers/net/vmxnet3/vmxnet3_xdp.c | 14 drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c | 5 drivers/net/wireless/ath/ath12k/mac.c | 57 - drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 5 drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c | 8 drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c | 3 drivers/net/wireless/intel/iwlwifi/Makefile | 2 drivers/net/wireless/intel/iwlwifi/cfg/dr.c | 167 +++ drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 13 drivers/net/wireless/intel/iwlwifi/iwl-config.h | 10 drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 16 drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c | 21 drivers/net/wireless/mediatek/mt76/mt7915/init.c | 4 drivers/net/wireless/mediatek/mt76/mt7921/usb.c | 3 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h | 4 drivers/net/wireless/realtek/rtw88/main.h | 4 drivers/net/wireless/realtek/rtw88/rtw8703b.c | 8 drivers/net/wireless/realtek/rtw88/rtw8723x.h | 8 drivers/net/wireless/realtek/rtw88/rtw8821c.h | 9 drivers/net/wireless/realtek/rtw88/rtw8822b.h | 9 drivers/net/wireless/realtek/rtw88/rtw8822c.h | 9 drivers/net/wireless/realtek/rtw88/sdio.c | 2 drivers/net/wireless/realtek/rtw89/pci.c | 16 drivers/net/wireless/realtek/rtw89/pci.h | 9 drivers/net/wireless/realtek/rtw89/pci_be.c | 1 drivers/net/wireless/realtek/rtw89/phy.c | 11 drivers/net/wireless/realtek/rtw89/phy.h | 2 drivers/net/wwan/iosm/iosm_ipc_pcie.c | 56 + drivers/nvme/host/core.c | 8 drivers/nvme/host/fc.c | 9 drivers/nvme/host/pci.c | 4 drivers/nvme/host/sysfs.c | 2 drivers/nvme/target/admin-cmd.c | 1 drivers/nvmem/core.c | 2 drivers/nvmem/imx-ocotp-ele.c | 38 drivers/nvmem/qcom-spmi-sdam.c | 1 drivers/of/address.c | 12 drivers/of/base.c | 8 drivers/of/of_reserved_mem.c | 9 drivers/pci/controller/dwc/pcie-designware-ep.c | 46 drivers/pci/endpoint/pci-epf-core.c | 1 drivers/pci/tph.c | 2 drivers/perf/fsl_imx9_ddr_perf.c | 33 drivers/pinctrl/renesas/pinctrl-rzg2l.c | 2 drivers/pinctrl/samsung/pinctrl-samsung.c | 2 drivers/platform/x86/acer-wmi.c | 45 drivers/platform/x86/intel/int3472/discrete.c | 3 drivers/platform/x86/intel/int3472/tps68470.c | 3 drivers/platform/x86/serdev_helpers.h | 4 drivers/ptp/ptp_clock.c | 8 drivers/pwm/pwm-microchip-core.c | 2 drivers/remoteproc/omap_remoteproc.c | 17 drivers/rtc/rtc-zynqmp.c | 4 drivers/scsi/qla2xxx/qla_def.h | 2 drivers/scsi/qla2xxx/qla_dfs.c | 124 ++ drivers/scsi/qla2xxx/qla_gbl.h | 3 drivers/scsi/qla2xxx/qla_init.c | 28 drivers/scsi/scsi_lib.c | 9 drivers/scsi/st.c | 6 drivers/scsi/st.h | 1 drivers/scsi/storvsc_drv.c | 1 drivers/soc/mediatek/mtk-devapc.c | 19 drivers/soc/qcom/llcc-qcom.c | 1 drivers/soc/qcom/smem_state.c | 3 drivers/soc/qcom/socinfo.c | 2 drivers/soc/samsung/exynos-pmu.c | 2 drivers/spi/atmel-quadspi.c | 118 +- drivers/tty/serial/sh-sci.c | 25 drivers/tty/serial/xilinx_uartps.c | 8 drivers/tty/vt/selection.c | 14 drivers/tty/vt/vt.c | 2 drivers/ufs/core/ufshcd.c | 31 drivers/ufs/host/ufs-qcom.c | 18 drivers/ufs/host/ufshcd-pci.c | 2 drivers/ufs/host/ufshcd-pltfrm.c | 28 drivers/usb/gadget/function/f_tcm.c | 54 - drivers/vfio/platform/vfio_platform_common.c | 10 fs/binfmt_flat.c | 2 fs/btrfs/ctree.c | 2 fs/btrfs/file.c | 2 fs/btrfs/ordered-data.c | 12 fs/btrfs/qgroup.c | 5 fs/btrfs/raid-stripe-tree.c | 26 fs/btrfs/relocation.c | 14 fs/btrfs/transaction.c | 4 fs/ceph/mds_client.c | 16 fs/exec.c | 29 fs/namespace.c | 50 - fs/netfs/read_collect.c | 21 fs/netfs/read_pgpriv2.c | 5 fs/nfs/Kconfig | 3 fs/nfs/flexfilelayout/flexfilelayout.c | 27 fs/nfsd/nfs4xdr.c | 20 fs/nilfs2/inode.c | 6 fs/ocfs2/super.c | 2 fs/ocfs2/symlink.c | 5 fs/pidfs.c | 34 fs/proc/array.c | 2 fs/smb/client/cifsglob.h | 14 fs/smb/client/dir.c | 6 fs/smb/client/smb1ops.c | 2 fs/smb/client/smb2inode.c | 108 +- fs/smb/client/smb2ops.c | 41 fs/smb/client/smb2pdu.c | 2 fs/smb/client/smb2proto.h | 2 fs/smb/server/transport_ipc.c | 9 fs/xfs/xfs_exchrange.c | 71 - fs/xfs/xfs_inode.c | 7 fs/xfs/xfs_iomap.c | 6 include/drm/drm_connector.h | 5 include/drm/drm_utils.h | 4 include/linux/binfmts.h | 4 include/linux/call_once.h | 45 include/linux/hrtimer_defs.h | 1 include/linux/jiffies.h | 2 include/linux/kvm_host.h | 9 include/linux/mlx5/driver.h | 1 include/linux/platform_data/x86/asus-wmi.h | 5 include/net/sch_generic.h | 2 include/rv/da_monitor.h | 4 include/trace/events/rxrpc.h | 1 include/uapi/drm/amdgpu_drm.h | 9 include/uapi/linux/input-event-codes.h | 1 include/uapi/linux/iommufd.h | 4 include/uapi/linux/raid/md_p.h | 2 include/uapi/linux/raid/md_u.h | 2 include/ufs/ufs.h | 4 include/ufs/ufshcd.h | 1 io_uring/net.c | 5 io_uring/poll.c | 4 kernel/bpf/verifier.c | 2 kernel/locking/test-ww_mutex.c | 9 kernel/printk/printk.c | 2 kernel/sched/core.c | 6 kernel/sched/fair.c | 19 kernel/seccomp.c | 12 kernel/time/hrtimer.c | 103 +- kernel/time/timer_migration.c | 10 kernel/trace/ring_buffer.c | 13 kernel/trace/trace_functions_graph.c | 2 kernel/trace/trace_osnoise.c | 17 lib/Kconfig.debug | 8 lib/atomic64.c | 78 - lib/maple_tree.c | 23 mm/compaction.c | 3 mm/gup.c | 14 mm/hugetlb.c | 24 mm/kfence/core.c | 2 mm/kmemleak.c | 2 mm/vmscan.c | 7 net/bluetooth/l2cap_sock.c | 7 net/bluetooth/mgmt.c | 12 net/ethtool/ioctl.c | 2 net/ethtool/rss.c | 3 net/ipv4/udp.c | 4 net/ipv6/udp.c | 4 net/ncsi/ncsi-manage.c | 13 net/nfc/nci/hci.c | 2 net/rose/af_rose.c | 24 net/rxrpc/ar-internal.h | 2 net/rxrpc/call_object.c | 6 net/rxrpc/conn_event.c | 21 net/rxrpc/conn_object.c | 1 net/rxrpc/input.c | 2 net/rxrpc/sendmsg.c | 2 net/sched/sch_fifo.c | 3 net/sched/sch_netem.c | 2 net/tipc/crypto.c | 4 rust/kernel/init.rs | 2 scripts/Makefile.extrawarn | 5 scripts/gdb/linux/cpus.py | 2 scripts/generate_rust_target.rs | 18 security/keys/trusted-keys/trusted_dcp.c | 22 security/safesetid/securityfs.c | 3 security/tomoyo/common.c | 2 sound/pci/hda/hda_auto_parser.c | 8 sound/pci/hda/hda_auto_parser.h | 1 sound/pci/hda/patch_realtek.c | 20 sound/soc/amd/Kconfig | 2 sound/soc/amd/yc/acp6x-mach.c | 28 sound/soc/intel/boards/sof_sdw.c | 5 sound/soc/renesas/rz-ssi.c | 10 sound/soc/soc-pcm.c | 32 sound/soc/sof/intel/hda-dai.c | 12 sound/soc/sof/intel/hda.c | 5 tools/perf/bench/epoll-wait.c | 7 tools/testing/selftests/bpf/progs/exceptions_fail.c | 4 tools/testing/selftests/bpf/progs/preempt_lock.c | 14 tools/testing/selftests/bpf/progs/verifier_spin_lock.c | 2 tools/testing/selftests/drivers/net/hw/rss_ctx.py | 2 tools/testing/selftests/net/ipsec.c | 3 tools/testing/selftests/net/mptcp/mptcp_connect.c | 2 tools/testing/selftests/net/udpgso.c | 26 tools/tracing/rtla/src/osnoise.c | 2 tools/tracing/rtla/src/timerlat_hist.c | 26 tools/tracing/rtla/src/timerlat_top.c | 27 tools/tracing/rtla/src/trace.c | 8 tools/tracing/rtla/src/trace.h | 1 478 files changed, 5311 insertions(+), 2635 deletions(-)
Abel Vesa (1): arm64: dts: qcom: x1e80100: Fix usb_2 controller interrupts
Abhinav Kumar (1): drm/msm/dpu: filter out too wide modes if no 3dmux is present
Alain Volmat (1): media: stm32: dcmipp: correct dma_set_mask_and_coherent mask value
Alex Williamson (1): vfio/platform: check the bounds of read/write syscalls
Alexander Sverdlin (1): leds: lp8860: Write full EEPROM, not only half of it
Alice Ryhl (1): x86: rust: set rustc-abi=x86-softfloat on rustc>=1.86.0
Anandu Krishnan E (1): misc: fastrpc: Deregister device nodes properly in error scenarios
Anastasia Belova (1): clk: qcom: clk-rpmh: prevent integer overflow in recalc_rate
Andre Przywara (1): Revert "mfd: axp20x: Allow multiple regulators"
Andreas Kemnade (2): cpufreq: fix using cpufreq-dt as module ARM: dts: ti/omap: gta04: fix pm issues caused by spi module
Andrew Halaney (1): Bluetooth: btusb: Add new VID/PID 13d3/3610 for MT7922
André Draszik (1): scsi: ufs: core: Fix use-after free in init error and remove paths
Andy Shevchenko (1): ACPI: property: Fix return value for nval == 0 in acpi_data_prop_read()
Angelo Dureghello (2): iio: dac: ad3552r-common: fix ad3541/2r ranges iio: dac: ad3552r-hs: clear reset status flag
Ankit Nautiyal (1): drm/i915/dp: fix the Adaptive sync Operation mode for SDP
Anshuman Khandual (1): arm64/mm: Ensure adequate HUGE_MAX_HSTATE
Antoine Viallon (1): ceph: fix memory leak in ceph_mds_auth_match()
Ard Biesheuvel (3): arm64/kvm: Configure HYP TCR.PS/DS based on host stage1 arm64/mm: Override PARange for !LPA2 and use it consistently arm64/mm: Reduce PA space to 48 bits when LPA2 is not enabled
Aric Cyr (1): drm/amd/display: Optimize cursor position updates
Armin Wolf (3): platform/x86: acer-wmi: Add support for Acer PH14-51 platform/x86: acer-wmi: Add support for Acer Predator PH16-72 platform/x86: acer-wmi: Ignore AC events
Ashutosh Dixit (1): drm/xe/oa: Preserve oa_ctrl unused bits
Aubrey Li (1): ACPI: PRM: Remove unnecessary strict handler address checks
Ausef Yousof (2): drm/amd/display: Populate chroma prefetch parameters, DET buffer fix drm/amd/display: Overwriting dualDPP UBF values before usage
Bao D. Nguyen (1): scsi: ufs: core: Fix the HIGH/LOW_TEMP Bit Definitions
Bard Liao (1): ASoC: SOF: Intel: hda-dai: Ensure DAI widget is valid during params
Bart Van Assche (1): md: Fix linear_set_limits()
Bartosz Golaszewski (3): gpio: sim: lock hog configfs items if present crypto: qce - fix goto jump in error path crypto: qce - unregister previously registered algos in error path
Bence Csókás (1): spi: atmel-qspi: Memory barriers after memory-mapped I/O
Binbin Zhou (1): clk: clk-loongson2: Fix the number count of clk provider
Bitterblue Smith (1): wifi: rtlwifi: rtl8821ae: Fix media status report
Borislav Petkov (1): APEI: GHES: Have GHES honor the panic= setting
Brad Griffis (1): arm64: tegra: Fix Tegra234 PCIe interrupt-map
Brian Geffon (1): drm/i915: Fix page cleanup on DMA remap failure
Carlos Llamas (1): lockdep: Fix upper limit for LOCKDEP_*_BITS configs
Catalin Marinas (1): mm: kmemleak: fix upper boundary check for physical address objects
Chao Gao (1): KVM: nVMX: Defer SVI update to vmcs01 on EOI when L2 is active w/o VID
Chen-Yu Tsai (2): arm64: dts: mediatek: mt8183: Disable DPI display output by default arm64: dts: mediatek: mt8183: Disable DSI display output by default
Chih-Kang Chang (1): wifi: rtw89: add crystal_cap check to avoid setting as overflow value
Christian Brauner (2): pidfs: check for valid ioctl commands pidfs: improve ioctl handling
Christoph Hellwig (1): xfs: don't call remap_verify_area with sb write protection held
Chuck Lever (1): NFSD: Encode COMPOUND operation status on page boundaries
Ciprian Marian Costea (1): mmc: sdhci-esdhc-imx: enable 'SDHCI_QUIRK_NO_LED' quirk for S32G
Claudiu Beznea (3): ASoC: renesas: rz-ssi: Terminate all the DMA transactions serial: sh-sci: Drop __initdata macro for port_cfg serial: sh-sci: Do not probe the serial port if its slot in sci_ports[] is in use
Cody Eksal (1): clk: sunxi-ng: a100: enable MMC clock reparenting
Cong Wang (1): netem: Update sch->q.qlen before qdisc_tree_reduce_backlog()
Conor Dooley (1): pwm: microchip-core: fix incorrect comparison with max period
Cosmin Tanislav (1): media: mc: fix endpoint iteration
Csókás, Bence (1): spi: atmel-quadspi: Create `atmel_qspi_ops` to support newer SoC families
Dan Carpenter (7): tipc: re-order conditions in tipc_crypto_key_rcv() binfmt_flat: Fix integer overflow bug on 32 bit systems ksmbd: fix integer overflows on 32 bit systems ASoC: renesas: rz-ssi: Add a check for negative sample_space iio: chemical: bme680: Fix uninitialized variable in __bme680_read_raw() NFC: nci: Add bounds checking in nci_hci_create_pipe() md/md-linear: Fix a NULL vs IS_ERR() bug in linear_add()
Daniel Golle (5): clk: mediatek: mt2701-vdec: fix conversion to mtk_clk_simple_probe clk: mediatek: mt2701-aud: fix conversion to mtk_clk_simple_probe clk: mediatek: mt2701-bdp: add missing dummy clk clk: mediatek: mt2701-img: add missing dummy clk clk: mediatek: mt2701-mm: add missing dummy clk
Daniel Wagner (2): nvme: handle connectivity loss in nvme_set_queue_count nvme-fc: use ctrl state getter
Daniele Ceraolo Spurio (1): drm/i915/guc: Debug print LRC state entries only if the context is pinned
Dave Young (1): x86/efi: skip memattr table on kexec boot
David Gstir (1): KEYS: trusted: dcp: fix improper sg use with CONFIG_VMAP_STACK=y
David Hildenbrand (1): KVM: s390: vsie: fix some corner-cases when grabbing vsie pages
David Howells (2): rxrpc: Fix the rxrpc_connection attend queue handling rxrpc: Fix call state set to not include the SERVER_SECURING state
David Woodhouse (1): x86/kexec: Allocate PGD for x86_64 transition page tables separately
Denis Arefev (1): ubi: Add a check for ubi_num
Dmitry Antipov (1): wifi: brcmsmac: add gain range check to wlc_phy_iqcal_gainparams_nphy()
Dmitry Baryshkov (13): drm/tests: hdmi: handle empty modes in find_preferred_mode() drm/tests: hdmi: return meaningful value from set_connector_edid() drm/connector: add mutex to protect ELD from concurrent access drm/bridge: anx7625: use eld_mutex to protect access to connector->eld drm/bridge: ite-it66121: use eld_mutex to protect access to connector->eld drm/amd/display: use eld_mutex to protect access to connector->eld drm/exynos: hdmi: use eld_mutex to protect access to connector->eld drm/msm/dp: use eld_mutex to protect access to connector->eld drm/radeon: use eld_mutex to protect access to connector->eld drm/sti: hdmi: use eld_mutex to protect access to connector->eld drm/vc4: hdmi: use eld_mutex to protect access to connector->eld arm64: dts: qcom: sm8550: correct MDSS interconnects arm64: dts: qcom: sm8650: correct MDSS interconnects
Dmitry Torokhov (1): Input: synaptics - fix crash when enabling pass-through port
Dongwon Kim (1): drm/virtio: New fence for every plane update
Dragan Simic (1): nfs: Make NFS_FSCACHE select NETFS_SUPPORT instead of depending on it
Dustin L. Howett (1): drm: panel-backlight-quirks: Add Framework 13 glossy and 2.8k panels
Easwar Hariharan (1): jiffies: Cast to unsigned long in secs_to_jiffies() conversion
Edson Juliano Drosdeck (1): ALSA: hda/realtek: Enable headset mic on Positivo C6400
Ekansh Gupta (2): misc: fastrpc: Fix registered buffer page address misc: fastrpc: Fix copy buffer page size
En-Wei Wu (1): Bluetooth: btusb: Add new VID/PID 13d3/3628 for MT7925
Eric Biggers (2): scsi: ufs: qcom: Fix crypto key eviction crypto: qce - fix priority to be less than ARMv8 CE
Eric Dumazet (1): net: rose: lock the socket in rose_bind()
Even Xu (1): HID: Wacom: Add PCI Wacom device support
Eyal Birger (1): seccomp: passthrough uretprobe systemcall without filtering
Fangzhi Zuo (1): drm/amd/display: Fix Mode Cutoff in DSC Passthrough to DP2.1 Monitor
Fedor Pchelkin (2): Bluetooth: L2CAP: handle NULL sock pointer in l2cap_sock_alloc Bluetooth: L2CAP: accept zero as a special value for MTU auto-selection
Filipe Manana (3): btrfs: fix lockdep splat while merging a relocation root btrfs: fix assertion failure when splitting ordered extent after transaction abort btrfs: fix use-after-free when attempting to join an aborted transaction
Fiona Klute (1): wifi: rtw88: sdio: Fix disconnection after beacon loss
Florian Fainelli (1): net: bcmgenet: Correct overlaying of PHY and MAC Wake-on-LAN
Foster Snowhill (7): usbnet: ipheth: fix possible overflow in DPE length check usbnet: ipheth: use static NDP16 location in URB usbnet: ipheth: check that DPE points past NCM header usbnet: ipheth: refactor NCM datagram loop usbnet: ipheth: break up NCM header size computation usbnet: ipheth: fix DPE OoB read usbnet: ipheth: document scope of NCM implementation
Frank Li (1): i3c: master: Fix missing 'ret' assignment in set_speed()
Frederic Weisbecker (2): hrtimers: Force migrate away hrtimers queued after CPUHP_AP_HRTIMERS_DYING timers/migration: Fix off-by-one root mis-connection
Gabe Teeger (1): drm/amd/display: Limit Scaling Ratio on DCN3.01
Gabor Juhos (1): clk: qcom: clk-alpha-pll: fix alpha mode configuration
Gabriele Monaco (1): rv: Reset per-task monitors also for idle tasks
Geert Uytterhoeven (2): irqchip/lan966x-oic: Make CONFIG_LAN966X_OIC depend on CONFIG_MCHP_LAN966X_PCI gpio: GPIO_GRGPIO should depend on OF
Georg Gottleuber (2): nvme-pci: Add TUXEDO InfinityFlex to Samsung sleep quirk nvme-pci: Add TUXEDO IBP Gen9 to Samsung sleep quirk
Greg Kroah-Hartman (1): Linux 6.13.3
Günther Noack (1): tty: Permit some TIOCL_SETSEL modes without CAP_SYS_ADMIN
Hans Verkuil (1): gpu: drm_dp_cec: fix broken CEC adapter properties check
Hans de Goede (3): mfd: lpc_ich: Add another Gemini Lake ISA bridge PCI device-id platform/x86: int3472: Check for adev == NULL platform/x86: serdev_helpers: Check for serial_ctrl_uid == NULL
Hao-ran Zheng (1): btrfs: fix data race when accessing the inode's disk_i_size at btrfs_drop_extents()
Haoxiang Li (1): drm/komeda: Add check for komeda_get_layer_fourcc_list()
Heiko Carstens (2): s390/futex: Fix FUTEX_OP_ANDN implementation s390/fpu: Add fpc exception handler / remove fixup section again
Heiko Stuebner (1): HID: hid-sensor-hub: don't use stale platform-data on remove
Helge Deller (1): parisc: Temporarily disable jump label support
Heming Zhao (1): ocfs2: fix incorrect CPU endianness conversion causing mount failure
Hermes Wu (5): drm/bridge: it6505: Change definition MAX_HDCP_DOWN_STREAM_COUNT drm/bridge: it6505: fix HDCP Bstatus check drm/bridge: it6505: fix HDCP encryption when R0 ready drm/bridge: it6505: fix HDCP CTS compare V matching drm/bridge: it6505: fix HDCP CTS KSV list wait timer
Hou Tao (2): dm-crypt: don't update io->sector after kcryptd_crypt_write_io_submit() dm-crypt: track tag_offset in convert_context
Hridesh MG (1): platform/x86: acer-wmi: add support for Acer Nitro AN515-58
Ido Schimmel (1): net: sched: Fix truncation of offloaded action statistics
Igor Pylypiv (1): scsi: core: Do not retry I/Os during depopulation
Illia Ostapyshyn (1): Input: allocate keycode for phone linking
Ivan Stepchenko (1): mtd: onenand: Fix uninitialized retlen in do_otp_read()
Jacek Lawrynowicz (4): accel/ivpu: Fix Qemu crash when running in passthrough accel/ivpu: Fix error handling in ivpu_boot() accel/ivpu: Clear runtime_error after pm_runtime_resume_and_get() fails accel/ivpu: Fix error handling in recovery/reset
Jacob Moroni (1): net: atlantic: fix warning during hot unplug
Jakob Unterwurzacher (1): arm64: dts: rockchip: increase gmac rx_delay on rk3399-puma
Jakub Kicinski (3): ethtool: rss: fix hiding unsupported fields in dumps ethtool: ntuple: fix rss + ring_cookie check selftests: drv-net: rss_ctx: add missing cleanup in queue reconfigure
Jan Kiszka (1): scripts/gdb: fix aarch64 userspace detection in get_current_task
Jani Nikula (1): drm/i915/dp: Iterate DSC BPP from high to low on all platforms
Jarkko Sakkinen (1): tpm: Change to kvalloc() in eventlog/acpi.c
Javier Carrasco (2): iio: light: as73211: fix channel handling in only-color triggered buffer pinctrl: samsung: fix fwnode refcount cleanup if platform_get_irq_optional() fails
Jay Cornwall (1): drm/amdkfd: Block per-queue reset when halt_if_hws_hang=1
Jeff Layton (1): fs: prepend statmount.mnt_opts string with security_sb_mnt_opts()
Jennifer Berringer (1): nvmem: core: improve range check for nvmem_cell_write()
Jens Axboe (2): block: don't revert iter for -EIOCBQUEUED io_uring/net: don't retry connect operation on EPOLLERR
Jeongjun Park (1): ring-buffer: Make reading page consistent with the code logic
Jiasheng Jiang (1): ice: Add check for devm_kzalloc()
Jiaxun Yang (1): MIPS: pci-legacy: Override pci_address_to_pio
Johannes Thumshirn (1): btrfs: don't use btrfs_set_item_key_safe on RAID stripe-extents
Josef Bacik (1): btrfs: convert BUG_ON in btrfs_reloc_cow_block() to proper error handling
Juergen Gross (2): x86/xen: fix xen_hypercall_hvm() to not clobber %rbx x86/xen: add FRAME_END to xen_hypercall_hvm()
K Prateek Nayak (1): sched/fair: Fix inaccurate h_nr_runnable accounting with delayed dequeue
Kai Mäkisara (1): scsi: st: Don't set pos_unknown just after device recognition
Kalle Valo (1): wifi: ath12k: ath12k_mac_op_set_key(): fix uninitialized symbol 'ret'
Karol Przybylski (1): wifi: ath12k: Fix for out-of bound access error
Kees Bakker (1): iommu/vt-d: Avoid use of NULL after WARN_ON_ONCE
Kees Cook (1): exec: fix up /proc/pid/comm in the execveat(AT_EMPTY_PATH) case
Keith Busch (2): nvme: make nvme_tls_attrs_group static kvm: defer huge page recovery vhost task to later
Kenneth Feng (1): drm/amd/amdgpu: change the config of cgcg on gfx12
Kexy Biscuit (1): MIPS: Loongson64: remove ROM Size unit in boardinfo
Konrad Dybcio (2): clk: qcom: Make GCC_8150 depend on QCOM_GDSC soc: qcom: llcc: Enable LLCC_WRCACHE at boot on X1
Krzysztof Kozlowski (29): firmware: qcom: scm: Fix missing read barrier in qcom_scm_is_available() firmware: qcom: scm: Fix missing read barrier in qcom_scm_get_tzmem_pool() arm64: dts: qcom: sdx75: Fix MPSS memory length arm64: dts: qcom: x1e80100: Fix ADSP memory base and length arm64: dts: qcom: x1e80100: Fix CDSP memory length arm64: dts: qcom: sm6115: Fix MPSS memory length arm64: dts: qcom: sm6115: Fix CDSP memory length arm64: dts: qcom: sm6115: Fix ADSP memory base and length arm64: dts: qcom: sm6350: Fix ADSP memory length arm64: dts: qcom: sm6350: Fix MPSS memory length arm64: dts: qcom: sm6375: Fix ADSP memory length arm64: dts: qcom: sm6375: Fix CDSP memory base and length arm64: dts: qcom: sm6375: Fix MPSS memory base and length arm64: dts: qcom: sm8350: Fix ADSP memory base and length arm64: dts: qcom: sm8350: Fix CDSP memory base and length arm64: dts: qcom: sm8350: Fix MPSS memory length arm64: dts: qcom: sm8450: Fix ADSP memory base and length arm64: dts: qcom: sm8450: Fix CDSP memory length arm64: dts: qcom: sm8450: Fix MPSS memory length arm64: dts: qcom: sm8550: Fix ADSP memory base and length arm64: dts: qcom: sm8550: Fix CDSP memory length arm64: dts: qcom: sm8550: Fix MPSS memory length arm64: dts: qcom: sm8650: Fix ADSP memory base and length arm64: dts: qcom: sm8650: Fix CDSP memory length arm64: dts: qcom: sm8650: Fix MPSS memory length soc: samsung: exynos-pmu: Fix uninitialized ret in tensor_set_bits_atomic() soc: mediatek: mtk-devapc: Fix leaking IO map on error paths soc: mediatek: mtk-devapc: Fix leaking IO map on driver remove soc: qcom: smem_state: fix missing of_node_put in error path
Kuan-Wei Chiu (3): printk: Fix signed integer overflow when defining LOG_BUF_LEN_MAX perf bench: Fix undefined behavior in cmpworker() ALSA: hda: Fix headset detection failure due to unstable sort
Kumar Kartikeya Dwivedi (1): bpf: Improve verifier log for resource leak on exit
Kuninori Morimoto (1): ASoC: soc-pcm: don't use soc_pcm_ret() on .prepare callback
Lad Prabhakar (1): pinctrl: renesas: rzg2l: Fix PFC_MASK for RZ/V2H and RZ/G3E
Lenny Szubowicz (1): tg3: Disable tg3 PCIe AER on system reboot
Leo Stone (1): safesetid: check size of policy writes
Li Zhijian (1): mm/vmscan: accumulate nr_demoted for accurate demotion statistics
Lijo Lazar (1): drm/amd/pm: Mark MM activity as unsupported
Liu Shixin (1): mm/compaction: fix UBSAN shift-out-of-bounds warning
Liu Ye (1): selftests/net/ipsec: Fix Null pointer dereference in rtattr_pack()
Lo-an Chen (1): drm/amd/display: Fix seamless boot sequence
Long Li (1): scsi: storvsc: Set correct data length for sending SCSI command without payload
Lubomir Rintel (2): clk: mmp2: call pm_genpd_init() only after genpd.name is set media: mmp: Bring back registration of the device
Luca Weiss (4): clk: qcom: gcc-sm6350: Add missing parent_map for two clocks clk: qcom: dispcc-sm6350: Add missing parent_map for a clock arm64: dts: qcom: sm6350: Fix uart1 interconnect path nvmem: qcom-spmi-sdam: Set size in struct nvmem_config
Lucas De Marchi (2): drm/xe/devcoredump: Move exec queue snapshot to Contexts section drm/xe: Fix and re-enable xe_print_blob_ascii85()
Luke D. Jones (1): HID: hid-asus: Disable OOBE mode on the ProArt P16
Maarten Lankhorst (2): drm/modeset: Handle tiled displays in pan_display_atomic. drm/client: Handle tiled displays better
Maciej Fijalkowski (3): ice: put Rx buffers after being done with current frame ice: gather page_count()'s of each frag right before XDP prog call ice: stop storing XDP verdict within ice_rx_buf
Maciej S. Szmigiero (1): net: wwan: iosm: Fix hibernation by re-binding the driver around it
Manivannan Sadhasivam (2): clk: qcom: gcc-sm8550: Do not turn off PCIe GDSCs during gdsc_disable() clk: qcom: gcc-sm8650: Do not turn off PCIe GDSCs during gdsc_disable()
Marc Zyngier (2): arm64: Filter out SVE hwcaps when FEAT_SVE isn't implemented KVM: arm64: timer: Always evaluate the need for a soft timer
Marcel Hamer (1): wifi: brcmfmac: fix NULL pointer dereference in brcmf_txfinalize()
Marco Elver (1): kfence: skip __GFP_THISNODE allocations on NUMA systems
Marek Olšák (1): drm/amdgpu: add a BO metadata flag to disable write compression for Vulkan
Mario Limonciello (1): ASoC: acp: Support microphone from Lenovo Go S
Mark Brown (1): arm64/sme: Move storage of reg_smidr to __cpuinfo_store_cpu()
Mark Dietzer (1): Bluetooth: btusb: Add ID 0x2c7c:0x0130 for Qualcomm WCN785x
Mark Tomlinson (1): gpio: pca953x: Improve interrupt support
Mateusz Jończyk (1): mips/math-emu: fix emulation of the prefx instruction
Matthew Wilcox (Oracle) (1): ocfs2: handle a symlink read error correctly
Matthieu Baerts (NGI0) (1): selftests: mptcp: connect: -f: no reconnect
Max Kellermann (2): fs/netfs/read_pgpriv2: skip folio queues without `marks3` fs/netfs/read_collect: fix crash due to uninitialized `prev` variable
Mazin Al Haddad (1): Bluetooth: MGMT: Fix slab-use-after-free Read in mgmt_remove_adv_monitor_sync
Meetakshi Setiya (1): smb: client: change lease epoch type from unsigned int to __u16
Mehdi Djait (1): media: ccs: Fix cleanup order in ccs_probe()
Michal Simek (1): rtc: zynqmp: Fix optional clock name property
Michal Wajdeczko (1): drm/xe/pf: Fix migration initialization
Miguel Ojeda (1): rust: init: use explicit ABI to clean warning in future compilers
Mike Snitzer (1): pnfs/flexfiles: retry getting layout segment for reads
Miklos Szeredi (2): statmount: let unset strings be empty fs: fix adding security options to statmount.mnt_opt
Milos Reljin (1): net: phy: c45-tjaxx: add delay between MDIO write and read in soft_reset
Ming Lei (1): block: mark GFP_NOIO around sysfs ->store()
Miri Korenblit (1): wifi: iwlwifi: avoid memory leak
Nam Cao (1): fs/proc: do_task_stat: Fix ESP not readable during coredump
Narayana Murty N (1): powerpc/pseries/eeh: Fix get PE state translation
Nathan Chancellor (4): drm/amd/display: Increase sanitizer frame larger than limit when compile testing with clang efi: libstub: Use '-std=gnu11' to fix build with GCC 15 kbuild: Move -Wenum-enum-conversion to W=2 x86/boot: Use '-std=gnu11' to fix build with GCC 15
Naushir Patuck (1): media: imx296: Add standby delay during probe
Nick Chan (1): irqchip/apple-aic: Only handle PMC interrupt as FIQ when configured so
Nick Morrow (1): wifi: mt76: mt7921u: Add VID/PID for TP-Link TXE50UH
Nicolin Chen (4): iommufd: Fix struct iommu_hwpt_pgfault init and padding iommu/tegra241-cmdqv: Read SMMU IDR1.CMDQS instead of hardcoding iommufd/fault: Destroy response and mutex in iommufd_fault_destroy() iommufd/fault: Use a separate spinlock to protect fault->deliver list
Nikita Zhandarovich (1): nilfs2: fix possible int overflows in nilfs_fiemap()
Niklas Cassel (3): PCI: dwc: ep: Write BAR_MASK before iATU registers in pci_epc_set_bar() PCI: dwc: ep: Prevent changing BAR size/flags in pci_epc_set_bar() ata: libata-sff: Ensure that we cannot write outside the allocated buffer
Niklas Schnelle (1): s390/pci: Fix SR-IOV for PFs initially in standby
Pali Rohár (1): cifs: Remove intermediate object of failed create SFU call
Paul Fertser (1): net/ncsi: wait for the last response to Deselect Package before configuring channel
Pavel Begunkov (1): io_uring: fix multishots with selected buffers
Pekka Pessi (1): mailbox: tegra-hsp: Clear mailbox before using message
Peng Fan (1): Input: bbnsm_pwrkey - add remove hook
Peter Xu (1): mm/hugetlb: fix avoid_reserve to allow taking folio from subpool
Peter Zijlstra (2): x86: Convert unreachable() to BUG() x86/mm: Convert unreachable() to BUG()
Philip Yang (2): drm/amdgpu: Don't enable sdma 4.4.5 CTXEMPTY interrupt drm/amdkfd: Queue interrupt work to different CPU
Ping-Ke Shih (2): wifi: rtw88: add __packed attribute to efuse layout struct wifi: rtw89: pci: disable PCIE wake bit when PCIE deinit
Prasad Pandit (1): firmware: iscsi_ibft: fix ISCSI_IBFT Kconfig entry
Prike Liang (1): drm/amdkfd: only flush the validate MES contex
Qu Wenruo (1): btrfs: do not output error message if a qgroup has been already cleaned up
Quang Le (1): pfifo_tail_enqueue: Drop new packet when sch->limit == 0
Quinn Tran (1): scsi: qla2xxx: Move FCE Trace buffer allocation to user control
Randolph Ha (1): i2c: Force ELAN06FA touchpad I2C bus freq to 100KHz
Ricardo Ribalda (6): media: uvcvideo: Fix crash during unbind if gpio unit is in use media: uvcvideo: Fix event flags in uvc_ctrl_send_events media: uvcvideo: Support partial control reads media: uvcvideo: Only save async fh if success media: uvcvideo: Remove redundant NULL assignment media: uvcvideo: Remove dangling pointers
Richard Acayan (1): iommu/arm-smmu-qcom: add sdm670 adreno iommu compatible
Ritesh Harjani (IBM) (1): mm/hugetlb: fix hugepage allocation for interleaved memory nodes
Robin Murphy (3): iommu/arm-smmu-v3: Clean up more on probe failure PCI/TPH: Restore TPH Requester Enable correctly remoteproc: omap: Handle ARM dma_iommu_mapping
Rodrigo Siqueira (1): Revert "drm/amd/display: Fix green screen issue after suspend"
Roger Quadros (1): net: ethernet: ti: am65-cpsw: ensure proper channel cleanup in error path
Romain Naour (1): ARM: dts: dra7: Add bus_dma_limit for l4 cfg bus
Ruben Devos (1): smb: client: fix order of arguments of tracepoints
Sagi Grimberg (1): nvmet: fix a memory leak in controller identify
Sakari Ailus (3): media: ccs: Clean up parsed CCS static data on parse failure media: Documentation: tx-rx: Fix formatting media: ccs: Fix CCS static data parsing for large block sizes
Sam Bobrowicz (1): media: ov5640: fix get_light_freq on auto
Sankararaman Jayaraman (1): vmxnet3: Fix tx queue race condition with XDP
Sascha Hauer (4): nvmem: imx-ocotp-ele: simplify read beyond device check nvmem: imx-ocotp-ele: fix MAC address byte order nvmem: imx-ocotp-ele: fix reading from non zero offset nvmem: imx-ocotp-ele: set word length to 1
Satya Priya Kakitapalli (1): clk: qcom: gcc-mdm9607: Fix cmd_rcgr offset for blsp1_uart6 rcg
Sean Anderson (1): tty: xilinx_uartps: split sysrq handling
Sean Christopherson (2): KVM: Explicitly verify target vCPU is online in kvm_get_vcpu() KVM: x86/mmu: Ensure NX huge page recovery thread is alive before waking
Sebastian Wiese-Wagner (1): ALSA: hda/realtek: Enable Mute LED on HP Laptop 14s-fq1xxx
Sergey Senozhatsky (1): media: venus: destroy hfi session after m2m_ctx release
Shawn Lin (1): mmc: core: Respect quirk_max_rate for non-UHS SDIO card
Shayne Chen (1): wifi: mt76: mt7915: add module param to select 5 GHz or 6 GHz on MT7916
Shinas Rasheed (2): octeon_ep: update tx/rx stats locally for persistence octeon_ep_vf: update tx/rx stats locally for persistence
Simon Trimmer (1): ASoC: Intel: sof_sdw: Correct quirk for Lenovo Yoga Slim 7
Somashekhar(Som) (1): wifi: iwlwifi: pcie: Add support for new device ids
Stanislaw Gruszka (1): media: intel/ipu6: remove cpu latency qos request on error
Stas Sergeev (1): tun: fix group permission check
Stefan Dösinger (1): wifi: brcmfmac: Check the return value of of_property_read_string_index()
Stefan Eichenberger (1): irqchip/irq-mvebu-icu: Fix access to msi_data from irq_domain::host_data
Stephan Gerhold (8): arm64: dts: qcom: x1e80100-asus-vivobook-s15: Fix USB QMP PHY supplies arm64: dts: qcom: x1e80100-dell-xps13-9345: Fix USB QMP PHY supplies arm64: dts: qcom: x1e80100-qcp: Fix USB QMP PHY supplies arm64: dts: qcom: x1e78100-lenovo-thinkpad-t14s: Fix USB QMP PHY supplies arm64: dts: qcom: x1e80100-crd: Fix USB QMP PHY supplies arm64: dts: qcom: x1e80100-lenovo-yoga-slim7x: Fix USB QMP PHY supplies arm64: dts: qcom: x1e80100-microsoft-romulus: Fix USB QMP PHY supplies soc: qcom: socinfo: Avoid out of bounds read of serial number
Steven Rostedt (4): ring-buffer: Do not allow events in NMI with generic atomic64 cmpxchg() atomic64: Use arch_spin_locks instead of raw_spin_locks fgraph: Fix set_graph_notrace with setting TRACE_GRAPH_NOTRACE_BIT tracing/osnoise: Fix resetting of tracepoints
Suleiman Souhlal (1): sched: Don't try to catch up excess steal time.
Sumit Gupta (2): arm64: tegra: Fix typo in Tegra234 dce-fabric compatible arm64: tegra: Disable Tegra234 sce-fabric node
Suraj Kandpal (1): drm/i915/hdcp: Fix Repeater authentication during topology change
Sven Schnelle (1): s390/stackleak: Use exrl instead of ex in __stackleak_poison()
Takashi Iwai (2): ALSA: hda/realtek: Fix quirk matching for Legion Pro 7 ALSA: hda/realtek: Workaround for resume on Dell Venue 11 Pro 7130
Tetsuo Handa (1): tomoyo: don't emit warning in tomoyo_write_control()
Thadeu Lima de Souza Cascardo (1): Revert "media: uvcvideo: Require entities to have a non-zero unique ID"
Thinh Nguyen (4): usb: gadget: f_tcm: Translate error to sense usb: gadget: f_tcm: Decrement command ref count on cleanup usb: gadget: f_tcm: ep_autoconfig with fullspeed endpoint usb: gadget: f_tcm: Don't prepare BOT write request twice
Thomas Weißschuh (5): drm: Add panel backlight quirks drm/amd/display: Add support for minimum backlight quirk drm: panel-backlight-quirks: Add Framework 13 matte panel of: address: Fix empty resource handling in __of_address_resource_bounds() ptp: Ensure info->enable callback is always set
Thomas Zimmermann (3): m68k: vga: Fix I/O defines drm/rockchip: cdn-dp: Use drm_connector_helper_hpd_irq_event() drm/ast: astdp: Fix timeout for enabling video signal
Thorsten Blum (1): locking/ww_mutex/test: Use swap() macro
Tiezhu Yang (1): LoongArch: Extend the maximum number of watchpoints
Tom Chung (1): Revert "drm/amd/display: Use HW lock mgr for PSR1"
Tomas Glozar (6): rtla/osnoise: Distinguish missing workload option rtla/timerlat_hist: Set OSNOISE_WORKLOAD for kernel threads rtla/timerlat_top: Set OSNOISE_WORKLOAD for kernel threads rtla: Add trace_instance_stop rtla/timerlat_hist: Stop timerlat tracer on signal rtla/timerlat_top: Stop timerlat tracer on signal
Tomi Valkeinen (5): media: i2c: ds90ub960: Fix UB9702 refclk register access media: i2c: ds90ub9x3: Fix extra fwnode_handle_put() media: i2c: ds90ub960: Fix use of non-existing registers on UB9702 media: i2c: ds90ub960: Fix UB9702 VC map media: i2c: ds90ub960: Fix logging SP & EQ status only for UB9702
Uros Bizjak (1): mailbox: zynqmp: Remove invalid __percpu annotation in zynqmp_ipi_probe()
Vadim Fedorenko (1): net/mlx5: use do_aux_work for PHC overflow checks
Vasily Khoruzhick (1): wifi: rtw88: 8703b: Fix RX/TX issues
Ville Syrjälä (1): drm/i915: Drop 64bpp YUV formats from ICL+ SDR planes
Vimal Agrawal (1): misc: misc_minor_alloc to use ida for all dynamic/misc dynamic minors
Viresh Kumar (1): cpufreq: s3c64xx: Fix compilation warning
WangYuli (1): MIPS: ftrace: Declare ftrace_get_parent_ra_addr() as static
Wei Yang (1): maple_tree: simplify split calculation
Wentao Liang (2): xfs: Propagate errors from xfs_reflink_cancel_cow_range in xfs_dax_write_iomap_end xfs: Add error handling for xfs_reflink_cancel_cow_range
Werner Sembach (1): PCI: Avoid putting some root ports into D3 on TUXEDO Sirius Gen1
Willem de Bruijn (1): tun: revert fix group permission check
Xi Ruoyao (1): Revert "MIPS: csrc-r4k: Select HAVE_UNSTABLE_SCHED_CLOCK if SMP && 64BIT"
Xu Yang (1): perf: imx9_perf: Introduce AXI filter version to refactor the driver and better extension
Yan Zhai (1): udp: gso: do not drop small packets when PMTU reduces
Yazen Ghannam (1): x86/amd_nb: Restrict init function to AMD-based systems
Yevgeny Kliteynik (2): net/mlx5: HWS, change error flow on matcher disconnect net/mlx5: HWS, num_of_rules counter on matcher should be atomic
Yishai Hadas (1): RDMA/mlx5: Fix a race for an ODP MR which leads to CQE with error
Youwan Wang (1): HID: multitouch: Add quirk for Hantick 5288 touchpad
Yu Kuai (1): md: reintroduce md-linear
Yu-Chun Lin (1): ASoC: amd: Add ACPI dependency to fix build error
Yuanjie Yang (1): mmc: sdhci-msm: Correctly set the load for the regulator
Zhang Rui (1): x86/acpi: Fix LAPIC/x2APIC parsing order
Zhaoyang Huang (1): mm: gup: fix infinite loop within __get_longterm_locked
Zhen Lei (1): media: nuvoton: Fix an error check in npcm_video_ece_init()
Zhi Wang (2): nvkm/gsp: correctly advance the read pointer of GSP message queue nvkm: correctly calculate the available space of the GSP cmdq buffer
Zijun Hu (6): blk-cgroup: Fix class @block_class's subsystem refcount leakage of: Correct child specifier used as input of the 2nd nexus node of: Fix of_find_node_opts_by_path() handling of alias+path+options of: reserved-memory: Fix using wrong number of cells to get property 'alignment' of: reserved-memory: Warn for missing static reserved memory regions PCI: endpoint: Finish virtual EP removal in pci_epf_remove_vepf()
diff --git a/Documentation/arch/arm64/elf_hwcaps.rst b/Documentation/arch/arm64/elf_hwcaps.rst index 2ff922a406ad..1a31723e79fd 100644 --- a/Documentation/arch/arm64/elf_hwcaps.rst +++ b/Documentation/arch/arm64/elf_hwcaps.rst @@ -178,22 +178,28 @@ HWCAP2_DCPODP Functionality implied by ID_AA64ISAR1_EL1.DPB == 0b0010.
HWCAP2_SVE2 - Functionality implied by ID_AA64ZFR0_EL1.SVEver == 0b0001. + Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and + ID_AA64ZFR0_EL1.SVEver == 0b0001.
HWCAP2_SVEAES - Functionality implied by ID_AA64ZFR0_EL1.AES == 0b0001. + Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and + ID_AA64ZFR0_EL1.AES == 0b0001.
HWCAP2_SVEPMULL - Functionality implied by ID_AA64ZFR0_EL1.AES == 0b0010. + Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and + ID_AA64ZFR0_EL1.AES == 0b0010.
HWCAP2_SVEBITPERM - Functionality implied by ID_AA64ZFR0_EL1.BitPerm == 0b0001. + Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and + ID_AA64ZFR0_EL1.BitPerm == 0b0001.
HWCAP2_SVESHA3 - Functionality implied by ID_AA64ZFR0_EL1.SHA3 == 0b0001. + Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and + ID_AA64ZFR0_EL1.SHA3 == 0b0001.
HWCAP2_SVESM4 - Functionality implied by ID_AA64ZFR0_EL1.SM4 == 0b0001. + Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and + ID_AA64ZFR0_EL1.SM4 == 0b0001.
HWCAP2_FLAGM2 Functionality implied by ID_AA64ISAR0_EL1.TS == 0b0010. @@ -202,16 +208,20 @@ HWCAP2_FRINT Functionality implied by ID_AA64ISAR1_EL1.FRINTTS == 0b0001.
HWCAP2_SVEI8MM - Functionality implied by ID_AA64ZFR0_EL1.I8MM == 0b0001. + Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and + ID_AA64ZFR0_EL1.I8MM == 0b0001.
HWCAP2_SVEF32MM - Functionality implied by ID_AA64ZFR0_EL1.F32MM == 0b0001. + Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and + ID_AA64ZFR0_EL1.F32MM == 0b0001.
HWCAP2_SVEF64MM - Functionality implied by ID_AA64ZFR0_EL1.F64MM == 0b0001. + Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and + ID_AA64ZFR0_EL1.F64MM == 0b0001.
HWCAP2_SVEBF16 - Functionality implied by ID_AA64ZFR0_EL1.BF16 == 0b0001. + Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and + ID_AA64ZFR0_EL1.BF16 == 0b0001.
HWCAP2_I8MM Functionality implied by ID_AA64ISAR1_EL1.I8MM == 0b0001. @@ -277,7 +287,8 @@ HWCAP2_EBF16 Functionality implied by ID_AA64ISAR1_EL1.BF16 == 0b0010.
HWCAP2_SVE_EBF16 - Functionality implied by ID_AA64ZFR0_EL1.BF16 == 0b0010. + Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and + ID_AA64ZFR0_EL1.BF16 == 0b0010.
HWCAP2_CSSC Functionality implied by ID_AA64ISAR2_EL1.CSSC == 0b0001. @@ -286,7 +297,8 @@ HWCAP2_RPRFM Functionality implied by ID_AA64ISAR2_EL1.RPRFM == 0b0001.
HWCAP2_SVE2P1 - Functionality implied by ID_AA64ZFR0_EL1.SVEver == 0b0010. + Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and + ID_AA64ZFR0_EL1.SVEver == 0b0010.
HWCAP2_SME2 Functionality implied by ID_AA64SMFR0_EL1.SMEver == 0b0001. @@ -313,7 +325,8 @@ HWCAP2_HBC Functionality implied by ID_AA64ISAR2_EL1.BC == 0b0001.
HWCAP2_SVE_B16B16 - Functionality implied by ID_AA64ZFR0_EL1.B16B16 == 0b0001. + Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and + ID_AA64ZFR0_EL1.B16B16 == 0b0001.
HWCAP2_LRCPC3 Functionality implied by ID_AA64ISAR1_EL1.LRCPC == 0b0011. diff --git a/Documentation/driver-api/media/tx-rx.rst b/Documentation/driver-api/media/tx-rx.rst index dd09484df1d3..b936065dd640 100644 --- a/Documentation/driver-api/media/tx-rx.rst +++ b/Documentation/driver-api/media/tx-rx.rst @@ -50,7 +50,7 @@ The :ref:`V4L2_CID_LINK_FREQ <v4l2-cid-link-freq>` control is used to tell the receiver the frequency of the bus (i.e. it is not the same as the symbol rate).
``.enable_streams()`` and ``.disable_streams()`` callbacks -^^^^^^^^^^^^^^^^^^^^^^^^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The struct v4l2_subdev_pad_ops->enable_streams() and struct v4l2_subdev_pad_ops->disable_streams() callbacks are used by the receiver driver diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index 8cf2f041af47..b4ee25af1702 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -221,6 +221,9 @@ Panel Helper Reference .. kernel-doc:: drivers/gpu/drm/drm_panel_orientation_quirks.c :export:
+.. kernel-doc:: drivers/gpu/drm/drm_panel_backlight_quirks.c + :export: + Panel Self Refresh Helper Reference ===================================
diff --git a/Makefile b/Makefile index 9de0dc460a83..423d087afad2 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 6 PATCHLEVEL = 13 -SUBLEVEL = 2 +SUBLEVEL = 3 EXTRAVERSION = NAME = Baby Opossum Posse
diff --git a/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi b/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi index 6e67d99832ac..ba7fdaae9c6e 100644 --- a/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi +++ b/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi @@ -12,6 +12,7 @@ &l4_cfg { /* 0x4a000000 */ ranges = <0x00000000 0x4a000000 0x100000>, /* segment 0 */ <0x00100000 0x4a100000 0x100000>, /* segment 1 */ <0x00200000 0x4a200000 0x100000>; /* segment 2 */ + dma-ranges;
segment@0 { /* 0x4a000000 */ compatible = "simple-pm-bus"; @@ -557,6 +558,7 @@ segment@100000 { /* 0x4a100000 */ <0x0007e000 0x0017e000 0x001000>, /* ap 124 */ <0x00059000 0x00159000 0x001000>, /* ap 125 */ <0x0005a000 0x0015a000 0x001000>; /* ap 126 */ + dma-ranges;
target-module@2000 { /* 0x4a102000, ap 27 3c.0 */ compatible = "ti,sysc"; diff --git a/arch/arm/boot/dts/ti/omap/omap3-gta04.dtsi b/arch/arm/boot/dts/ti/omap/omap3-gta04.dtsi index 2ee3ddd64020..536070e80b2c 100644 --- a/arch/arm/boot/dts/ti/omap/omap3-gta04.dtsi +++ b/arch/arm/boot/dts/ti/omap/omap3-gta04.dtsi @@ -446,6 +446,7 @@ &omap3_pmx_core2 { pinctrl-names = "default"; pinctrl-0 = < &hsusb2_2_pins + &mcspi3hog_pins >;
hsusb2_2_pins: hsusb2-2-pins { @@ -459,6 +460,15 @@ OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_d >; };
+ mcspi3hog_pins: mcspi3hog-pins { + pinctrl-single,pins = < + OMAP3630_CORE2_IOPAD(0x25dc, PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* etk_d0 */ + OMAP3630_CORE2_IOPAD(0x25de, PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* etk_d1 */ + OMAP3630_CORE2_IOPAD(0x25e0, PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* etk_d2 */ + OMAP3630_CORE2_IOPAD(0x25e2, PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* etk_d3 */ + >; + }; + spi_gpio_pins: spi-gpio-pinmux-pins { pinctrl-single,pins = < OMAP3630_CORE2_IOPAD(0x25d8, PIN_OUTPUT | MUX_MODE4) /* clk */ diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi index 4b974bb781b1..bbb29218661b 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi @@ -269,11 +269,6 @@ dsi_out: endpoint { }; };
-&dpi0 { - /* TODO Re-enable after DP to Type-C port muxing can be described */ - status = "disabled"; -}; - &gic { mediatek,broken-save-restore-fw; }; diff --git a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts index 61a6f66914b8..dbdee604edab 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts +++ b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts @@ -522,10 +522,6 @@ &scp { status = "okay"; };
-&dsi0 { - status = "disabled"; -}; - &dpi0 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&dpi_func_pins>; diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi index 9af6349dbfcf..0aa34e5bbaaa 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi @@ -1835,6 +1835,7 @@ dsi0: dsi@14014000 { resets = <&mmsys MT8183_MMSYS_SW0_RST_B_DISP_DSI0>; phys = <&mipi_tx0>; phy-names = "dphy"; + status = "disabled"; };
dpi0: dpi@14015000 { @@ -1846,6 +1847,7 @@ dpi0: dpi@14015000 { <&mmsys CLK_MM_DPI_MM>, <&apmixedsys CLK_APMIXED_TVDPLL>; clock-names = "pixel", "engine", "pll"; + status = "disabled";
port { dpi_out: endpoint { }; diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi index 570331baa09e..2601b43b2d8c 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi @@ -3815,7 +3815,7 @@ sce-fabric@b600000 { compatible = "nvidia,tegra234-sce-fabric"; reg = <0x0 0xb600000 0x0 0x40000>; interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>; - status = "okay"; + status = "disabled"; };
rce-fabric@be00000 { @@ -3995,7 +3995,7 @@ bpmp-fabric@d600000 { };
dce-fabric@de00000 { - compatible = "nvidia,tegra234-sce-fabric"; + compatible = "nvidia,tegra234-dce-fabric"; reg = <0x0 0xde00000 0x0 0x40000>; interrupts = <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH>; status = "okay"; @@ -4018,6 +4018,8 @@ gic: interrupt-controller@f400000 { #redistributor-regions = <1>; #interrupt-cells = <3>; interrupt-controller; + + #address-cells = <0>; };
smmu_iso: iommu@10000000 { diff --git a/arch/arm64/boot/dts/qcom/sdx75.dtsi b/arch/arm64/boot/dts/qcom/sdx75.dtsi index 68d7dbe037b6..227f4705587a 100644 --- a/arch/arm64/boot/dts/qcom/sdx75.dtsi +++ b/arch/arm64/boot/dts/qcom/sdx75.dtsi @@ -893,7 +893,7 @@ tcsr: syscon@1fc0000 {
remoteproc_mpss: remoteproc@4080000 { compatible = "qcom,sdx75-mpss-pas"; - reg = <0 0x04080000 0 0x4040>; + reg = <0 0x04080000 0 0x10000>;
interrupts-extended = <&intc GIC_SPI 250 IRQ_TYPE_EDGE_RISING>, <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>, diff --git a/arch/arm64/boot/dts/qcom/sm6115.dtsi b/arch/arm64/boot/dts/qcom/sm6115.dtsi index 9b23534c456b..7016843c2ca5 100644 --- a/arch/arm64/boot/dts/qcom/sm6115.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6115.dtsi @@ -2027,7 +2027,7 @@ dispcc: clock-controller@5f00000 {
remoteproc_mpss: remoteproc@6080000 { compatible = "qcom,sm6115-mpss-pas"; - reg = <0x0 0x06080000 0x0 0x100>; + reg = <0x0 0x06080000 0x0 0x10000>;
interrupts-extended = <&intc GIC_SPI 307 IRQ_TYPE_EDGE_RISING>, <&modem_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, @@ -2670,9 +2670,9 @@ funnel_apss1_in: endpoint { }; };
- remoteproc_adsp: remoteproc@ab00000 { + remoteproc_adsp: remoteproc@a400000 { compatible = "qcom,sm6115-adsp-pas"; - reg = <0x0 0x0ab00000 0x0 0x100>; + reg = <0x0 0x0a400000 0x0 0x4040>;
interrupts-extended = <&intc GIC_SPI 282 IRQ_TYPE_EDGE_RISING>, <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, @@ -2744,7 +2744,7 @@ compute-cb@7 {
remoteproc_cdsp: remoteproc@b300000 { compatible = "qcom,sm6115-cdsp-pas"; - reg = <0x0 0x0b300000 0x0 0x100000>; + reg = <0x0 0x0b300000 0x0 0x4040>;
interrupts-extended = <&intc GIC_SPI 265 IRQ_TYPE_EDGE_RISING>, <&cdsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi index 8d697280249f..fd662591f7c6 100644 --- a/arch/arm64/boot/dts/qcom/sm6350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi @@ -936,7 +936,7 @@ uart1: serial@884000 { power-domains = <&rpmhpd SM6350_CX>; operating-points-v2 = <&qup_opp_table>; interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>, - <&aggre1_noc MASTER_QUP_0 0 &clk_virt SLAVE_EBI_CH0 0>; + <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1283,7 +1283,7 @@ tcsr_mutex: hwlock@1f40000 {
adsp: remoteproc@3000000 { compatible = "qcom,sm6350-adsp-pas"; - reg = <0 0x03000000 0 0x100>; + reg = <0x0 0x03000000 0x0 0x10000>;
interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, @@ -1503,7 +1503,7 @@ gpucc: clock-controller@3d90000 {
mpss: remoteproc@4080000 { compatible = "qcom,sm6350-mpss-pas"; - reg = <0x0 0x04080000 0x0 0x4040>; + reg = <0x0 0x04080000 0x0 0x10000>;
interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_EDGE_RISING>, <&modem_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, diff --git a/arch/arm64/boot/dts/qcom/sm6375.dtsi b/arch/arm64/boot/dts/qcom/sm6375.dtsi index 7c929168ed08..0faa3a40ff82 100644 --- a/arch/arm64/boot/dts/qcom/sm6375.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6375.dtsi @@ -1516,9 +1516,9 @@ gpucc: clock-controller@5990000 { #power-domain-cells = <1>; };
- remoteproc_mss: remoteproc@6000000 { + remoteproc_mss: remoteproc@6080000 { compatible = "qcom,sm6375-mpss-pas"; - reg = <0 0x06000000 0 0x4040>; + reg = <0x0 0x06080000 0x0 0x10000>;
interrupts-extended = <&intc GIC_SPI 307 IRQ_TYPE_EDGE_RISING>, <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>, @@ -1559,7 +1559,7 @@ IPCC_MPROC_SIGNAL_GLINK_QMP
remoteproc_adsp: remoteproc@a400000 { compatible = "qcom,sm6375-adsp-pas"; - reg = <0 0x0a400000 0 0x100>; + reg = <0 0x0a400000 0 0x10000>;
interrupts-extended = <&intc GIC_SPI 282 IRQ_TYPE_EDGE_RISING>, <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, @@ -1595,9 +1595,9 @@ IPCC_MPROC_SIGNAL_GLINK_QMP }; };
- remoteproc_cdsp: remoteproc@b000000 { + remoteproc_cdsp: remoteproc@b300000 { compatible = "qcom,sm6375-cdsp-pas"; - reg = <0x0 0x0b000000 0x0 0x100000>; + reg = <0x0 0x0b300000 0x0 0x10000>;
interrupts-extended = <&intc GIC_SPI 265 IRQ_TYPE_EDGE_RISING>, <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi index 15b7f15b3836..766da4a701a0 100644 --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi @@ -1876,6 +1876,142 @@ tcsr: syscon@1fc0000 { reg = <0x0 0x1fc0000 0x0 0x30000>; };
+ adsp: remoteproc@3000000 { + compatible = "qcom,sm8350-adsp-pas"; + reg = <0x0 0x03000000 0x0 0x10000>; + + interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", "fatal", "ready", + "handover", "stop-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + power-domains = <&rpmhpd RPMHPD_LCX>, + <&rpmhpd RPMHPD_LMX>; + power-domain-names = "lcx", "lmx"; + + memory-region = <&pil_adsp_mem>; + + qcom,qmp = <&aoss_qmp>; + + qcom,smem-states = <&smp2p_adsp_out 0>; + qcom,smem-state-names = "stop"; + + status = "disabled"; + + glink-edge { + interrupts-extended = <&ipcc IPCC_CLIENT_LPASS + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + mboxes = <&ipcc IPCC_CLIENT_LPASS + IPCC_MPROC_SIGNAL_GLINK_QMP>; + + label = "lpass"; + qcom,remote-pid = <2>; + + apr { + compatible = "qcom,apr-v2"; + qcom,glink-channels = "apr_audio_svc"; + qcom,domain = <APR_DOMAIN_ADSP>; + #address-cells = <1>; + #size-cells = <0>; + + service@3 { + reg = <APR_SVC_ADSP_CORE>; + compatible = "qcom,q6core"; + qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; + }; + + q6afe: service@4 { + compatible = "qcom,q6afe"; + reg = <APR_SVC_AFE>; + qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; + + q6afedai: dais { + compatible = "qcom,q6afe-dais"; + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <1>; + }; + + q6afecc: clock-controller { + compatible = "qcom,q6afe-clocks"; + #clock-cells = <2>; + }; + }; + + q6asm: service@7 { + compatible = "qcom,q6asm"; + reg = <APR_SVC_ASM>; + qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; + + q6asmdai: dais { + compatible = "qcom,q6asm-dais"; + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <1>; + iommus = <&apps_smmu 0x1801 0x0>; + + dai@0 { + reg = <0>; + }; + + dai@1 { + reg = <1>; + }; + + dai@2 { + reg = <2>; + }; + }; + }; + + q6adm: service@8 { + compatible = "qcom,q6adm"; + reg = <APR_SVC_ADM>; + qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; + + q6routing: routing { + compatible = "qcom,q6adm-routing"; + #sound-dai-cells = <0>; + }; + }; + }; + + fastrpc { + compatible = "qcom,fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "adsp"; + qcom,non-secure-domain; + #address-cells = <1>; + #size-cells = <0>; + + compute-cb@3 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <3>; + iommus = <&apps_smmu 0x1803 0x0>; + }; + + compute-cb@4 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <4>; + iommus = <&apps_smmu 0x1804 0x0>; + }; + + compute-cb@5 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <5>; + iommus = <&apps_smmu 0x1805 0x0>; + }; + }; + }; + }; + lpass_tlmm: pinctrl@33c0000 { compatible = "qcom,sm8350-lpass-lpi-pinctrl"; reg = <0 0x033c0000 0 0x20000>, @@ -2078,7 +2214,7 @@ lpass_ag_noc: interconnect@3c40000 {
mpss: remoteproc@4080000 { compatible = "qcom,sm8350-mpss-pas"; - reg = <0x0 0x04080000 0x0 0x4040>; + reg = <0x0 0x04080000 0x0 0x10000>;
interrupts-extended = <&intc GIC_SPI 264 IRQ_TYPE_EDGE_RISING>, <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>, @@ -2360,6 +2496,115 @@ compute_noc: interconnect@a0c0000 { qcom,bcm-voters = <&apps_bcm_voter>; };
+ cdsp: remoteproc@a300000 { + compatible = "qcom,sm8350-cdsp-pas"; + reg = <0x0 0x0a300000 0x0 0x10000>; + + interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 3 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", "fatal", "ready", + "handover", "stop-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + power-domains = <&rpmhpd RPMHPD_CX>, + <&rpmhpd RPMHPD_MXC>; + power-domain-names = "cx", "mxc"; + + interconnects = <&compute_noc MASTER_CDSP_PROC 0 &mc_virt SLAVE_EBI1 0>; + + memory-region = <&pil_cdsp_mem>; + + qcom,qmp = <&aoss_qmp>; + + qcom,smem-states = <&smp2p_cdsp_out 0>; + qcom,smem-state-names = "stop"; + + status = "disabled"; + + glink-edge { + interrupts-extended = <&ipcc IPCC_CLIENT_CDSP + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + mboxes = <&ipcc IPCC_CLIENT_CDSP + IPCC_MPROC_SIGNAL_GLINK_QMP>; + + label = "cdsp"; + qcom,remote-pid = <5>; + + fastrpc { + compatible = "qcom,fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "cdsp"; + qcom,non-secure-domain; + #address-cells = <1>; + #size-cells = <0>; + + compute-cb@1 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <1>; + iommus = <&apps_smmu 0x2161 0x0400>, + <&apps_smmu 0x1181 0x0420>; + }; + + compute-cb@2 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <2>; + iommus = <&apps_smmu 0x2162 0x0400>, + <&apps_smmu 0x1182 0x0420>; + }; + + compute-cb@3 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <3>; + iommus = <&apps_smmu 0x2163 0x0400>, + <&apps_smmu 0x1183 0x0420>; + }; + + compute-cb@4 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <4>; + iommus = <&apps_smmu 0x2164 0x0400>, + <&apps_smmu 0x1184 0x0420>; + }; + + compute-cb@5 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <5>; + iommus = <&apps_smmu 0x2165 0x0400>, + <&apps_smmu 0x1185 0x0420>; + }; + + compute-cb@6 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <6>; + iommus = <&apps_smmu 0x2166 0x0400>, + <&apps_smmu 0x1186 0x0420>; + }; + + compute-cb@7 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <7>; + iommus = <&apps_smmu 0x2167 0x0400>, + <&apps_smmu 0x1187 0x0420>; + }; + + compute-cb@8 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <8>; + iommus = <&apps_smmu 0x2168 0x0400>, + <&apps_smmu 0x1188 0x0420>; + }; + + /* note: secure cb9 in downstream */ + }; + }; + }; + usb_1: usb@a6f8800 { compatible = "qcom,sm8350-dwc3", "qcom,dwc3"; reg = <0 0x0a6f8800 0 0x400>; @@ -3285,142 +3530,6 @@ apps_smmu: iommu@15000000 { dma-coherent; };
- adsp: remoteproc@17300000 { - compatible = "qcom,sm8350-adsp-pas"; - reg = <0 0x17300000 0 0x100>; - - interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>; - interrupt-names = "wdog", "fatal", "ready", - "handover", "stop-ack"; - - clocks = <&rpmhcc RPMH_CXO_CLK>; - clock-names = "xo"; - - power-domains = <&rpmhpd RPMHPD_LCX>, - <&rpmhpd RPMHPD_LMX>; - power-domain-names = "lcx", "lmx"; - - memory-region = <&pil_adsp_mem>; - - qcom,qmp = <&aoss_qmp>; - - qcom,smem-states = <&smp2p_adsp_out 0>; - qcom,smem-state-names = "stop"; - - status = "disabled"; - - glink-edge { - interrupts-extended = <&ipcc IPCC_CLIENT_LPASS - IPCC_MPROC_SIGNAL_GLINK_QMP - IRQ_TYPE_EDGE_RISING>; - mboxes = <&ipcc IPCC_CLIENT_LPASS - IPCC_MPROC_SIGNAL_GLINK_QMP>; - - label = "lpass"; - qcom,remote-pid = <2>; - - apr { - compatible = "qcom,apr-v2"; - qcom,glink-channels = "apr_audio_svc"; - qcom,domain = <APR_DOMAIN_ADSP>; - #address-cells = <1>; - #size-cells = <0>; - - service@3 { - reg = <APR_SVC_ADSP_CORE>; - compatible = "qcom,q6core"; - qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; - }; - - q6afe: service@4 { - compatible = "qcom,q6afe"; - reg = <APR_SVC_AFE>; - qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; - - q6afedai: dais { - compatible = "qcom,q6afe-dais"; - #address-cells = <1>; - #size-cells = <0>; - #sound-dai-cells = <1>; - }; - - q6afecc: clock-controller { - compatible = "qcom,q6afe-clocks"; - #clock-cells = <2>; - }; - }; - - q6asm: service@7 { - compatible = "qcom,q6asm"; - reg = <APR_SVC_ASM>; - qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; - - q6asmdai: dais { - compatible = "qcom,q6asm-dais"; - #address-cells = <1>; - #size-cells = <0>; - #sound-dai-cells = <1>; - iommus = <&apps_smmu 0x1801 0x0>; - - dai@0 { - reg = <0>; - }; - - dai@1 { - reg = <1>; - }; - - dai@2 { - reg = <2>; - }; - }; - }; - - q6adm: service@8 { - compatible = "qcom,q6adm"; - reg = <APR_SVC_ADM>; - qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; - - q6routing: routing { - compatible = "qcom,q6adm-routing"; - #sound-dai-cells = <0>; - }; - }; - }; - - fastrpc { - compatible = "qcom,fastrpc"; - qcom,glink-channels = "fastrpcglink-apps-dsp"; - label = "adsp"; - qcom,non-secure-domain; - #address-cells = <1>; - #size-cells = <0>; - - compute-cb@3 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <3>; - iommus = <&apps_smmu 0x1803 0x0>; - }; - - compute-cb@4 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <4>; - iommus = <&apps_smmu 0x1804 0x0>; - }; - - compute-cb@5 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <5>; - iommus = <&apps_smmu 0x1805 0x0>; - }; - }; - }; - }; - intc: interrupt-controller@17a00000 { compatible = "arm,gic-v3"; #interrupt-cells = <3>; @@ -3589,115 +3698,6 @@ cpufreq_hw: cpufreq@18591000 { #freq-domain-cells = <1>; #clock-cells = <1>; }; - - cdsp: remoteproc@98900000 { - compatible = "qcom,sm8350-cdsp-pas"; - reg = <0 0x98900000 0 0x1400000>; - - interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, - <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, - <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>, - <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>, - <&smp2p_cdsp_in 3 IRQ_TYPE_EDGE_RISING>; - interrupt-names = "wdog", "fatal", "ready", - "handover", "stop-ack"; - - clocks = <&rpmhcc RPMH_CXO_CLK>; - clock-names = "xo"; - - power-domains = <&rpmhpd RPMHPD_CX>, - <&rpmhpd RPMHPD_MXC>; - power-domain-names = "cx", "mxc"; - - interconnects = <&compute_noc MASTER_CDSP_PROC 0 &mc_virt SLAVE_EBI1 0>; - - memory-region = <&pil_cdsp_mem>; - - qcom,qmp = <&aoss_qmp>; - - qcom,smem-states = <&smp2p_cdsp_out 0>; - qcom,smem-state-names = "stop"; - - status = "disabled"; - - glink-edge { - interrupts-extended = <&ipcc IPCC_CLIENT_CDSP - IPCC_MPROC_SIGNAL_GLINK_QMP - IRQ_TYPE_EDGE_RISING>; - mboxes = <&ipcc IPCC_CLIENT_CDSP - IPCC_MPROC_SIGNAL_GLINK_QMP>; - - label = "cdsp"; - qcom,remote-pid = <5>; - - fastrpc { - compatible = "qcom,fastrpc"; - qcom,glink-channels = "fastrpcglink-apps-dsp"; - label = "cdsp"; - qcom,non-secure-domain; - #address-cells = <1>; - #size-cells = <0>; - - compute-cb@1 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <1>; - iommus = <&apps_smmu 0x2161 0x0400>, - <&apps_smmu 0x1181 0x0420>; - }; - - compute-cb@2 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <2>; - iommus = <&apps_smmu 0x2162 0x0400>, - <&apps_smmu 0x1182 0x0420>; - }; - - compute-cb@3 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <3>; - iommus = <&apps_smmu 0x2163 0x0400>, - <&apps_smmu 0x1183 0x0420>; - }; - - compute-cb@4 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <4>; - iommus = <&apps_smmu 0x2164 0x0400>, - <&apps_smmu 0x1184 0x0420>; - }; - - compute-cb@5 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <5>; - iommus = <&apps_smmu 0x2165 0x0400>, - <&apps_smmu 0x1185 0x0420>; - }; - - compute-cb@6 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <6>; - iommus = <&apps_smmu 0x2166 0x0400>, - <&apps_smmu 0x1186 0x0420>; - }; - - compute-cb@7 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <7>; - iommus = <&apps_smmu 0x2167 0x0400>, - <&apps_smmu 0x1187 0x0420>; - }; - - compute-cb@8 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <8>; - iommus = <&apps_smmu 0x2168 0x0400>, - <&apps_smmu 0x1188 0x0420>; - }; - - /* note: secure cb9 in downstream */ - }; - }; - }; };
thermal_zones: thermal-zones { diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi index 7a0b901799bc..e71e5fd5c9a5 100644 --- a/arch/arm64/boot/dts/qcom/sm8450.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi @@ -2496,6 +2496,112 @@ compute-cb@3 { }; };
+ remoteproc_adsp: remoteproc@3000000 { + compatible = "qcom,sm8450-adsp-pas"; + reg = <0x0 0x03000000 0x0 0x10000>; + + interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", "fatal", "ready", + "handover", "stop-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + power-domains = <&rpmhpd RPMHPD_LCX>, + <&rpmhpd RPMHPD_LMX>; + power-domain-names = "lcx", "lmx"; + + memory-region = <&adsp_mem>; + + qcom,qmp = <&aoss_qmp>; + + qcom,smem-states = <&smp2p_adsp_out 0>; + qcom,smem-state-names = "stop"; + + status = "disabled"; + + remoteproc_adsp_glink: glink-edge { + interrupts-extended = <&ipcc IPCC_CLIENT_LPASS + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + mboxes = <&ipcc IPCC_CLIENT_LPASS + IPCC_MPROC_SIGNAL_GLINK_QMP>; + + label = "lpass"; + qcom,remote-pid = <2>; + + gpr { + compatible = "qcom,gpr"; + qcom,glink-channels = "adsp_apps"; + qcom,domain = <GPR_DOMAIN_ID_ADSP>; + qcom,intents = <512 20>; + #address-cells = <1>; + #size-cells = <0>; + + q6apm: service@1 { + compatible = "qcom,q6apm"; + reg = <GPR_APM_MODULE_IID>; + #sound-dai-cells = <0>; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + + q6apmdai: dais { + compatible = "qcom,q6apm-dais"; + iommus = <&apps_smmu 0x1801 0x0>; + }; + + q6apmbedai: bedais { + compatible = "qcom,q6apm-lpass-dais"; + #sound-dai-cells = <1>; + }; + }; + + q6prm: service@2 { + compatible = "qcom,q6prm"; + reg = <GPR_PRM_MODULE_IID>; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + + q6prmcc: clock-controller { + compatible = "qcom,q6prm-lpass-clocks"; + #clock-cells = <2>; + }; + }; + }; + + fastrpc { + compatible = "qcom,fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "adsp"; + qcom,non-secure-domain; + #address-cells = <1>; + #size-cells = <0>; + + compute-cb@3 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <3>; + iommus = <&apps_smmu 0x1803 0x0>; + }; + + compute-cb@4 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <4>; + iommus = <&apps_smmu 0x1804 0x0>; + }; + + compute-cb@5 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <5>; + iommus = <&apps_smmu 0x1805 0x0>; + }; + }; + }; + }; + wsa2macro: codec@31e0000 { compatible = "qcom,sm8450-lpass-wsa-macro"; reg = <0 0x031e0000 0 0x1000>; @@ -2692,115 +2798,9 @@ vamacro: codec@33f0000 { status = "disabled"; };
- remoteproc_adsp: remoteproc@30000000 { - compatible = "qcom,sm8450-adsp-pas"; - reg = <0 0x30000000 0 0x100>; - - interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>; - interrupt-names = "wdog", "fatal", "ready", - "handover", "stop-ack"; - - clocks = <&rpmhcc RPMH_CXO_CLK>; - clock-names = "xo"; - - power-domains = <&rpmhpd RPMHPD_LCX>, - <&rpmhpd RPMHPD_LMX>; - power-domain-names = "lcx", "lmx"; - - memory-region = <&adsp_mem>; - - qcom,qmp = <&aoss_qmp>; - - qcom,smem-states = <&smp2p_adsp_out 0>; - qcom,smem-state-names = "stop"; - - status = "disabled"; - - remoteproc_adsp_glink: glink-edge { - interrupts-extended = <&ipcc IPCC_CLIENT_LPASS - IPCC_MPROC_SIGNAL_GLINK_QMP - IRQ_TYPE_EDGE_RISING>; - mboxes = <&ipcc IPCC_CLIENT_LPASS - IPCC_MPROC_SIGNAL_GLINK_QMP>; - - label = "lpass"; - qcom,remote-pid = <2>; - - gpr { - compatible = "qcom,gpr"; - qcom,glink-channels = "adsp_apps"; - qcom,domain = <GPR_DOMAIN_ID_ADSP>; - qcom,intents = <512 20>; - #address-cells = <1>; - #size-cells = <0>; - - q6apm: service@1 { - compatible = "qcom,q6apm"; - reg = <GPR_APM_MODULE_IID>; - #sound-dai-cells = <0>; - qcom,protection-domain = "avs/audio", - "msm/adsp/audio_pd"; - - q6apmdai: dais { - compatible = "qcom,q6apm-dais"; - iommus = <&apps_smmu 0x1801 0x0>; - }; - - q6apmbedai: bedais { - compatible = "qcom,q6apm-lpass-dais"; - #sound-dai-cells = <1>; - }; - }; - - q6prm: service@2 { - compatible = "qcom,q6prm"; - reg = <GPR_PRM_MODULE_IID>; - qcom,protection-domain = "avs/audio", - "msm/adsp/audio_pd"; - - q6prmcc: clock-controller { - compatible = "qcom,q6prm-lpass-clocks"; - #clock-cells = <2>; - }; - }; - }; - - fastrpc { - compatible = "qcom,fastrpc"; - qcom,glink-channels = "fastrpcglink-apps-dsp"; - label = "adsp"; - qcom,non-secure-domain; - #address-cells = <1>; - #size-cells = <0>; - - compute-cb@3 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <3>; - iommus = <&apps_smmu 0x1803 0x0>; - }; - - compute-cb@4 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <4>; - iommus = <&apps_smmu 0x1804 0x0>; - }; - - compute-cb@5 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <5>; - iommus = <&apps_smmu 0x1805 0x0>; - }; - }; - }; - }; - remoteproc_cdsp: remoteproc@32300000 { compatible = "qcom,sm8450-cdsp-pas"; - reg = <0 0x32300000 0 0x1400000>; + reg = <0 0x32300000 0 0x10000>;
interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, @@ -2907,7 +2907,7 @@ compute-cb@8 {
remoteproc_mpss: remoteproc@4080000 { compatible = "qcom,sm8450-mpss-pas"; - reg = <0x0 0x04080000 0x0 0x4040>; + reg = <0x0 0x04080000 0x0 0x10000>;
interrupts-extended = <&intc GIC_SPI 264 IRQ_TYPE_EDGE_RISING>, <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>, diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi index e7774d32fb6d..a2daf9712fc0 100644 --- a/arch/arm64/boot/dts/qcom/sm8550.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi @@ -2314,7 +2314,7 @@ ipa: ipa@3f40000 {
remoteproc_mpss: remoteproc@4080000 { compatible = "qcom,sm8550-mpss-pas"; - reg = <0x0 0x04080000 0x0 0x4040>; + reg = <0x0 0x04080000 0x0 0x10000>;
interrupts-extended = <&intc GIC_SPI 264 IRQ_TYPE_EDGE_RISING>, <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>, @@ -2354,6 +2354,137 @@ IPCC_MPROC_SIGNAL_GLINK_QMP }; };
+ remoteproc_adsp: remoteproc@6800000 { + compatible = "qcom,sm8550-adsp-pas"; + reg = <0x0 0x06800000 0x0 0x10000>; + + interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", "fatal", "ready", + "handover", "stop-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + power-domains = <&rpmhpd RPMHPD_LCX>, + <&rpmhpd RPMHPD_LMX>; + power-domain-names = "lcx", "lmx"; + + interconnects = <&lpass_lpicx_noc MASTER_LPASS_PROC 0 &mc_virt SLAVE_EBI1 0>; + + memory-region = <&adspslpi_mem>, <&q6_adsp_dtb_mem>; + + qcom,qmp = <&aoss_qmp>; + + qcom,smem-states = <&smp2p_adsp_out 0>; + qcom,smem-state-names = "stop"; + + status = "disabled"; + + remoteproc_adsp_glink: glink-edge { + interrupts-extended = <&ipcc IPCC_CLIENT_LPASS + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + mboxes = <&ipcc IPCC_CLIENT_LPASS + IPCC_MPROC_SIGNAL_GLINK_QMP>; + + label = "lpass"; + qcom,remote-pid = <2>; + + fastrpc { + compatible = "qcom,fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "adsp"; + qcom,non-secure-domain; + #address-cells = <1>; + #size-cells = <0>; + + compute-cb@3 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <3>; + iommus = <&apps_smmu 0x1003 0x80>, + <&apps_smmu 0x1063 0x0>; + dma-coherent; + }; + + compute-cb@4 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <4>; + iommus = <&apps_smmu 0x1004 0x80>, + <&apps_smmu 0x1064 0x0>; + dma-coherent; + }; + + compute-cb@5 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <5>; + iommus = <&apps_smmu 0x1005 0x80>, + <&apps_smmu 0x1065 0x0>; + dma-coherent; + }; + + compute-cb@6 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <6>; + iommus = <&apps_smmu 0x1006 0x80>, + <&apps_smmu 0x1066 0x0>; + dma-coherent; + }; + + compute-cb@7 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <7>; + iommus = <&apps_smmu 0x1007 0x80>, + <&apps_smmu 0x1067 0x0>; + dma-coherent; + }; + }; + + gpr { + compatible = "qcom,gpr"; + qcom,glink-channels = "adsp_apps"; + qcom,domain = <GPR_DOMAIN_ID_ADSP>; + qcom,intents = <512 20>; + #address-cells = <1>; + #size-cells = <0>; + + q6apm: service@1 { + compatible = "qcom,q6apm"; + reg = <GPR_APM_MODULE_IID>; + #sound-dai-cells = <0>; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + + q6apmdai: dais { + compatible = "qcom,q6apm-dais"; + iommus = <&apps_smmu 0x1001 0x80>, + <&apps_smmu 0x1061 0x0>; + }; + + q6apmbedai: bedais { + compatible = "qcom,q6apm-lpass-dais"; + #sound-dai-cells = <1>; + }; + }; + + q6prm: service@2 { + compatible = "qcom,q6prm"; + reg = <GPR_PRM_MODULE_IID>; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + + q6prmcc: clock-controller { + compatible = "qcom,q6prm-lpass-clocks"; + #clock-cells = <2>; + }; + }; + }; + }; + }; + lpass_wsa2macro: codec@6aa0000 { compatible = "qcom,sm8550-lpass-wsa-macro"; reg = <0 0x06aa0000 0 0x1000>; @@ -2872,9 +3003,8 @@ mdss: display-subsystem@ae00000 {
power-domains = <&dispcc MDSS_GDSC>;
- interconnects = <&mmss_noc MASTER_MDP 0 &gem_noc SLAVE_LLCC 0>, - <&mc_virt MASTER_LLCC 0 &mc_virt SLAVE_EBI1 0>; - interconnect-names = "mdp0-mem", "mdp1-mem"; + interconnects = <&mmss_noc MASTER_MDP 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "mdp0-mem";
iommus = <&apps_smmu 0x1c00 0x2>;
@@ -4576,137 +4706,6 @@ system-cache-controller@25000000 { interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>; };
- remoteproc_adsp: remoteproc@30000000 { - compatible = "qcom,sm8550-adsp-pas"; - reg = <0x0 0x30000000 0x0 0x100>; - - interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>; - interrupt-names = "wdog", "fatal", "ready", - "handover", "stop-ack"; - - clocks = <&rpmhcc RPMH_CXO_CLK>; - clock-names = "xo"; - - power-domains = <&rpmhpd RPMHPD_LCX>, - <&rpmhpd RPMHPD_LMX>; - power-domain-names = "lcx", "lmx"; - - interconnects = <&lpass_lpicx_noc MASTER_LPASS_PROC 0 &mc_virt SLAVE_EBI1 0>; - - memory-region = <&adspslpi_mem>, <&q6_adsp_dtb_mem>; - - qcom,qmp = <&aoss_qmp>; - - qcom,smem-states = <&smp2p_adsp_out 0>; - qcom,smem-state-names = "stop"; - - status = "disabled"; - - remoteproc_adsp_glink: glink-edge { - interrupts-extended = <&ipcc IPCC_CLIENT_LPASS - IPCC_MPROC_SIGNAL_GLINK_QMP - IRQ_TYPE_EDGE_RISING>; - mboxes = <&ipcc IPCC_CLIENT_LPASS - IPCC_MPROC_SIGNAL_GLINK_QMP>; - - label = "lpass"; - qcom,remote-pid = <2>; - - fastrpc { - compatible = "qcom,fastrpc"; - qcom,glink-channels = "fastrpcglink-apps-dsp"; - label = "adsp"; - qcom,non-secure-domain; - #address-cells = <1>; - #size-cells = <0>; - - compute-cb@3 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <3>; - iommus = <&apps_smmu 0x1003 0x80>, - <&apps_smmu 0x1063 0x0>; - dma-coherent; - }; - - compute-cb@4 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <4>; - iommus = <&apps_smmu 0x1004 0x80>, - <&apps_smmu 0x1064 0x0>; - dma-coherent; - }; - - compute-cb@5 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <5>; - iommus = <&apps_smmu 0x1005 0x80>, - <&apps_smmu 0x1065 0x0>; - dma-coherent; - }; - - compute-cb@6 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <6>; - iommus = <&apps_smmu 0x1006 0x80>, - <&apps_smmu 0x1066 0x0>; - dma-coherent; - }; - - compute-cb@7 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <7>; - iommus = <&apps_smmu 0x1007 0x80>, - <&apps_smmu 0x1067 0x0>; - dma-coherent; - }; - }; - - gpr { - compatible = "qcom,gpr"; - qcom,glink-channels = "adsp_apps"; - qcom,domain = <GPR_DOMAIN_ID_ADSP>; - qcom,intents = <512 20>; - #address-cells = <1>; - #size-cells = <0>; - - q6apm: service@1 { - compatible = "qcom,q6apm"; - reg = <GPR_APM_MODULE_IID>; - #sound-dai-cells = <0>; - qcom,protection-domain = "avs/audio", - "msm/adsp/audio_pd"; - - q6apmdai: dais { - compatible = "qcom,q6apm-dais"; - iommus = <&apps_smmu 0x1001 0x80>, - <&apps_smmu 0x1061 0x0>; - }; - - q6apmbedai: bedais { - compatible = "qcom,q6apm-lpass-dais"; - #sound-dai-cells = <1>; - }; - }; - - q6prm: service@2 { - compatible = "qcom,q6prm"; - reg = <GPR_PRM_MODULE_IID>; - qcom,protection-domain = "avs/audio", - "msm/adsp/audio_pd"; - - q6prmcc: clock-controller { - compatible = "qcom,q6prm-lpass-clocks"; - #clock-cells = <2>; - }; - }; - }; - }; - }; - nsp_noc: interconnect@320c0000 { compatible = "qcom,sm8550-nsp-noc"; reg = <0 0x320c0000 0 0xe080>; @@ -4716,7 +4715,7 @@ nsp_noc: interconnect@320c0000 {
remoteproc_cdsp: remoteproc@32300000 { compatible = "qcom,sm8550-cdsp-pas"; - reg = <0x0 0x32300000 0x0 0x1400000>; + reg = <0x0 0x32300000 0x0 0x10000>;
interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi index 1e2d6ba0b8c1..1de6bab244b3 100644 --- a/arch/arm64/boot/dts/qcom/sm8650.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi @@ -2853,7 +2853,7 @@ ipa: ipa@3f40000 {
remoteproc_mpss: remoteproc@4080000 { compatible = "qcom,sm8650-mpss-pas"; - reg = <0 0x04080000 0 0x4040>; + reg = <0x0 0x04080000 0x0 0x10000>;
interrupts-extended = <&intc GIC_SPI 264 IRQ_TYPE_EDGE_RISING>, <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>, @@ -2904,6 +2904,154 @@ IPCC_MPROC_SIGNAL_GLINK_QMP }; };
+ remoteproc_adsp: remoteproc@6800000 { + compatible = "qcom,sm8650-adsp-pas"; + reg = <0x0 0x06800000 0x0 0x10000>; + + interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", + "fatal", + "ready", + "handover", + "stop-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + interconnects = <&lpass_lpicx_noc MASTER_LPASS_PROC QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + + power-domains = <&rpmhpd RPMHPD_LCX>, + <&rpmhpd RPMHPD_LMX>; + power-domain-names = "lcx", + "lmx"; + + memory-region = <&adspslpi_mem>, <&q6_adsp_dtb_mem>; + + qcom,qmp = <&aoss_qmp>; + + qcom,smem-states = <&smp2p_adsp_out 0>; + qcom,smem-state-names = "stop"; + + status = "disabled"; + + remoteproc_adsp_glink: glink-edge { + interrupts-extended = <&ipcc IPCC_CLIENT_LPASS + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + + mboxes = <&ipcc IPCC_CLIENT_LPASS + IPCC_MPROC_SIGNAL_GLINK_QMP>; + + qcom,remote-pid = <2>; + + label = "lpass"; + + fastrpc { + compatible = "qcom,fastrpc"; + + qcom,glink-channels = "fastrpcglink-apps-dsp"; + + label = "adsp"; + + qcom,non-secure-domain; + + #address-cells = <1>; + #size-cells = <0>; + + compute-cb@3 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <3>; + + iommus = <&apps_smmu 0x1003 0x80>, + <&apps_smmu 0x1043 0x20>; + dma-coherent; + }; + + compute-cb@4 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <4>; + + iommus = <&apps_smmu 0x1004 0x80>, + <&apps_smmu 0x1044 0x20>; + dma-coherent; + }; + + compute-cb@5 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <5>; + + iommus = <&apps_smmu 0x1005 0x80>, + <&apps_smmu 0x1045 0x20>; + dma-coherent; + }; + + compute-cb@6 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <6>; + + iommus = <&apps_smmu 0x1006 0x80>, + <&apps_smmu 0x1046 0x20>; + dma-coherent; + }; + + compute-cb@7 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <7>; + + iommus = <&apps_smmu 0x1007 0x40>, + <&apps_smmu 0x1067 0x0>, + <&apps_smmu 0x1087 0x0>; + dma-coherent; + }; + }; + + gpr { + compatible = "qcom,gpr"; + qcom,glink-channels = "adsp_apps"; + qcom,domain = <GPR_DOMAIN_ID_ADSP>; + qcom,intents = <512 20>; + #address-cells = <1>; + #size-cells = <0>; + + q6apm: service@1 { + compatible = "qcom,q6apm"; + reg = <GPR_APM_MODULE_IID>; + #sound-dai-cells = <0>; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + + q6apmbedai: bedais { + compatible = "qcom,q6apm-lpass-dais"; + #sound-dai-cells = <1>; + }; + + q6apmdai: dais { + compatible = "qcom,q6apm-dais"; + iommus = <&apps_smmu 0x1001 0x80>, + <&apps_smmu 0x1061 0x0>; + }; + }; + + q6prm: service@2 { + compatible = "qcom,q6prm"; + reg = <GPR_PRM_MODULE_IID>; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + + q6prmcc: clock-controller { + compatible = "qcom,q6prm-lpass-clocks"; + #clock-cells = <2>; + }; + }; + }; + }; + }; + lpass_wsa2macro: codec@6aa0000 { compatible = "qcom,sm8650-lpass-wsa-macro", "qcom,sm8550-lpass-wsa-macro"; reg = <0 0x06aa0000 0 0x1000>; @@ -3455,11 +3603,8 @@ mdss: display-subsystem@ae00000 { resets = <&dispcc DISP_CC_MDSS_CORE_BCR>;
interconnects = <&mmss_noc MASTER_MDP QCOM_ICC_TAG_ALWAYS - &gem_noc SLAVE_LLCC QCOM_ICC_TAG_ALWAYS>, - <&mc_virt MASTER_LLCC QCOM_ICC_TAG_ALWAYS &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; - interconnect-names = "mdp0-mem", - "mdp1-mem"; + interconnect-names = "mdp0-mem";
power-domains = <&dispcc MDSS_GDSC>;
@@ -5322,154 +5467,6 @@ system-cache-controller@25000000 { interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>; };
- remoteproc_adsp: remoteproc@30000000 { - compatible = "qcom,sm8650-adsp-pas"; - reg = <0 0x30000000 0 0x100>; - - interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>; - interrupt-names = "wdog", - "fatal", - "ready", - "handover", - "stop-ack"; - - clocks = <&rpmhcc RPMH_CXO_CLK>; - clock-names = "xo"; - - interconnects = <&lpass_lpicx_noc MASTER_LPASS_PROC QCOM_ICC_TAG_ALWAYS - &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; - - power-domains = <&rpmhpd RPMHPD_LCX>, - <&rpmhpd RPMHPD_LMX>; - power-domain-names = "lcx", - "lmx"; - - memory-region = <&adspslpi_mem>, <&q6_adsp_dtb_mem>; - - qcom,qmp = <&aoss_qmp>; - - qcom,smem-states = <&smp2p_adsp_out 0>; - qcom,smem-state-names = "stop"; - - status = "disabled"; - - remoteproc_adsp_glink: glink-edge { - interrupts-extended = <&ipcc IPCC_CLIENT_LPASS - IPCC_MPROC_SIGNAL_GLINK_QMP - IRQ_TYPE_EDGE_RISING>; - - mboxes = <&ipcc IPCC_CLIENT_LPASS - IPCC_MPROC_SIGNAL_GLINK_QMP>; - - qcom,remote-pid = <2>; - - label = "lpass"; - - fastrpc { - compatible = "qcom,fastrpc"; - - qcom,glink-channels = "fastrpcglink-apps-dsp"; - - label = "adsp"; - - qcom,non-secure-domain; - - #address-cells = <1>; - #size-cells = <0>; - - compute-cb@3 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <3>; - - iommus = <&apps_smmu 0x1003 0x80>, - <&apps_smmu 0x1043 0x20>; - dma-coherent; - }; - - compute-cb@4 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <4>; - - iommus = <&apps_smmu 0x1004 0x80>, - <&apps_smmu 0x1044 0x20>; - dma-coherent; - }; - - compute-cb@5 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <5>; - - iommus = <&apps_smmu 0x1005 0x80>, - <&apps_smmu 0x1045 0x20>; - dma-coherent; - }; - - compute-cb@6 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <6>; - - iommus = <&apps_smmu 0x1006 0x80>, - <&apps_smmu 0x1046 0x20>; - dma-coherent; - }; - - compute-cb@7 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <7>; - - iommus = <&apps_smmu 0x1007 0x40>, - <&apps_smmu 0x1067 0x0>, - <&apps_smmu 0x1087 0x0>; - dma-coherent; - }; - }; - - gpr { - compatible = "qcom,gpr"; - qcom,glink-channels = "adsp_apps"; - qcom,domain = <GPR_DOMAIN_ID_ADSP>; - qcom,intents = <512 20>; - #address-cells = <1>; - #size-cells = <0>; - - q6apm: service@1 { - compatible = "qcom,q6apm"; - reg = <GPR_APM_MODULE_IID>; - #sound-dai-cells = <0>; - qcom,protection-domain = "avs/audio", - "msm/adsp/audio_pd"; - - q6apmbedai: bedais { - compatible = "qcom,q6apm-lpass-dais"; - #sound-dai-cells = <1>; - }; - - q6apmdai: dais { - compatible = "qcom,q6apm-dais"; - iommus = <&apps_smmu 0x1001 0x80>, - <&apps_smmu 0x1061 0x0>; - }; - }; - - q6prm: service@2 { - compatible = "qcom,q6prm"; - reg = <GPR_PRM_MODULE_IID>; - qcom,protection-domain = "avs/audio", - "msm/adsp/audio_pd"; - - q6prmcc: clock-controller { - compatible = "qcom,q6prm-lpass-clocks"; - #clock-cells = <2>; - }; - }; - }; - }; - }; - nsp_noc: interconnect@320c0000 { compatible = "qcom,sm8650-nsp-noc"; reg = <0 0x320c0000 0 0xf080>; @@ -5481,7 +5478,7 @@ nsp_noc: interconnect@320c0000 {
remoteproc_cdsp: remoteproc@32300000 { compatible = "qcom,sm8650-cdsp-pas"; - reg = <0 0x32300000 0 0x1400000>; + reg = <0x0 0x32300000 0x0 0x10000>;
interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts index 66513fc8e67a..8435e55f63e8 100644 --- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts +++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts @@ -763,7 +763,7 @@ &usb_1_ss0_hsphy { };
&usb_1_ss0_qmpphy { - vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-phy-supply = <&vreg_l2j_1p2>; vdda-pll-supply = <&vreg_l1j_0p8>;
status = "okay"; @@ -795,7 +795,7 @@ &usb_1_ss1_hsphy { };
&usb_1_ss1_qmpphy { - vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-phy-supply = <&vreg_l2j_1p2>; vdda-pll-supply = <&vreg_l2d_0p9>;
status = "okay"; diff --git a/arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dts b/arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dts index 8515c254e158..3eb59d32c874 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dts @@ -591,7 +591,7 @@ &usb_1_ss0_hsphy { };
&usb_1_ss0_qmpphy { - vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-phy-supply = <&vreg_l2j_1p2>; vdda-pll-supply = <&vreg_l1j_0p8>;
status = "okay"; @@ -623,7 +623,7 @@ &usb_1_ss1_hsphy { };
&usb_1_ss1_qmpphy { - vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-phy-supply = <&vreg_l2j_1p2>; vdda-pll-supply = <&vreg_l2d_0p9>;
status = "okay"; diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts index d51a9bdcf67f..1d79eec6ecfa 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts @@ -1187,7 +1187,7 @@ &usb_1_ss0_hsphy { };
&usb_1_ss0_qmpphy { - vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-phy-supply = <&vreg_l2j_1p2>; vdda-pll-supply = <&vreg_l1j_0p8>;
status = "okay"; @@ -1219,7 +1219,7 @@ &usb_1_ss1_hsphy { };
&usb_1_ss1_qmpphy { - vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-phy-supply = <&vreg_l2j_1p2>; vdda-pll-supply = <&vreg_l2d_0p9>;
status = "okay"; @@ -1251,7 +1251,7 @@ &usb_1_ss2_hsphy { };
&usb_1_ss2_qmpphy { - vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-phy-supply = <&vreg_l2j_1p2>; vdda-pll-supply = <&vreg_l2d_0p9>;
status = "okay"; diff --git a/arch/arm64/boot/dts/qcom/x1e80100-dell-xps13-9345.dts b/arch/arm64/boot/dts/qcom/x1e80100-dell-xps13-9345.dts index 05624226faf9..210cb2336d14 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-dell-xps13-9345.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-dell-xps13-9345.dts @@ -820,7 +820,7 @@ &usb_1_ss0_hsphy { };
&usb_1_ss0_qmpphy { - vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-phy-supply = <&vreg_l2j_1p2>; vdda-pll-supply = <&vreg_l1j_0p9>;
status = "okay"; @@ -852,7 +852,7 @@ &usb_1_ss1_hsphy { };
&usb_1_ss1_qmpphy { - vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-phy-supply = <&vreg_l2j_1p2>; vdda-pll-supply = <&vreg_l2d_0p9>;
status = "okay"; diff --git a/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts b/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts index ca5a808f2c7d..77908462aef6 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts @@ -908,7 +908,7 @@ &usb_1_ss0_hsphy { };
&usb_1_ss0_qmpphy { - vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-phy-supply = <&vreg_l2j_1p2>; vdda-pll-supply = <&vreg_l1j_0p8>;
status = "okay"; @@ -940,7 +940,7 @@ &usb_1_ss1_hsphy { };
&usb_1_ss1_qmpphy { - vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-phy-supply = <&vreg_l2j_1p2>; vdda-pll-supply = <&vreg_l2d_0p9>;
status = "okay"; @@ -972,7 +972,7 @@ &usb_1_ss2_hsphy { };
&usb_1_ss2_qmpphy { - vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-phy-supply = <&vreg_l2j_1p2>; vdda-pll-supply = <&vreg_l2d_0p9>;
status = "okay"; diff --git a/arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus.dtsi b/arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus.dtsi index 8761874dc2f0..85d28fb8d878 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus.dtsi +++ b/arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus.dtsi @@ -823,7 +823,7 @@ &usb_1_ss0_hsphy { };
&usb_1_ss0_qmpphy { - vdda-phy-supply = <&vreg_l3e>; + vdda-phy-supply = <&vreg_l2j>; vdda-pll-supply = <&vreg_l1j>;
status = "okay"; @@ -855,7 +855,7 @@ &usb_1_ss1_hsphy { };
&usb_1_ss1_qmpphy { - vdda-phy-supply = <&vreg_l3e>; + vdda-phy-supply = <&vreg_l2j>; vdda-pll-supply = <&vreg_l2d>;
status = "okay"; diff --git a/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts b/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts index 5ef030c60abe..af76aa034d0e 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts @@ -896,7 +896,7 @@ &usb_1_ss0_hsphy { };
&usb_1_ss0_qmpphy { - vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-phy-supply = <&vreg_l2j_1p2>; vdda-pll-supply = <&vreg_l1j_0p8>;
status = "okay"; @@ -928,7 +928,7 @@ &usb_1_ss1_hsphy { };
&usb_1_ss1_qmpphy { - vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-phy-supply = <&vreg_l2j_1p2>; vdda-pll-supply = <&vreg_l2d_0p9>;
status = "okay"; @@ -960,7 +960,7 @@ &usb_1_ss2_hsphy { };
&usb_1_ss2_qmpphy { - vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-phy-supply = <&vreg_l2j_1p2>; vdda-pll-supply = <&vreg_l2d_0p9>;
status = "okay"; diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi index 4dfea255c83f..857dc50e01b3 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi +++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi @@ -3518,6 +3518,143 @@ nsp_noc: interconnect@320c0000 { #interconnect-cells = <2>; };
+ remoteproc_adsp: remoteproc@6800000 { + compatible = "qcom,x1e80100-adsp-pas"; + reg = <0x0 0x06800000 0x0 0x10000>; + + interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", + "fatal", + "ready", + "handover", + "stop-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + power-domains = <&rpmhpd RPMHPD_LCX>, + <&rpmhpd RPMHPD_LMX>; + power-domain-names = "lcx", + "lmx"; + + interconnects = <&lpass_lpicx_noc MASTER_LPASS_PROC QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + + memory-region = <&adspslpi_mem>, + <&q6_adsp_dtb_mem>; + + qcom,qmp = <&aoss_qmp>; + + qcom,smem-states = <&smp2p_adsp_out 0>; + qcom,smem-state-names = "stop"; + + status = "disabled"; + + glink-edge { + interrupts-extended = <&ipcc IPCC_CLIENT_LPASS + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + mboxes = <&ipcc IPCC_CLIENT_LPASS + IPCC_MPROC_SIGNAL_GLINK_QMP>; + + label = "lpass"; + qcom,remote-pid = <2>; + + fastrpc { + compatible = "qcom,fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "adsp"; + qcom,non-secure-domain; + #address-cells = <1>; + #size-cells = <0>; + + compute-cb@3 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <3>; + iommus = <&apps_smmu 0x1003 0x80>, + <&apps_smmu 0x1063 0x0>; + dma-coherent; + }; + + compute-cb@4 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <4>; + iommus = <&apps_smmu 0x1004 0x80>, + <&apps_smmu 0x1064 0x0>; + dma-coherent; + }; + + compute-cb@5 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <5>; + iommus = <&apps_smmu 0x1005 0x80>, + <&apps_smmu 0x1065 0x0>; + dma-coherent; + }; + + compute-cb@6 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <6>; + iommus = <&apps_smmu 0x1006 0x80>, + <&apps_smmu 0x1066 0x0>; + dma-coherent; + }; + + compute-cb@7 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <7>; + iommus = <&apps_smmu 0x1007 0x80>, + <&apps_smmu 0x1067 0x0>; + dma-coherent; + }; + }; + + gpr { + compatible = "qcom,gpr"; + qcom,glink-channels = "adsp_apps"; + qcom,domain = <GPR_DOMAIN_ID_ADSP>; + qcom,intents = <512 20>; + #address-cells = <1>; + #size-cells = <0>; + + q6apm: service@1 { + compatible = "qcom,q6apm"; + reg = <GPR_APM_MODULE_IID>; + #sound-dai-cells = <0>; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + + q6apmbedai: bedais { + compatible = "qcom,q6apm-lpass-dais"; + #sound-dai-cells = <1>; + }; + + q6apmdai: dais { + compatible = "qcom,q6apm-dais"; + iommus = <&apps_smmu 0x1001 0x80>, + <&apps_smmu 0x1061 0x0>; + }; + }; + + q6prm: service@2 { + compatible = "qcom,q6prm"; + reg = <GPR_PRM_MODULE_IID>; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + + q6prmcc: clock-controller { + compatible = "qcom,q6prm-lpass-clocks"; + #clock-cells = <2>; + }; + }; + }; + }; + }; + lpass_wsa2macro: codec@6aa0000 { compatible = "qcom,x1e80100-lpass-wsa-macro", "qcom,sm8550-lpass-wsa-macro"; reg = <0 0x06aa0000 0 0x1000>; @@ -4118,7 +4255,7 @@ usb_2: usb@a2f8800 { <&gcc GCC_USB20_MASTER_CLK>; assigned-clock-rates = <19200000>, <200000000>;
- interrupts-extended = <&intc GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&intc GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>, <&pdc 50 IRQ_TYPE_EDGE_BOTH>, <&pdc 49 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "pwr_event", @@ -4144,7 +4281,7 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, usb_2_dwc3: usb@a200000 { compatible = "snps,dwc3"; reg = <0 0x0a200000 0 0xcd00>; - interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>; iommus = <&apps_smmu 0x14e0 0x0>; phys = <&usb_2_hsphy>; phy-names = "usb2-phy"; @@ -6111,146 +6248,9 @@ system-cache-controller@25000000 { interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>; };
- remoteproc_adsp: remoteproc@30000000 { - compatible = "qcom,x1e80100-adsp-pas"; - reg = <0 0x30000000 0 0x100>; - - interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, - <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>; - interrupt-names = "wdog", - "fatal", - "ready", - "handover", - "stop-ack"; - - clocks = <&rpmhcc RPMH_CXO_CLK>; - clock-names = "xo"; - - power-domains = <&rpmhpd RPMHPD_LCX>, - <&rpmhpd RPMHPD_LMX>; - power-domain-names = "lcx", - "lmx"; - - interconnects = <&lpass_lpicx_noc MASTER_LPASS_PROC QCOM_ICC_TAG_ALWAYS - &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; - - memory-region = <&adspslpi_mem>, - <&q6_adsp_dtb_mem>; - - qcom,qmp = <&aoss_qmp>; - - qcom,smem-states = <&smp2p_adsp_out 0>; - qcom,smem-state-names = "stop"; - - status = "disabled"; - - glink-edge { - interrupts-extended = <&ipcc IPCC_CLIENT_LPASS - IPCC_MPROC_SIGNAL_GLINK_QMP - IRQ_TYPE_EDGE_RISING>; - mboxes = <&ipcc IPCC_CLIENT_LPASS - IPCC_MPROC_SIGNAL_GLINK_QMP>; - - label = "lpass"; - qcom,remote-pid = <2>; - - fastrpc { - compatible = "qcom,fastrpc"; - qcom,glink-channels = "fastrpcglink-apps-dsp"; - label = "adsp"; - qcom,non-secure-domain; - #address-cells = <1>; - #size-cells = <0>; - - compute-cb@3 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <3>; - iommus = <&apps_smmu 0x1003 0x80>, - <&apps_smmu 0x1063 0x0>; - dma-coherent; - }; - - compute-cb@4 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <4>; - iommus = <&apps_smmu 0x1004 0x80>, - <&apps_smmu 0x1064 0x0>; - dma-coherent; - }; - - compute-cb@5 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <5>; - iommus = <&apps_smmu 0x1005 0x80>, - <&apps_smmu 0x1065 0x0>; - dma-coherent; - }; - - compute-cb@6 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <6>; - iommus = <&apps_smmu 0x1006 0x80>, - <&apps_smmu 0x1066 0x0>; - dma-coherent; - }; - - compute-cb@7 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <7>; - iommus = <&apps_smmu 0x1007 0x80>, - <&apps_smmu 0x1067 0x0>; - dma-coherent; - }; - }; - - gpr { - compatible = "qcom,gpr"; - qcom,glink-channels = "adsp_apps"; - qcom,domain = <GPR_DOMAIN_ID_ADSP>; - qcom,intents = <512 20>; - #address-cells = <1>; - #size-cells = <0>; - - q6apm: service@1 { - compatible = "qcom,q6apm"; - reg = <GPR_APM_MODULE_IID>; - #sound-dai-cells = <0>; - qcom,protection-domain = "avs/audio", - "msm/adsp/audio_pd"; - - q6apmbedai: bedais { - compatible = "qcom,q6apm-lpass-dais"; - #sound-dai-cells = <1>; - }; - - q6apmdai: dais { - compatible = "qcom,q6apm-dais"; - iommus = <&apps_smmu 0x1001 0x80>, - <&apps_smmu 0x1061 0x0>; - }; - }; - - q6prm: service@2 { - compatible = "qcom,q6prm"; - reg = <GPR_PRM_MODULE_IID>; - qcom,protection-domain = "avs/audio", - "msm/adsp/audio_pd"; - - q6prmcc: clock-controller { - compatible = "qcom,q6prm-lpass-clocks"; - #clock-cells = <2>; - }; - }; - }; - }; - }; - remoteproc_cdsp: remoteproc@32300000 { compatible = "qcom,x1e80100-cdsp-pas"; - reg = <0 0x32300000 0 0x1400000>; + reg = <0x0 0x32300000 0x0 0x10000>;
interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi index d12e661dfd99..995b30a7aae0 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi @@ -182,7 +182,7 @@ &gmac { snps,reset-active-low; snps,reset-delays-us = <0 10000 50000>; tx_delay = <0x10>; - rx_delay = <0x10>; + rx_delay = <0x23>; status = "okay"; };
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index 3d8d534a7a77..ad63457a05c5 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h @@ -343,6 +343,11 @@ alternative_cb_end // Narrow PARange to fit the PS field in TCR_ELx ubfx \tmp0, \tmp0, #ID_AA64MMFR0_EL1_PARANGE_SHIFT, #3 mov \tmp1, #ID_AA64MMFR0_EL1_PARANGE_MAX +#ifdef CONFIG_ARM64_LPA2 +alternative_if_not ARM64_HAS_VA52 + mov \tmp1, #ID_AA64MMFR0_EL1_PARANGE_48 +alternative_else_nop_endif +#endif cmp \tmp0, \tmp1 csel \tmp0, \tmp1, \tmp0, hi bfi \tcr, \tmp0, \pos, #3 diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h index c78a988cca93..a9136cc551cc 100644 --- a/arch/arm64/include/asm/pgtable-hwdef.h +++ b/arch/arm64/include/asm/pgtable-hwdef.h @@ -222,12 +222,6 @@ */ #define S1_TABLE_AP (_AT(pmdval_t, 3) << 61)
-/* - * Highest possible physical address supported. - */ -#define PHYS_MASK_SHIFT (CONFIG_ARM64_PA_BITS) -#define PHYS_MASK ((UL(1) << PHYS_MASK_SHIFT) - 1) - #define TTBR_CNP_BIT (UL(1) << 0)
/* diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h index 9f9cf13bbd95..a95f1f77bb39 100644 --- a/arch/arm64/include/asm/pgtable-prot.h +++ b/arch/arm64/include/asm/pgtable-prot.h @@ -81,6 +81,7 @@ extern unsigned long prot_ns_shared; #define lpa2_is_enabled() false #define PTE_MAYBE_SHARED PTE_SHARED #define PMD_MAYBE_SHARED PMD_SECT_S +#define PHYS_MASK_SHIFT (CONFIG_ARM64_PA_BITS) #else static inline bool __pure lpa2_is_enabled(void) { @@ -89,8 +90,14 @@ static inline bool __pure lpa2_is_enabled(void)
#define PTE_MAYBE_SHARED (lpa2_is_enabled() ? 0 : PTE_SHARED) #define PMD_MAYBE_SHARED (lpa2_is_enabled() ? 0 : PMD_SECT_S) +#define PHYS_MASK_SHIFT (lpa2_is_enabled() ? CONFIG_ARM64_PA_BITS : 48) #endif
+/* + * Highest possible physical address supported. + */ +#define PHYS_MASK ((UL(1) << PHYS_MASK_SHIFT) - 1) + /* * If we have userspace only BTI we don't want to mark kernel pages * guarded even if the system does support BTI. diff --git a/arch/arm64/include/asm/sparsemem.h b/arch/arm64/include/asm/sparsemem.h index 8a8acc220371..84783efdc9d1 100644 --- a/arch/arm64/include/asm/sparsemem.h +++ b/arch/arm64/include/asm/sparsemem.h @@ -5,7 +5,10 @@ #ifndef __ASM_SPARSEMEM_H #define __ASM_SPARSEMEM_H
-#define MAX_PHYSMEM_BITS CONFIG_ARM64_PA_BITS +#include <asm/pgtable-prot.h> + +#define MAX_PHYSMEM_BITS PHYS_MASK_SHIFT +#define MAX_POSSIBLE_PHYSMEM_BITS (52)
/* * Section size must be at least 512MB for 64K base diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 6ce71f444ed8..a5fe6b641a9f 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1167,12 +1167,6 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info) id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) { unsigned long cpacr = cpacr_save_enable_kernel_sme();
- /* - * We mask out SMPS since even if the hardware - * supports priorities the kernel does not at present - * and we block access to them. - */ - info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS; vec_init_vq_map(ARM64_VEC_SME);
cpacr_restore(cpacr); @@ -1423,13 +1417,6 @@ void update_cpu_features(int cpu, id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) { unsigned long cpacr = cpacr_save_enable_kernel_sme();
- /* - * We mask out SMPS since even if the hardware - * supports priorities the kernel does not at present - * and we block access to them. - */ - info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS; - /* Probe vector lengths */ if (!system_capabilities_finalized()) vec_update_vq_map(ARM64_VEC_SME); @@ -3022,6 +3009,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .matches = match, \ }
+#define HWCAP_CAP_MATCH_ID(match, reg, field, min_value, cap_type, cap) \ + { \ + __HWCAP_CAP(#cap, cap_type, cap) \ + HWCAP_CPUID_MATCH(reg, field, min_value) \ + .matches = match, \ + } + #ifdef CONFIG_ARM64_PTR_AUTH static const struct arm64_cpu_capabilities ptr_auth_hwcap_addr_matches[] = { { @@ -3050,6 +3044,13 @@ static const struct arm64_cpu_capabilities ptr_auth_hwcap_gen_matches[] = { }; #endif
+#ifdef CONFIG_ARM64_SVE +static bool has_sve_feature(const struct arm64_cpu_capabilities *cap, int scope) +{ + return system_supports_sve() && has_user_cpuid_feature(cap, scope); +} +#endif + static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { HWCAP_CAP(ID_AA64ISAR0_EL1, AES, PMULL, CAP_HWCAP, KERNEL_HWCAP_PMULL), HWCAP_CAP(ID_AA64ISAR0_EL1, AES, AES, CAP_HWCAP, KERNEL_HWCAP_AES), @@ -3092,19 +3093,19 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { HWCAP_CAP(ID_AA64MMFR2_EL1, AT, IMP, CAP_HWCAP, KERNEL_HWCAP_USCAT), #ifdef CONFIG_ARM64_SVE HWCAP_CAP(ID_AA64PFR0_EL1, SVE, IMP, CAP_HWCAP, KERNEL_HWCAP_SVE), - HWCAP_CAP(ID_AA64ZFR0_EL1, SVEver, SVE2p1, CAP_HWCAP, KERNEL_HWCAP_SVE2P1), - HWCAP_CAP(ID_AA64ZFR0_EL1, SVEver, SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2), - HWCAP_CAP(ID_AA64ZFR0_EL1, AES, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEAES), - HWCAP_CAP(ID_AA64ZFR0_EL1, AES, PMULL128, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL), - HWCAP_CAP(ID_AA64ZFR0_EL1, BitPerm, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM), - HWCAP_CAP(ID_AA64ZFR0_EL1, B16B16, IMP, CAP_HWCAP, KERNEL_HWCAP_SVE_B16B16), - HWCAP_CAP(ID_AA64ZFR0_EL1, BF16, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBF16), - HWCAP_CAP(ID_AA64ZFR0_EL1, BF16, EBF16, CAP_HWCAP, KERNEL_HWCAP_SVE_EBF16), - HWCAP_CAP(ID_AA64ZFR0_EL1, SHA3, IMP, CAP_HWCAP, KERNEL_HWCAP_SVESHA3), - HWCAP_CAP(ID_AA64ZFR0_EL1, SM4, IMP, CAP_HWCAP, KERNEL_HWCAP_SVESM4), - HWCAP_CAP(ID_AA64ZFR0_EL1, I8MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM), - HWCAP_CAP(ID_AA64ZFR0_EL1, F32MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM), - HWCAP_CAP(ID_AA64ZFR0_EL1, F64MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM), + HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SVEver, SVE2p1, CAP_HWCAP, KERNEL_HWCAP_SVE2P1), + HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SVEver, SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2), + HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, AES, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEAES), + HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, AES, PMULL128, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL), + HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, BitPerm, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM), + HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, B16B16, IMP, CAP_HWCAP, KERNEL_HWCAP_SVE_B16B16), + HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, BF16, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBF16), + HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, BF16, EBF16, CAP_HWCAP, KERNEL_HWCAP_SVE_EBF16), + HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SHA3, IMP, CAP_HWCAP, KERNEL_HWCAP_SVESHA3), + HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SM4, IMP, CAP_HWCAP, KERNEL_HWCAP_SVESM4), + HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, I8MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM), + HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, F32MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM), + HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, F64MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM), #endif #ifdef CONFIG_ARM64_GCS HWCAP_CAP(ID_AA64PFR1_EL1, GCS, IMP, CAP_HWCAP, KERNEL_HWCAP_GCS), @@ -3478,7 +3479,7 @@ static void verify_hyp_capabilities(void) return;
safe_mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1); - mmfr0 = read_cpuid(ID_AA64MMFR0_EL1); + mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1); mmfr1 = read_cpuid(ID_AA64MMFR1_EL1);
/* Verify VMID bits */ diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index d79e88fccdfc..c45633b5ae23 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c @@ -482,6 +482,16 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info) if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0)) info->reg_mpamidr = read_cpuid(MPAMIDR_EL1);
+ if (IS_ENABLED(CONFIG_ARM64_SME) && + id_aa64pfr1_sme(info->reg_id_aa64pfr1)) { + /* + * We mask out SMPS since even if the hardware + * supports priorities the kernel does not at present + * and we block access to them. + */ + info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS; + } + cpuinfo_detect_icache_policy(info); }
diff --git a/arch/arm64/kernel/pi/idreg-override.c b/arch/arm64/kernel/pi/idreg-override.c index 22159251eb3a..c6b185b885f7 100644 --- a/arch/arm64/kernel/pi/idreg-override.c +++ b/arch/arm64/kernel/pi/idreg-override.c @@ -83,6 +83,15 @@ static bool __init mmfr2_varange_filter(u64 val) id_aa64mmfr0_override.val |= (ID_AA64MMFR0_EL1_TGRAN_LPA2 - 1) << ID_AA64MMFR0_EL1_TGRAN_SHIFT; id_aa64mmfr0_override.mask |= 0xfU << ID_AA64MMFR0_EL1_TGRAN_SHIFT; + + /* + * Override PARange to 48 bits - the override will just be + * ignored if the actual PARange is smaller, but this is + * unlikely to be the case for LPA2 capable silicon. + */ + id_aa64mmfr0_override.val |= + ID_AA64MMFR0_EL1_PARANGE_48 << ID_AA64MMFR0_EL1_PARANGE_SHIFT; + id_aa64mmfr0_override.mask |= 0xfU << ID_AA64MMFR0_EL1_PARANGE_SHIFT; } #endif return true; diff --git a/arch/arm64/kernel/pi/map_kernel.c b/arch/arm64/kernel/pi/map_kernel.c index f374a3e5a5fe..e57b043f324b 100644 --- a/arch/arm64/kernel/pi/map_kernel.c +++ b/arch/arm64/kernel/pi/map_kernel.c @@ -136,6 +136,12 @@ static void noinline __section(".idmap.text") set_ttbr0_for_lpa2(u64 ttbr) { u64 sctlr = read_sysreg(sctlr_el1); u64 tcr = read_sysreg(tcr_el1) | TCR_DS; + u64 mmfr0 = read_sysreg(id_aa64mmfr0_el1); + u64 parange = cpuid_feature_extract_unsigned_field(mmfr0, + ID_AA64MMFR0_EL1_PARANGE_SHIFT); + + tcr &= ~TCR_IPS_MASK; + tcr |= parange << TCR_IPS_SHIFT;
asm(" msr sctlr_el1, %0 ;" " isb ;" diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 1215df590418..754914d9ec68 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -466,10 +466,8 @@ static void timer_emulate(struct arch_timer_context *ctx)
trace_kvm_timer_emulate(ctx, should_fire);
- if (should_fire != ctx->irq.level) { + if (should_fire != ctx->irq.level) kvm_timer_update_irq(ctx->vcpu, should_fire, ctx); - return; - }
/* * If the timer can fire now, we don't need to have a soft timer diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index a102c3aebdbc..7b2735ad32e9 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1990,8 +1990,7 @@ static int kvm_init_vector_slots(void) static void __init cpu_prepare_hyp_mode(int cpu, u32 hyp_va_bits) { struct kvm_nvhe_init_params *params = per_cpu_ptr_nvhe_sym(kvm_init_params, cpu); - u64 mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1); - unsigned long tcr; + unsigned long tcr, ips;
/* * Calculate the raw per-cpu offset without a translation from the @@ -2005,6 +2004,7 @@ static void __init cpu_prepare_hyp_mode(int cpu, u32 hyp_va_bits) params->mair_el2 = read_sysreg(mair_el1);
tcr = read_sysreg(tcr_el1); + ips = FIELD_GET(TCR_IPS_MASK, tcr); if (cpus_have_final_cap(ARM64_KVM_HVHE)) { tcr |= TCR_EPD1_MASK; } else { @@ -2014,8 +2014,8 @@ static void __init cpu_prepare_hyp_mode(int cpu, u32 hyp_va_bits) tcr &= ~TCR_T0SZ_MASK; tcr |= TCR_T0SZ(hyp_va_bits); tcr &= ~TCR_EL2_PS_MASK; - tcr |= FIELD_PREP(TCR_EL2_PS_MASK, kvm_get_parange(mmfr0)); - if (kvm_lpa2_is_enabled()) + tcr |= FIELD_PREP(TCR_EL2_PS_MASK, ips); + if (lpa2_is_enabled()) tcr |= TCR_EL2_DS; params->tcr_el2 = tcr;
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index 3215adf48a1b..98a2a0e64e25 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -519,6 +519,18 @@ pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
static int __init hugetlbpage_init(void) { + /* + * HugeTLB pages are supported on maximum four page table + * levels (PUD, CONT PMD, PMD, CONT PTE) for a given base + * page size, corresponding to hugetlb_add_hstate() calls + * here. + * + * HUGE_MAX_HSTATE should at least match maximum supported + * HugeTLB page sizes on the platform. Any new addition to + * supported HugeTLB page sizes will also require changing + * HUGE_MAX_HSTATE as well. + */ + BUILD_BUG_ON(HUGE_MAX_HSTATE < 4); if (pud_sect_supported()) hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index ccdef53872a0..9c0b8d9558fc 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -279,7 +279,12 @@ void __init arm64_memblock_init(void)
if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) { extern u16 memstart_offset_seed; - u64 mmfr0 = read_cpuid(ID_AA64MMFR0_EL1); + + /* + * Use the sanitised version of id_aa64mmfr0_el1 so that linear + * map randomization can be enabled by shrinking the IPA space. + */ + u64 mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1); int parange = cpuid_feature_extract_unsigned_field( mmfr0, ID_AA64MMFR0_EL1_PARANGE_SHIFT); s64 range = linear_region_size - diff --git a/arch/loongarch/include/uapi/asm/ptrace.h b/arch/loongarch/include/uapi/asm/ptrace.h index ac915f841650..aafb3cd9e943 100644 --- a/arch/loongarch/include/uapi/asm/ptrace.h +++ b/arch/loongarch/include/uapi/asm/ptrace.h @@ -72,6 +72,16 @@ struct user_watch_state { } dbg_regs[8]; };
+struct user_watch_state_v2 { + uint64_t dbg_info; + struct { + uint64_t addr; + uint64_t mask; + uint32_t ctrl; + uint32_t pad; + } dbg_regs[14]; +}; + #define PTRACE_SYSEMU 0x1f #define PTRACE_SYSEMU_SINGLESTEP 0x20
diff --git a/arch/loongarch/kernel/ptrace.c b/arch/loongarch/kernel/ptrace.c index 19dc6eff45cc..5e2402cfcab0 100644 --- a/arch/loongarch/kernel/ptrace.c +++ b/arch/loongarch/kernel/ptrace.c @@ -720,7 +720,7 @@ static int hw_break_set(struct task_struct *target, unsigned int note_type = regset->core_note_type;
/* Resource info */ - offset = offsetof(struct user_watch_state, dbg_regs); + offset = offsetof(struct user_watch_state_v2, dbg_regs); user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, offset);
/* (address, mask, ctrl) registers */ @@ -920,7 +920,7 @@ static const struct user_regset loongarch64_regsets[] = { #ifdef CONFIG_HAVE_HW_BREAKPOINT [REGSET_HW_BREAK] = { .core_note_type = NT_LOONGARCH_HW_BREAK, - .n = sizeof(struct user_watch_state) / sizeof(u32), + .n = sizeof(struct user_watch_state_v2) / sizeof(u32), .size = sizeof(u32), .align = sizeof(u32), .regset_get = hw_break_get, @@ -928,7 +928,7 @@ static const struct user_regset loongarch64_regsets[] = { }, [REGSET_HW_WATCH] = { .core_note_type = NT_LOONGARCH_HW_WATCH, - .n = sizeof(struct user_watch_state) / sizeof(u32), + .n = sizeof(struct user_watch_state_v2) / sizeof(u32), .size = sizeof(u32), .align = sizeof(u32), .regset_get = hw_break_get, diff --git a/arch/m68k/include/asm/vga.h b/arch/m68k/include/asm/vga.h index 4742e6bc3ab8..cdd414fa8710 100644 --- a/arch/m68k/include/asm/vga.h +++ b/arch/m68k/include/asm/vga.h @@ -9,7 +9,7 @@ */ #ifndef CONFIG_PCI
-#include <asm/raw_io.h> +#include <asm/io.h> #include <asm/kmap.h>
/* @@ -29,9 +29,9 @@ #define inw_p(port) 0 #define outb_p(port, val) do { } while (0) #define outw(port, val) do { } while (0) -#define readb raw_inb -#define writeb raw_outb -#define writew raw_outw +#define readb __raw_readb +#define writeb __raw_writeb +#define writew __raw_writew
#endif /* CONFIG_PCI */ #endif /* _ASM_M68K_VGA_H */ diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 467b10f4361a..5078ebf071ec 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1084,7 +1084,6 @@ config CSRC_IOASIC
config CSRC_R4K select CLOCKSOURCE_WATCHDOG if CPU_FREQ - select HAVE_UNSTABLE_SCHED_CLOCK if SMP && 64BIT bool
config CSRC_SB1250 diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index 8c401e42301c..f39e85fd58fa 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c @@ -248,7 +248,7 @@ int ftrace_disable_ftrace_graph_caller(void) #define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */ #define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */
-unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long +static unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long old_parent_ra, unsigned long parent_ra_addr, unsigned long fp) { unsigned long sp, ip, tmp; diff --git a/arch/mips/loongson64/boardinfo.c b/arch/mips/loongson64/boardinfo.c index 280989c5a137..8bb275c93ac0 100644 --- a/arch/mips/loongson64/boardinfo.c +++ b/arch/mips/loongson64/boardinfo.c @@ -21,13 +21,11 @@ static ssize_t boardinfo_show(struct kobject *kobj, "BIOS Info\n" "Vendor\t\t\t: %s\n" "Version\t\t\t: %s\n" - "ROM Size\t\t: %d KB\n" "Release Date\t\t: %s\n", strsep(&tmp_board_manufacturer, "-"), eboard->name, strsep(&tmp_bios_vendor, "-"), einter->description, - einter->size, especial->special_name); } static struct kobj_attribute boardinfo_attr = __ATTR(boardinfo, 0444, diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index 265bc57819df..c89e70df43d8 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -1660,7 +1660,7 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, break; }
- case 0x3: + case 0x7: if (MIPSInst_FUNC(ir) != pfetch_op) return SIGILL;
diff --git a/arch/mips/pci/pci-legacy.c b/arch/mips/pci/pci-legacy.c index ec2567f8efd8..66898fd182dc 100644 --- a/arch/mips/pci/pci-legacy.c +++ b/arch/mips/pci/pci-legacy.c @@ -29,6 +29,14 @@ static LIST_HEAD(controllers);
static int pci_initialized;
+unsigned long pci_address_to_pio(phys_addr_t address) +{ + if (address > IO_SPACE_LIMIT) + return (unsigned long)-1; + + return (unsigned long) address; +} + /* * We need to avoid collisions with `mirrored' VGA ports * and other strange ISA hardware, so we always want the diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index aa6a3cad275d..fcc5973f7519 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -60,8 +60,8 @@ config PARISC select HAVE_ARCH_MMAP_RND_BITS select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_HASH - select HAVE_ARCH_JUMP_LABEL - select HAVE_ARCH_JUMP_LABEL_RELATIVE + # select HAVE_ARCH_JUMP_LABEL + # select HAVE_ARCH_JUMP_LABEL_RELATIVE select HAVE_ARCH_KFENCE select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c index 1893f66371fa..b12ef382fec7 100644 --- a/arch/powerpc/platforms/pseries/eeh_pseries.c +++ b/arch/powerpc/platforms/pseries/eeh_pseries.c @@ -580,8 +580,10 @@ static int pseries_eeh_get_state(struct eeh_pe *pe, int *delay)
switch(rets[0]) { case 0: - result = EEH_STATE_MMIO_ACTIVE | - EEH_STATE_DMA_ACTIVE; + result = EEH_STATE_MMIO_ACTIVE | + EEH_STATE_DMA_ACTIVE | + EEH_STATE_MMIO_ENABLED | + EEH_STATE_DMA_ENABLED; break; case 1: result = EEH_STATE_RESET_ACTIVE | diff --git a/arch/s390/include/asm/asm-extable.h b/arch/s390/include/asm/asm-extable.h index 4a6b0a8b6412..00a67464c445 100644 --- a/arch/s390/include/asm/asm-extable.h +++ b/arch/s390/include/asm/asm-extable.h @@ -14,6 +14,7 @@ #define EX_TYPE_UA_LOAD_REG 5 #define EX_TYPE_UA_LOAD_REGPAIR 6 #define EX_TYPE_ZEROPAD 7 +#define EX_TYPE_FPC 8
#define EX_DATA_REG_ERR_SHIFT 0 #define EX_DATA_REG_ERR GENMASK(3, 0) @@ -84,4 +85,7 @@ #define EX_TABLE_ZEROPAD(_fault, _target, _regdata, _regaddr) \ __EX_TABLE(__ex_table, _fault, _target, EX_TYPE_ZEROPAD, _regdata, _regaddr, 0)
+#define EX_TABLE_FPC(_fault, _target) \ + __EX_TABLE(__ex_table, _fault, _target, EX_TYPE_FPC, __stringify(%%r0), __stringify(%%r0), 0) + #endif /* __ASM_EXTABLE_H */ diff --git a/arch/s390/include/asm/fpu-insn.h b/arch/s390/include/asm/fpu-insn.h index c1e2e521d9af..a4c9b4db62ff 100644 --- a/arch/s390/include/asm/fpu-insn.h +++ b/arch/s390/include/asm/fpu-insn.h @@ -100,19 +100,12 @@ static __always_inline void fpu_lfpc(unsigned int *fpc) */ static inline void fpu_lfpc_safe(unsigned int *fpc) { - u32 tmp; - instrument_read(fpc, sizeof(*fpc)); - asm volatile("\n" - "0: lfpc %[fpc]\n" - "1: nopr %%r7\n" - ".pushsection .fixup, "ax"\n" - "2: lghi %[tmp],0\n" - " sfpc %[tmp]\n" - " jg 1b\n" - ".popsection\n" - EX_TABLE(1b, 2b) - : [tmp] "=d" (tmp) + asm_inline volatile( + " lfpc %[fpc]\n" + "0: nopr %%r7\n" + EX_TABLE_FPC(0b, 0b) + : : [fpc] "Q" (*fpc) : "memory"); } diff --git a/arch/s390/include/asm/futex.h b/arch/s390/include/asm/futex.h index eaeaeb3ff0be..752a2310f0d6 100644 --- a/arch/s390/include/asm/futex.h +++ b/arch/s390/include/asm/futex.h @@ -44,7 +44,7 @@ static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, break; case FUTEX_OP_ANDN: __futex_atomic_op("lr %2,%1\nnr %2,%5\n", - ret, oldval, newval, uaddr, oparg); + ret, oldval, newval, uaddr, ~oparg); break; case FUTEX_OP_XOR: __futex_atomic_op("lr %2,%1\nxr %2,%5\n", diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 8761fd01a9f0..4f8d5592c298 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -163,8 +163,7 @@ static __always_inline void __stackleak_poison(unsigned long erase_low, " la %[addr],256(%[addr])\n" " brctg %[tmp],0b\n" "1: stg %[poison],0(%[addr])\n" - " larl %[tmp],3f\n" - " ex %[count],0(%[tmp])\n" + " exrl %[count],3f\n" " j 4f\n" "2: stg %[poison],0(%[addr])\n" " j 4f\n" diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 377b9aaf8c92..ff1ddba96352 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -52,7 +52,6 @@ SECTIONS SOFTIRQENTRY_TEXT FTRACE_HOTPATCH_TRAMPOLINES_TEXT *(.text.*_indirect_*) - *(.fixup) *(.gnu.warning) . = ALIGN(PAGE_SIZE); _etext = .; /* End of text section */ diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c index a687695d8f68..513e608567cc 100644 --- a/arch/s390/kvm/vsie.c +++ b/arch/s390/kvm/vsie.c @@ -1362,8 +1362,14 @@ static struct vsie_page *get_vsie_page(struct kvm *kvm, unsigned long addr) page = radix_tree_lookup(&kvm->arch.vsie.addr_to_page, addr >> 9); rcu_read_unlock(); if (page) { - if (page_ref_inc_return(page) == 2) - return page_to_virt(page); + if (page_ref_inc_return(page) == 2) { + if (page->index == addr) + return page_to_virt(page); + /* + * We raced with someone reusing + putting this vsie + * page before we grabbed it. + */ + } page_ref_dec(page); }
@@ -1393,15 +1399,20 @@ static struct vsie_page *get_vsie_page(struct kvm *kvm, unsigned long addr) kvm->arch.vsie.next++; kvm->arch.vsie.next %= nr_vcpus; } - radix_tree_delete(&kvm->arch.vsie.addr_to_page, page->index >> 9); + if (page->index != ULONG_MAX) + radix_tree_delete(&kvm->arch.vsie.addr_to_page, + page->index >> 9); } - page->index = addr; - /* double use of the same address */ + /* Mark it as invalid until it resides in the tree. */ + page->index = ULONG_MAX; + + /* Double use of the same address or allocation failure. */ if (radix_tree_insert(&kvm->arch.vsie.addr_to_page, addr >> 9, page)) { page_ref_dec(page); mutex_unlock(&kvm->arch.vsie.mutex); return NULL; } + page->index = addr; mutex_unlock(&kvm->arch.vsie.mutex);
vsie_page = page_to_virt(page); @@ -1496,7 +1507,9 @@ void kvm_s390_vsie_destroy(struct kvm *kvm) vsie_page = page_to_virt(page); release_gmap_shadow(vsie_page); /* free the radix tree entry */ - radix_tree_delete(&kvm->arch.vsie.addr_to_page, page->index >> 9); + if (page->index != ULONG_MAX) + radix_tree_delete(&kvm->arch.vsie.addr_to_page, + page->index >> 9); __free_page(page); } kvm->arch.vsie.page_count = 0; diff --git a/arch/s390/mm/extable.c b/arch/s390/mm/extable.c index 0a0738a473af..812ec5be1291 100644 --- a/arch/s390/mm/extable.c +++ b/arch/s390/mm/extable.c @@ -77,6 +77,13 @@ static bool ex_handler_zeropad(const struct exception_table_entry *ex, struct pt return true; }
+static bool ex_handler_fpc(const struct exception_table_entry *ex, struct pt_regs *regs) +{ + asm volatile("sfpc %[val]\n" : : [val] "d" (0)); + regs->psw.addr = extable_fixup(ex); + return true; +} + bool fixup_exception(struct pt_regs *regs) { const struct exception_table_entry *ex; @@ -99,6 +106,8 @@ bool fixup_exception(struct pt_regs *regs) return ex_handler_ua_load_reg(ex, true, regs); case EX_TYPE_ZEROPAD: return ex_handler_zeropad(ex, regs); + case EX_TYPE_FPC: + return ex_handler_fpc(ex, regs); } panic("invalid exception table entry"); } diff --git a/arch/s390/pci/pci_bus.c b/arch/s390/pci/pci_bus.c index d5ace00d10f0..857afbc4828f 100644 --- a/arch/s390/pci/pci_bus.c +++ b/arch/s390/pci/pci_bus.c @@ -171,7 +171,6 @@ void zpci_bus_scan_busses(void) static bool zpci_bus_is_multifunction_root(struct zpci_dev *zdev) { return !s390_pci_no_rid && zdev->rid_available && - zpci_is_device_configured(zdev) && !zdev->vfn; }
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index f2051644de94..606c74f27459 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -25,6 +25,7 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \ # avoid errors with '-march=i386', and future flags may depend on the target to # be valid. KBUILD_CFLAGS := -m$(BITS) -O2 $(CLANG_FLAGS) +KBUILD_CFLAGS += -std=gnu11 KBUILD_CFLAGS += -fno-strict-aliasing -fPIE KBUILD_CFLAGS += -Wundef KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h index ae5482a2f0ca..ccb8ff37fa9d 100644 --- a/arch/x86/include/asm/kexec.h +++ b/arch/x86/include/asm/kexec.h @@ -16,6 +16,7 @@ # define PAGES_NR 4 #endif
+# define KEXEC_CONTROL_PAGE_SIZE 4096 # define KEXEC_CONTROL_CODE_MAX_SIZE 2048
#ifndef __ASSEMBLY__ @@ -43,7 +44,6 @@ struct kimage; /* Maximum address we can use for the control code buffer */ # define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
-# define KEXEC_CONTROL_PAGE_SIZE 4096
/* The native architecture */ # define KEXEC_ARCH KEXEC_ARCH_386 @@ -58,9 +58,6 @@ struct kimage; /* Maximum address we can use for the control pages */ # define KEXEC_CONTROL_MEMORY_LIMIT (MAXMEM-1)
-/* Allocate one page for the pdp and the second for the code */ -# define KEXEC_CONTROL_PAGE_SIZE (4096UL + 4096UL) - /* The native architecture */ # define KEXEC_ARCH KEXEC_ARCH_X86_64 #endif @@ -145,6 +142,19 @@ struct kimage_arch { }; #else struct kimage_arch { + /* + * This is a kimage control page, as it must not overlap with either + * source or destination address ranges. + */ + pgd_t *pgd; + /* + * The virtual mapping of the control code page itself is used only + * during the transition, while the current kernel's pages are all + * in place. Thus the intermediate page table pages used to map it + * are not control pages, but instead just normal pages obtained + * with get_zeroed_page(). And have to be tracked (below) so that + * they can be freed. + */ p4d_t *p4d; pud_t *pud; pmd_t *pmd; diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 5aa50dfe0104..c1043f8c9b03 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -27,6 +27,7 @@ #include <linux/hyperv.h> #include <linux/kfifo.h> #include <linux/sched/vhost_task.h> +#include <linux/call_once.h>
#include <asm/apic.h> #include <asm/pvclock-abi.h> @@ -1445,6 +1446,7 @@ struct kvm_arch { struct kvm_x86_pmu_event_filter __rcu *pmu_event_filter; struct vhost_task *nx_huge_page_recovery_thread; u64 nx_huge_page_last; + struct once nx_once;
#ifdef CONFIG_X86_64 /* The number of TDP MMU pages across all roots. */ diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 3a44a9dc3fb7..18485170d51b 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -226,6 +226,28 @@ acpi_parse_x2apic(union acpi_subtable_headers *header, const unsigned long end) return 0; }
+static int __init +acpi_check_lapic(union acpi_subtable_headers *header, const unsigned long end) +{ + struct acpi_madt_local_apic *processor = NULL; + + processor = (struct acpi_madt_local_apic *)header; + + if (BAD_MADT_ENTRY(processor, end)) + return -EINVAL; + + /* Ignore invalid ID */ + if (processor->id == 0xff) + return 0; + + /* Ignore processors that can not be onlined */ + if (!acpi_is_processor_usable(processor->lapic_flags)) + return 0; + + has_lapic_cpus = true; + return 0; +} + static int __init acpi_parse_lapic(union acpi_subtable_headers * header, const unsigned long end) { @@ -257,7 +279,6 @@ acpi_parse_lapic(union acpi_subtable_headers * header, const unsigned long end) processor->processor_id, /* ACPI ID */ processor->lapic_flags & ACPI_MADT_ENABLED);
- has_lapic_cpus = true; return 0; }
@@ -1029,6 +1050,8 @@ static int __init early_acpi_parse_madt_lapic_addr_ovr(void) static int __init acpi_parse_madt_lapic_entries(void) { int count, x2count = 0; + struct acpi_subtable_proc madt_proc[2]; + int ret;
if (!boot_cpu_has(X86_FEATURE_APIC)) return -ENODEV; @@ -1037,10 +1060,27 @@ static int __init acpi_parse_madt_lapic_entries(void) acpi_parse_sapic, MAX_LOCAL_APIC);
if (!count) { - count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC, - acpi_parse_lapic, MAX_LOCAL_APIC); - x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC, - acpi_parse_x2apic, MAX_LOCAL_APIC); + /* Check if there are valid LAPIC entries */ + acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC, acpi_check_lapic, MAX_LOCAL_APIC); + + /* + * Enumerate the APIC IDs in the order that they appear in the + * MADT, no matter LAPIC entry or x2APIC entry is used. + */ + memset(madt_proc, 0, sizeof(madt_proc)); + madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_APIC; + madt_proc[0].handler = acpi_parse_lapic; + madt_proc[1].id = ACPI_MADT_TYPE_LOCAL_X2APIC; + madt_proc[1].handler = acpi_parse_x2apic; + ret = acpi_table_parse_entries_array(ACPI_SIG_MADT, + sizeof(struct acpi_table_madt), + madt_proc, ARRAY_SIZE(madt_proc), MAX_LOCAL_APIC); + if (ret < 0) { + pr_err("Error parsing LAPIC/X2APIC entries\n"); + return ret; + } + count = madt_proc[0].count; + x2count = madt_proc[1].count; } if (!count && !x2count) { pr_err("No LAPIC entries present\n"); diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index 9fe9972d2071..37b8244899d8 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -582,6 +582,10 @@ static __init void fix_erratum_688(void)
static __init int init_amd_nbs(void) { + if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD && + boot_cpu_data.x86_vendor != X86_VENDOR_HYGON) + return 0; + amd_cache_northbridges(); amd_cache_gart();
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index 9c9ac606893e..7223c38a8708 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c @@ -146,7 +146,8 @@ static void free_transition_pgtable(struct kimage *image) image->arch.pte = NULL; }
-static int init_transition_pgtable(struct kimage *image, pgd_t *pgd) +static int init_transition_pgtable(struct kimage *image, pgd_t *pgd, + unsigned long control_page) { pgprot_t prot = PAGE_KERNEL_EXEC_NOENC; unsigned long vaddr, paddr; @@ -157,7 +158,7 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd) pte_t *pte;
vaddr = (unsigned long)relocate_kernel; - paddr = __pa(page_address(image->control_code_page)+PAGE_SIZE); + paddr = control_page; pgd += pgd_index(vaddr); if (!pgd_present(*pgd)) { p4d = (p4d_t *)get_zeroed_page(GFP_KERNEL); @@ -216,7 +217,7 @@ static void *alloc_pgt_page(void *data) return p; }
-static int init_pgtable(struct kimage *image, unsigned long start_pgtable) +static int init_pgtable(struct kimage *image, unsigned long control_page) { struct x86_mapping_info info = { .alloc_pgt_page = alloc_pgt_page, @@ -225,12 +226,12 @@ static int init_pgtable(struct kimage *image, unsigned long start_pgtable) .kernpg_flag = _KERNPG_TABLE_NOENC, }; unsigned long mstart, mend; - pgd_t *level4p; int result; int i;
- level4p = (pgd_t *)__va(start_pgtable); - clear_page(level4p); + image->arch.pgd = alloc_pgt_page(image); + if (!image->arch.pgd) + return -ENOMEM;
if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) { info.page_flag |= _PAGE_ENC; @@ -244,8 +245,8 @@ static int init_pgtable(struct kimage *image, unsigned long start_pgtable) mstart = pfn_mapped[i].start << PAGE_SHIFT; mend = pfn_mapped[i].end << PAGE_SHIFT;
- result = kernel_ident_mapping_init(&info, - level4p, mstart, mend); + result = kernel_ident_mapping_init(&info, image->arch.pgd, + mstart, mend); if (result) return result; } @@ -260,8 +261,8 @@ static int init_pgtable(struct kimage *image, unsigned long start_pgtable) mstart = image->segment[i].mem; mend = mstart + image->segment[i].memsz;
- result = kernel_ident_mapping_init(&info, - level4p, mstart, mend); + result = kernel_ident_mapping_init(&info, image->arch.pgd, + mstart, mend);
if (result) return result; @@ -271,15 +272,19 @@ static int init_pgtable(struct kimage *image, unsigned long start_pgtable) * Prepare EFI systab and ACPI tables for kexec kernel since they are * not covered by pfn_mapped. */ - result = map_efi_systab(&info, level4p); + result = map_efi_systab(&info, image->arch.pgd); if (result) return result;
- result = map_acpi_tables(&info, level4p); + result = map_acpi_tables(&info, image->arch.pgd); if (result) return result;
- return init_transition_pgtable(image, level4p); + /* + * This must be last because the intermediate page table pages it + * allocates will not be control pages and may overlap the image. + */ + return init_transition_pgtable(image, image->arch.pgd, control_page); }
static void load_segments(void) @@ -296,14 +301,14 @@ static void load_segments(void)
int machine_kexec_prepare(struct kimage *image) { - unsigned long start_pgtable; + unsigned long control_page; int result;
/* Calculate the offsets */ - start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT; + control_page = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
/* Setup the identity mapped 64bit page table */ - result = init_pgtable(image, start_pgtable); + result = init_pgtable(image, control_page); if (result) return result;
@@ -357,13 +362,12 @@ void machine_kexec(struct kimage *image) #endif }
- control_page = page_address(image->control_code_page) + PAGE_SIZE; + control_page = page_address(image->control_code_page); __memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
page_list[PA_CONTROL_PAGE] = virt_to_phys(control_page); page_list[VA_CONTROL_PAGE] = (unsigned long)control_page; - page_list[PA_TABLE_PAGE] = - (unsigned long)__pa(page_address(image->control_code_page)); + page_list[PA_TABLE_PAGE] = (unsigned long)__pa(image->arch.pgd);
if (image->type == KEXEC_TYPE_DEFAULT) page_list[PA_SWAP_PAGE] = (page_to_pfn(image->swap_page) @@ -573,8 +577,7 @@ static void kexec_mark_crashkres(bool protect)
/* Don't touch the control code page used in crash_kexec().*/ control = PFN_PHYS(page_to_pfn(kexec_crash_image->control_code_page)); - /* Control code page is located in the 2nd page. */ - kexec_mark_range(crashk_res.start, control + PAGE_SIZE - 1, protect); + kexec_mark_range(crashk_res.start, control - 1, protect); control += KEXEC_CONTROL_PAGE_SIZE; kexec_mark_range(control, crashk_res.end, protect); } diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index f63f8fd00a91..15507e739c25 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -838,7 +838,7 @@ void __noreturn stop_this_cpu(void *dummy) #ifdef CONFIG_SMP if (smp_ops.stop_this_cpu) { smp_ops.stop_this_cpu(); - unreachable(); + BUG(); } #endif
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 615922838c51..dc1dd3f3e67f 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -883,7 +883,7 @@ static int crash_nmi_callback(unsigned int val, struct pt_regs *regs)
if (smp_ops.stop_this_cpu) { smp_ops.stop_this_cpu(); - unreachable(); + BUG(); }
/* Assume hlt works */ diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 39ae2f5f9866..d0913aceeae4 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -816,6 +816,17 @@ static inline void apic_clear_isr(int vec, struct kvm_lapic *apic) } }
+void kvm_apic_update_hwapic_isr(struct kvm_vcpu *vcpu) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + + if (WARN_ON_ONCE(!lapic_in_kernel(vcpu)) || !apic->apicv_active) + return; + + kvm_x86_call(hwapic_isr_update)(vcpu, apic_find_highest_isr(apic)); +} +EXPORT_SYMBOL_GPL(kvm_apic_update_hwapic_isr); + int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu) { /* This may race with setting of irr in __apic_accept_irq() and diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 24add38beaf0..1a8553ebdb42 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -118,6 +118,7 @@ void kvm_apic_send_ipi(struct kvm_lapic *apic, u32 icr_low, u32 icr_high); int kvm_apic_set_base(struct kvm_vcpu *vcpu, u64 value, bool host_initiated); int kvm_apic_get_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s); int kvm_apic_set_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s); +void kvm_apic_update_hwapic_isr(struct kvm_vcpu *vcpu); int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu);
u64 kvm_get_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 2401606db260..74c455193090 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -7090,6 +7090,19 @@ static void mmu_destroy_caches(void) kmem_cache_destroy(mmu_page_header_cache); }
+static void kvm_wake_nx_recovery_thread(struct kvm *kvm) +{ + /* + * The NX recovery thread is spawned on-demand at the first KVM_RUN and + * may not be valid even though the VM is globally visible. Do nothing, + * as such a VM can't have any possible NX huge pages. + */ + struct vhost_task *nx_thread = READ_ONCE(kvm->arch.nx_huge_page_recovery_thread); + + if (nx_thread) + vhost_task_wake(nx_thread); +} + static int get_nx_huge_pages(char *buffer, const struct kernel_param *kp) { if (nx_hugepage_mitigation_hard_disabled) @@ -7150,7 +7163,7 @@ static int set_nx_huge_pages(const char *val, const struct kernel_param *kp) kvm_mmu_zap_all_fast(kvm); mutex_unlock(&kvm->slots_lock);
- vhost_task_wake(kvm->arch.nx_huge_page_recovery_thread); + kvm_wake_nx_recovery_thread(kvm); } mutex_unlock(&kvm_lock); } @@ -7279,7 +7292,7 @@ static int set_nx_huge_pages_recovery_param(const char *val, const struct kernel mutex_lock(&kvm_lock);
list_for_each_entry(kvm, &vm_list, vm_list) - vhost_task_wake(kvm->arch.nx_huge_page_recovery_thread); + kvm_wake_nx_recovery_thread(kvm);
mutex_unlock(&kvm_lock); } @@ -7411,20 +7424,34 @@ static bool kvm_nx_huge_page_recovery_worker(void *data) return true; }
+static void kvm_mmu_start_lpage_recovery(struct once *once) +{ + struct kvm_arch *ka = container_of(once, struct kvm_arch, nx_once); + struct kvm *kvm = container_of(ka, struct kvm, arch); + struct vhost_task *nx_thread; + + kvm->arch.nx_huge_page_last = get_jiffies_64(); + nx_thread = vhost_task_create(kvm_nx_huge_page_recovery_worker, + kvm_nx_huge_page_recovery_worker_kill, + kvm, "kvm-nx-lpage-recovery"); + + if (!nx_thread) + return; + + vhost_task_start(nx_thread); + + /* Make the task visible only once it is fully started. */ + WRITE_ONCE(kvm->arch.nx_huge_page_recovery_thread, nx_thread); +} + int kvm_mmu_post_init_vm(struct kvm *kvm) { if (nx_hugepage_mitigation_hard_disabled) return 0;
- kvm->arch.nx_huge_page_last = get_jiffies_64(); - kvm->arch.nx_huge_page_recovery_thread = vhost_task_create( - kvm_nx_huge_page_recovery_worker, kvm_nx_huge_page_recovery_worker_kill, - kvm, "kvm-nx-lpage-recovery"); - + call_once(&kvm->arch.nx_once, kvm_mmu_start_lpage_recovery); if (!kvm->arch.nx_huge_page_recovery_thread) return -ENOMEM; - - vhost_task_start(kvm->arch.nx_huge_page_recovery_thread); return 0; }
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 943bd074a5d3..fe6cc763fd51 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -3820,7 +3820,7 @@ static int snp_begin_psc(struct vcpu_svm *svm, struct psc_buffer *psc) goto next_range; }
- unreachable(); + BUG(); }
static int __sev_snp_update_protected_guest_state(struct kvm_vcpu *vcpu) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index aa78b6f38dfe..103baa8e4cf8 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -5050,6 +5050,11 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason, kvm_make_request(KVM_REQ_APICV_UPDATE, vcpu); }
+ if (vmx->nested.update_vmcs01_hwapic_isr) { + vmx->nested.update_vmcs01_hwapic_isr = false; + kvm_apic_update_hwapic_isr(vcpu); + } + if ((vm_exit_reason != -1) && (enable_shadow_vmcs || nested_vmx_is_evmptr12_valid(vmx))) vmx->nested.need_vmcs12_to_shadow_sync = true; diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 22cb11ab8709..01abcdcbbf70 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -6867,6 +6867,27 @@ void vmx_hwapic_isr_update(struct kvm_vcpu *vcpu, int max_isr) u16 status; u8 old;
+ /* + * If L2 is active, defer the SVI update until vmcs01 is loaded, as SVI + * is only relevant for if and only if Virtual Interrupt Delivery is + * enabled in vmcs12, and if VID is enabled then L2 EOIs affect L2's + * vAPIC, not L1's vAPIC. KVM must update vmcs01 on the next nested + * VM-Exit, otherwise L1 with run with a stale SVI. + */ + if (is_guest_mode(vcpu)) { + /* + * KVM is supposed to forward intercepted L2 EOIs to L1 if VID + * is enabled in vmcs12; as above, the EOIs affect L2's vAPIC. + * Note, userspace can stuff state while L2 is active; assert + * that VID is disabled if and only if the vCPU is in KVM_RUN + * to avoid false positives if userspace is setting APIC state. + */ + WARN_ON_ONCE(vcpu->wants_to_run && + nested_cpu_has_vid(get_vmcs12(vcpu))); + to_vmx(vcpu)->nested.update_vmcs01_hwapic_isr = true; + return; + } + if (max_isr == -1) max_isr = 0;
diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index 43f573f6ca46..892302022094 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -176,6 +176,7 @@ struct nested_vmx { bool reload_vmcs01_apic_access_page; bool update_vmcs01_cpu_dirty_logging; bool update_vmcs01_apicv_status; + bool update_vmcs01_hwapic_isr;
/* * Enlightened VMCS has been enabled. It does not mean that L1 has to diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c79a8cc57ba4..23bf088fc4ae 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -11463,6 +11463,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) struct kvm_run *kvm_run = vcpu->run; int r;
+ r = kvm_mmu_post_init_vm(vcpu->kvm); + if (r) + return r; + vcpu_load(vcpu); kvm_sigset_activate(vcpu); kvm_run->flags = 0; @@ -12742,7 +12746,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
int kvm_arch_post_init_vm(struct kvm *kvm) { - return kvm_mmu_post_init_vm(kvm); + once_init(&kvm->arch.nx_once); + return 0; }
static void kvm_unload_vcpu_mmu(struct kvm_vcpu *vcpu) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index e6c469b323cc..ac52255fab01 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -678,7 +678,7 @@ page_fault_oops(struct pt_regs *regs, unsigned long error_code, ASM_CALL_ARG3, , [arg1] "r" (regs), [arg2] "r" (address), [arg3] "r" (&info));
- unreachable(); + BUG(); } #endif
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 0681ecfe3430..f348a3179b2d 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c @@ -1010,4 +1010,34 @@ DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_AMD, 0x1668, amd_rp_pme_suspend); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1668, amd_rp_pme_resume); DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_AMD, 0x1669, amd_rp_pme_suspend); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1669, amd_rp_pme_resume); + +/* + * Putting PCIe root ports on Ryzen SoCs with USB4 controllers into D3hot + * may cause problems when the system attempts wake up from s2idle. + * + * On the TUXEDO Sirius 16 Gen 1 with a specific old BIOS this manifests as + * a system hang. + */ +static const struct dmi_system_id quirk_tuxeo_rp_d3_dmi_table[] = { + { + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TUXEDO"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "APX958"), + DMI_EXACT_MATCH(DMI_BIOS_VERSION, "V1.00A00_20240108"), + }, + }, + {} +}; + +static void quirk_tuxeo_rp_d3(struct pci_dev *pdev) +{ + struct pci_dev *root_pdev; + + if (dmi_check_system(quirk_tuxeo_rp_d3_dmi_table)) { + root_pdev = pcie_find_root_port(pdev); + if (root_pdev) + root_pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3; + } +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1502, quirk_tuxeo_rp_d3); #endif /* CONFIG_SUSPEND */ diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c index 846bf49f2508..553f330198f2 100644 --- a/arch/x86/platform/efi/quirks.c +++ b/arch/x86/platform/efi/quirks.c @@ -561,6 +561,11 @@ int __init efi_reuse_config(u64 tables, int nr_tables)
if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID)) ((efi_config_table_64_t *)p)->table = data->smbios; + + /* Do not bother to play with mem attr table across kexec */ + if (!efi_guidcmp(guid, EFI_MEMORY_ATTRIBUTES_TABLE_GUID)) + ((efi_config_table_64_t *)p)->table = EFI_INVALID_TABLE_ADDR; + p += sz; } early_memunmap(tablep, nr_tables * sz); diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S index 9252652afe59..4e481b0eefc9 100644 --- a/arch/x86/xen/xen-head.S +++ b/arch/x86/xen/xen-head.S @@ -117,8 +117,8 @@ SYM_FUNC_START(xen_hypercall_hvm) pop %ebx pop %eax #else - lea xen_hypercall_amd(%rip), %rbx - cmp %rax, %rbx + lea xen_hypercall_amd(%rip), %rcx + cmp %rax, %rcx #ifdef CONFIG_FRAME_POINTER pop %rax /* Dummy pop. */ #endif @@ -132,6 +132,7 @@ SYM_FUNC_START(xen_hypercall_hvm) pop %rcx pop %rax #endif + FRAME_END /* Use correct hypercall function. */ jz xen_hypercall_amd jmp xen_hypercall_intel diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 45a395862fbc..f1cf7f2909f3 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -1138,6 +1138,7 @@ static void blkcg_fill_root_iostats(void) blkg_iostat_set(&blkg->iostat.cur, &tmp); u64_stats_update_end_irqrestore(&blkg->iostat.sync, flags); } + class_dev_iter_exit(&iter); }
static void blkcg_print_one_stat(struct blkcg_gq *blkg, struct seq_file *s) diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index e828be777206..e09b455874bf 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -681,6 +681,7 @@ queue_attr_store(struct kobject *kobj, struct attribute *attr, struct queue_sysfs_entry *entry = to_queue(attr); struct gendisk *disk = container_of(kobj, struct gendisk, queue_kobj); struct request_queue *q = disk->queue; + unsigned int noio_flag; ssize_t res;
if (!entry->store_limit && !entry->store) @@ -711,7 +712,9 @@ queue_attr_store(struct kobject *kobj, struct attribute *attr,
mutex_lock(&q->sysfs_lock); blk_mq_freeze_queue(q); + noio_flag = memalloc_noio_save(); res = entry->store(disk, page, length); + memalloc_noio_restore(noio_flag); blk_mq_unfreeze_queue(q); mutex_unlock(&q->sysfs_lock); return res; diff --git a/block/fops.c b/block/fops.c index 13a67940d040..43983be5a2b3 100644 --- a/block/fops.c +++ b/block/fops.c @@ -758,11 +758,12 @@ static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to) file_accessed(iocb->ki_filp);
ret = blkdev_direct_IO(iocb, to); - if (ret >= 0) { + if (ret > 0) { iocb->ki_pos += ret; count -= ret; } - iov_iter_revert(to, count - iov_iter_count(to)); + if (ret != -EIOCBQUEUED) + iov_iter_revert(to, count - iov_iter_count(to)); if (ret < 0 || !count) goto reexpand; } diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index ca2bf47ce248..0c4a82271c26 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -397,15 +397,19 @@ int ivpu_boot(struct ivpu_device *vdev) if (ivpu_fw_is_cold_boot(vdev)) { ret = ivpu_pm_dct_init(vdev); if (ret) - goto err_diagnose_failure; + goto err_disable_ipc;
ret = ivpu_hw_sched_init(vdev); if (ret) - goto err_diagnose_failure; + goto err_disable_ipc; }
return 0;
+err_disable_ipc: + ivpu_ipc_disable(vdev); + ivpu_hw_irq_disable(vdev); + disable_irq(vdev->irq); err_diagnose_failure: ivpu_hw_diagnose_failure(vdev); ivpu_mmu_evtq_dump(vdev); diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index 949f4233946c..5060c5dd40d1 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -78,8 +78,8 @@ static int ivpu_resume(struct ivpu_device *vdev) int ret;
retry: - pci_restore_state(to_pci_dev(vdev->drm.dev)); pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D0); + pci_restore_state(to_pci_dev(vdev->drm.dev));
ret = ivpu_hw_power_up(vdev); if (ret) { @@ -115,41 +115,57 @@ static int ivpu_resume(struct ivpu_device *vdev) return ret; }
-static void ivpu_pm_recovery_work(struct work_struct *work) +static void ivpu_pm_reset_begin(struct ivpu_device *vdev) { - struct ivpu_pm_info *pm = container_of(work, struct ivpu_pm_info, recovery_work); - struct ivpu_device *vdev = pm->vdev; - char *evt[2] = {"IVPU_PM_EVENT=IVPU_RECOVER", NULL}; - int ret; - - ivpu_err(vdev, "Recovering the NPU (reset #%d)\n", atomic_read(&vdev->pm->reset_counter)); - - ret = pm_runtime_resume_and_get(vdev->drm.dev); - if (ret) - ivpu_err(vdev, "Failed to resume NPU: %d\n", ret); - - ivpu_jsm_state_dump(vdev); - ivpu_dev_coredump(vdev); + pm_runtime_disable(vdev->drm.dev);
atomic_inc(&vdev->pm->reset_counter); atomic_set(&vdev->pm->reset_pending, 1); down_write(&vdev->pm->reset_lock); +} + +static void ivpu_pm_reset_complete(struct ivpu_device *vdev) +{ + int ret;
- ivpu_suspend(vdev); ivpu_pm_prepare_cold_boot(vdev); ivpu_jobs_abort_all(vdev); ivpu_ms_cleanup_all(vdev);
ret = ivpu_resume(vdev); - if (ret) + if (ret) { ivpu_err(vdev, "Failed to resume NPU: %d\n", ret); + pm_runtime_set_suspended(vdev->drm.dev); + } else { + pm_runtime_set_active(vdev->drm.dev); + }
up_write(&vdev->pm->reset_lock); atomic_set(&vdev->pm->reset_pending, 0);
- kobject_uevent_env(&vdev->drm.dev->kobj, KOBJ_CHANGE, evt); pm_runtime_mark_last_busy(vdev->drm.dev); - pm_runtime_put_autosuspend(vdev->drm.dev); + pm_runtime_enable(vdev->drm.dev); +} + +static void ivpu_pm_recovery_work(struct work_struct *work) +{ + struct ivpu_pm_info *pm = container_of(work, struct ivpu_pm_info, recovery_work); + struct ivpu_device *vdev = pm->vdev; + char *evt[2] = {"IVPU_PM_EVENT=IVPU_RECOVER", NULL}; + + ivpu_err(vdev, "Recovering the NPU (reset #%d)\n", atomic_read(&vdev->pm->reset_counter)); + + ivpu_pm_reset_begin(vdev); + + if (!pm_runtime_status_suspended(vdev->drm.dev)) { + ivpu_jsm_state_dump(vdev); + ivpu_dev_coredump(vdev); + ivpu_suspend(vdev); + } + + ivpu_pm_reset_complete(vdev); + + kobject_uevent_env(&vdev->drm.dev->kobj, KOBJ_CHANGE, evt); }
void ivpu_pm_trigger_recovery(struct ivpu_device *vdev, const char *reason) @@ -309,7 +325,10 @@ int ivpu_rpm_get(struct ivpu_device *vdev) int ret;
ret = pm_runtime_resume_and_get(vdev->drm.dev); - drm_WARN_ON(&vdev->drm, ret < 0); + if (ret < 0) { + ivpu_err(vdev, "Failed to resume NPU: %d\n", ret); + pm_runtime_set_suspended(vdev->drm.dev); + }
return ret; } @@ -325,16 +344,13 @@ void ivpu_pm_reset_prepare_cb(struct pci_dev *pdev) struct ivpu_device *vdev = pci_get_drvdata(pdev);
ivpu_dbg(vdev, PM, "Pre-reset..\n"); - atomic_inc(&vdev->pm->reset_counter); - atomic_set(&vdev->pm->reset_pending, 1);
- pm_runtime_get_sync(vdev->drm.dev); - down_write(&vdev->pm->reset_lock); - ivpu_prepare_for_reset(vdev); - ivpu_hw_reset(vdev); - ivpu_pm_prepare_cold_boot(vdev); - ivpu_jobs_abort_all(vdev); - ivpu_ms_cleanup_all(vdev); + ivpu_pm_reset_begin(vdev); + + if (!pm_runtime_status_suspended(vdev->drm.dev)) { + ivpu_prepare_for_reset(vdev); + ivpu_hw_reset(vdev); + }
ivpu_dbg(vdev, PM, "Pre-reset done.\n"); } @@ -342,18 +358,12 @@ void ivpu_pm_reset_prepare_cb(struct pci_dev *pdev) void ivpu_pm_reset_done_cb(struct pci_dev *pdev) { struct ivpu_device *vdev = pci_get_drvdata(pdev); - int ret;
ivpu_dbg(vdev, PM, "Post-reset..\n"); - ret = ivpu_resume(vdev); - if (ret) - ivpu_err(vdev, "Failed to set RESUME state: %d\n", ret); - up_write(&vdev->pm->reset_lock); - atomic_set(&vdev->pm->reset_pending, 0); - ivpu_dbg(vdev, PM, "Post-reset done.\n");
- pm_runtime_mark_last_busy(vdev->drm.dev); - pm_runtime_put_autosuspend(vdev->drm.dev); + ivpu_pm_reset_complete(vdev); + + ivpu_dbg(vdev, PM, "Post-reset done.\n"); }
void ivpu_pm_init(struct ivpu_device *vdev) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 07789f0b59bc..b72772494655 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -173,8 +173,6 @@ static struct gen_pool *ghes_estatus_pool; static struct ghes_estatus_cache __rcu *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE]; static atomic_t ghes_estatus_cache_alloced;
-static int ghes_panic_timeout __read_mostly = 30; - static void __iomem *ghes_map(u64 pfn, enum fixed_addresses fixmap_idx) { phys_addr_t paddr; @@ -983,14 +981,16 @@ static void __ghes_panic(struct ghes *ghes, struct acpi_hest_generic_status *estatus, u64 buf_paddr, enum fixed_addresses fixmap_idx) { + const char *msg = GHES_PFX "Fatal hardware error"; + __ghes_print_estatus(KERN_EMERG, ghes->generic, estatus);
ghes_clear_estatus(ghes, estatus, buf_paddr, fixmap_idx);
- /* reboot to log the error! */ if (!panic_timeout) - panic_timeout = ghes_panic_timeout; - panic("Fatal hardware error!"); + pr_emerg("%s but panic disabled\n", msg); + + panic(msg); }
static int ghes_proc(struct ghes *ghes) diff --git a/drivers/acpi/prmt.c b/drivers/acpi/prmt.c index 747f83f7114d..e549914a636c 100644 --- a/drivers/acpi/prmt.c +++ b/drivers/acpi/prmt.c @@ -287,9 +287,7 @@ static acpi_status acpi_platformrt_space_handler(u32 function, if (!handler || !module) goto invalid_guid;
- if (!handler->handler_addr || - !handler->static_data_buffer_addr || - !handler->acpi_param_buffer_addr) { + if (!handler->handler_addr) { buffer->prm_status = PRM_HANDLER_ERROR; return AE_OK; } diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index 80a52a4e66dd..e9186339f6e6 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -1187,8 +1187,6 @@ static int acpi_data_prop_read(const struct acpi_device_data *data, } break; } - if (nval == 0) - return -EINVAL;
if (obj->type == ACPI_TYPE_BUFFER) { if (proptype != DEV_PROP_U8) @@ -1212,9 +1210,11 @@ static int acpi_data_prop_read(const struct acpi_device_data *data, ret = acpi_copy_property_array_uint(items, (u64 *)val, nval); break; case DEV_PROP_STRING: - ret = acpi_copy_property_array_string( - items, (char **)val, - min_t(u32, nval, obj->package.count)); + nval = min_t(u32, nval, obj->package.count); + if (nval == 0) + return -ENODATA; + + ret = acpi_copy_property_array_string(items, (char **)val, nval); break; default: ret = -EINVAL; diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 67f277e1c3bf..5a46c066abc3 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -601,7 +601,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct page *page; - unsigned int offset; + unsigned int offset, count;
if (!qc->cursg) { qc->curbytes = qc->nbytes; @@ -617,25 +617,27 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) page = nth_page(page, (offset >> PAGE_SHIFT)); offset %= PAGE_SIZE;
- trace_ata_sff_pio_transfer_data(qc, offset, qc->sect_size); + /* don't overrun current sg */ + count = min(qc->cursg->length - qc->cursg_ofs, qc->sect_size); + + trace_ata_sff_pio_transfer_data(qc, offset, count);
/* * Split the transfer when it splits a page boundary. Note that the * split still has to be dword aligned like all ATA data transfers. */ WARN_ON_ONCE(offset % 4); - if (offset + qc->sect_size > PAGE_SIZE) { + if (offset + count > PAGE_SIZE) { unsigned int split_len = PAGE_SIZE - offset;
ata_pio_xfer(qc, page, offset, split_len); - ata_pio_xfer(qc, nth_page(page, 1), 0, - qc->sect_size - split_len); + ata_pio_xfer(qc, nth_page(page, 1), 0, count - split_len); } else { - ata_pio_xfer(qc, page, offset, qc->sect_size); + ata_pio_xfer(qc, page, offset, count); }
- qc->curbytes += qc->sect_size; - qc->cursg_ofs += qc->sect_size; + qc->curbytes += count; + qc->cursg_ofs += count;
if (qc->cursg_ofs == qc->cursg->length) { qc->cursg = sg_next(qc->cursg); diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index f69df515d668..72e85673b709 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -377,6 +377,8 @@ static const struct usb_device_id quirks_table[] = { BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x13d3, 0x3623), .driver_info = BTUSB_QCA_WCN6855 | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x2c7c, 0x0130), .driver_info = BTUSB_QCA_WCN6855 | + BTUSB_WIDEBAND_SPEECH },
/* Broadcom BCM2035 */ { USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 }, @@ -610,6 +612,8 @@ static const struct usb_device_id quirks_table[] = { /* MediaTek MT7922 Bluetooth devices */ { USB_DEVICE(0x13d3, 0x3585), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3610), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH },
/* MediaTek MT7922A Bluetooth devices */ { USB_DEVICE(0x0489, 0xe0d8), .driver_info = BTUSB_MEDIATEK | @@ -674,6 +678,8 @@ static const struct usb_device_id quirks_table[] = { BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x13d3, 0x3608), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3628), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH },
/* Additional Realtek 8723AE Bluetooth devices */ { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK }, diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 541edc26ec89..2cf595d2e10b 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -63,16 +63,30 @@ static DEFINE_MUTEX(misc_mtx); #define DYNAMIC_MINORS 128 /* like dynamic majors */ static DEFINE_IDA(misc_minors_ida);
-static int misc_minor_alloc(void) +static int misc_minor_alloc(int minor) { - int ret; - - ret = ida_alloc_max(&misc_minors_ida, DYNAMIC_MINORS - 1, GFP_KERNEL); - if (ret >= 0) { - ret = DYNAMIC_MINORS - ret - 1; + int ret = 0; + + if (minor == MISC_DYNAMIC_MINOR) { + /* allocate free id */ + ret = ida_alloc_max(&misc_minors_ida, DYNAMIC_MINORS - 1, GFP_KERNEL); + if (ret >= 0) { + ret = DYNAMIC_MINORS - ret - 1; + } else { + ret = ida_alloc_range(&misc_minors_ida, MISC_DYNAMIC_MINOR + 1, + MINORMASK, GFP_KERNEL); + } } else { - ret = ida_alloc_range(&misc_minors_ida, MISC_DYNAMIC_MINOR + 1, - MINORMASK, GFP_KERNEL); + /* specific minor, check if it is in dynamic or misc dynamic range */ + if (minor < DYNAMIC_MINORS) { + minor = DYNAMIC_MINORS - minor - 1; + ret = ida_alloc_range(&misc_minors_ida, minor, minor, GFP_KERNEL); + } else if (minor > MISC_DYNAMIC_MINOR) { + ret = ida_alloc_range(&misc_minors_ida, minor, minor, GFP_KERNEL); + } else { + /* case of non-dynamic minors, no need to allocate id */ + ret = 0; + } } return ret; } @@ -219,7 +233,7 @@ int misc_register(struct miscdevice *misc) mutex_lock(&misc_mtx);
if (is_dynamic) { - int i = misc_minor_alloc(); + int i = misc_minor_alloc(misc->minor);
if (i < 0) { err = -EBUSY; @@ -228,6 +242,7 @@ int misc_register(struct miscdevice *misc) misc->minor = i; } else { struct miscdevice *c; + int i;
list_for_each_entry(c, &misc_list, list) { if (c->minor == misc->minor) { @@ -235,6 +250,12 @@ int misc_register(struct miscdevice *misc) goto out; } } + + i = misc_minor_alloc(misc->minor); + if (i < 0) { + err = -EBUSY; + goto out; + } }
dev = MKDEV(MISC_MAJOR, misc->minor); diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c index 69533d0bfb51..cf02ec646f46 100644 --- a/drivers/char/tpm/eventlog/acpi.c +++ b/drivers/char/tpm/eventlog/acpi.c @@ -63,6 +63,11 @@ static bool tpm_is_tpm2_log(void *bios_event_log, u64 len) return n == 0; }
+static void tpm_bios_log_free(void *data) +{ + kvfree(data); +} + /* read binary bios log */ int tpm_read_log_acpi(struct tpm_chip *chip) { @@ -136,7 +141,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip) }
/* malloc EventLog space */ - log->bios_event_log = devm_kmalloc(&chip->dev, len, GFP_KERNEL); + log->bios_event_log = kvmalloc(len, GFP_KERNEL); if (!log->bios_event_log) return -ENOMEM;
@@ -161,10 +166,16 @@ int tpm_read_log_acpi(struct tpm_chip *chip) goto err; }
+ ret = devm_add_action(&chip->dev, tpm_bios_log_free, log->bios_event_log); + if (ret) { + log->bios_event_log = NULL; + goto err; + } + return format;
err: - devm_kfree(&chip->dev, log->bios_event_log); + tpm_bios_log_free(log->bios_event_log); log->bios_event_log = NULL; return ret; } diff --git a/drivers/clk/clk-loongson2.c b/drivers/clk/clk-loongson2.c index 7082b4309c6f..0d9485e83938 100644 --- a/drivers/clk/clk-loongson2.c +++ b/drivers/clk/clk-loongson2.c @@ -294,7 +294,7 @@ static int loongson2_clk_probe(struct platform_device *pdev) return -EINVAL;
for (p = data; p->name; p++) - clks_num++; + clks_num = max(clks_num, p->id + 1);
clp = devm_kzalloc(dev, struct_size(clp, clk_data.hws, clks_num), GFP_KERNEL); @@ -309,6 +309,9 @@ static int loongson2_clk_probe(struct platform_device *pdev) clp->clk_data.num = clks_num; clp->dev = dev;
+ /* Avoid returning NULL for unused id */ + memset_p((void **)clp->clk_data.hws, ERR_PTR(-ENOENT), clks_num); + for (i = 0; i < clks_num; i++) { p = &data[i]; switch (p->type) { diff --git a/drivers/clk/mediatek/clk-mt2701-aud.c b/drivers/clk/mediatek/clk-mt2701-aud.c index 425c69cfb105..e103121cf58e 100644 --- a/drivers/clk/mediatek/clk-mt2701-aud.c +++ b/drivers/clk/mediatek/clk-mt2701-aud.c @@ -55,10 +55,16 @@ static const struct mtk_gate audio_clks[] = { GATE_DUMMY(CLK_DUMMY, "aud_dummy"), /* AUDIO0 */ GATE_AUDIO0(CLK_AUD_AFE, "audio_afe", "aud_intbus_sel", 2), + GATE_DUMMY(CLK_AUD_LRCK_DETECT, "audio_lrck_detect_dummy"), + GATE_DUMMY(CLK_AUD_I2S, "audio_i2c_dummy"), + GATE_DUMMY(CLK_AUD_APLL_TUNER, "audio_apll_tuner_dummy"), GATE_AUDIO0(CLK_AUD_HDMI, "audio_hdmi", "audpll_sel", 20), GATE_AUDIO0(CLK_AUD_SPDF, "audio_spdf", "audpll_sel", 21), GATE_AUDIO0(CLK_AUD_SPDF2, "audio_spdf2", "audpll_sel", 22), GATE_AUDIO0(CLK_AUD_APLL, "audio_apll", "audpll_sel", 23), + GATE_DUMMY(CLK_AUD_TML, "audio_tml_dummy"), + GATE_DUMMY(CLK_AUD_AHB_IDLE_EXT, "audio_ahb_idle_ext_dummy"), + GATE_DUMMY(CLK_AUD_AHB_IDLE_INT, "audio_ahb_idle_int_dummy"), /* AUDIO1 */ GATE_AUDIO1(CLK_AUD_I2SIN1, "audio_i2sin1", "aud_mux1_sel", 0), GATE_AUDIO1(CLK_AUD_I2SIN2, "audio_i2sin2", "aud_mux1_sel", 1), @@ -76,10 +82,12 @@ static const struct mtk_gate audio_clks[] = { GATE_AUDIO1(CLK_AUD_ASRCI2, "audio_asrci2", "asm_h_sel", 13), GATE_AUDIO1(CLK_AUD_ASRCO1, "audio_asrco1", "asm_h_sel", 14), GATE_AUDIO1(CLK_AUD_ASRCO2, "audio_asrco2", "asm_h_sel", 15), + GATE_DUMMY(CLK_AUD_HDMIRX, "audio_hdmirx_dummy"), GATE_AUDIO1(CLK_AUD_INTDIR, "audio_intdir", "intdir_sel", 20), GATE_AUDIO1(CLK_AUD_A1SYS, "audio_a1sys", "aud_mux1_sel", 21), GATE_AUDIO1(CLK_AUD_A2SYS, "audio_a2sys", "aud_mux2_sel", 22), GATE_AUDIO1(CLK_AUD_AFE_CONN, "audio_afe_conn", "aud_mux1_sel", 23), + GATE_DUMMY(CLK_AUD_AFE_PCMIF, "audio_afe_pcmif_dummy"), GATE_AUDIO1(CLK_AUD_AFE_MRGIF, "audio_afe_mrgif", "aud_mux1_sel", 25), /* AUDIO2 */ GATE_AUDIO2(CLK_AUD_MMIF_UL1, "audio_ul1", "aud_mux1_sel", 0), @@ -100,6 +108,8 @@ static const struct mtk_gate audio_clks[] = { GATE_AUDIO2(CLK_AUD_MMIF_AWB2, "audio_awb2", "aud_mux1_sel", 15), GATE_AUDIO2(CLK_AUD_MMIF_DAI, "audio_dai", "aud_mux1_sel", 16), /* AUDIO3 */ + GATE_DUMMY(CLK_AUD_DMIC1, "audio_dmic1_dummy"), + GATE_DUMMY(CLK_AUD_DMIC2, "audio_dmic2_dummy"), GATE_AUDIO3(CLK_AUD_ASRCI3, "audio_asrci3", "asm_h_sel", 2), GATE_AUDIO3(CLK_AUD_ASRCI4, "audio_asrci4", "asm_h_sel", 3), GATE_AUDIO3(CLK_AUD_ASRCI5, "audio_asrci5", "asm_h_sel", 4), diff --git a/drivers/clk/mediatek/clk-mt2701-bdp.c b/drivers/clk/mediatek/clk-mt2701-bdp.c index 5da3eabffd3e..f11c7a4fa37b 100644 --- a/drivers/clk/mediatek/clk-mt2701-bdp.c +++ b/drivers/clk/mediatek/clk-mt2701-bdp.c @@ -31,6 +31,7 @@ static const struct mtk_gate_regs bdp1_cg_regs = { GATE_MTK(_id, _name, _parent, &bdp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
static const struct mtk_gate bdp_clks[] = { + GATE_DUMMY(CLK_DUMMY, "bdp_dummy"), GATE_BDP0(CLK_BDP_BRG_BA, "brg_baclk", "mm_sel", 0), GATE_BDP0(CLK_BDP_BRG_DRAM, "brg_dram", "mm_sel", 1), GATE_BDP0(CLK_BDP_LARB_DRAM, "larb_dram", "mm_sel", 2), diff --git a/drivers/clk/mediatek/clk-mt2701-img.c b/drivers/clk/mediatek/clk-mt2701-img.c index 875594bc9dcb..c158e54c4652 100644 --- a/drivers/clk/mediatek/clk-mt2701-img.c +++ b/drivers/clk/mediatek/clk-mt2701-img.c @@ -22,6 +22,7 @@ static const struct mtk_gate_regs img_cg_regs = { GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
static const struct mtk_gate img_clks[] = { + GATE_DUMMY(CLK_DUMMY, "img_dummy"), GATE_IMG(CLK_IMG_SMI_COMM, "img_smi_comm", "mm_sel", 0), GATE_IMG(CLK_IMG_RESZ, "img_resz", "mm_sel", 1), GATE_IMG(CLK_IMG_JPGDEC_SMI, "img_jpgdec_smi", "mm_sel", 5), diff --git a/drivers/clk/mediatek/clk-mt2701-mm.c b/drivers/clk/mediatek/clk-mt2701-mm.c index bc68fa718878..474d87d62e83 100644 --- a/drivers/clk/mediatek/clk-mt2701-mm.c +++ b/drivers/clk/mediatek/clk-mt2701-mm.c @@ -31,6 +31,7 @@ static const struct mtk_gate_regs disp1_cg_regs = { GATE_MTK(_id, _name, _parent, &disp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
static const struct mtk_gate mm_clks[] = { + GATE_DUMMY(CLK_DUMMY, "mm_dummy"), GATE_DISP0(CLK_MM_SMI_COMMON, "mm_smi_comm", "mm_sel", 0), GATE_DISP0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1), GATE_DISP0(CLK_MM_CMDQ, "mm_cmdq", "mm_sel", 2), diff --git a/drivers/clk/mediatek/clk-mt2701-vdec.c b/drivers/clk/mediatek/clk-mt2701-vdec.c index 94db86f8d0a4..5299d92f3aba 100644 --- a/drivers/clk/mediatek/clk-mt2701-vdec.c +++ b/drivers/clk/mediatek/clk-mt2701-vdec.c @@ -31,6 +31,7 @@ static const struct mtk_gate_regs vdec1_cg_regs = { GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
static const struct mtk_gate vdec_clks[] = { + GATE_DUMMY(CLK_DUMMY, "vdec_dummy"), GATE_VDEC0(CLK_VDEC_CKGEN, "vdec_cken", "vdec_sel", 0), GATE_VDEC1(CLK_VDEC_LARB, "vdec_larb_cken", "mm_sel", 0), }; diff --git a/drivers/clk/mmp/pwr-island.c b/drivers/clk/mmp/pwr-island.c index edaa2433a472..eaf5d2c5e593 100644 --- a/drivers/clk/mmp/pwr-island.c +++ b/drivers/clk/mmp/pwr-island.c @@ -106,10 +106,10 @@ struct generic_pm_domain *mmp_pm_domain_register(const char *name, pm_domain->flags = flags; pm_domain->lock = lock;
- pm_genpd_init(&pm_domain->genpd, NULL, true); pm_domain->genpd.name = name; pm_domain->genpd.power_on = mmp_pm_domain_power_on; pm_domain->genpd.power_off = mmp_pm_domain_power_off; + pm_genpd_init(&pm_domain->genpd, NULL, true);
return &pm_domain->genpd; } diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index ef89d686cbc4..c27ea46283fd 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -1079,6 +1079,7 @@ config SM_GCC_7150 config SM_GCC_8150 tristate "SM8150 Global Clock Controller" depends on ARM64 || COMPILE_TEST + select QCOM_GDSC help Support for the global clock controller on SM8150 devices. Say Y if you want to use peripheral devices such as UART, diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index b8351f8c0b84..35e97eab5d05 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -432,6 +432,8 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, mask |= config->pre_div_mask; mask |= config->post_div_mask; mask |= config->vco_mask; + mask |= config->alpha_en_mask; + mask |= config->alpha_mode_mask;
regmap_update_bits(regmap, PLL_USER_CTL(pll), mask, val);
diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index eefc322ce367..e6c33010cfbf 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -329,7 +329,7 @@ static unsigned long clk_rpmh_bcm_recalc_rate(struct clk_hw *hw, { struct clk_rpmh *c = to_clk_rpmh(hw);
- return c->aggr_state * c->unit; + return (unsigned long)c->aggr_state * c->unit; }
static const struct clk_ops clk_rpmh_bcm_ops = { diff --git a/drivers/clk/qcom/dispcc-sm6350.c b/drivers/clk/qcom/dispcc-sm6350.c index 50facb36701a..2bc6b5f99f57 100644 --- a/drivers/clk/qcom/dispcc-sm6350.c +++ b/drivers/clk/qcom/dispcc-sm6350.c @@ -187,13 +187,12 @@ static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = { .cmd_rcgr = 0x1144, .mnd_width = 0, .hid_width = 5, + .parent_map = disp_cc_parent_map_6, .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "disp_cc_mdss_dp_aux_clk_src", - .parent_data = &(const struct clk_parent_data){ - .fw_name = "bi_tcxo", - }, - .num_parents = 1, + .parent_data = disp_cc_parent_data_6, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_6), .ops = &clk_rcg2_ops, }, }; diff --git a/drivers/clk/qcom/gcc-mdm9607.c b/drivers/clk/qcom/gcc-mdm9607.c index 6e6068b168e6..07f1b78d737a 100644 --- a/drivers/clk/qcom/gcc-mdm9607.c +++ b/drivers/clk/qcom/gcc-mdm9607.c @@ -535,7 +535,7 @@ static struct clk_rcg2 blsp1_uart5_apps_clk_src = { };
static struct clk_rcg2 blsp1_uart6_apps_clk_src = { - .cmd_rcgr = 0x6044, + .cmd_rcgr = 0x7044, .mnd_width = 16, .hid_width = 5, .parent_map = gcc_xo_gpll0_map, diff --git a/drivers/clk/qcom/gcc-sm6350.c b/drivers/clk/qcom/gcc-sm6350.c index a811fad2aa27..74346dc02606 100644 --- a/drivers/clk/qcom/gcc-sm6350.c +++ b/drivers/clk/qcom/gcc-sm6350.c @@ -182,6 +182,14 @@ static const struct clk_parent_data gcc_parent_data_2_ao[] = { { .hw = &gpll0_out_odd.clkr.hw }, };
+static const struct parent_map gcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data gcc_parent_data_3[] = { + { .fw_name = "bi_tcxo" }, +}; + static const struct parent_map gcc_parent_map_4[] = { { P_BI_TCXO, 0 }, { P_GPLL0_OUT_MAIN, 1 }, @@ -701,13 +709,12 @@ static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = { .cmd_rcgr = 0x3a0b0, .mnd_width = 0, .hid_width = 5, + .parent_map = gcc_parent_map_3, .freq_tbl = ftbl_gcc_ufs_phy_phy_aux_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_phy_phy_aux_clk_src", - .parent_data = &(const struct clk_parent_data){ - .fw_name = "bi_tcxo", - }, - .num_parents = 1, + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), .ops = &clk_rcg2_ops, }, }; @@ -764,13 +771,12 @@ static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { .cmd_rcgr = 0x1a034, .mnd_width = 0, .hid_width = 5, + .parent_map = gcc_parent_map_3, .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_usb30_prim_mock_utmi_clk_src", - .parent_data = &(const struct clk_parent_data){ - .fw_name = "bi_tcxo", - }, - .num_parents = 1, + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), .ops = &clk_rcg2_ops, }, }; diff --git a/drivers/clk/qcom/gcc-sm8550.c b/drivers/clk/qcom/gcc-sm8550.c index 5abaeddd6afc..862a9bf73bcb 100644 --- a/drivers/clk/qcom/gcc-sm8550.c +++ b/drivers/clk/qcom/gcc-sm8550.c @@ -3003,7 +3003,7 @@ static struct gdsc pcie_0_gdsc = { .pd = { .name = "pcie_0_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, };
@@ -3014,7 +3014,7 @@ static struct gdsc pcie_0_phy_gdsc = { .pd = { .name = "pcie_0_phy_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, };
@@ -3025,7 +3025,7 @@ static struct gdsc pcie_1_gdsc = { .pd = { .name = "pcie_1_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, };
@@ -3036,7 +3036,7 @@ static struct gdsc pcie_1_phy_gdsc = { .pd = { .name = "pcie_1_phy_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, };
diff --git a/drivers/clk/qcom/gcc-sm8650.c b/drivers/clk/qcom/gcc-sm8650.c index fd9d6544bdd5..9dd5c48f33be 100644 --- a/drivers/clk/qcom/gcc-sm8650.c +++ b/drivers/clk/qcom/gcc-sm8650.c @@ -3437,7 +3437,7 @@ static struct gdsc pcie_0_gdsc = { .pd = { .name = "pcie_0_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, };
@@ -3448,7 +3448,7 @@ static struct gdsc pcie_0_phy_gdsc = { .pd = { .name = "pcie_0_phy_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, };
@@ -3459,7 +3459,7 @@ static struct gdsc pcie_1_gdsc = { .pd = { .name = "pcie_1_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, };
@@ -3470,7 +3470,7 @@ static struct gdsc pcie_1_phy_gdsc = { .pd = { .name = "pcie_1_phy_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, };
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c index 7133377d4163..1f81c7ac41af 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c @@ -436,7 +436,7 @@ static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0", mmc_parents, 0x830, 24, 2, /* mux */ BIT(31), /* gate */ 2, /* post-div */ - CLK_SET_RATE_NO_REPARENT); + 0);
static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834, 0, 4, /* M */ @@ -444,7 +444,7 @@ static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834, 24, 2, /* mux */ BIT(31), /* gate */ 2, /* post-div */ - CLK_SET_RATE_NO_REPARENT); + 0);
static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2", mmc_parents, 0x838, 0, 4, /* M */ @@ -452,7 +452,7 @@ static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2", mmc_parents, 0x838, 24, 2, /* mux */ BIT(31), /* gate */ 2, /* post-div */ - CLK_SET_RATE_NO_REPARENT); + 0);
static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb3", 0x84c, BIT(0), 0); static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb3", 0x84c, BIT(1), 0); diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 26e98fea991a..d64b07ec48e5 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -232,7 +232,7 @@ config CPUFREQ_VIRT If in doubt, say N.
config CPUFREQ_DT_PLATDEV - tristate "Generic DT based cpufreq platdev driver" + bool "Generic DT based cpufreq platdev driver" depends on OF help This adds a generic DT based cpufreq platdev driver for frequency diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c index 2a3e8bd317c9..9c198bd4f7e9 100644 --- a/drivers/cpufreq/cpufreq-dt-platdev.c +++ b/drivers/cpufreq/cpufreq-dt-platdev.c @@ -235,5 +235,3 @@ static int __init cpufreq_dt_platdev_init(void) sizeof(struct cpufreq_dt_platform_data))); } core_initcall(cpufreq_dt_platdev_init); -MODULE_DESCRIPTION("Generic DT based cpufreq platdev driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c index c6bdfc308e99..9cef71528076 100644 --- a/drivers/cpufreq/s3c64xx-cpufreq.c +++ b/drivers/cpufreq/s3c64xx-cpufreq.c @@ -24,6 +24,7 @@ struct s3c64xx_dvfs { unsigned int vddarm_max; };
+#ifdef CONFIG_REGULATOR static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = { [0] = { 1000000, 1150000 }, [1] = { 1050000, 1150000 }, @@ -31,6 +32,7 @@ static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = { [3] = { 1200000, 1350000 }, [4] = { 1300000, 1350000 }, }; +#endif
static struct cpufreq_frequency_table s3c64xx_freq_table[] = { { 0, 0, 66000 }, @@ -51,15 +53,16 @@ static struct cpufreq_frequency_table s3c64xx_freq_table[] = { static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index) { - struct s3c64xx_dvfs *dvfs; - unsigned int old_freq, new_freq; + unsigned int new_freq = s3c64xx_freq_table[index].frequency; int ret;
+#ifdef CONFIG_REGULATOR + struct s3c64xx_dvfs *dvfs; + unsigned int old_freq; + old_freq = clk_get_rate(policy->clk) / 1000; - new_freq = s3c64xx_freq_table[index].frequency; dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data];
-#ifdef CONFIG_REGULATOR if (vddarm && new_freq > old_freq) { ret = regulator_set_voltage(vddarm, dvfs->vddarm_min, diff --git a/drivers/crypto/qce/aead.c b/drivers/crypto/qce/aead.c index 7d811728f047..97b56e92ea33 100644 --- a/drivers/crypto/qce/aead.c +++ b/drivers/crypto/qce/aead.c @@ -786,7 +786,7 @@ static int qce_aead_register_one(const struct qce_aead_def *def, struct qce_devi alg->init = qce_aead_init; alg->exit = qce_aead_exit;
- alg->base.cra_priority = 300; + alg->base.cra_priority = 275; alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY | CRYPTO_ALG_KERN_DRIVER_ONLY | diff --git a/drivers/crypto/qce/core.c b/drivers/crypto/qce/core.c index e228a31fe28d..848e5e802b92 100644 --- a/drivers/crypto/qce/core.c +++ b/drivers/crypto/qce/core.c @@ -51,16 +51,19 @@ static void qce_unregister_algs(struct qce_device *qce) static int qce_register_algs(struct qce_device *qce) { const struct qce_algo_ops *ops; - int i, ret = -ENODEV; + int i, j, ret = -ENODEV;
for (i = 0; i < ARRAY_SIZE(qce_ops); i++) { ops = qce_ops[i]; ret = ops->register_algs(qce); - if (ret) - break; + if (ret) { + for (j = i - 1; j >= 0; j--) + ops->unregister_algs(qce); + return ret; + } }
- return ret; + return 0; }
static int qce_handle_request(struct crypto_async_request *async_req) @@ -247,7 +250,7 @@ static int qce_crypto_probe(struct platform_device *pdev)
ret = qce_check_version(qce); if (ret) - goto err_clks; + goto err_dma;
spin_lock_init(&qce->lock); tasklet_init(&qce->done_tasklet, qce_tasklet_req_done, diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c index fc72af8aa9a7..71b748183cfa 100644 --- a/drivers/crypto/qce/sha.c +++ b/drivers/crypto/qce/sha.c @@ -482,7 +482,7 @@ static int qce_ahash_register_one(const struct qce_ahash_def *def,
base = &alg->halg.base; base->cra_blocksize = def->blocksize; - base->cra_priority = 300; + base->cra_priority = 175; base->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY; base->cra_ctxsize = sizeof(struct qce_sha_ctx); base->cra_alignmask = 0; diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c index 5b493fdc1e74..ffb334eb5b34 100644 --- a/drivers/crypto/qce/skcipher.c +++ b/drivers/crypto/qce/skcipher.c @@ -461,7 +461,7 @@ static int qce_skcipher_register_one(const struct qce_skcipher_def *def, alg->encrypt = qce_skcipher_encrypt; alg->decrypt = qce_skcipher_decrypt;
- alg->base.cra_priority = 300; + alg->base.cra_priority = 275; alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY | CRYPTO_ALG_KERN_DRIVER_ONLY; diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index 71d8b26c4103..9f35f69e0f9e 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -106,7 +106,7 @@ config ISCSI_IBFT select ISCSI_BOOT_SYSFS select ISCSI_IBFT_FIND if X86 depends on ACPI && SCSI && SCSI_LOWLEVEL - default n + default n help This option enables support for detection and exposing of iSCSI Boot Firmware Table (iBFT) via sysfs to userspace. If you wish to diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index ed4e8ddbe76a..1141cd06011f 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -11,7 +11,7 @@ cflags-y := $(KBUILD_CFLAGS)
cflags-$(CONFIG_X86_32) := -march=i386 cflags-$(CONFIG_X86_64) := -mcmodel=small -cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ \ +cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ -std=gnu11 \ -fPIC -fno-strict-aliasing -mno-red-zone \ -mno-mmx -mno-sse -fshort-wchar \ -Wno-pointer-sign \ diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 26312a5131d2..959bc156f35f 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -217,7 +217,10 @@ static DEFINE_SPINLOCK(scm_query_lock);
struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void) { - return __scm ? __scm->mempool : NULL; + if (!qcom_scm_is_available()) + return NULL; + + return __scm->mempool; }
static enum qcom_scm_convention __get_convention(void) @@ -1867,7 +1870,8 @@ static int qcom_scm_qseecom_init(struct qcom_scm *scm) */ bool qcom_scm_is_available(void) { - return !!READ_ONCE(__scm); + /* Paired with smp_store_release() in qcom_scm_probe */ + return !!smp_load_acquire(&__scm); } EXPORT_SYMBOL_GPL(qcom_scm_is_available);
@@ -2024,7 +2028,7 @@ static int qcom_scm_probe(struct platform_device *pdev) if (ret) return ret;
- /* Let all above stores be available after this */ + /* Paired with smp_load_acquire() in qcom_scm_is_available(). */ smp_store_release(&__scm, scm);
irq = platform_get_irq_optional(pdev, 0); diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 93ee3aa092f8..1a66ca075ade 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -338,6 +338,7 @@ config GPIO_GRANITERAPIDS
config GPIO_GRGPIO tristate "Aeroflex Gaisler GRGPIO support" + depends on OF || COMPILE_TEST select GPIO_GENERIC select IRQ_DOMAIN help diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index be4c9981ebc4..d63c1030e6ac 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -841,25 +841,6 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pendin DECLARE_BITMAP(trigger, MAX_LINE); int ret;
- if (chip->driver_data & PCA_PCAL) { - /* Read the current interrupt status from the device */ - ret = pca953x_read_regs(chip, PCAL953X_INT_STAT, trigger); - if (ret) - return false; - - /* Check latched inputs and clear interrupt status */ - ret = pca953x_read_regs(chip, chip->regs->input, cur_stat); - if (ret) - return false; - - /* Apply filter for rising/falling edge selection */ - bitmap_replace(new_stat, chip->irq_trig_fall, chip->irq_trig_raise, cur_stat, gc->ngpio); - - bitmap_and(pending, new_stat, trigger, gc->ngpio); - - return !bitmap_empty(pending, gc->ngpio); - } - ret = pca953x_read_regs(chip, chip->regs->input, cur_stat); if (ret) return false; diff --git a/drivers/gpio/gpio-sim.c b/drivers/gpio/gpio-sim.c index 686ae3d11ba3..940165235db6 100644 --- a/drivers/gpio/gpio-sim.c +++ b/drivers/gpio/gpio-sim.c @@ -1033,20 +1033,23 @@ gpio_sim_device_lockup_configfs(struct gpio_sim_device *dev, bool lock) struct configfs_subsystem *subsys = dev->group.cg_subsys; struct gpio_sim_bank *bank; struct gpio_sim_line *line; + struct config_item *item;
/* - * The device only needs to depend on leaf line entries. This is + * The device only needs to depend on leaf entries. This is * sufficient to lock up all the configfs entries that the * instantiated, alive device depends on. */ list_for_each_entry(bank, &dev->bank_list, siblings) { list_for_each_entry(line, &bank->line_list, siblings) { + item = line->hog ? &line->hog->item + : &line->group.cg_item; + if (lock) - WARN_ON(configfs_depend_item_unlocked( - subsys, &line->group.cg_item)); + WARN_ON(configfs_depend_item_unlocked(subsys, + item)); else - configfs_undepend_item_unlocked( - &line->group.cg_item); + configfs_undepend_item_unlocked(item); } } } diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 772fc7625639..b55be8889e2c 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -530,6 +530,10 @@ config DRM_HYPERV config DRM_EXPORT_FOR_TESTS bool
+# Separate option as not all DRM drivers use it +config DRM_PANEL_BACKLIGHT_QUIRKS + tristate + config DRM_LIB_RANDOM bool default n diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 463afad1b5ca..06b73068d248 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -95,6 +95,7 @@ drm-$(CONFIG_DRM_PANIC_SCREEN_QR_CODE) += drm_panic_qr.o obj-$(CONFIG_DRM) += drm.o
obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o +obj-$(CONFIG_DRM_PANEL_BACKLIGHT_QUIRKS) += drm_panel_backlight_quirks.o
# # Memory-management helpers diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig b/drivers/gpu/drm/amd/amdgpu/Kconfig index 41fa3377d9cf..1a11cab741ac 100644 --- a/drivers/gpu/drm/amd/amdgpu/Kconfig +++ b/drivers/gpu/drm/amd/amdgpu/Kconfig @@ -26,6 +26,7 @@ config DRM_AMDGPU select DRM_BUDDY select DRM_SUBALLOC_HELPER select DRM_EXEC + select DRM_PANEL_BACKLIGHT_QUIRKS # amdgpu depends on ACPI_VIDEO when ACPI is enabled, for select to work # ACPI_VIDEO's dependencies must also be selected. select INPUT if ACPI diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 38686203bea6..e63efe5c5b75 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -119,9 +119,10 @@ * - 3.57.0 - Compute tunneling on GFX10+ * - 3.58.0 - Add GFX12 DCC support * - 3.59.0 - Cleared VRAM + * - 3.60.0 - Add AMDGPU_TILING_GFX12_DCC_WRITE_COMPRESS_DISABLE (Vulkan requirement) */ #define KMS_DRIVER_MAJOR 3 -#define KMS_DRIVER_MINOR 59 +#define KMS_DRIVER_MINOR 60 #define KMS_DRIVER_PATCHLEVEL 0
/* diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index c4da62d11105..2890f54339ad 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -309,7 +309,7 @@ int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev, mutex_lock(&adev->mman.gtt_window_lock); while (src_mm.remaining) { uint64_t from, to, cur_size, tiling_flags; - uint32_t num_type, data_format, max_com; + uint32_t num_type, data_format, max_com, write_compress_disable; struct dma_fence *next;
/* Never copy more than 256MiB at once to avoid a timeout */ @@ -340,9 +340,13 @@ int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev, max_com = AMDGPU_TILING_GET(tiling_flags, GFX12_DCC_MAX_COMPRESSED_BLOCK); num_type = AMDGPU_TILING_GET(tiling_flags, GFX12_DCC_NUMBER_TYPE); data_format = AMDGPU_TILING_GET(tiling_flags, GFX12_DCC_DATA_FORMAT); + write_compress_disable = + AMDGPU_TILING_GET(tiling_flags, GFX12_DCC_WRITE_COMPRESS_DISABLE); copy_flags |= (AMDGPU_COPY_FLAGS_SET(MAX_COMPRESSED, max_com) | AMDGPU_COPY_FLAGS_SET(NUMBER_TYPE, num_type) | - AMDGPU_COPY_FLAGS_SET(DATA_FORMAT, data_format)); + AMDGPU_COPY_FLAGS_SET(DATA_FORMAT, data_format) | + AMDGPU_COPY_FLAGS_SET(WRITE_COMPRESS_DISABLE, + write_compress_disable)); }
r = amdgpu_copy_buffer(ring, from, to, cur_size, resv, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h index 2852a6064c9a..cd349a3c7988 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h @@ -119,6 +119,8 @@ struct amdgpu_copy_mem { #define AMDGPU_COPY_FLAGS_NUMBER_TYPE_MASK 0x07 #define AMDGPU_COPY_FLAGS_DATA_FORMAT_SHIFT 8 #define AMDGPU_COPY_FLAGS_DATA_FORMAT_MASK 0x3f +#define AMDGPU_COPY_FLAGS_WRITE_COMPRESS_DISABLE_SHIFT 14 +#define AMDGPU_COPY_FLAGS_WRITE_COMPRESS_DISABLE_MASK 0x1
#define AMDGPU_COPY_FLAGS_SET(field, value) \ (((__u32)(value) & AMDGPU_COPY_FLAGS_##field##_MASK) << AMDGPU_COPY_FLAGS_##field##_SHIFT) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c index da327ab48a57..5b50e07ba4c7 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c @@ -3999,17 +3999,6 @@ static void gfx_v12_0_update_coarse_grain_clock_gating(struct amdgpu_device *ade
if (def != data) WREG32_SOC15(GC, 0, regRLC_CGCG_CGLS_CTRL_3D, data); - - data = RREG32_SOC15(GC, 0, regSDMA0_RLC_CGCG_CTRL); - data &= ~SDMA0_RLC_CGCG_CTRL__CGCG_INT_ENABLE_MASK; - WREG32_SOC15(GC, 0, regSDMA0_RLC_CGCG_CTRL, data); - - /* Some ASICs only have one SDMA instance, not need to configure SDMA1 */ - if (adev->sdma.num_instances > 1) { - data = RREG32_SOC15(GC, 0, regSDMA1_RLC_CGCG_CTRL); - data &= ~SDMA1_RLC_CGCG_CTRL__CGCG_INT_ENABLE_MASK; - WREG32_SOC15(GC, 0, regSDMA1_RLC_CGCG_CTRL, data); - } } }
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c index a38553f38fdc..ed68d7971a93 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c @@ -953,10 +953,12 @@ static int sdma_v4_4_2_inst_start(struct amdgpu_device *adev, /* set utc l1 enable flag always to 1 */ temp = RREG32_SDMA(i, regSDMA_CNTL); temp = REG_SET_FIELD(temp, SDMA_CNTL, UTC_L1_ENABLE, 1); - /* enable context empty interrupt during initialization */ - temp = REG_SET_FIELD(temp, SDMA_CNTL, CTXEMPTY_INT_ENABLE, 1); - WREG32_SDMA(i, regSDMA_CNTL, temp);
+ if (amdgpu_ip_version(adev, SDMA0_HWIP, 0) < IP_VERSION(4, 4, 5)) { + /* enable context empty interrupt during initialization */ + temp = REG_SET_FIELD(temp, SDMA_CNTL, CTXEMPTY_INT_ENABLE, 1); + WREG32_SDMA(i, regSDMA_CNTL, temp); + } if (!amdgpu_sriov_vf(adev)) { if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { /* unhalt engine */ diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c index d2ce6b6a7ff6..d41e38a0bd41 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c @@ -1684,11 +1684,12 @@ static void sdma_v7_0_emit_copy_buffer(struct amdgpu_ib *ib, uint32_t byte_count, uint32_t copy_flags) { - uint32_t num_type, data_format, max_com; + uint32_t num_type, data_format, max_com, write_cm;
max_com = AMDGPU_COPY_FLAGS_GET(copy_flags, MAX_COMPRESSED); data_format = AMDGPU_COPY_FLAGS_GET(copy_flags, DATA_FORMAT); num_type = AMDGPU_COPY_FLAGS_GET(copy_flags, NUMBER_TYPE); + write_cm = AMDGPU_COPY_FLAGS_GET(copy_flags, WRITE_COMPRESS_DISABLE) ? 2 : 1;
ib->ptr[ib->length_dw++] = SDMA_PKT_COPY_LINEAR_HEADER_OP(SDMA_OP_COPY) | SDMA_PKT_COPY_LINEAR_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR) | @@ -1705,7 +1706,7 @@ static void sdma_v7_0_emit_copy_buffer(struct amdgpu_ib *ib, if ((copy_flags & (AMDGPU_COPY_FLAGS_READ_DECOMPRESSED | AMDGPU_COPY_FLAGS_WRITE_COMPRESSED))) ib->ptr[ib->length_dw++] = SDMA_DCC_DATA_FORMAT(data_format) | SDMA_DCC_NUM_TYPE(num_type) | ((copy_flags & AMDGPU_COPY_FLAGS_READ_DECOMPRESSED) ? SDMA_DCC_READ_CM(2) : 0) | - ((copy_flags & AMDGPU_COPY_FLAGS_WRITE_COMPRESSED) ? SDMA_DCC_WRITE_CM(1) : 0) | + ((copy_flags & AMDGPU_COPY_FLAGS_WRITE_COMPRESSED) ? SDMA_DCC_WRITE_CM(write_cm) : 0) | SDMA_DCC_MAX_COM(max_com) | SDMA_DCC_MAX_UCOM(1); else ib->ptr[ib->length_dw++] = 0; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 9b51dd75fefc..35caa71f317d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -638,6 +638,14 @@ static void kfd_cleanup_nodes(struct kfd_dev *kfd, unsigned int num_nodes) struct kfd_node *knode; unsigned int i;
+ /* + * flush_work ensures that there are no outstanding + * work-queue items that will access interrupt_ring. New work items + * can't be created because we stopped interrupt handling above. + */ + flush_workqueue(kfd->ih_wq); + destroy_workqueue(kfd->ih_wq); + for (i = 0; i < num_nodes; i++) { knode = kfd->nodes[i]; device_queue_manager_uninit(knode->dqm); @@ -1059,21 +1067,6 @@ static int kfd_resume(struct kfd_node *node) return err; }
-static inline void kfd_queue_work(struct workqueue_struct *wq, - struct work_struct *work) -{ - int cpu, new_cpu; - - cpu = new_cpu = smp_processor_id(); - do { - new_cpu = cpumask_next(new_cpu, cpu_online_mask) % nr_cpu_ids; - if (cpu_to_node(new_cpu) == numa_node_id()) - break; - } while (cpu != new_cpu); - - queue_work_on(new_cpu, wq, work); -} - /* This is called directly from KGD at ISR. */ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry) { @@ -1099,7 +1092,7 @@ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry) patched_ihre, &is_patched) && enqueue_ih_ring_entry(node, is_patched ? patched_ihre : ih_ring_entry)) { - kfd_queue_work(node->ih_wq, &node->interrupt_work); + queue_work(node->kfd->ih_wq, &node->interrupt_work); spin_unlock_irqrestore(&node->interrupt_lock, flags); return; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 16b5daaa272f..6f3099488053 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -2325,9 +2325,9 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm, */ mqd_mgr = dqm->mqd_mgrs[KFD_MQD_TYPE_HIQ]; if (mqd_mgr->check_preemption_failed(mqd_mgr, dqm->packet_mgr.priv_queue->queue->mqd)) { + while (halt_if_hws_hang) + schedule(); if (reset_queues_on_hws_hang(dqm)) { - while (halt_if_hws_hang) - schedule(); dqm->is_hws_hang = true; kfd_hws_hang(dqm); retval = -ETIME; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c index 9b6b6e882593..15b4b70cf199 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c @@ -62,11 +62,14 @@ int kfd_interrupt_init(struct kfd_node *node) return r; }
- node->ih_wq = alloc_workqueue("KFD IH", WQ_HIGHPRI, 1); - if (unlikely(!node->ih_wq)) { - kfifo_free(&node->ih_fifo); - dev_err(node->adev->dev, "Failed to allocate KFD IH workqueue\n"); - return -ENOMEM; + if (!node->kfd->ih_wq) { + node->kfd->ih_wq = alloc_workqueue("KFD IH", WQ_HIGHPRI | WQ_UNBOUND, + node->kfd->num_nodes); + if (unlikely(!node->kfd->ih_wq)) { + kfifo_free(&node->ih_fifo); + dev_err(node->adev->dev, "Failed to allocate KFD IH workqueue\n"); + return -ENOMEM; + } } spin_lock_init(&node->interrupt_lock);
@@ -96,16 +99,6 @@ void kfd_interrupt_exit(struct kfd_node *node) spin_lock_irqsave(&node->interrupt_lock, flags); node->interrupts_active = false; spin_unlock_irqrestore(&node->interrupt_lock, flags); - - /* - * flush_work ensures that there are no outstanding - * work-queue items that will access interrupt_ring. New work items - * can't be created because we stopped interrupt handling above. - */ - flush_workqueue(node->ih_wq); - - destroy_workqueue(node->ih_wq); - kfifo_free(&node->ih_fifo); }
@@ -162,7 +155,7 @@ static void interrupt_wq(struct work_struct *work) /* If we spent more than a second processing signals, * reschedule the worker to avoid soft-lockup warnings */ - queue_work(dev->ih_wq, &dev->interrupt_work); + queue_work(dev->kfd->ih_wq, &dev->interrupt_work); break; } } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 9e5ca0b93b2a..74881a5ca59a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -273,7 +273,6 @@ struct kfd_node {
/* Interrupts */ struct kfifo ih_fifo; - struct workqueue_struct *ih_wq; struct work_struct interrupt_work; spinlock_t interrupt_lock;
@@ -366,6 +365,8 @@ struct kfd_dev { struct kfd_node *nodes[MAX_KFD_NODES]; unsigned int num_nodes;
+ struct workqueue_struct *ih_wq; + /* Kernel doorbells for KFD device */ struct amdgpu_bo *doorbells;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c index 59b92d66e958..bd595b1db15f 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c @@ -86,9 +86,12 @@ void kfd_process_dequeue_from_device(struct kfd_process_device *pdd)
if (pdd->already_dequeued) return; - + /* The MES context flush needs to filter out the case which the + * KFD process is created without setting up the MES context and + * queue for creating a compute queue. + */ dev->dqm->ops.process_termination(dev->dqm, &pdd->qpd); - if (dev->kfd->shared_resources.enable_mes && + if (dev->kfd->shared_resources.enable_mes && !!pdd->proc_ctx_gpu_addr && down_read_trylock(&dev->adev->reset_domain->sem)) { amdgpu_mes_flush_shader_debugger(dev->adev, pdd->proc_ctx_gpu_addr); 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 53694baca966..f7c0d7625ff1 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -93,6 +93,7 @@ #include <drm/drm_fourcc.h> #include <drm/drm_edid.h> #include <drm/drm_eld.h> +#include <drm/drm_utils.h> #include <drm/drm_vblank.h> #include <drm/drm_audio_component.h> #include <drm/drm_gem_atomic_helper.h> @@ -1036,8 +1037,10 @@ static int amdgpu_dm_audio_component_get_eld(struct device *kdev, int port, continue;
*enabled = true; + mutex_lock(&connector->eld_mutex); ret = drm_eld_size(connector->eld); memcpy(buf, connector->eld, min(max_bytes, ret)); + mutex_unlock(&connector->eld_mutex);
break; } @@ -3457,6 +3460,7 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector) struct drm_connector *conn_base; struct amdgpu_device *adev; struct drm_luminance_range_info *luminance_range; + int min_input_signal_override;
if (aconnector->bl_idx == -1 || aconnector->dc_link->connector_signal != SIGNAL_TYPE_EDP) @@ -3493,6 +3497,10 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector) caps->aux_min_input_signal = 0; caps->aux_max_input_signal = 512; } + + min_input_signal_override = drm_get_panel_min_brightness_quirk(aconnector->drm_edid); + if (min_input_signal_override >= 0) + caps->min_input_signal = min_input_signal_override; }
void amdgpu_dm_update_connector_after_detect( @@ -5522,8 +5530,7 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev, const u64 tiling_flags, struct dc_plane_info *plane_info, struct dc_plane_address *address, - bool tmz_surface, - bool force_disable_dcc) + bool tmz_surface) { const struct drm_framebuffer *fb = plane_state->fb; const struct amdgpu_framebuffer *afb = @@ -5622,7 +5629,7 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev, &plane_info->tiling_info, &plane_info->plane_size, &plane_info->dcc, address, - tmz_surface, force_disable_dcc); + tmz_surface); if (ret) return ret;
@@ -5643,7 +5650,6 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, struct dc_scaling_info scaling_info; struct dc_plane_info plane_info; int ret; - bool force_disable_dcc = false;
ret = amdgpu_dm_plane_fill_dc_scaling_info(adev, plane_state, &scaling_info); if (ret) @@ -5654,13 +5660,11 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, dc_plane_state->clip_rect = scaling_info.clip_rect; dc_plane_state->scaling_quality = scaling_info.scaling_quality;
- force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend; ret = fill_dc_plane_info_and_addr(adev, plane_state, afb->tiling_flags, &plane_info, &dc_plane_state->address, - afb->tmz_surface, - force_disable_dcc); + afb->tmz_surface); if (ret) return ret;
@@ -9068,7 +9072,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, afb->tiling_flags, &bundle->plane_infos[planes_count], &bundle->flip_addrs[planes_count].address, - afb->tmz_surface, false); + afb->tmz_surface);
drm_dbg_state(state->dev, "plane: id=%d dcc_en=%d\n", new_plane_state->plane->index, 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 1080075ccb17..e096fb562122 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 @@ -1695,16 +1695,16 @@ int pre_validate_dsc(struct drm_atomic_state *state, return ret; }
-static unsigned int kbps_from_pbn(unsigned int pbn) +static uint32_t kbps_from_pbn(unsigned int pbn) { - unsigned int kbps = pbn; + uint64_t kbps = (uint64_t)pbn;
kbps *= (1000000 / PEAK_FACTOR_X1000); kbps *= 8; kbps *= 54; kbps /= 64;
- return kbps; + return (uint32_t)kbps; }
static bool is_dsc_common_config_possible(struct dc_stream_state *stream, diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c index 495e3cd70426..83c7c8853ede 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c @@ -309,8 +309,7 @@ static int amdgpu_dm_plane_fill_gfx9_plane_attributes_from_modifiers(struct amdg const struct plane_size *plane_size, union dc_tiling_info *tiling_info, struct dc_plane_dcc_param *dcc, - struct dc_plane_address *address, - const bool force_disable_dcc) + struct dc_plane_address *address) { const uint64_t modifier = afb->base.modifier; int ret = 0; @@ -318,7 +317,7 @@ static int amdgpu_dm_plane_fill_gfx9_plane_attributes_from_modifiers(struct amdg amdgpu_dm_plane_fill_gfx9_tiling_info_from_modifier(adev, tiling_info, modifier); tiling_info->gfx9.swizzle = amdgpu_dm_plane_modifier_gfx9_swizzle_mode(modifier);
- if (amdgpu_dm_plane_modifier_has_dcc(modifier) && !force_disable_dcc) { + if (amdgpu_dm_plane_modifier_has_dcc(modifier)) { uint64_t dcc_address = afb->address + afb->base.offsets[1]; bool independent_64b_blks = AMD_FMT_MOD_GET(DCC_INDEPENDENT_64B, modifier); bool independent_128b_blks = AMD_FMT_MOD_GET(DCC_INDEPENDENT_128B, modifier); @@ -360,8 +359,7 @@ static int amdgpu_dm_plane_fill_gfx12_plane_attributes_from_modifiers(struct amd const struct plane_size *plane_size, union dc_tiling_info *tiling_info, struct dc_plane_dcc_param *dcc, - struct dc_plane_address *address, - const bool force_disable_dcc) + struct dc_plane_address *address) { const uint64_t modifier = afb->base.modifier; int ret = 0; @@ -371,7 +369,7 @@ static int amdgpu_dm_plane_fill_gfx12_plane_attributes_from_modifiers(struct amd
tiling_info->gfx9.swizzle = amdgpu_dm_plane_modifier_gfx9_swizzle_mode(modifier);
- if (amdgpu_dm_plane_modifier_has_dcc(modifier) && !force_disable_dcc) { + if (amdgpu_dm_plane_modifier_has_dcc(modifier)) { int max_compressed_block = AMD_FMT_MOD_GET(DCC_MAX_COMPRESSED_BLOCK, modifier);
dcc->enable = 1; @@ -839,8 +837,7 @@ int amdgpu_dm_plane_fill_plane_buffer_attributes(struct amdgpu_device *adev, struct plane_size *plane_size, struct dc_plane_dcc_param *dcc, struct dc_plane_address *address, - bool tmz_surface, - bool force_disable_dcc) + bool tmz_surface) { const struct drm_framebuffer *fb = &afb->base; int ret; @@ -900,16 +897,14 @@ int amdgpu_dm_plane_fill_plane_buffer_attributes(struct amdgpu_device *adev, ret = amdgpu_dm_plane_fill_gfx12_plane_attributes_from_modifiers(adev, afb, format, rotation, plane_size, tiling_info, dcc, - address, - force_disable_dcc); + address); if (ret) return ret; } else if (adev->family >= AMDGPU_FAMILY_AI) { ret = amdgpu_dm_plane_fill_gfx9_plane_attributes_from_modifiers(adev, afb, format, rotation, plane_size, tiling_info, dcc, - address, - force_disable_dcc); + address); if (ret) return ret; } else { @@ -1000,14 +995,13 @@ static int amdgpu_dm_plane_helper_prepare_fb(struct drm_plane *plane, dm_plane_state_old->dc_state != dm_plane_state_new->dc_state) { struct dc_plane_state *plane_state = dm_plane_state_new->dc_state; - bool force_disable_dcc = !plane_state->dcc.enable;
amdgpu_dm_plane_fill_plane_buffer_attributes( adev, afb, plane_state->format, plane_state->rotation, afb->tiling_flags, &plane_state->tiling_info, &plane_state->plane_size, &plane_state->dcc, &plane_state->address, - afb->tmz_surface, force_disable_dcc); + afb->tmz_surface); }
return 0; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h index 6498359bff6f..2eef13b1c05a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h @@ -51,8 +51,7 @@ int amdgpu_dm_plane_fill_plane_buffer_attributes(struct amdgpu_device *adev, struct plane_size *plane_size, struct dc_plane_dcc_param *dcc, struct dc_plane_address *address, - bool tmz_surface, - bool force_disable_dcc); + bool tmz_surface);
int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, struct drm_plane *plane, diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 2723558049d6..9f37b3902705 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2063,7 +2063,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
dc_enable_stereo(dc, context, dc_streams, context->stream_count);
- if (context->stream_count > get_seamless_boot_stream_count(context) || + if (get_seamless_boot_stream_count(context) == 0 || context->stream_count == 0) { /* Must wait for no flips to be pending before doing optimize bw */ hwss_wait_for_no_pipes_pending(dc, context); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c index 5bb8b78bf250..bf636b28e3e1 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c @@ -63,8 +63,7 @@ void dmub_hw_lock_mgr_inbox0_cmd(struct dc_dmub_srv *dmub_srv,
bool should_use_dmub_lock(struct dc_link *link) { - if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1 || - link->psr_settings.psr_version == DC_PSR_VERSION_1) + if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) return true;
if (link->replay_settings.replay_feature_enabled) diff --git a/drivers/gpu/drm/amd/display/dc/dml2/Makefile b/drivers/gpu/drm/amd/display/dc/dml2/Makefile index c4378e620cbf..986a69c5bd4b 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dml2/Makefile @@ -29,7 +29,11 @@ dml2_rcflags := $(CC_FLAGS_NO_FPU)
ifneq ($(CONFIG_FRAME_WARN),0) ifeq ($(filter y,$(CONFIG_KASAN)$(CONFIG_KCSAN)),y) +ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_COMPILE_TEST),yy) +frame_warn_flag := -Wframe-larger-than=4096 +else frame_warn_flag := -Wframe-larger-than=3072 +endif else frame_warn_flag := -Wframe-larger-than=2048 endif diff --git a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c index 8dabb1ac0b68..6822b0795120 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c @@ -6301,9 +6301,9 @@ static void dml_prefetch_check(struct display_mode_lib_st *mode_lib) mode_lib->ms.meta_row_bandwidth_this_state, mode_lib->ms.dpte_row_bandwidth_this_state, mode_lib->ms.NoOfDPPThisState, - mode_lib->ms.UrgentBurstFactorLuma, - mode_lib->ms.UrgentBurstFactorChroma, - mode_lib->ms.UrgentBurstFactorCursor); + mode_lib->ms.UrgentBurstFactorLuma[j], + mode_lib->ms.UrgentBurstFactorChroma[j], + mode_lib->ms.UrgentBurstFactorCursor[j]);
s->VMDataOnlyReturnBWPerState = dml_get_return_bw_mbps_vm_only( &mode_lib->ms.soc, @@ -6434,7 +6434,7 @@ static void dml_prefetch_check(struct display_mode_lib_st *mode_lib) /* Output */ &mode_lib->ms.UrgentBurstFactorCursorPre[k], &mode_lib->ms.UrgentBurstFactorLumaPre[k], - &mode_lib->ms.UrgentBurstFactorChroma[k], + &mode_lib->ms.UrgentBurstFactorChromaPre[k], &mode_lib->ms.NotUrgentLatencyHidingPre[k]);
mode_lib->ms.cursor_bw_pre[k] = mode_lib->ms.cache_display_cfg.plane.NumberOfCursors[k] * mode_lib->ms.cache_display_cfg.plane.CursorWidth[k] * @@ -6458,9 +6458,9 @@ static void dml_prefetch_check(struct display_mode_lib_st *mode_lib) mode_lib->ms.cursor_bw_pre, mode_lib->ms.prefetch_vmrow_bw, mode_lib->ms.NoOfDPPThisState, - mode_lib->ms.UrgentBurstFactorLuma, - mode_lib->ms.UrgentBurstFactorChroma, - mode_lib->ms.UrgentBurstFactorCursor, + mode_lib->ms.UrgentBurstFactorLuma[j], + mode_lib->ms.UrgentBurstFactorChroma[j], + mode_lib->ms.UrgentBurstFactorCursor[j], mode_lib->ms.UrgentBurstFactorLumaPre, mode_lib->ms.UrgentBurstFactorChromaPre, mode_lib->ms.UrgentBurstFactorCursorPre, @@ -6517,9 +6517,9 @@ static void dml_prefetch_check(struct display_mode_lib_st *mode_lib) mode_lib->ms.cursor_bw, mode_lib->ms.cursor_bw_pre, mode_lib->ms.NoOfDPPThisState, - mode_lib->ms.UrgentBurstFactorLuma, - mode_lib->ms.UrgentBurstFactorChroma, - mode_lib->ms.UrgentBurstFactorCursor, + mode_lib->ms.UrgentBurstFactorLuma[j], + mode_lib->ms.UrgentBurstFactorChroma[j], + mode_lib->ms.UrgentBurstFactorCursor[j], mode_lib->ms.UrgentBurstFactorLumaPre, mode_lib->ms.UrgentBurstFactorChromaPre, mode_lib->ms.UrgentBurstFactorCursorPre); @@ -6586,9 +6586,9 @@ static void dml_prefetch_check(struct display_mode_lib_st *mode_lib) mode_lib->ms.cursor_bw_pre, mode_lib->ms.prefetch_vmrow_bw, mode_lib->ms.NoOfDPP[j], // VBA_ERROR DPPPerSurface is not assigned at this point, should use NoOfDpp here - mode_lib->ms.UrgentBurstFactorLuma, - mode_lib->ms.UrgentBurstFactorChroma, - mode_lib->ms.UrgentBurstFactorCursor, + mode_lib->ms.UrgentBurstFactorLuma[j], + mode_lib->ms.UrgentBurstFactorChroma[j], + mode_lib->ms.UrgentBurstFactorCursor[j], mode_lib->ms.UrgentBurstFactorLumaPre, mode_lib->ms.UrgentBurstFactorChromaPre, mode_lib->ms.UrgentBurstFactorCursorPre, @@ -7809,9 +7809,9 @@ dml_bool_t dml_core_mode_support(struct display_mode_lib_st *mode_lib) mode_lib->ms.DETBufferSizeYThisState[k], mode_lib->ms.DETBufferSizeCThisState[k], /* Output */ - &mode_lib->ms.UrgentBurstFactorCursor[k], - &mode_lib->ms.UrgentBurstFactorLuma[k], - &mode_lib->ms.UrgentBurstFactorChroma[k], + &mode_lib->ms.UrgentBurstFactorCursor[j][k], + &mode_lib->ms.UrgentBurstFactorLuma[j][k], + &mode_lib->ms.UrgentBurstFactorChroma[j][k], &mode_lib->ms.NotUrgentLatencyHiding[k]); }
@@ -9190,6 +9190,8 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc &locals->FractionOfUrgentBandwidth, &s->dummy_boolean[0]); // dml_bool_t *PrefetchBandwidthSupport
+ + if (s->VRatioPrefetchMoreThanMax != false || s->DestinationLineTimesForPrefetchLessThan2 != false) { dml_print("DML::%s: VRatioPrefetchMoreThanMax = %u\n", __func__, s->VRatioPrefetchMoreThanMax); dml_print("DML::%s: DestinationLineTimesForPrefetchLessThan2 = %u\n", __func__, s->DestinationLineTimesForPrefetchLessThan2); @@ -9204,6 +9206,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc } }
+ if (locals->PrefetchModeSupported == true && mode_lib->ms.support.ImmediateFlipSupport == true) { locals->BandwidthAvailableForImmediateFlip = CalculateBandwidthAvailableForImmediateFlip( mode_lib->ms.num_active_planes, diff --git a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core_structs.h b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core_structs.h index f951936bb579..504c427b3b31 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core_structs.h +++ b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core_structs.h @@ -884,11 +884,11 @@ struct mode_support_st { dml_uint_t meta_row_height[__DML_NUM_PLANES__]; dml_uint_t meta_row_height_chroma[__DML_NUM_PLANES__]; dml_float_t UrgLatency; - dml_float_t UrgentBurstFactorCursor[__DML_NUM_PLANES__]; + dml_float_t UrgentBurstFactorCursor[2][__DML_NUM_PLANES__]; dml_float_t UrgentBurstFactorCursorPre[__DML_NUM_PLANES__]; - dml_float_t UrgentBurstFactorLuma[__DML_NUM_PLANES__]; + dml_float_t UrgentBurstFactorLuma[2][__DML_NUM_PLANES__]; dml_float_t UrgentBurstFactorLumaPre[__DML_NUM_PLANES__]; - dml_float_t UrgentBurstFactorChroma[__DML_NUM_PLANES__]; + dml_float_t UrgentBurstFactorChroma[2][__DML_NUM_PLANES__]; dml_float_t UrgentBurstFactorChromaPre[__DML_NUM_PLANES__]; dml_float_t MaximumSwathWidthInLineBufferLuma; dml_float_t MaximumSwathWidthInLineBufferChroma; diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c index 9190c1328d5b..340791d40ecb 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c @@ -531,14 +531,21 @@ static bool optimize_pstate_with_svp_and_drr(struct dml2_context *dml2, struct d static bool call_dml_mode_support_and_programming(struct dc_state *context) { unsigned int result = 0; - unsigned int min_state; + unsigned int min_state = 0; int min_state_for_g6_temp_read = 0; + + + if (!context) + return false; + struct dml2_context *dml2 = context->bw_ctx.dml2; struct dml2_wrapper_scratch *s = &dml2->v20.scratch;
- min_state_for_g6_temp_read = calculate_lowest_supported_state_for_temp_read(dml2, context); + if (!context->streams[0]->sink->link->dc->caps.is_apu) { + min_state_for_g6_temp_read = calculate_lowest_supported_state_for_temp_read(dml2, context);
- ASSERT(min_state_for_g6_temp_read >= 0); + ASSERT(min_state_for_g6_temp_read >= 0); + }
if (!dml2->config.use_native_pstate_optimization) { result = optimize_pstate_with_svp_and_drr(dml2, context); @@ -549,14 +556,20 @@ static bool call_dml_mode_support_and_programming(struct dc_state *context) /* Upon trying to sett certain frequencies in FRL, min_state_for_g6_temp_read is reported as -1. This leads to an invalid value of min_state causing crashes later on. * Use the default logic for min_state only when min_state_for_g6_temp_read is a valid value. In other cases, use the value calculated by the DML directly. */ - if (min_state_for_g6_temp_read >= 0) - min_state = min_state_for_g6_temp_read > s->mode_support_params.out_lowest_state_idx ? min_state_for_g6_temp_read : s->mode_support_params.out_lowest_state_idx; - else - min_state = s->mode_support_params.out_lowest_state_idx; - - if (result) - result = dml_mode_programming(&dml2->v20.dml_core_ctx, min_state, &s->cur_display_config, true); + if (!context->streams[0]->sink->link->dc->caps.is_apu) { + if (min_state_for_g6_temp_read >= 0) + min_state = min_state_for_g6_temp_read > s->mode_support_params.out_lowest_state_idx ? min_state_for_g6_temp_read : s->mode_support_params.out_lowest_state_idx; + else + min_state = s->mode_support_params.out_lowest_state_idx; + }
+ if (result) { + if (!context->streams[0]->sink->link->dc->caps.is_apu) { + result = dml_mode_programming(&dml2->v20.dml_core_ctx, min_state, &s->cur_display_config, true); + } else { + result = dml_mode_programming(&dml2->v20.dml_core_ctx, s->mode_support_params.out_lowest_state_idx, &s->cur_display_config, true); + } + } return result; }
@@ -685,6 +698,8 @@ static bool dml2_validate_only(struct dc_state *context) build_unoptimized_policy_settings(dml2->v20.dml_core_ctx.project, &dml2->v20.dml_core_ctx.policy);
map_dc_state_into_dml_display_cfg(dml2, context, &dml2->v20.scratch.cur_display_config); + if (!dml2->config.skip_hw_state_mapping) + dml2_apply_det_buffer_allocation_policy(dml2, &dml2->v20.scratch.cur_display_config);
result = pack_and_call_dml_mode_support_ex(dml2, &dml2->v20.scratch.cur_display_config, diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp.c index 961d8936150a..75fb77bca83b 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp.c @@ -483,10 +483,11 @@ void dpp1_set_cursor_position( if (src_y_offset + cursor_height <= 0) cur_en = 0; /* not visible beyond top edge*/
- REG_UPDATE(CURSOR0_CONTROL, - CUR0_ENABLE, cur_en); + if (dpp_base->pos.cur0_ctl.bits.cur0_enable != cur_en) { + REG_UPDATE(CURSOR0_CONTROL, CUR0_ENABLE, cur_en);
- dpp_base->pos.cur0_ctl.bits.cur0_enable = cur_en; + dpp_base->pos.cur0_ctl.bits.cur0_enable = cur_en; + } }
void dpp1_cnv_set_optional_cursor_attributes( diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c index 3b6ca7974e18..1236e0f9a256 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c @@ -154,9 +154,11 @@ void dpp401_set_cursor_position( struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base); uint32_t cur_en = pos->enable ? 1 : 0;
- REG_UPDATE(CURSOR0_CONTROL, CUR0_ENABLE, cur_en); + if (dpp_base->pos.cur0_ctl.bits.cur0_enable != cur_en) { + REG_UPDATE(CURSOR0_CONTROL, CUR0_ENABLE, cur_en);
- dpp_base->pos.cur0_ctl.bits.cur0_enable = cur_en; + dpp_base->pos.cur0_ctl.bits.cur0_enable = cur_en; + } }
void dpp401_set_optional_cursor_attributes( diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn30/dcn30_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn30/dcn30_hubbub.c index fe741100c0f8..d347bb06577a 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn30/dcn30_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn30/dcn30_hubbub.c @@ -129,7 +129,8 @@ bool hubbub3_program_watermarks( REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 0x1FF);
- hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter); + if (safe_to_lower || hubbub->ctx->dc->debug.disable_stutter) + hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
return wm_pending; } diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn31/dcn31_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn31/dcn31_hubbub.c index 7fb5523f9722..b98505b240a7 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn31/dcn31_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn31/dcn31_hubbub.c @@ -750,7 +750,8 @@ static bool hubbub31_program_watermarks( REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 0x1FF);*/
- hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter); + if (safe_to_lower || hubbub->ctx->dc->debug.disable_stutter) + hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter); return wm_pending; }
diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn32/dcn32_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn32/dcn32_hubbub.c index 5264dc26cce1..32a6be543105 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn32/dcn32_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn32/dcn32_hubbub.c @@ -786,7 +786,8 @@ static bool hubbub32_program_watermarks( REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 0x1FF);*/
- hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter); + if (safe_to_lower || hubbub->ctx->dc->debug.disable_stutter) + hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
hubbub32_force_usr_retraining_allow(hubbub, hubbub->ctx->dc->debug.force_usr_allow);
diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c index 5eb3da8d5206..dce7269959ce 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c @@ -326,7 +326,8 @@ static bool hubbub35_program_watermarks( DCHUBBUB_ARB_MIN_REQ_OUTSTAND_COMMIT_THRESHOLD, 0xA);/*hw delta*/ REG_UPDATE(DCHUBBUB_ARB_HOSTVM_CNTL, DCHUBBUB_ARB_MAX_QOS_COMMIT_THRESHOLD, 0xF);
- hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter); + if (safe_to_lower || hubbub->ctx->dc->debug.disable_stutter) + hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
hubbub32_force_usr_retraining_allow(hubbub, hubbub->ctx->dc->debug.force_usr_allow);
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c index b405fa22f87a..c74ee2d50a69 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c @@ -1044,11 +1044,13 @@ void hubp2_cursor_set_position( if (src_y_offset + cursor_height <= 0) cur_en = 0; /* not visible beyond top edge*/
- if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0) - hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr); + if (hubp->pos.cur_ctl.bits.cur_enable != cur_en) { + if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0) + hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr);
- REG_UPDATE(CURSOR_CONTROL, + REG_UPDATE(CURSOR_CONTROL, CURSOR_ENABLE, cur_en); + }
REG_SET_2(CURSOR_POSITION, 0, CURSOR_X_POSITION, pos->x, diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c index c55b1b8be8ff..5cf7e6771cb4 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c @@ -484,6 +484,8 @@ void hubp3_init(struct hubp *hubp) //hubp[i].HUBPREQ_DEBUG.HUBPREQ_DEBUG[26] = 1; REG_WRITE(HUBPREQ_DEBUG, 1 << 26);
+ REG_UPDATE(DCHUBP_CNTL, HUBP_TTU_DISABLE, 0); + hubp_reset(hubp); }
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c index 45023fa9b708..c4f41350d1b3 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c @@ -168,6 +168,8 @@ void hubp32_init(struct hubp *hubp) { struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); REG_WRITE(HUBPREQ_DEBUG_DB, 1 << 8); + + REG_UPDATE(DCHUBP_CNTL, HUBP_TTU_DISABLE, 0); } static struct hubp_funcs dcn32_hubp_funcs = { .hubp_enable_tripleBuffer = hubp2_enable_triplebuffer, diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c index 2d52100510f0..7013c124efcf 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c @@ -718,11 +718,13 @@ void hubp401_cursor_set_position( dc_fixpt_from_int(dst_x_offset), param->h_scale_ratio));
- if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0) - hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr); + if (hubp->pos.cur_ctl.bits.cur_enable != cur_en) { + if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0) + hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr);
- REG_UPDATE(CURSOR_CONTROL, - CURSOR_ENABLE, cur_en); + REG_UPDATE(CURSOR_CONTROL, + CURSOR_ENABLE, cur_en); + }
REG_SET_2(CURSOR_POSITION, 0, CURSOR_X_POSITION, x_pos, diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c index 463f7abe35a7..70295ecfbe5e 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c @@ -236,7 +236,8 @@ void dcn35_init_hw(struct dc *dc) }
hws->funcs.init_pipes(dc, dc->current_state); - if (dc->res_pool->hubbub->funcs->allow_self_refresh_control) + if (dc->res_pool->hubbub->funcs->allow_self_refresh_control && + !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter) dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub, !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter); } diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c index a9816affd312..0cc8a27be593 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c @@ -671,9 +671,9 @@ static const struct dc_plane_cap plane_cap = {
/* 6:1 downscaling ratio: 1000/6 = 166.666 */ .max_downscale_factor = { - .argb8888 = 167, - .nv12 = 167, - .fp16 = 167 + .argb8888 = 358, + .nv12 = 358, + .fp16 = 358 }, 64, 64 @@ -693,7 +693,7 @@ static const struct dc_debug_options debug_defaults_drv = { .disable_dcc = DCC_ENABLE, .vsr_support = true, .performance_trace = false, - .max_downscale_src_width = 7680,/*upto 8K*/ + .max_downscale_src_width = 4096,/*upto true 4k*/ .scl_reset_length10 = true, .sanity_checks = false, .underflow_assert_delay_us = 0xFFFFFFFF, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c index f6b029354327..83163d7c7f00 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c @@ -1732,7 +1732,6 @@ static ssize_t aldebaran_get_gpu_metrics(struct smu_context *smu,
gpu_metrics->average_gfx_activity = metrics.AverageGfxActivity; gpu_metrics->average_umc_activity = metrics.AverageUclkActivity; - gpu_metrics->average_mm_activity = 0;
/* Valid power data is available only from primary die */ if (aldebaran_is_primary(smu)) { diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c index ebccb74306a7..f30b3d5eeca5 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c @@ -160,6 +160,10 @@ static int komeda_wb_connector_add(struct komeda_kms_dev *kms, formats = komeda_get_layer_fourcc_list(&mdev->fmt_tbl, kwb_conn->wb_layer->layer_type, &n_formats); + if (!formats) { + kfree(kwb_conn); + return -ENOMEM; + }
err = drm_writeback_connector_init(&kms->base, wb_conn, &komeda_wb_connector_funcs, diff --git a/drivers/gpu/drm/ast/ast_dp.c b/drivers/gpu/drm/ast/ast_dp.c index 0e282b7b167c..b9eb67e3fa90 100644 --- a/drivers/gpu/drm/ast/ast_dp.c +++ b/drivers/gpu/drm/ast/ast_dp.c @@ -195,7 +195,7 @@ static bool __ast_dp_wait_enable(struct ast_device *ast, bool enabled) if (enabled) vgacrdf_test |= AST_IO_VGACRDF_DP_VIDEO_ENABLE;
- for (i = 0; i < 200; ++i) { + for (i = 0; i < 1000; ++i) { if (i) mdelay(1); vgacrdf = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xdf, diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index a2675b121fe4..c036bbc92ba9 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -2002,8 +2002,10 @@ static int anx7625_audio_get_eld(struct device *dev, void *data, memset(buf, 0, len); } else { dev_dbg(dev, "audio copy eld\n"); + mutex_lock(&ctx->connector->eld_mutex); memcpy(buf, ctx->connector->eld, min(sizeof(ctx->connector->eld), len)); + mutex_unlock(&ctx->connector->eld_mutex); }
return 0; diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index cf891e7677c0..faee8e2e82a0 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -296,7 +296,7 @@ #define MAX_LANE_COUNT 4 #define MAX_LINK_RATE HBR #define AUTO_TRAIN_RETRY 3 -#define MAX_HDCP_DOWN_STREAM_COUNT 10 +#define MAX_HDCP_DOWN_STREAM_COUNT 127 #define MAX_CR_LEVEL 0x03 #define MAX_EQ_LEVEL 0x03 #define AUX_WAIT_TIMEOUT_MS 15 @@ -2023,7 +2023,7 @@ static bool it6505_hdcp_part2_ksvlist_check(struct it6505 *it6505) { struct device *dev = it6505->dev; u8 av[5][4], bv[5][4]; - int i, err; + int i, err, retry;
i = it6505_setup_sha1_input(it6505, it6505->sha1_input); if (i <= 0) { @@ -2032,22 +2032,28 @@ static bool it6505_hdcp_part2_ksvlist_check(struct it6505 *it6505) }
it6505_sha1_digest(it6505, it6505->sha1_input, i, (u8 *)av); + /*1B-05 V' must retry 3 times */ + for (retry = 0; retry < 3; retry++) { + err = it6505_get_dpcd(it6505, DP_AUX_HDCP_V_PRIME(0), (u8 *)bv, + sizeof(bv));
- err = it6505_get_dpcd(it6505, DP_AUX_HDCP_V_PRIME(0), (u8 *)bv, - sizeof(bv)); + if (err < 0) { + dev_err(dev, "Read V' value Fail %d", retry); + continue; + }
- if (err < 0) { - dev_err(dev, "Read V' value Fail"); - return false; - } + for (i = 0; i < 5; i++) { + if (bv[i][3] != av[i][0] || bv[i][2] != av[i][1] || + av[i][1] != av[i][2] || bv[i][0] != av[i][3]) + break;
- for (i = 0; i < 5; i++) - if (bv[i][3] != av[i][0] || bv[i][2] != av[i][1] || - bv[i][1] != av[i][2] || bv[i][0] != av[i][3]) - return false; + DRM_DEV_DEBUG_DRIVER(dev, "V' all match!! %d, %d", retry, i); + return true; + } + }
- DRM_DEV_DEBUG_DRIVER(dev, "V' all match!!"); - return true; + DRM_DEV_DEBUG_DRIVER(dev, "V' NOT match!! %d", retry); + return false; }
static void it6505_hdcp_wait_ksv_list(struct work_struct *work) @@ -2055,12 +2061,13 @@ static void it6505_hdcp_wait_ksv_list(struct work_struct *work) struct it6505 *it6505 = container_of(work, struct it6505, hdcp_wait_ksv_list); struct device *dev = it6505->dev; - unsigned int timeout = 5000; - u8 bstatus = 0; + u8 bstatus; bool ksv_list_check; + /* 1B-04 wait ksv list for 5s */ + unsigned long timeout = jiffies + + msecs_to_jiffies(5000) + 1;
- timeout /= 20; - while (timeout > 0) { + for (;;) { if (!it6505_get_sink_hpd_status(it6505)) return;
@@ -2069,27 +2076,23 @@ static void it6505_hdcp_wait_ksv_list(struct work_struct *work) if (bstatus & DP_BSTATUS_READY) break;
- msleep(20); - timeout--; - } + if (time_after(jiffies, timeout)) { + DRM_DEV_DEBUG_DRIVER(dev, "KSV list wait timeout"); + goto timeout; + }
- if (timeout == 0) { - DRM_DEV_DEBUG_DRIVER(dev, "timeout and ksv list wait failed"); - goto timeout; + msleep(20); }
ksv_list_check = it6505_hdcp_part2_ksvlist_check(it6505); DRM_DEV_DEBUG_DRIVER(dev, "ksv list ready, ksv list check %s", ksv_list_check ? "pass" : "fail"); - if (ksv_list_check) { - it6505_set_bits(it6505, REG_HDCP_TRIGGER, - HDCP_TRIGGER_KSV_DONE, HDCP_TRIGGER_KSV_DONE); + + if (ksv_list_check) return; - } + timeout: - it6505_set_bits(it6505, REG_HDCP_TRIGGER, - HDCP_TRIGGER_KSV_DONE | HDCP_TRIGGER_KSV_FAIL, - HDCP_TRIGGER_KSV_DONE | HDCP_TRIGGER_KSV_FAIL); + it6505_start_hdcp(it6505); }
static void it6505_hdcp_work(struct work_struct *work) @@ -2312,14 +2315,20 @@ static int it6505_process_hpd_irq(struct it6505 *it6505) DRM_DEV_DEBUG_DRIVER(dev, "dp_irq_vector = 0x%02x", dp_irq_vector);
if (dp_irq_vector & DP_CP_IRQ) { - it6505_set_bits(it6505, REG_HDCP_TRIGGER, HDCP_TRIGGER_CPIRQ, - HDCP_TRIGGER_CPIRQ); - bstatus = it6505_dpcd_read(it6505, DP_AUX_HDCP_BSTATUS); if (bstatus < 0) return bstatus;
DRM_DEV_DEBUG_DRIVER(dev, "Bstatus = 0x%02x", bstatus); + + /*Check BSTATUS when recive CP_IRQ */ + if (bstatus & DP_BSTATUS_R0_PRIME_READY && + it6505->hdcp_status == HDCP_AUTH_GOING) + it6505_set_bits(it6505, REG_HDCP_TRIGGER, HDCP_TRIGGER_CPIRQ, + HDCP_TRIGGER_CPIRQ); + else if (bstatus & (DP_BSTATUS_REAUTH_REQ | DP_BSTATUS_LINK_FAILURE) && + it6505->hdcp_status == HDCP_AUTH_DONE) + it6505_start_hdcp(it6505); }
ret = drm_dp_dpcd_read_link_status(&it6505->aux, link_status); @@ -2456,7 +2465,11 @@ static void it6505_irq_hdcp_ksv_check(struct it6505 *it6505) { struct device *dev = it6505->dev;
- DRM_DEV_DEBUG_DRIVER(dev, "HDCP event Interrupt"); + DRM_DEV_DEBUG_DRIVER(dev, "HDCP repeater R0 event Interrupt"); + /* 1B01 HDCP encription should start when R0 is ready*/ + it6505_set_bits(it6505, REG_HDCP_TRIGGER, + HDCP_TRIGGER_KSV_DONE, HDCP_TRIGGER_KSV_DONE); + schedule_work(&it6505->hdcp_wait_ksv_list); }
diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c index 35ae3f0e8f51..940083e5d2dd 100644 --- a/drivers/gpu/drm/bridge/ite-it66121.c +++ b/drivers/gpu/drm/bridge/ite-it66121.c @@ -1450,8 +1450,10 @@ static int it66121_audio_get_eld(struct device *dev, void *data, dev_dbg(dev, "No connector present, passing empty EDID data"); memset(buf, 0, len); } else { + mutex_lock(&ctx->connector->eld_mutex); memcpy(buf, ctx->connector->eld, min(sizeof(ctx->connector->eld), len)); + mutex_unlock(&ctx->connector->eld_mutex); } mutex_unlock(&ctx->lock);
diff --git a/drivers/gpu/drm/display/drm_dp_cec.c b/drivers/gpu/drm/display/drm_dp_cec.c index 007ceb281d00..56a4965e518c 100644 --- a/drivers/gpu/drm/display/drm_dp_cec.c +++ b/drivers/gpu/drm/display/drm_dp_cec.c @@ -311,16 +311,6 @@ void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address) if (!aux->transfer) return;
-#ifndef CONFIG_MEDIA_CEC_RC - /* - * CEC_CAP_RC is part of CEC_CAP_DEFAULTS, but it is stripped by - * cec_allocate_adapter() if CONFIG_MEDIA_CEC_RC is undefined. - * - * Do this here as well to ensure the tests against cec_caps are - * correct. - */ - cec_caps &= ~CEC_CAP_RC; -#endif cancel_delayed_work_sync(&aux->cec.unregister_work);
mutex_lock(&aux->cec.lock); @@ -337,7 +327,9 @@ void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address) num_las = CEC_MAX_LOG_ADDRS;
if (aux->cec.adap) { - if (aux->cec.adap->capabilities == cec_caps && + /* Check if the adapter properties have changed */ + if ((aux->cec.adap->capabilities & CEC_CAP_MONITOR_ALL) == + (cec_caps & CEC_CAP_MONITOR_ALL) && aux->cec.adap->available_log_addrs == num_las) { /* Unchanged, so just set the phys addr */ cec_s_phys_addr(aux->cec.adap, source_physical_address, false); diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c index 251f94313717..aca442c25209 100644 --- a/drivers/gpu/drm/drm_client_modeset.c +++ b/drivers/gpu/drm/drm_client_modeset.c @@ -743,6 +743,15 @@ static bool drm_client_firmware_config(struct drm_client_dev *client, if ((conn_configured & mask) != mask && conn_configured != conn_seq) goto retry;
+ for (i = 0; i < count; i++) { + struct drm_connector *connector = connectors[i]; + + if (connector->has_tile) + drm_client_get_tile_offsets(dev, connectors, connector_count, + modes, offsets, i, + connector->tile_h_loc, connector->tile_v_loc); + } + /* * If the BIOS didn't enable everything it could, fall back to have the * same user experiencing of lighting up as much as possible like the diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index ca7f43c8d6f1..0e6021235a93 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -277,6 +277,7 @@ static int __drm_connector_init(struct drm_device *dev, INIT_LIST_HEAD(&connector->probed_modes); INIT_LIST_HEAD(&connector->modes); mutex_init(&connector->mutex); + mutex_init(&connector->eld_mutex); mutex_init(&connector->edid_override_mutex); mutex_init(&connector->hdmi.infoframes.lock); connector->edid_blob_ptr = NULL; diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 855beafb76ff..13bc4c290b17 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -5605,7 +5605,9 @@ EXPORT_SYMBOL(drm_edid_get_monitor_name);
static void clear_eld(struct drm_connector *connector) { + mutex_lock(&connector->eld_mutex); memset(connector->eld, 0, sizeof(connector->eld)); + mutex_unlock(&connector->eld_mutex);
connector->latency_present[0] = false; connector->latency_present[1] = false; @@ -5657,6 +5659,8 @@ static void drm_edid_to_eld(struct drm_connector *connector, if (!drm_edid) return;
+ mutex_lock(&connector->eld_mutex); + mnl = get_monitor_name(drm_edid, &eld[DRM_ELD_MONITOR_NAME_STRING]); drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s] ELD monitor %s\n", connector->base.id, connector->name, @@ -5717,6 +5721,8 @@ static void drm_edid_to_eld(struct drm_connector *connector, drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s] ELD size %d, SAD count %d\n", connector->base.id, connector->name, drm_eld_size(eld), total_sad_count); + + mutex_unlock(&connector->eld_mutex); }
static int _drm_edid_to_sad(const struct drm_edid *drm_edid, diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index c9008113111b..fb3614a7ba44 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -1354,14 +1354,14 @@ int drm_fb_helper_set_par(struct fb_info *info) } EXPORT_SYMBOL(drm_fb_helper_set_par);
-static void pan_set(struct drm_fb_helper *fb_helper, int x, int y) +static void pan_set(struct drm_fb_helper *fb_helper, int dx, int dy) { struct drm_mode_set *mode_set;
mutex_lock(&fb_helper->client.modeset_mutex); drm_client_for_each_modeset(mode_set, &fb_helper->client) { - mode_set->x = x; - mode_set->y = y; + mode_set->x += dx; + mode_set->y += dy; } mutex_unlock(&fb_helper->client.modeset_mutex); } @@ -1370,16 +1370,18 @@ static int pan_display_atomic(struct fb_var_screeninfo *var, struct fb_info *info) { struct drm_fb_helper *fb_helper = info->par; - int ret; + int ret, dx, dy;
- pan_set(fb_helper, var->xoffset, var->yoffset); + dx = var->xoffset - info->var.xoffset; + dy = var->yoffset - info->var.yoffset; + pan_set(fb_helper, dx, dy);
ret = drm_client_modeset_commit_locked(&fb_helper->client); if (!ret) { info->var.xoffset = var->xoffset; info->var.yoffset = var->yoffset; } else - pan_set(fb_helper, info->var.xoffset, info->var.yoffset); + pan_set(fb_helper, -dx, -dy);
return ret; } diff --git a/drivers/gpu/drm/drm_panel_backlight_quirks.c b/drivers/gpu/drm/drm_panel_backlight_quirks.c new file mode 100644 index 000000000000..c477d98ade2b --- /dev/null +++ b/drivers/gpu/drm/drm_panel_backlight_quirks.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/array_size.h> +#include <linux/dmi.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <drm/drm_edid.h> +#include <drm/drm_utils.h> + +struct drm_panel_min_backlight_quirk { + struct { + enum dmi_field field; + const char * const value; + } dmi_match; + struct drm_edid_ident ident; + u8 min_brightness; +}; + +static const struct drm_panel_min_backlight_quirk drm_panel_min_backlight_quirks[] = { + /* 13 inch matte panel */ + { + .dmi_match.field = DMI_BOARD_VENDOR, + .dmi_match.value = "Framework", + .ident.panel_id = drm_edid_encode_panel_id('B', 'O', 'E', 0x0bca), + .ident.name = "NE135FBM-N41", + .min_brightness = 0, + }, + /* 13 inch glossy panel */ + { + .dmi_match.field = DMI_BOARD_VENDOR, + .dmi_match.value = "Framework", + .ident.panel_id = drm_edid_encode_panel_id('B', 'O', 'E', 0x095f), + .ident.name = "NE135FBM-N41", + .min_brightness = 0, + }, + /* 13 inch 2.8k panel */ + { + .dmi_match.field = DMI_BOARD_VENDOR, + .dmi_match.value = "Framework", + .ident.panel_id = drm_edid_encode_panel_id('B', 'O', 'E', 0x0cb4), + .ident.name = "NE135A1M-NY1", + .min_brightness = 0, + }, +}; + +static bool drm_panel_min_backlight_quirk_matches(const struct drm_panel_min_backlight_quirk *quirk, + const struct drm_edid *edid) +{ + if (!dmi_match(quirk->dmi_match.field, quirk->dmi_match.value)) + return false; + + if (!drm_edid_match(edid, &quirk->ident)) + return false; + + return true; +} + +/** + * drm_get_panel_min_brightness_quirk - Get minimum supported brightness level for a panel. + * @edid: EDID of the panel to check + * + * This function checks for platform specific (e.g. DMI based) quirks + * providing info on the minimum backlight brightness for systems where this + * cannot be probed correctly from the hard-/firm-ware. + * + * Returns: + * A negative error value or + * an override value in the range [0, 255] representing 0-100% to be scaled to + * the drivers target range. + */ +int drm_get_panel_min_brightness_quirk(const struct drm_edid *edid) +{ + const struct drm_panel_min_backlight_quirk *quirk; + size_t i; + + if (!IS_ENABLED(CONFIG_DMI)) + return -ENODATA; + + if (!edid) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(drm_panel_min_backlight_quirks); i++) { + quirk = &drm_panel_min_backlight_quirks[i]; + + if (drm_panel_min_backlight_quirk_matches(quirk, edid)) + return quirk->min_brightness; + } + + return -ENODATA; +} +EXPORT_SYMBOL(drm_get_panel_min_brightness_quirk); + +MODULE_DESCRIPTION("Quirks for panel backlight overrides"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 466a9e514aa1..7a57d4a23e41 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -1648,7 +1648,9 @@ static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, struct hdmi_context *hdata = dev_get_drvdata(dev); struct drm_connector *connector = &hdata->connector;
+ mutex_lock(&connector->eld_mutex); memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); + mutex_unlock(&connector->eld_mutex);
return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index ff5ba7b3035f..4ae7459e1145 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2049,11 +2049,10 @@ icl_dsc_compute_link_config(struct intel_dp *intel_dp, /* Compressed BPP should be less than the Input DSC bpp */ dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1);
- for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp); i++) { - if (valid_dsc_bpp[i] < dsc_min_bpp) + for (i = ARRAY_SIZE(valid_dsc_bpp) - 1; i >= 0; i--) { + if (valid_dsc_bpp[i] < dsc_min_bpp || + valid_dsc_bpp[i] > dsc_max_bpp) continue; - if (valid_dsc_bpp[i] > dsc_max_bpp) - break;
ret = dsc_compute_link_config(intel_dp, pipe_config, @@ -2778,7 +2777,6 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp,
crtc_state->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC);
- /* Currently only DP_AS_SDP_AVT_FIXED_VTOTAL mode supported */ as_sdp->sdp_type = DP_SDP_ADAPTIVE_SYNC; as_sdp->length = 0x9; as_sdp->duration_incr_ms = 0; @@ -2789,7 +2787,7 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp, as_sdp->target_rr = drm_mode_vrefresh(adjusted_mode); as_sdp->target_rr_divider = true; } else { - as_sdp->mode = DP_AS_SDP_AVT_FIXED_VTOTAL; + as_sdp->mode = DP_AS_SDP_AVT_DYNAMIC_VTOTAL; as_sdp->vtotal = adjusted_mode->vtotal; as_sdp->target_rr = 0; } diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 8fee26d791f4..3bf42871a4f0 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -2180,6 +2180,19 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
drm_dbg_kms(display->drm, "HDCP2.2 Downstream topology change\n"); + + ret = hdcp2_authenticate_repeater_topology(connector); + if (!ret) { + intel_hdcp_update_value(connector, + DRM_MODE_CONTENT_PROTECTION_ENABLED, + true); + goto out; + } + + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] Repeater topology auth failed.(%d)\n", + connector->base.base.id, connector->base.name, + ret); } else { drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP2.2 link failed, retrying auth\n", diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 038ca2ec5d7a..decf0ebeec0b 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -106,8 +106,6 @@ static const u32 icl_sdr_y_plane_formats[] = { DRM_FORMAT_Y216, DRM_FORMAT_XYUV8888, DRM_FORMAT_XVYU2101010, - DRM_FORMAT_XVYU12_16161616, - DRM_FORMAT_XVYU16161616, };
static const u32 icl_sdr_uv_plane_formats[] = { @@ -134,8 +132,6 @@ static const u32 icl_sdr_uv_plane_formats[] = { DRM_FORMAT_Y216, DRM_FORMAT_XYUV8888, DRM_FORMAT_XVYU2101010, - DRM_FORMAT_XVYU12_16161616, - DRM_FORMAT_XVYU16161616, };
static const u32 icl_hdr_plane_formats[] = { diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c index fe69f2c8527d..ae3343c81a64 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c @@ -209,8 +209,6 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj) struct address_space *mapping = obj->base.filp->f_mapping; unsigned int max_segment = i915_sg_segment_size(i915->drm.dev); struct sg_table *st; - struct sgt_iter sgt_iter; - struct page *page; int ret;
/* @@ -239,9 +237,7 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj) * for PAGE_SIZE chunks instead may be helpful. */ if (max_segment > PAGE_SIZE) { - for_each_sgt_page(page, sgt_iter, st) - put_page(page); - sg_free_table(st); + shmem_sg_free_table(st, mapping, false, false); kfree(st);
max_segment = PAGE_SIZE; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index c0bd730383f2..4b12a6c7c247 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -5511,12 +5511,20 @@ static inline void guc_log_context(struct drm_printer *p, { drm_printf(p, "GuC lrc descriptor %u:\n", ce->guc_id.id); drm_printf(p, "\tHW Context Desc: 0x%08x\n", ce->lrc.lrca); - drm_printf(p, "\t\tLRC Head: Internal %u, Memory %u\n", - ce->ring->head, - ce->lrc_reg_state[CTX_RING_HEAD]); - drm_printf(p, "\t\tLRC Tail: Internal %u, Memory %u\n", - ce->ring->tail, - ce->lrc_reg_state[CTX_RING_TAIL]); + if (intel_context_pin_if_active(ce)) { + drm_printf(p, "\t\tLRC Head: Internal %u, Memory %u\n", + ce->ring->head, + ce->lrc_reg_state[CTX_RING_HEAD]); + drm_printf(p, "\t\tLRC Tail: Internal %u, Memory %u\n", + ce->ring->tail, + ce->lrc_reg_state[CTX_RING_TAIL]); + intel_context_unpin(ce); + } else { + drm_printf(p, "\t\tLRC Head: Internal %u, Memory not pinned\n", + ce->ring->head); + drm_printf(p, "\t\tLRC Tail: Internal %u, Memory not pinned\n", + ce->ring->tail); + } drm_printf(p, "\t\tContext Pin Count: %u\n", atomic_read(&ce->pin_count)); drm_printf(p, "\t\tGuC ID Ref Count: %u\n", diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 9f6ffd344693..ad3462476a14 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -732,6 +732,13 @@ static int _dpu_crtc_check_and_setup_lm_bounds(struct drm_crtc *crtc, struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc); int i;
+ /* if we cannot merge 2 LMs (no 3d mux) better to fail earlier + * before even checking the width after the split + */ + if (!dpu_kms->catalog->caps->has_3d_merge && + adj_mode->hdisplay > dpu_kms->catalog->caps->max_mixer_width) + return -E2BIG; + for (i = 0; i < cstate->num_mixers; i++) { struct drm_rect *r = &cstate->lm_bounds[i]; r->x1 = crtc_split_width * i; @@ -1251,6 +1258,12 @@ static enum drm_mode_status dpu_crtc_mode_valid(struct drm_crtc *crtc, { struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
+ /* if there is no 3d_mux block we cannot merge LMs so we cannot + * split the large layer into 2 LMs, filter out such modes + */ + if (!dpu_kms->catalog->caps->has_3d_merge && + mode->hdisplay > dpu_kms->catalog->caps->max_mixer_width) + return MODE_BAD_HVALUE; /* * max crtc width is equal to the max mixer width * 2 and max height is 4K */ diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c b/drivers/gpu/drm/msm/dp/dp_audio.c index 5cbb11986460..c179ed0e9e2b 100644 --- a/drivers/gpu/drm/msm/dp/dp_audio.c +++ b/drivers/gpu/drm/msm/dp/dp_audio.c @@ -414,8 +414,10 @@ static int msm_dp_audio_get_eld(struct device *dev, return -ENODEV; }
+ mutex_lock(&msm_dp_display->connector->eld_mutex); memcpy(buf, msm_dp_display->connector->eld, min(sizeof(msm_dp_display->connector->eld), len)); + mutex_unlock(&msm_dp_display->connector->eld_mutex);
return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c index d586aea30898..9c83bab0a530 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c @@ -121,6 +121,8 @@ r535_gsp_msgq_wait(struct nvkm_gsp *gsp, u32 repc, u32 *prepc, int *ptime) return mqe->data; }
+ size = ALIGN(repc + GSP_MSG_HDR_SIZE, GSP_PAGE_SIZE); + msg = kvmalloc(repc, GFP_KERNEL); if (!msg) return ERR_PTR(-ENOMEM); @@ -129,19 +131,15 @@ r535_gsp_msgq_wait(struct nvkm_gsp *gsp, u32 repc, u32 *prepc, int *ptime) len = min_t(u32, repc, len); memcpy(msg, mqe->data, len);
- rptr += DIV_ROUND_UP(len, GSP_PAGE_SIZE); - if (rptr == gsp->msgq.cnt) - rptr = 0; - repc -= len;
if (repc) { mqe = (void *)((u8 *)gsp->shm.msgq.ptr + 0x1000 + 0 * 0x1000); memcpy(msg + len, mqe, repc); - - rptr += DIV_ROUND_UP(repc, GSP_PAGE_SIZE); }
+ rptr = (rptr + DIV_ROUND_UP(size, GSP_PAGE_SIZE)) % gsp->msgq.cnt; + mb(); (*gsp->msgq.rptr) = rptr; return msg; @@ -163,7 +161,7 @@ r535_gsp_cmdq_push(struct nvkm_gsp *gsp, void *argv) u64 *end; u64 csum = 0; int free, time = 1000000; - u32 wptr, size; + u32 wptr, size, step; u32 off = 0;
argc = ALIGN(GSP_MSG_HDR_SIZE + argc, GSP_PAGE_SIZE); @@ -197,7 +195,9 @@ r535_gsp_cmdq_push(struct nvkm_gsp *gsp, void *argv) }
cqe = (void *)((u8 *)gsp->shm.cmdq.ptr + 0x1000 + wptr * 0x1000); - size = min_t(u32, argc, (gsp->cmdq.cnt - wptr) * GSP_PAGE_SIZE); + step = min_t(u32, free, (gsp->cmdq.cnt - wptr)); + size = min_t(u32, argc, step * GSP_PAGE_SIZE); + memcpy(cqe, (u8 *)cmd + off, size);
wptr += DIV_ROUND_UP(size, 0x1000); diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index 5b69cc8011b4..8d64ba18572e 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -775,8 +775,10 @@ static int radeon_audio_component_get_eld(struct device *kdev, int port, if (!dig->pin || dig->pin->id != port) continue; *enabled = true; + mutex_lock(&connector->eld_mutex); ret = drm_eld_size(connector->eld); memcpy(buf, connector->eld, min(max_bytes, ret)); + mutex_unlock(&connector->eld_mutex); break; }
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c index ff9d95e2c4d4..a7891a139c88 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c @@ -947,9 +947,6 @@ static void cdn_dp_pd_event_work(struct work_struct *work) { struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device, event_work); - struct drm_connector *connector = &dp->connector; - enum drm_connector_status old_status; - int ret;
mutex_lock(&dp->lock); @@ -1009,11 +1006,7 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
out: mutex_unlock(&dp->lock); - - old_status = connector->status; - connector->status = connector->funcs->detect(connector, false); - if (old_status != connector->status) - drm_kms_helper_hotplug_event(dp->drm_dev); + drm_connector_helper_hpd_irq_event(&dp->connector); }
static int cdn_dp_pd_event(struct notifier_block *nb, diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c index 21b46a6465f0..f8bbae6393ef 100644 --- a/drivers/gpu/drm/sti/sti_hdmi.c +++ b/drivers/gpu/drm/sti/sti_hdmi.c @@ -1225,7 +1225,9 @@ static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, size struct drm_connector *connector = hdmi->drm_connector;
DRM_DEBUG_DRIVER("\n"); + mutex_lock(&connector->eld_mutex); memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); + mutex_unlock(&connector->eld_mutex);
return 0; } diff --git a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c index 294773342e71..4ba869e0e794 100644 --- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c @@ -46,7 +46,7 @@ static struct drm_display_mode *find_preferred_mode(struct drm_connector *connec struct drm_display_mode *mode, *preferred;
mutex_lock(&drm->mode_config.mutex); - preferred = list_first_entry(&connector->modes, struct drm_display_mode, head); + preferred = list_first_entry_or_null(&connector->modes, struct drm_display_mode, head); list_for_each_entry(mode, &connector->modes, head) if (mode->type & DRM_MODE_TYPE_PREFERRED) preferred = mode; @@ -105,9 +105,8 @@ static int set_connector_edid(struct kunit *test, struct drm_connector *connecto mutex_lock(&drm->mode_config.mutex); ret = connector->funcs->fill_modes(connector, 4096, 4096); mutex_unlock(&drm->mode_config.mutex); - KUNIT_ASSERT_GT(test, ret, 0);
- return 0; + return ret; }
static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = { @@ -223,7 +222,7 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test, ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_max_200mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0);
return priv; } @@ -728,7 +727,7 @@ static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test) ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0);
ctx = drm_kunit_helper_acquire_ctx_alloc(test); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); @@ -802,7 +801,7 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test) ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0);
ctx = drm_kunit_helper_acquire_ctx_alloc(test); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); @@ -873,7 +872,7 @@ static void drm_test_check_output_bpc_dvi(struct kunit *test) ret = set_connector_edid(test, conn, test_edid_dvi_1080p, ARRAY_SIZE(test_edid_dvi_1080p)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0);
info = &conn->display_info; KUNIT_ASSERT_FALSE(test, info->is_hdmi); @@ -920,7 +919,7 @@ static void drm_test_check_tmds_char_rate_rgb_8bpc(struct kunit *test) ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_max_200mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0);
ctx = drm_kunit_helper_acquire_ctx_alloc(test); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); @@ -967,7 +966,7 @@ static void drm_test_check_tmds_char_rate_rgb_10bpc(struct kunit *test) ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0);
ctx = drm_kunit_helper_acquire_ctx_alloc(test); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); @@ -1014,7 +1013,7 @@ static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test) ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0);
ctx = drm_kunit_helper_acquire_ctx_alloc(test); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); @@ -1121,7 +1120,7 @@ static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test) ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0);
info = &conn->display_info; KUNIT_ASSERT_TRUE(test, info->is_hdmi); @@ -1190,7 +1189,7 @@ static void drm_test_check_max_tmds_rate_format_fallback(struct kunit *test) ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0);
info = &conn->display_info; KUNIT_ASSERT_TRUE(test, info->is_hdmi); @@ -1254,7 +1253,7 @@ static void drm_test_check_output_bpc_format_vic_1(struct kunit *test) ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0);
info = &conn->display_info; KUNIT_ASSERT_TRUE(test, info->is_hdmi); @@ -1314,7 +1313,7 @@ static void drm_test_check_output_bpc_format_driver_rgb_only(struct kunit *test) ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0);
info = &conn->display_info; KUNIT_ASSERT_TRUE(test, info->is_hdmi); @@ -1381,7 +1380,7 @@ static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_max_200mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0);
info = &conn->display_info; KUNIT_ASSERT_TRUE(test, info->is_hdmi); @@ -1447,7 +1446,7 @@ static void drm_test_check_output_bpc_format_driver_8bpc_only(struct kunit *test ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0);
info = &conn->display_info; KUNIT_ASSERT_TRUE(test, info->is_hdmi); @@ -1507,7 +1506,7 @@ static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *tes ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_max_340mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_340mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0);
info = &conn->display_info; KUNIT_ASSERT_TRUE(test, info->is_hdmi); diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index e3818c48c9b8..e86123009c90 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -2193,9 +2193,9 @@ static int vc4_hdmi_audio_get_eld(struct device *dev, void *data, struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); struct drm_connector *connector = &vc4_hdmi->connector;
- mutex_lock(&vc4_hdmi->mutex); + mutex_lock(&connector->eld_mutex); memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); - mutex_unlock(&vc4_hdmi->mutex); + mutex_unlock(&connector->eld_mutex);
return 0; } diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 64c236169db8..5dc8eeaf7123 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -194,6 +194,13 @@ struct virtio_gpu_framebuffer { #define to_virtio_gpu_framebuffer(x) \ container_of(x, struct virtio_gpu_framebuffer, base)
+struct virtio_gpu_plane_state { + struct drm_plane_state base; + struct virtio_gpu_fence *fence; +}; +#define to_virtio_gpu_plane_state(x) \ + container_of(x, struct virtio_gpu_plane_state, base) + struct virtio_gpu_queue { struct virtqueue *vq; spinlock_t qlock; diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index a72a2dbda031..7acd38b962c6 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -66,11 +66,28 @@ uint32_t virtio_gpu_translate_format(uint32_t drm_fourcc) return format; }
+static struct +drm_plane_state *virtio_gpu_plane_duplicate_state(struct drm_plane *plane) +{ + struct virtio_gpu_plane_state *new; + + if (WARN_ON(!plane->state)) + return NULL; + + new = kzalloc(sizeof(*new), GFP_KERNEL); + if (!new) + return NULL; + + __drm_atomic_helper_plane_duplicate_state(plane, &new->base); + + return &new->base; +} + static const struct drm_plane_funcs virtio_gpu_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, .reset = drm_atomic_helper_plane_reset, - .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, + .atomic_duplicate_state = virtio_gpu_plane_duplicate_state, .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, };
@@ -138,11 +155,13 @@ static void virtio_gpu_resource_flush(struct drm_plane *plane, struct drm_device *dev = plane->dev; struct virtio_gpu_device *vgdev = dev->dev_private; struct virtio_gpu_framebuffer *vgfb; + struct virtio_gpu_plane_state *vgplane_st; struct virtio_gpu_object *bo;
vgfb = to_virtio_gpu_framebuffer(plane->state->fb); + vgplane_st = to_virtio_gpu_plane_state(plane->state); bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]); - if (vgfb->fence) { + if (vgplane_st->fence) { struct virtio_gpu_object_array *objs;
objs = virtio_gpu_array_alloc(1); @@ -151,13 +170,11 @@ static void virtio_gpu_resource_flush(struct drm_plane *plane, virtio_gpu_array_add_obj(objs, vgfb->base.obj[0]); virtio_gpu_array_lock_resv(objs); virtio_gpu_cmd_resource_flush(vgdev, bo->hw_res_handle, x, y, - width, height, objs, vgfb->fence); + width, height, objs, + vgplane_st->fence); virtio_gpu_notify(vgdev); - - dma_fence_wait_timeout(&vgfb->fence->f, true, + dma_fence_wait_timeout(&vgplane_st->fence->f, true, msecs_to_jiffies(50)); - dma_fence_put(&vgfb->fence->f); - vgfb->fence = NULL; } else { virtio_gpu_cmd_resource_flush(vgdev, bo->hw_res_handle, x, y, width, height, NULL, NULL); @@ -247,20 +264,23 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane, struct drm_device *dev = plane->dev; struct virtio_gpu_device *vgdev = dev->dev_private; struct virtio_gpu_framebuffer *vgfb; + struct virtio_gpu_plane_state *vgplane_st; struct virtio_gpu_object *bo;
if (!new_state->fb) return 0;
vgfb = to_virtio_gpu_framebuffer(new_state->fb); + vgplane_st = to_virtio_gpu_plane_state(new_state); bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]); if (!bo || (plane->type == DRM_PLANE_TYPE_PRIMARY && !bo->guest_blob)) return 0;
- if (bo->dumb && (plane->state->fb != new_state->fb)) { - vgfb->fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, + if (bo->dumb) { + vgplane_st->fence = virtio_gpu_fence_alloc(vgdev, + vgdev->fence_drv.context, 0); - if (!vgfb->fence) + if (!vgplane_st->fence) return -ENOMEM; }
@@ -270,15 +290,15 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane, static void virtio_gpu_plane_cleanup_fb(struct drm_plane *plane, struct drm_plane_state *state) { - struct virtio_gpu_framebuffer *vgfb; + struct virtio_gpu_plane_state *vgplane_st;
if (!state->fb) return;
- vgfb = to_virtio_gpu_framebuffer(state->fb); - if (vgfb->fence) { - dma_fence_put(&vgfb->fence->f); - vgfb->fence = NULL; + vgplane_st = to_virtio_gpu_plane_state(state); + if (vgplane_st->fence) { + dma_fence_put(&vgplane_st->fence->f); + vgplane_st->fence = NULL; } }
@@ -291,6 +311,7 @@ static void virtio_gpu_cursor_plane_update(struct drm_plane *plane, struct virtio_gpu_device *vgdev = dev->dev_private; struct virtio_gpu_output *output = NULL; struct virtio_gpu_framebuffer *vgfb; + struct virtio_gpu_plane_state *vgplane_st; struct virtio_gpu_object *bo = NULL; uint32_t handle;
@@ -303,6 +324,7 @@ static void virtio_gpu_cursor_plane_update(struct drm_plane *plane,
if (plane->state->fb) { vgfb = to_virtio_gpu_framebuffer(plane->state->fb); + vgplane_st = to_virtio_gpu_plane_state(plane->state); bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]); handle = bo->hw_res_handle; } else { @@ -322,11 +344,9 @@ static void virtio_gpu_cursor_plane_update(struct drm_plane *plane, (vgdev, 0, plane->state->crtc_w, plane->state->crtc_h, - 0, 0, objs, vgfb->fence); + 0, 0, objs, vgplane_st->fence); virtio_gpu_notify(vgdev); - dma_fence_wait(&vgfb->fence->f, true); - dma_fence_put(&vgfb->fence->f); - vgfb->fence = NULL; + dma_fence_wait(&vgplane_st->fence->f, true); }
if (plane->state->fb != old_state->fb) { diff --git a/drivers/gpu/drm/xe/regs/xe_oa_regs.h b/drivers/gpu/drm/xe/regs/xe_oa_regs.h index a9b0091cb7ee..6d31573ed176 100644 --- a/drivers/gpu/drm/xe/regs/xe_oa_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_oa_regs.h @@ -59,6 +59,10 @@ /* Common to all OA units */ #define OA_OACONTROL_REPORT_BC_MASK REG_GENMASK(9, 9) #define OA_OACONTROL_COUNTER_SIZE_MASK REG_GENMASK(8, 8) +#define OAG_OACONTROL_USED_BITS \ + (OAG_OACONTROL_OA_PES_DISAG_EN | OAG_OACONTROL_OA_CCS_SELECT_MASK | \ + OAG_OACONTROL_OA_COUNTER_SEL_MASK | OAG_OACONTROL_OA_COUNTER_ENABLE | \ + OA_OACONTROL_REPORT_BC_MASK | OA_OACONTROL_COUNTER_SIZE_MASK)
#define OAG_OA_DEBUG XE_REG(0xdaf8, XE_REG_OPTION_MASKED) #define OAG_OA_DEBUG_DISABLE_MMIO_TRG REG_BIT(14) @@ -85,6 +89,8 @@ #define OAM_CONTEXT_CONTROL_OFFSET (0x1bc) #define OAM_CONTROL_OFFSET (0x194) #define OAM_CONTROL_COUNTER_SEL_MASK REG_GENMASK(3, 1) +#define OAM_OACONTROL_USED_BITS \ + (OAM_CONTROL_COUNTER_SEL_MASK | OAG_OACONTROL_OA_COUNTER_ENABLE) #define OAM_DEBUG_OFFSET (0x198) #define OAM_STATUS_OFFSET (0x19c) #define OAM_MMIO_TRG_OFFSET (0x1d0) diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c b/drivers/gpu/drm/xe/xe_devcoredump.c index 21a50d539426..2577291b396a 100644 --- a/drivers/gpu/drm/xe/xe_devcoredump.c +++ b/drivers/gpu/drm/xe/xe_devcoredump.c @@ -109,11 +109,7 @@ static ssize_t __xe_devcoredump_read(char *buffer, size_t count, drm_puts(&p, "\n**** GuC CT ****\n"); xe_guc_ct_snapshot_print(ss->guc.ct, &p);
- /* - * Don't add a new section header here because the mesa debug decoder - * tool expects the context information to be in the 'GuC CT' section. - */ - /* drm_puts(&p, "\n**** Contexts ****\n"); */ + drm_puts(&p, "\n**** Contexts ****\n"); xe_guc_exec_queue_snapshot_print(ss->ge, &p);
drm_puts(&p, "\n**** Job ****\n"); @@ -342,42 +338,34 @@ int xe_devcoredump_init(struct xe_device *xe) /** * xe_print_blob_ascii85 - print a BLOB to some useful location in ASCII85 * - * The output is split to multiple lines because some print targets, e.g. dmesg - * cannot handle arbitrarily long lines. Note also that printing to dmesg in - * piece-meal fashion is not possible, each separate call to drm_puts() has a - * line-feed automatically added! Therefore, the entire output line must be - * constructed in a local buffer first, then printed in one atomic output call. + * The output is split into multiple calls to drm_puts() because some print + * targets, e.g. dmesg, cannot handle arbitrarily long lines. These targets may + * add newlines, as is the case with dmesg: each drm_puts() call creates a + * separate line. * * There is also a scheduler yield call to prevent the 'task has been stuck for * 120s' kernel hang check feature from firing when printing to a slow target * such as dmesg over a serial port. * - * TODO: Add compression prior to the ASCII85 encoding to shrink huge buffers down. - * * @p: the printer object to output to * @prefix: optional prefix to add to output string + * @suffix: optional suffix to add at the end. 0 disables it and is + * not added to the output, which is useful when using multiple calls + * to dump data to @p * @blob: the Binary Large OBject to dump out * @offset: offset in bytes to skip from the front of the BLOB, must be a multiple of sizeof(u32) * @size: the size in bytes of the BLOB, must be a multiple of sizeof(u32) */ -void xe_print_blob_ascii85(struct drm_printer *p, const char *prefix, +void xe_print_blob_ascii85(struct drm_printer *p, const char *prefix, char suffix, const void *blob, size_t offset, size_t size) { const u32 *blob32 = (const u32 *)blob; char buff[ASCII85_BUFSZ], *line_buff; size_t line_pos = 0;
- /* - * Splitting blobs across multiple lines is not compatible with the mesa - * debug decoder tool. Note that even dropping the explicit '\n' below - * doesn't help because the GuC log is so big some underlying implementation - * still splits the lines at 512K characters. So just bail completely for - * the moment. - */ - return; - #define DMESG_MAX_LINE_LEN 800 -#define MIN_SPACE (ASCII85_BUFSZ + 2) /* 85 + "\n\0" */ + /* Always leave space for the suffix char and the \0 */ +#define MIN_SPACE (ASCII85_BUFSZ + 2) /* 85 + "<suffix>\0" */
if (size & 3) drm_printf(p, "Size not word aligned: %zu", size); @@ -409,7 +397,6 @@ void xe_print_blob_ascii85(struct drm_printer *p, const char *prefix, line_pos += strlen(line_buff + line_pos);
if ((line_pos + MIN_SPACE) >= DMESG_MAX_LINE_LEN) { - line_buff[line_pos++] = '\n'; line_buff[line_pos++] = 0;
drm_puts(p, line_buff); @@ -421,10 +408,11 @@ void xe_print_blob_ascii85(struct drm_printer *p, const char *prefix, } }
+ if (suffix) + line_buff[line_pos++] = suffix; + if (line_pos) { - line_buff[line_pos++] = '\n'; line_buff[line_pos++] = 0; - drm_puts(p, line_buff); }
diff --git a/drivers/gpu/drm/xe/xe_devcoredump.h b/drivers/gpu/drm/xe/xe_devcoredump.h index a4eebc285fc8..b231c8ad799f 100644 --- a/drivers/gpu/drm/xe/xe_devcoredump.h +++ b/drivers/gpu/drm/xe/xe_devcoredump.h @@ -26,7 +26,7 @@ static inline int xe_devcoredump_init(struct xe_device *xe) } #endif
-void xe_print_blob_ascii85(struct drm_printer *p, const char *prefix, +void xe_print_blob_ascii85(struct drm_printer *p, const char *prefix, char suffix, const void *blob, size_t offset, size_t size);
#endif diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c index 94d468d01253..77d818beb26d 100644 --- a/drivers/gpu/drm/xe/xe_gt.c +++ b/drivers/gpu/drm/xe/xe_gt.c @@ -532,8 +532,10 @@ static int all_fw_domain_init(struct xe_gt *gt) if (IS_SRIOV_PF(gt_to_xe(gt)) && !xe_gt_is_media_type(gt)) xe_lmtt_init_hw(>_to_tile(gt)->sriov.pf.lmtt);
- if (IS_SRIOV_PF(gt_to_xe(gt))) + if (IS_SRIOV_PF(gt_to_xe(gt))) { + xe_gt_sriov_pf_init(gt); xe_gt_sriov_pf_init_hw(gt); + }
xe_force_wake_put(gt_to_fw(gt), fw_ref);
diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf.c index e71fc3d2bda2..6f906c8e8108 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf.c @@ -68,6 +68,19 @@ int xe_gt_sriov_pf_init_early(struct xe_gt *gt) return 0; }
+/** + * xe_gt_sriov_pf_init - Prepare SR-IOV PF data structures on PF. + * @gt: the &xe_gt to initialize + * + * Late one-time initialization of the PF data. + * + * Return: 0 on success or a negative error code on failure. + */ +int xe_gt_sriov_pf_init(struct xe_gt *gt) +{ + return xe_gt_sriov_pf_migration_init(gt); +} + static bool pf_needs_enable_ggtt_guest_update(struct xe_device *xe) { return GRAPHICS_VERx100(xe) == 1200; @@ -90,7 +103,6 @@ void xe_gt_sriov_pf_init_hw(struct xe_gt *gt) pf_enable_ggtt_guest_update(gt);
xe_gt_sriov_pf_service_update(gt); - xe_gt_sriov_pf_migration_init(gt); }
static u32 pf_get_vf_regs_stride(struct xe_device *xe) diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf.h index 96fab779a906..f474509411c0 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf.h +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf.h @@ -10,6 +10,7 @@ struct xe_gt;
#ifdef CONFIG_PCI_IOV int xe_gt_sriov_pf_init_early(struct xe_gt *gt); +int xe_gt_sriov_pf_init(struct xe_gt *gt); void xe_gt_sriov_pf_init_hw(struct xe_gt *gt); void xe_gt_sriov_pf_sanitize_hw(struct xe_gt *gt, unsigned int vfid); void xe_gt_sriov_pf_restart(struct xe_gt *gt); @@ -19,6 +20,11 @@ static inline int xe_gt_sriov_pf_init_early(struct xe_gt *gt) return 0; }
+static inline int xe_gt_sriov_pf_init(struct xe_gt *gt) +{ + return 0; +} + static inline void xe_gt_sriov_pf_init_hw(struct xe_gt *gt) { } diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c index 8aeb1789805c..6eabf7a9d3b0 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.c +++ b/drivers/gpu/drm/xe/xe_guc_ct.c @@ -1700,7 +1700,8 @@ void xe_guc_ct_snapshot_print(struct xe_guc_ct_snapshot *snapshot, snapshot->g2h_outstanding);
if (snapshot->ctb) - xe_print_blob_ascii85(p, "CTB data", snapshot->ctb, 0, snapshot->ctb_size); + xe_print_blob_ascii85(p, "CTB data", '\n', + snapshot->ctb, 0, snapshot->ctb_size); } else { drm_puts(p, "CT disabled\n"); } diff --git a/drivers/gpu/drm/xe/xe_guc_log.c b/drivers/gpu/drm/xe/xe_guc_log.c index df4cfb698cdb..2baa4d95571f 100644 --- a/drivers/gpu/drm/xe/xe_guc_log.c +++ b/drivers/gpu/drm/xe/xe_guc_log.c @@ -211,8 +211,10 @@ void xe_guc_log_snapshot_print(struct xe_guc_log_snapshot *snapshot, struct drm_ remain = snapshot->size; for (i = 0; i < snapshot->num_chunks; i++) { size_t size = min(GUC_LOG_CHUNK_SIZE, remain); + const char *prefix = i ? NULL : "Log data"; + char suffix = i == snapshot->num_chunks - 1 ? '\n' : 0;
- xe_print_blob_ascii85(p, i ? NULL : "Log data", snapshot->copy[i], 0, size); + xe_print_blob_ascii85(p, prefix, suffix, snapshot->copy[i], 0, size); remain -= size; } } diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index 678fa40e4cea..d8af82dcdce4 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -445,6 +445,12 @@ static u32 __oa_ccs_select(struct xe_oa_stream *stream) return val; }
+static u32 __oactrl_used_bits(struct xe_oa_stream *stream) +{ + return stream->hwe->oa_unit->type == DRM_XE_OA_UNIT_TYPE_OAG ? + OAG_OACONTROL_USED_BITS : OAM_OACONTROL_USED_BITS; +} + static void xe_oa_enable(struct xe_oa_stream *stream) { const struct xe_oa_format *format = stream->oa_buffer.format; @@ -465,14 +471,14 @@ static void xe_oa_enable(struct xe_oa_stream *stream) stream->hwe->oa_unit->type == DRM_XE_OA_UNIT_TYPE_OAG) val |= OAG_OACONTROL_OA_PES_DISAG_EN;
- xe_mmio_write32(&stream->gt->mmio, regs->oa_ctrl, val); + xe_mmio_rmw32(&stream->gt->mmio, regs->oa_ctrl, __oactrl_used_bits(stream), val); }
static void xe_oa_disable(struct xe_oa_stream *stream) { struct xe_mmio *mmio = &stream->gt->mmio;
- xe_mmio_write32(mmio, __oa_regs(stream)->oa_ctrl, 0); + xe_mmio_rmw32(mmio, __oa_regs(stream)->oa_ctrl, __oactrl_used_bits(stream), 0); if (xe_mmio_wait32(mmio, __oa_regs(stream)->oa_ctrl, OAG_OACONTROL_OA_COUNTER_ENABLE, 0, 50000, NULL, false)) drm_err(&stream->oa->xe->drm, @@ -2569,6 +2575,8 @@ static void __xe_oa_init_oa_units(struct xe_gt *gt) u->type = DRM_XE_OA_UNIT_TYPE_OAM; }
+ xe_mmio_write32(>->mmio, u->regs.oa_ctrl, 0); + /* Ensure MMIO trigger remains disabled till there is a stream */ xe_mmio_write32(>->mmio, u->regs.oa_debug, oag_configure_mmio_trigger(NULL, false)); diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 506c6f377e7d..46e3e42f9eb5 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -432,6 +432,26 @@ static int asus_kbd_get_functions(struct hid_device *hdev, return ret; }
+static int asus_kbd_disable_oobe(struct hid_device *hdev) +{ + const u8 init[][6] = { + { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 }, + { FEATURE_KBD_REPORT_ID, 0xBA, 0xC5, 0xC4 }, + { FEATURE_KBD_REPORT_ID, 0xD0, 0x8F, 0x01 }, + { FEATURE_KBD_REPORT_ID, 0xD0, 0x85, 0xFF } + }; + int ret; + + for (size_t i = 0; i < ARRAY_SIZE(init); i++) { + ret = asus_kbd_set_report(hdev, init[i], sizeof(init[i])); + if (ret < 0) + return ret; + } + + hid_info(hdev, "Disabled OOBE for keyboard\n"); + return 0; +} + static void asus_schedule_work(struct asus_kbd_leds *led) { unsigned long flags; @@ -534,6 +554,12 @@ static int asus_kbd_register_leds(struct hid_device *hdev) ret = asus_kbd_init(hdev, FEATURE_KBD_LED_REPORT_ID2); if (ret < 0) return ret; + + if (dmi_match(DMI_PRODUCT_FAMILY, "ProArt P16")) { + ret = asus_kbd_disable_oobe(hdev); + if (ret < 0) + return ret; + } } else { /* Initialize keyboard */ ret = asus_kbd_init(hdev, FEATURE_KBD_REPORT_ID); diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 42c0bd9d2f31..82900857bfd8 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -2314,6 +2314,11 @@ static const struct hid_device_id mt_devices[] = { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_SIS_TOUCH, HID_ANY_ID) },
+ /* Hantick */ + { .driver_data = MT_CLS_NSMU, + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, + I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288) }, + /* Generic MT device */ { HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH, HID_ANY_ID, HID_ANY_ID) },
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 7bd86eef6ec7..4c94c03cb573 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -730,23 +730,30 @@ static int sensor_hub_probe(struct hid_device *hdev, return ret; }
+static int sensor_hub_finalize_pending_fn(struct device *dev, void *data) +{ + struct hid_sensor_hub_device *hsdev = dev->platform_data; + + if (hsdev->pending.status) + complete(&hsdev->pending.ready); + + return 0; +} + static void sensor_hub_remove(struct hid_device *hdev) { struct sensor_hub_data *data = hid_get_drvdata(hdev); unsigned long flags; - int i;
hid_dbg(hdev, " hardware removed\n"); hid_hw_close(hdev); hid_hw_stop(hdev); + spin_lock_irqsave(&data->lock, flags); - for (i = 0; i < data->hid_sensor_client_cnt; ++i) { - struct hid_sensor_hub_device *hsdev = - data->hid_sensor_hub_client_devs[i].platform_data; - if (hsdev->pending.status) - complete(&hsdev->pending.ready); - } + device_for_each_child(&hdev->dev, NULL, + sensor_hub_finalize_pending_fn); spin_unlock_irqrestore(&data->lock, flags); + mfd_remove_devices(&hdev->dev); mutex_destroy(&data->mutex); } diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 5501a560fb07..b60bfafc6a8f 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -4946,6 +4946,10 @@ static const struct wacom_features wacom_features_0x94 = HID_DEVICE(BUS_I2C, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ .driver_data = (kernel_ulong_t)&wacom_features_##prod
+#define PCI_DEVICE_WACOM(prod) \ + HID_DEVICE(BUS_PCI, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ + .driver_data = (kernel_ulong_t)&wacom_features_##prod + #define USB_DEVICE_LENOVO(prod) \ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \ .driver_data = (kernel_ulong_t)&wacom_features_##prod @@ -5115,6 +5119,7 @@ const struct hid_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(HID_ANY_ID) }, { I2C_DEVICE_WACOM(HID_ANY_ID) }, + { PCI_DEVICE_WACOM(HID_ANY_ID) }, { BT_DEVICE_WACOM(HID_ANY_ID) }, { } }; diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c index 14ae0cfc325e..d2499f302b50 100644 --- a/drivers/i2c/i2c-core-acpi.c +++ b/drivers/i2c/i2c-core-acpi.c @@ -355,6 +355,25 @@ static const struct acpi_device_id i2c_acpi_force_400khz_device_ids[] = { {} };
+static const struct acpi_device_id i2c_acpi_force_100khz_device_ids[] = { + /* + * When a 400KHz freq is used on this model of ELAN touchpad in Linux, + * excessive smoothing (similar to when the touchpad's firmware detects + * a noisy signal) is sometimes applied. As some devices' (e.g, Lenovo + * V15 G4) ACPI tables specify a 400KHz frequency for this device and + * some I2C busses (e.g, Designware I2C) default to a 400KHz freq, + * force the speed to 100KHz as a workaround. + * + * For future investigation: This problem may be related to the default + * HCNT/LCNT values given by some busses' drivers, because they are not + * specified in the aforementioned devices' ACPI tables, and because + * the device works without issues on Windows at what is expected to be + * a 400KHz frequency. The root cause of the issue is not known. + */ + { "ELAN06FA", 0 }, + {} +}; + static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level, void *data, void **return_value) { @@ -373,6 +392,9 @@ static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level, if (acpi_match_device_ids(adev, i2c_acpi_force_400khz_device_ids) == 0) lookup->force_speed = I2C_MAX_FAST_MODE_FREQ;
+ if (acpi_match_device_ids(adev, i2c_acpi_force_100khz_device_ids) == 0) + lookup->force_speed = I2C_MAX_STANDARD_MODE_FREQ; + return AE_OK; }
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c index 42310c9a00c2..53ab814b676f 100644 --- a/drivers/i3c/master.c +++ b/drivers/i3c/master.c @@ -1919,7 +1919,7 @@ static int i3c_master_bus_init(struct i3c_master_controller *master) goto err_bus_cleanup;
if (master->ops->set_speed) { - master->ops->set_speed(master, I3C_OPEN_DRAIN_NORMAL_SPEED); + ret = master->ops->set_speed(master, I3C_OPEN_DRAIN_NORMAL_SPEED); if (ret) goto err_bus_cleanup; } diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c index d12270409c8a..a2949daf9467 100644 --- a/drivers/iio/chemical/bme680_core.c +++ b/drivers/iio/chemical/bme680_core.c @@ -874,11 +874,11 @@ static int bme680_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_RAW: switch (chan->type) { case IIO_TEMP: - ret = bme680_read_temp(data, (s16 *)&chan_val); + ret = bme680_read_temp(data, &temp_chan_val); if (ret) return ret;
- *val = chan_val; + *val = temp_chan_val; return IIO_VAL_INT; case IIO_PRESSURE: ret = bme680_read_press(data, &chan_val); diff --git a/drivers/iio/dac/ad3552r-common.c b/drivers/iio/dac/ad3552r-common.c index 0f495df2e5ce..03e0864f5084 100644 --- a/drivers/iio/dac/ad3552r-common.c +++ b/drivers/iio/dac/ad3552r-common.c @@ -22,11 +22,10 @@ EXPORT_SYMBOL_NS_GPL(ad3552r_ch_ranges, "IIO_AD3552R");
const s32 ad3542r_ch_ranges[AD3542R_MAX_RANGES][2] = { [AD3542R_CH_OUTPUT_RANGE_0__2P5V] = { 0, 2500 }, - [AD3542R_CH_OUTPUT_RANGE_0__3V] = { 0, 3000 }, [AD3542R_CH_OUTPUT_RANGE_0__5V] = { 0, 5000 }, [AD3542R_CH_OUTPUT_RANGE_0__10V] = { 0, 10000 }, - [AD3542R_CH_OUTPUT_RANGE_NEG_2P5__7P5V] = { -2500, 7500 }, - [AD3542R_CH_OUTPUT_RANGE_NEG_5__5V] = { -5000, 5000 } + [AD3542R_CH_OUTPUT_RANGE_NEG_5__5V] = { -5000, 5000 }, + [AD3542R_CH_OUTPUT_RANGE_NEG_2P5__7P5V] = { -2500, 7500 } }; EXPORT_SYMBOL_NS_GPL(ad3542r_ch_ranges, "IIO_AD3552R");
diff --git a/drivers/iio/dac/ad3552r-hs.c b/drivers/iio/dac/ad3552r-hs.c index 216c634f3eaf..8974df625670 100644 --- a/drivers/iio/dac/ad3552r-hs.c +++ b/drivers/iio/dac/ad3552r-hs.c @@ -329,6 +329,12 @@ static int ad3552r_hs_setup(struct ad3552r_hs_state *st) dev_info(st->dev, "Chip ID error. Expected 0x%x, Read 0x%x\n", AD3552R_ID, id);
+ /* Clear reset error flag, see ad3552r manual, rev B table 38. */ + ret = st->data->bus_reg_write(st->back, AD3552R_REG_ADDR_ERR_STATUS, + AD3552R_MASK_RESET_STATUS, 1); + if (ret) + return ret; + ret = st->data->bus_reg_write(st->back, AD3552R_REG_ADDR_SH_REFERENCE_CONFIG, 0, 1); diff --git a/drivers/iio/dac/ad3552r.h b/drivers/iio/dac/ad3552r.h index fd5a3dfd1d1c..4b5581039ae9 100644 --- a/drivers/iio/dac/ad3552r.h +++ b/drivers/iio/dac/ad3552r.h @@ -131,7 +131,7 @@ #define AD3552R_CH1_ACTIVE BIT(1)
#define AD3552R_MAX_RANGES 5 -#define AD3542R_MAX_RANGES 6 +#define AD3542R_MAX_RANGES 5 #define AD3552R_QUAD_SPI 2
extern const s32 ad3552r_ch_ranges[AD3552R_MAX_RANGES][2]; @@ -189,16 +189,14 @@ enum ad3552r_ch_vref_select { enum ad3542r_ch_output_range { /* Range from 0 V to 2.5 V. Requires Rfb1x connection */ AD3542R_CH_OUTPUT_RANGE_0__2P5V, - /* Range from 0 V to 3 V. Requires Rfb1x connection */ - AD3542R_CH_OUTPUT_RANGE_0__3V, /* Range from 0 V to 5 V. Requires Rfb1x connection */ AD3542R_CH_OUTPUT_RANGE_0__5V, /* Range from 0 V to 10 V. Requires Rfb2x connection */ AD3542R_CH_OUTPUT_RANGE_0__10V, - /* Range from -2.5 V to 7.5 V. Requires Rfb2x connection */ - AD3542R_CH_OUTPUT_RANGE_NEG_2P5__7P5V, /* Range from -5 V to 5 V. Requires Rfb2x connection */ AD3542R_CH_OUTPUT_RANGE_NEG_5__5V, + /* Range from -2.5 V to 7.5 V. Requires Rfb2x connection */ + AD3542R_CH_OUTPUT_RANGE_NEG_2P5__7P5V, };
enum ad3552r_ch_output_range { diff --git a/drivers/iio/light/as73211.c b/drivers/iio/light/as73211.c index be0068081ebb..11fbdcdd26d6 100644 --- a/drivers/iio/light/as73211.c +++ b/drivers/iio/light/as73211.c @@ -177,6 +177,12 @@ struct as73211_data { BIT(AS73211_SCAN_INDEX_TEMP) | \ AS73211_SCAN_MASK_COLOR)
+static const unsigned long as73211_scan_masks[] = { + AS73211_SCAN_MASK_COLOR, + AS73211_SCAN_MASK_ALL, + 0 +}; + static const struct iio_chan_spec as73211_channels[] = { { .type = IIO_TEMP, @@ -672,9 +678,12 @@ static irqreturn_t as73211_trigger_handler(int irq __always_unused, void *p)
/* AS73211 starts reading at address 2 */ ret = i2c_master_recv(data->client, - (char *)&scan.chan[1], 3 * sizeof(scan.chan[1])); + (char *)&scan.chan[0], 3 * sizeof(scan.chan[0])); if (ret < 0) goto done; + + /* Avoid pushing uninitialized data */ + scan.chan[3] = 0; }
if (data_result) { @@ -682,9 +691,15 @@ static irqreturn_t as73211_trigger_handler(int irq __always_unused, void *p) * Saturate all channels (in case of overflows). Temperature channel * is not affected by overflows. */ - scan.chan[1] = cpu_to_le16(U16_MAX); - scan.chan[2] = cpu_to_le16(U16_MAX); - scan.chan[3] = cpu_to_le16(U16_MAX); + if (*indio_dev->active_scan_mask == AS73211_SCAN_MASK_ALL) { + scan.chan[1] = cpu_to_le16(U16_MAX); + scan.chan[2] = cpu_to_le16(U16_MAX); + scan.chan[3] = cpu_to_le16(U16_MAX); + } else { + scan.chan[0] = cpu_to_le16(U16_MAX); + scan.chan[1] = cpu_to_le16(U16_MAX); + scan.chan[2] = cpu_to_le16(U16_MAX); + } }
iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev)); @@ -758,6 +773,7 @@ static int as73211_probe(struct i2c_client *client) indio_dev->channels = data->spec_dev->channels; indio_dev->num_channels = data->spec_dev->num_channels; indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->available_scan_masks = as73211_scan_masks;
ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_OSR); if (ret < 0) diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index 45d9dc9c6c8f..bb02b6adbf2c 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -2021,6 +2021,11 @@ static int mlx5_revoke_mr(struct mlx5_ib_mr *mr) { struct mlx5_ib_dev *dev = to_mdev(mr->ibmr.device); struct mlx5_cache_ent *ent = mr->mmkey.cache_ent; + bool is_odp = is_odp_mr(mr); + int ret = 0; + + if (is_odp) + mutex_lock(&to_ib_umem_odp(mr->umem)->umem_mutex);
if (mr->mmkey.cacheable && !mlx5r_umr_revoke_mr(mr) && !cache_ent_find_and_store(dev, mr)) { ent = mr->mmkey.cache_ent; @@ -2032,7 +2037,7 @@ static int mlx5_revoke_mr(struct mlx5_ib_mr *mr) ent->tmp_cleanup_scheduled = true; } spin_unlock_irq(&ent->mkeys_queue.lock); - return 0; + goto out; }
if (ent) { @@ -2041,7 +2046,15 @@ static int mlx5_revoke_mr(struct mlx5_ib_mr *mr) mr->mmkey.cache_ent = NULL; spin_unlock_irq(&ent->mkeys_queue.lock); } - return destroy_mkey(dev, mr); + ret = destroy_mkey(dev, mr); +out: + if (is_odp) { + if (!ret) + to_ib_umem_odp(mr->umem)->private = NULL; + mutex_unlock(&to_ib_umem_odp(mr->umem)->umem_mutex); + } + + return ret; }
static int __mlx5_ib_dereg_mr(struct ib_mr *ibmr) diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c index 64b441542cd5..1d3bf5615770 100644 --- a/drivers/infiniband/hw/mlx5/odp.c +++ b/drivers/infiniband/hw/mlx5/odp.c @@ -282,6 +282,8 @@ static bool mlx5_ib_invalidate_range(struct mmu_interval_notifier *mni, if (!umem_odp->npages) goto out; mr = umem_odp->private; + if (!mr) + goto out;
start = max_t(u64, ib_umem_start(umem_odp), range->start); end = min_t(u64, ib_umem_end(umem_odp), range->end); diff --git a/drivers/input/misc/nxp-bbnsm-pwrkey.c b/drivers/input/misc/nxp-bbnsm-pwrkey.c index eb4173f9c820..7ba8d166d68c 100644 --- a/drivers/input/misc/nxp-bbnsm-pwrkey.c +++ b/drivers/input/misc/nxp-bbnsm-pwrkey.c @@ -187,6 +187,12 @@ static int bbnsm_pwrkey_probe(struct platform_device *pdev) return 0; }
+static void bbnsm_pwrkey_remove(struct platform_device *pdev) +{ + dev_pm_clear_wake_irq(&pdev->dev); + device_init_wakeup(&pdev->dev, false); +} + static int __maybe_unused bbnsm_pwrkey_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); @@ -223,6 +229,8 @@ static struct platform_driver bbnsm_pwrkey_driver = { .of_match_table = bbnsm_pwrkey_ids, }, .probe = bbnsm_pwrkey_probe, + .remove = bbnsm_pwrkey_remove, + }; module_platform_driver(bbnsm_pwrkey_driver);
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 2735f86c23cc..aba57abe6978 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -665,23 +665,50 @@ static void synaptics_pt_stop(struct serio *serio) priv->pt_port = NULL; }
+static int synaptics_pt_open(struct serio *serio) +{ + struct psmouse *parent = psmouse_from_serio(serio->parent); + struct synaptics_data *priv = parent->private; + + guard(serio_pause_rx)(parent->ps2dev.serio); + priv->pt_port_open = true; + + return 0; +} + +static void synaptics_pt_close(struct serio *serio) +{ + struct psmouse *parent = psmouse_from_serio(serio->parent); + struct synaptics_data *priv = parent->private; + + guard(serio_pause_rx)(parent->ps2dev.serio); + priv->pt_port_open = false; +} + static int synaptics_is_pt_packet(u8 *buf) { return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4; }
-static void synaptics_pass_pt_packet(struct serio *ptport, u8 *packet) +static void synaptics_pass_pt_packet(struct synaptics_data *priv, u8 *packet) { - struct psmouse *child = psmouse_from_serio(ptport); + struct serio *ptport;
- if (child && child->state == PSMOUSE_ACTIVATED) { - serio_interrupt(ptport, packet[1], 0); - serio_interrupt(ptport, packet[4], 0); - serio_interrupt(ptport, packet[5], 0); - if (child->pktsize == 4) - serio_interrupt(ptport, packet[2], 0); - } else { - serio_interrupt(ptport, packet[1], 0); + ptport = priv->pt_port; + if (!ptport) + return; + + serio_interrupt(ptport, packet[1], 0); + + if (priv->pt_port_open) { + struct psmouse *child = psmouse_from_serio(ptport); + + if (child->state == PSMOUSE_ACTIVATED) { + serio_interrupt(ptport, packet[4], 0); + serio_interrupt(ptport, packet[5], 0); + if (child->pktsize == 4) + serio_interrupt(ptport, packet[2], 0); + } } }
@@ -720,6 +747,8 @@ static void synaptics_pt_create(struct psmouse *psmouse) serio->write = synaptics_pt_write; serio->start = synaptics_pt_start; serio->stop = synaptics_pt_stop; + serio->open = synaptics_pt_open; + serio->close = synaptics_pt_close; serio->parent = psmouse->ps2dev.serio;
psmouse->pt_activate = synaptics_pt_activate; @@ -1216,11 +1245,10 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse)
if (SYN_CAP_PASS_THROUGH(priv->info.capabilities) && synaptics_is_pt_packet(psmouse->packet)) { - if (priv->pt_port) - synaptics_pass_pt_packet(priv->pt_port, - psmouse->packet); - } else + synaptics_pass_pt_packet(priv, psmouse->packet); + } else { synaptics_process_packet(psmouse); + }
return PSMOUSE_FULL_PACKET; } diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 899aee598632..3853165b6b3a 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h @@ -188,6 +188,7 @@ struct synaptics_data { bool disable_gesture; /* disable gestures */
struct serio *pt_port; /* Pass-through serio port */ + bool pt_port_open;
/* * Last received Advanced Gesture Mode (AGM) packet. An AGM packet diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index 6d15405f0ea3..42a89d499cda 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -4670,7 +4670,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev) /* Initialise in-memory data structures */ ret = arm_smmu_init_structures(smmu); if (ret) - return ret; + goto err_free_iopf;
/* Record our private device structure */ platform_set_drvdata(pdev, smmu); @@ -4681,22 +4681,29 @@ static int arm_smmu_device_probe(struct platform_device *pdev) /* Reset the device */ ret = arm_smmu_device_reset(smmu); if (ret) - return ret; + goto err_disable;
/* And we're up. Go go go! */ ret = iommu_device_sysfs_add(&smmu->iommu, dev, NULL, "smmu3.%pa", &ioaddr); if (ret) - return ret; + goto err_disable;
ret = iommu_device_register(&smmu->iommu, &arm_smmu_ops, dev); if (ret) { dev_err(dev, "Failed to register iommu\n"); - iommu_device_sysfs_remove(&smmu->iommu); - return ret; + goto err_free_sysfs; }
return 0; + +err_free_sysfs: + iommu_device_sysfs_remove(&smmu->iommu); +err_disable: + arm_smmu_device_disable(smmu); +err_free_iopf: + iopf_queue_free(smmu->evtq.iopf); + return ret; }
static void arm_smmu_device_remove(struct platform_device *pdev) diff --git a/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c b/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c index 6e41ddaa24d6..d525ab43a4ae 100644 --- a/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c +++ b/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c @@ -79,7 +79,6 @@ #define TEGRA241_VCMDQ_PAGE1(q) (TEGRA241_VCMDQ_PAGE1_BASE + 0x80*(q)) #define VCMDQ_ADDR GENMASK(47, 5) #define VCMDQ_LOG2SIZE GENMASK(4, 0) -#define VCMDQ_LOG2SIZE_MAX 19
#define TEGRA241_VCMDQ_BASE 0x00000 #define TEGRA241_VCMDQ_CONS_INDX_BASE 0x00008 @@ -505,12 +504,15 @@ static int tegra241_vcmdq_alloc_smmu_cmdq(struct tegra241_vcmdq *vcmdq) struct arm_smmu_cmdq *cmdq = &vcmdq->cmdq; struct arm_smmu_queue *q = &cmdq->q; char name[16]; + u32 regval; int ret;
snprintf(name, 16, "vcmdq%u", vcmdq->idx);
- /* Queue size, capped to ensure natural alignment */ - q->llq.max_n_shift = min_t(u32, CMDQ_MAX_SZ_SHIFT, VCMDQ_LOG2SIZE_MAX); + /* Cap queue size to SMMU's IDR1.CMDQS and ensure natural alignment */ + regval = readl_relaxed(smmu->base + ARM_SMMU_IDR1); + q->llq.max_n_shift = + min_t(u32, CMDQ_MAX_SZ_SHIFT, FIELD_GET(IDR1_CMDQS, regval));
/* Use the common helper to init the VCMDQ, and then... */ ret = arm_smmu_init_one_queue(smmu, q, vcmdq->page0, diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c index 6372f3e25c4b..601fb878d0ef 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c @@ -567,6 +567,7 @@ static const struct of_device_id __maybe_unused qcom_smmu_impl_of_match[] = { { .compatible = "qcom,sc8180x-smmu-500", .data = &qcom_smmu_500_impl0_data }, { .compatible = "qcom,sc8280xp-smmu-500", .data = &qcom_smmu_500_impl0_data }, { .compatible = "qcom,sdm630-smmu-v2", .data = &qcom_smmu_v2_data }, + { .compatible = "qcom,sdm670-smmu-v2", .data = &qcom_smmu_v2_data }, { .compatible = "qcom,sdm845-smmu-v2", .data = &qcom_smmu_v2_data }, { .compatible = "qcom,sdm845-smmu-500", .data = &sdm845_smmu_500_data }, { .compatible = "qcom,sm6115-smmu-500", .data = &qcom_smmu_500_impl0_data}, diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 79e0da9eb626..8f75c11a3ec4 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -4090,13 +4090,14 @@ void domain_remove_dev_pasid(struct iommu_domain *domain, break; } } - WARN_ON_ONCE(!dev_pasid); spin_unlock_irqrestore(&dmar_domain->lock, flags);
cache_tag_unassign_domain(dmar_domain, dev, pasid); domain_detach_iommu(dmar_domain, iommu); - intel_iommu_debugfs_remove_dev_pasid(dev_pasid); - kfree(dev_pasid); + if (!WARN_ON_ONCE(!dev_pasid)) { + intel_iommu_debugfs_remove_dev_pasid(dev_pasid); + kfree(dev_pasid); + } }
static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid, diff --git a/drivers/iommu/iommufd/fault.c b/drivers/iommu/iommufd/fault.c index 1fe804e28a86..d9a937450e55 100644 --- a/drivers/iommu/iommufd/fault.c +++ b/drivers/iommu/iommufd/fault.c @@ -103,15 +103,23 @@ static void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt, { struct iommufd_fault *fault = hwpt->fault; struct iopf_group *group, *next; + struct list_head free_list; unsigned long index;
if (!fault) return; + INIT_LIST_HEAD(&free_list);
mutex_lock(&fault->mutex); + spin_lock(&fault->lock); list_for_each_entry_safe(group, next, &fault->deliver, node) { if (group->attach_handle != &handle->handle) continue; + list_move(&group->node, &free_list); + } + spin_unlock(&fault->lock); + + list_for_each_entry_safe(group, next, &free_list, node) { list_del(&group->node); iopf_group_response(group, IOMMU_PAGE_RESP_INVALID); iopf_free_group(group); @@ -213,6 +221,7 @@ void iommufd_fault_destroy(struct iommufd_object *obj) { struct iommufd_fault *fault = container_of(obj, struct iommufd_fault, obj); struct iopf_group *group, *next; + unsigned long index;
/* * The iommufd object's reference count is zero at this point. @@ -225,6 +234,13 @@ void iommufd_fault_destroy(struct iommufd_object *obj) iopf_group_response(group, IOMMU_PAGE_RESP_INVALID); iopf_free_group(group); } + xa_for_each(&fault->response, index, group) { + xa_erase(&fault->response, index); + iopf_group_response(group, IOMMU_PAGE_RESP_INVALID); + iopf_free_group(group); + } + xa_destroy(&fault->response); + mutex_destroy(&fault->mutex); }
static void iommufd_compose_fault_message(struct iommu_fault *fault, @@ -247,7 +263,7 @@ static ssize_t iommufd_fault_fops_read(struct file *filep, char __user *buf, { size_t fault_size = sizeof(struct iommu_hwpt_pgfault); struct iommufd_fault *fault = filep->private_data; - struct iommu_hwpt_pgfault data; + struct iommu_hwpt_pgfault data = {}; struct iommufd_device *idev; struct iopf_group *group; struct iopf_fault *iopf; @@ -258,17 +274,19 @@ static ssize_t iommufd_fault_fops_read(struct file *filep, char __user *buf, return -ESPIPE;
mutex_lock(&fault->mutex); - while (!list_empty(&fault->deliver) && count > done) { - group = list_first_entry(&fault->deliver, - struct iopf_group, node); - - if (group->fault_count * fault_size > count - done) + while ((group = iommufd_fault_deliver_fetch(fault))) { + if (done >= count || + group->fault_count * fault_size > count - done) { + iommufd_fault_deliver_restore(fault, group); break; + }
rc = xa_alloc(&fault->response, &group->cookie, group, xa_limit_32b, GFP_KERNEL); - if (rc) + if (rc) { + iommufd_fault_deliver_restore(fault, group); break; + }
idev = to_iommufd_handle(group->attach_handle)->idev; list_for_each_entry(iopf, &group->faults, list) { @@ -277,13 +295,12 @@ static ssize_t iommufd_fault_fops_read(struct file *filep, char __user *buf, group->cookie); if (copy_to_user(buf + done, &data, fault_size)) { xa_erase(&fault->response, group->cookie); + iommufd_fault_deliver_restore(fault, group); rc = -EFAULT; break; } done += fault_size; } - - list_del(&group->node); } mutex_unlock(&fault->mutex);
@@ -341,10 +358,10 @@ static __poll_t iommufd_fault_fops_poll(struct file *filep, __poll_t pollflags = EPOLLOUT;
poll_wait(filep, &fault->wait_queue, wait); - mutex_lock(&fault->mutex); + spin_lock(&fault->lock); if (!list_empty(&fault->deliver)) pollflags |= EPOLLIN | EPOLLRDNORM; - mutex_unlock(&fault->mutex); + spin_unlock(&fault->lock);
return pollflags; } @@ -386,6 +403,7 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd) INIT_LIST_HEAD(&fault->deliver); xa_init_flags(&fault->response, XA_FLAGS_ALLOC1); mutex_init(&fault->mutex); + spin_lock_init(&fault->lock); init_waitqueue_head(&fault->wait_queue);
filep = anon_inode_getfile("[iommufd-pgfault]", &iommufd_fault_fops, @@ -434,9 +452,9 @@ int iommufd_fault_iopf_handler(struct iopf_group *group) hwpt = group->attach_handle->domain->fault_data; fault = hwpt->fault;
- mutex_lock(&fault->mutex); + spin_lock(&fault->lock); list_add_tail(&group->node, &fault->deliver); - mutex_unlock(&fault->mutex); + spin_unlock(&fault->lock);
wake_up_interruptible(&fault->wait_queue);
diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h index b6d706cf2c66..0b1bafc7fd99 100644 --- a/drivers/iommu/iommufd/iommufd_private.h +++ b/drivers/iommu/iommufd/iommufd_private.h @@ -443,14 +443,39 @@ struct iommufd_fault { struct iommufd_ctx *ictx; struct file *filep;
- /* The lists of outstanding faults protected by below mutex. */ - struct mutex mutex; + spinlock_t lock; /* protects the deliver list */ struct list_head deliver; + struct mutex mutex; /* serializes response flows */ struct xarray response;
struct wait_queue_head wait_queue; };
+/* Fetch the first node out of the fault->deliver list */ +static inline struct iopf_group * +iommufd_fault_deliver_fetch(struct iommufd_fault *fault) +{ + struct list_head *list = &fault->deliver; + struct iopf_group *group = NULL; + + spin_lock(&fault->lock); + if (!list_empty(list)) { + group = list_first_entry(list, struct iopf_group, node); + list_del(&group->node); + } + spin_unlock(&fault->lock); + return group; +} + +/* Restore a node back to the head of the fault->deliver list */ +static inline void iommufd_fault_deliver_restore(struct iommufd_fault *fault, + struct iopf_group *group) +{ + spin_lock(&fault->lock); + list_add(&group->node, &fault->deliver); + spin_unlock(&fault->lock); +} + struct iommufd_attach_handle { struct iommu_attach_handle handle; struct iommufd_device *idev; diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 9bee02db1643..990674713b86 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -169,6 +169,7 @@ config IXP4XX_IRQ
config LAN966X_OIC tristate "Microchip LAN966x OIC Support" + depends on MCHP_LAN966X_PCI || COMPILE_TEST select GENERIC_IRQ_CHIP select IRQ_DOMAIN help diff --git a/drivers/irqchip/irq-apple-aic.c b/drivers/irqchip/irq-apple-aic.c index da5250f0155c..2b1684c60e3c 100644 --- a/drivers/irqchip/irq-apple-aic.c +++ b/drivers/irqchip/irq-apple-aic.c @@ -577,7 +577,8 @@ static void __exception_irq_entry aic_handle_fiq(struct pt_regs *regs) AIC_FIQ_HWIRQ(AIC_TMR_EL02_VIRT)); }
- if (read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & PMCR0_IACT) { + if ((read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & (PMCR0_IMODE | PMCR0_IACT)) == + (FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_FIQ) | PMCR0_IACT)) { int irq; if (cpumask_test_cpu(smp_processor_id(), &aic_irqc->fiq_aff[AIC_CPU_PMU_P]->aff)) diff --git a/drivers/irqchip/irq-mvebu-icu.c b/drivers/irqchip/irq-mvebu-icu.c index b337f6c05f18..4eebed39880a 100644 --- a/drivers/irqchip/irq-mvebu-icu.c +++ b/drivers/irqchip/irq-mvebu-icu.c @@ -68,7 +68,8 @@ static int mvebu_icu_translate(struct irq_domain *d, struct irq_fwspec *fwspec, unsigned long *hwirq, unsigned int *type) { unsigned int param_count = static_branch_unlikely(&legacy_bindings) ? 3 : 2; - struct mvebu_icu_msi_data *msi_data = d->host_data; + struct msi_domain_info *info = d->host_data; + struct mvebu_icu_msi_data *msi_data = info->chip_data; struct mvebu_icu *icu = msi_data->icu;
/* Check the count of the parameters in dt */ diff --git a/drivers/leds/leds-lp8860.c b/drivers/leds/leds-lp8860.c index 7a136fd81720..06196d851ade 100644 --- a/drivers/leds/leds-lp8860.c +++ b/drivers/leds/leds-lp8860.c @@ -265,7 +265,7 @@ static int lp8860_init(struct lp8860_led *led) goto out; }
- reg_count = ARRAY_SIZE(lp8860_eeprom_disp_regs) / sizeof(lp8860_eeprom_disp_regs[0]); + reg_count = ARRAY_SIZE(lp8860_eeprom_disp_regs); for (i = 0; i < reg_count; i++) { ret = regmap_write(led->eeprom_regmap, lp8860_eeprom_disp_regs[i].reg, diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c index 8d5e2d7dc03b..c1981f091bd1 100644 --- a/drivers/mailbox/tegra-hsp.c +++ b/drivers/mailbox/tegra-hsp.c @@ -388,7 +388,6 @@ static void tegra_hsp_sm_recv32(struct tegra_hsp_channel *channel) value = tegra_hsp_channel_readl(channel, HSP_SM_SHRD_MBOX); value &= ~HSP_SM_SHRD_MBOX_FULL; msg = (void *)(unsigned long)value; - mbox_chan_received_data(channel->chan, msg);
/* * Need to clear all bits here since some producers, such as TCU, depend @@ -398,6 +397,8 @@ static void tegra_hsp_sm_recv32(struct tegra_hsp_channel *channel) * explicitly, so we have to make sure we cover all possible cases. */ tegra_hsp_channel_writel(channel, 0x0, HSP_SM_SHRD_MBOX); + + mbox_chan_received_data(channel->chan, msg); }
static const struct tegra_hsp_sm_ops tegra_hsp_sm_32bit_ops = { @@ -433,7 +434,6 @@ static void tegra_hsp_sm_recv128(struct tegra_hsp_channel *channel) value[3] = tegra_hsp_channel_readl(channel, HSP_SHRD_MBOX_TYPE1_DATA3);
msg = (void *)(unsigned long)value; - mbox_chan_received_data(channel->chan, msg);
/* * Clear data registers and tag. @@ -443,6 +443,8 @@ static void tegra_hsp_sm_recv128(struct tegra_hsp_channel *channel) tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_DATA2); tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_DATA3); tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_TAG); + + mbox_chan_received_data(channel->chan, msg); }
static const struct tegra_hsp_sm_ops tegra_hsp_sm_128bit_ops = { diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c index aa5249da59b2..0c143beaafda 100644 --- a/drivers/mailbox/zynqmp-ipi-mailbox.c +++ b/drivers/mailbox/zynqmp-ipi-mailbox.c @@ -905,7 +905,7 @@ static int zynqmp_ipi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *nc, *np = pdev->dev.of_node; - struct zynqmp_ipi_pdata __percpu *pdata; + struct zynqmp_ipi_pdata *pdata; struct of_phandle_args out_irq; struct zynqmp_ipi_mbox *mbox; int num_mboxes, ret = -EINVAL; diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index 1e9db8e4acdf..0b1870a09e1f 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig @@ -61,6 +61,19 @@ config MD_BITMAP_FILE various kernel APIs and can only work with files on a file system not actually sitting on the MD device.
+config MD_LINEAR + tristate "Linear (append) mode" + depends on BLK_DEV_MD + help + If you say Y here, then your multiple devices driver will be able to + use the so-called linear mode, i.e. it will combine the hard disk + partitions by simply appending one to the other. + + To compile this as a module, choose M here: the module + will be called linear. + + If unsure, say Y. + config MD_RAID0 tristate "RAID-0 (striping) mode" depends on BLK_DEV_MD diff --git a/drivers/md/Makefile b/drivers/md/Makefile index 476a214e4bdc..87bdfc9fe14c 100644 --- a/drivers/md/Makefile +++ b/drivers/md/Makefile @@ -29,12 +29,14 @@ dm-zoned-y += dm-zoned-target.o dm-zoned-metadata.o dm-zoned-reclaim.o
md-mod-y += md.o md-bitmap.o raid456-y += raid5.o raid5-cache.o raid5-ppl.o +linear-y += md-linear.o
# Note: link order is important. All raid personalities # and must come before md.o, as they each initialise # themselves, and md.o may use the personalities when it # auto-initialised.
+obj-$(CONFIG_MD_LINEAR) += linear.o obj-$(CONFIG_MD_RAID0) += raid0.o obj-$(CONFIG_MD_RAID1) += raid1.o obj-$(CONFIG_MD_RAID10) += raid10.o diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 1ae2c71bb383..78c975d7cd5f 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -59,6 +59,7 @@ struct convert_context { struct bio *bio_out; struct bvec_iter iter_out; atomic_t cc_pending; + unsigned int tag_offset; u64 cc_sector; union { struct skcipher_request *req; @@ -1256,6 +1257,7 @@ static void crypt_convert_init(struct crypt_config *cc, if (bio_out) ctx->iter_out = bio_out->bi_iter; ctx->cc_sector = sector + cc->iv_offset; + ctx->tag_offset = 0; init_completion(&ctx->restart); }
@@ -1588,7 +1590,6 @@ static void crypt_free_req(struct crypt_config *cc, void *req, struct bio *base_ static blk_status_t crypt_convert(struct crypt_config *cc, struct convert_context *ctx, bool atomic, bool reset_pending) { - unsigned int tag_offset = 0; unsigned int sector_step = cc->sector_size >> SECTOR_SHIFT; int r;
@@ -1611,9 +1612,9 @@ static blk_status_t crypt_convert(struct crypt_config *cc, atomic_inc(&ctx->cc_pending);
if (crypt_integrity_aead(cc)) - r = crypt_convert_block_aead(cc, ctx, ctx->r.req_aead, tag_offset); + r = crypt_convert_block_aead(cc, ctx, ctx->r.req_aead, ctx->tag_offset); else - r = crypt_convert_block_skcipher(cc, ctx, ctx->r.req, tag_offset); + r = crypt_convert_block_skcipher(cc, ctx, ctx->r.req, ctx->tag_offset);
switch (r) { /* @@ -1633,8 +1634,8 @@ static blk_status_t crypt_convert(struct crypt_config *cc, * exit and continue processing in a workqueue */ ctx->r.req = NULL; + ctx->tag_offset++; ctx->cc_sector += sector_step; - tag_offset++; return BLK_STS_DEV_RESOURCE; } } else { @@ -1648,8 +1649,8 @@ static blk_status_t crypt_convert(struct crypt_config *cc, */ case -EINPROGRESS: ctx->r.req = NULL; + ctx->tag_offset++; ctx->cc_sector += sector_step; - tag_offset++; continue; /* * The request was already processed (synchronously). @@ -1657,7 +1658,7 @@ static blk_status_t crypt_convert(struct crypt_config *cc, case 0: atomic_dec(&ctx->cc_pending); ctx->cc_sector += sector_step; - tag_offset++; + ctx->tag_offset++; if (!atomic) cond_resched(); continue; @@ -2092,7 +2093,6 @@ static void kcryptd_crypt_write_continue(struct work_struct *work) struct crypt_config *cc = io->cc; struct convert_context *ctx = &io->ctx; int crypt_finished; - sector_t sector = io->sector; blk_status_t r;
wait_for_completion(&ctx->restart); @@ -2109,10 +2109,8 @@ static void kcryptd_crypt_write_continue(struct work_struct *work) }
/* Encryption was already finished, submit io now */ - if (crypt_finished) { + if (crypt_finished) kcryptd_crypt_write_io_submit(io, 0); - io->sector = sector; - }
crypt_dec_pending(io); } @@ -2123,14 +2121,13 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) struct convert_context *ctx = &io->ctx; struct bio *clone; int crypt_finished; - sector_t sector = io->sector; blk_status_t r;
/* * Prevent io from disappearing until this function completes. */ crypt_inc_pending(io); - crypt_convert_init(cc, ctx, NULL, io->base_bio, sector); + crypt_convert_init(cc, ctx, NULL, io->base_bio, io->sector);
clone = crypt_alloc_buffer(io, io->base_bio->bi_iter.bi_size); if (unlikely(!clone)) { @@ -2147,8 +2144,6 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) io->ctx.iter_in = clone->bi_iter; }
- sector += bio_sectors(clone); - crypt_inc_pending(io); r = crypt_convert(cc, ctx, test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags), true); @@ -2172,10 +2167,8 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) }
/* Encryption was already finished, submit io now */ - if (crypt_finished) { + if (crypt_finished) kcryptd_crypt_write_io_submit(io, 0); - io->sector = sector; - }
dec: crypt_dec_pending(io); diff --git a/drivers/md/md-autodetect.c b/drivers/md/md-autodetect.c index b2a00f213c2c..4b80165afd23 100644 --- a/drivers/md/md-autodetect.c +++ b/drivers/md/md-autodetect.c @@ -49,6 +49,7 @@ static int md_setup_ents __initdata; * instead of just one. -- KTK * 18May2000: Added support for persistent-superblock arrays: * md=n,0,factor,fault,device-list uses RAID0 for device n + * md=n,-1,factor,fault,device-list uses LINEAR for device n * md=n,device-list reads a RAID superblock from the devices * elements in device-list are read by name_to_kdev_t so can be * a hex number or something like /dev/hda1 /dev/sdb @@ -87,7 +88,7 @@ static int __init md_setup(char *str) md_setup_ents++; switch (get_option(&str, &level)) { /* RAID level */ case 2: /* could be 0 or -1.. */ - if (level == 0) { + if (level == 0 || level == LEVEL_LINEAR) { if (get_option(&str, &factor) != 2 || /* Chunk Size */ get_option(&str, &fault) != 2) { printk(KERN_WARNING "md: Too few arguments supplied to md=.\n"); @@ -95,7 +96,10 @@ static int __init md_setup(char *str) } md_setup_args[ent].level = level; md_setup_args[ent].chunk = 1 << (factor+12); - pername = "raid0"; + if (level == LEVEL_LINEAR) + pername = "linear"; + else + pername = "raid0"; break; } fallthrough; diff --git a/drivers/md/md-linear.c b/drivers/md/md-linear.c new file mode 100644 index 000000000000..369aed044b40 --- /dev/null +++ b/drivers/md/md-linear.c @@ -0,0 +1,352 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * linear.c : Multiple Devices driver for Linux Copyright (C) 1994-96 Marc + * ZYNGIER zyngier@ufr-info-p7.ibp.fr or maz@gloups.fdn.fr + */ + +#include <linux/blkdev.h> +#include <linux/raid/md_u.h> +#include <linux/seq_file.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <trace/events/block.h> +#include "md.h" + +struct dev_info { + struct md_rdev *rdev; + sector_t end_sector; +}; + +struct linear_conf { + struct rcu_head rcu; + sector_t array_sectors; + /* a copy of mddev->raid_disks */ + int raid_disks; + struct dev_info disks[] __counted_by(raid_disks); +}; + +/* + * find which device holds a particular offset + */ +static inline struct dev_info *which_dev(struct mddev *mddev, sector_t sector) +{ + int lo, mid, hi; + struct linear_conf *conf; + + lo = 0; + hi = mddev->raid_disks - 1; + conf = mddev->private; + + /* + * Binary Search + */ + + while (hi > lo) { + + mid = (hi + lo) / 2; + if (sector < conf->disks[mid].end_sector) + hi = mid; + else + lo = mid + 1; + } + + return conf->disks + lo; +} + +static sector_t linear_size(struct mddev *mddev, sector_t sectors, int raid_disks) +{ + struct linear_conf *conf; + sector_t array_sectors; + + conf = mddev->private; + WARN_ONCE(sectors || raid_disks, + "%s does not support generic reshape\n", __func__); + array_sectors = conf->array_sectors; + + return array_sectors; +} + +static int linear_set_limits(struct mddev *mddev) +{ + struct queue_limits lim; + int err; + + md_init_stacking_limits(&lim); + lim.max_hw_sectors = mddev->chunk_sectors; + lim.max_write_zeroes_sectors = mddev->chunk_sectors; + lim.io_min = mddev->chunk_sectors << 9; + err = mddev_stack_rdev_limits(mddev, &lim, MDDEV_STACK_INTEGRITY); + if (err) + return err; + + return queue_limits_set(mddev->gendisk->queue, &lim); +} + +static struct linear_conf *linear_conf(struct mddev *mddev, int raid_disks) +{ + struct linear_conf *conf; + struct md_rdev *rdev; + int ret = -EINVAL; + int cnt; + int i; + + conf = kzalloc(struct_size(conf, disks, raid_disks), GFP_KERNEL); + if (!conf) + return ERR_PTR(-ENOMEM); + + /* + * conf->raid_disks is copy of mddev->raid_disks. The reason to + * keep a copy of mddev->raid_disks in struct linear_conf is, + * mddev->raid_disks may not be consistent with pointers number of + * conf->disks[] when it is updated in linear_add() and used to + * iterate old conf->disks[] earray in linear_congested(). + * Here conf->raid_disks is always consitent with number of + * pointers in conf->disks[] array, and mddev->private is updated + * with rcu_assign_pointer() in linear_addr(), such race can be + * avoided. + */ + conf->raid_disks = raid_disks; + + cnt = 0; + conf->array_sectors = 0; + + rdev_for_each(rdev, mddev) { + int j = rdev->raid_disk; + struct dev_info *disk = conf->disks + j; + sector_t sectors; + + if (j < 0 || j >= raid_disks || disk->rdev) { + pr_warn("md/linear:%s: disk numbering problem. Aborting!\n", + mdname(mddev)); + goto out; + } + + disk->rdev = rdev; + if (mddev->chunk_sectors) { + sectors = rdev->sectors; + sector_div(sectors, mddev->chunk_sectors); + rdev->sectors = sectors * mddev->chunk_sectors; + } + + conf->array_sectors += rdev->sectors; + cnt++; + } + if (cnt != raid_disks) { + pr_warn("md/linear:%s: not enough drives present. Aborting!\n", + mdname(mddev)); + goto out; + } + + /* + * Here we calculate the device offsets. + */ + conf->disks[0].end_sector = conf->disks[0].rdev->sectors; + + for (i = 1; i < raid_disks; i++) + conf->disks[i].end_sector = + conf->disks[i-1].end_sector + + conf->disks[i].rdev->sectors; + + if (!mddev_is_dm(mddev)) { + ret = linear_set_limits(mddev); + if (ret) + goto out; + } + + return conf; + +out: + kfree(conf); + return ERR_PTR(ret); +} + +static int linear_run(struct mddev *mddev) +{ + struct linear_conf *conf; + int ret; + + if (md_check_no_bitmap(mddev)) + return -EINVAL; + + conf = linear_conf(mddev, mddev->raid_disks); + if (IS_ERR(conf)) + return PTR_ERR(conf); + + mddev->private = conf; + md_set_array_sectors(mddev, linear_size(mddev, 0, 0)); + + ret = md_integrity_register(mddev); + if (ret) { + kfree(conf); + mddev->private = NULL; + } + return ret; +} + +static int linear_add(struct mddev *mddev, struct md_rdev *rdev) +{ + /* Adding a drive to a linear array allows the array to grow. + * It is permitted if the new drive has a matching superblock + * already on it, with raid_disk equal to raid_disks. + * It is achieved by creating a new linear_private_data structure + * and swapping it in in-place of the current one. + * The current one is never freed until the array is stopped. + * This avoids races. + */ + struct linear_conf *newconf, *oldconf; + + if (rdev->saved_raid_disk != mddev->raid_disks) + return -EINVAL; + + rdev->raid_disk = rdev->saved_raid_disk; + rdev->saved_raid_disk = -1; + + newconf = linear_conf(mddev, mddev->raid_disks + 1); + if (IS_ERR(newconf)) + return PTR_ERR(newconf); + + /* newconf->raid_disks already keeps a copy of * the increased + * value of mddev->raid_disks, WARN_ONCE() is just used to make + * sure of this. It is possible that oldconf is still referenced + * in linear_congested(), therefore kfree_rcu() is used to free + * oldconf until no one uses it anymore. + */ + oldconf = rcu_dereference_protected(mddev->private, + lockdep_is_held(&mddev->reconfig_mutex)); + mddev->raid_disks++; + WARN_ONCE(mddev->raid_disks != newconf->raid_disks, + "copied raid_disks doesn't match mddev->raid_disks"); + rcu_assign_pointer(mddev->private, newconf); + md_set_array_sectors(mddev, linear_size(mddev, 0, 0)); + set_capacity_and_notify(mddev->gendisk, mddev->array_sectors); + kfree_rcu(oldconf, rcu); + return 0; +} + +static void linear_free(struct mddev *mddev, void *priv) +{ + struct linear_conf *conf = priv; + + kfree(conf); +} + +static bool linear_make_request(struct mddev *mddev, struct bio *bio) +{ + struct dev_info *tmp_dev; + sector_t start_sector, end_sector, data_offset; + sector_t bio_sector = bio->bi_iter.bi_sector; + + if (unlikely(bio->bi_opf & REQ_PREFLUSH) + && md_flush_request(mddev, bio)) + return true; + + tmp_dev = which_dev(mddev, bio_sector); + start_sector = tmp_dev->end_sector - tmp_dev->rdev->sectors; + end_sector = tmp_dev->end_sector; + data_offset = tmp_dev->rdev->data_offset; + + if (unlikely(bio_sector >= end_sector || + bio_sector < start_sector)) + goto out_of_bounds; + + if (unlikely(is_rdev_broken(tmp_dev->rdev))) { + md_error(mddev, tmp_dev->rdev); + bio_io_error(bio); + return true; + } + + if (unlikely(bio_end_sector(bio) > end_sector)) { + /* This bio crosses a device boundary, so we have to split it */ + struct bio *split = bio_split(bio, end_sector - bio_sector, + GFP_NOIO, &mddev->bio_set); + + if (IS_ERR(split)) { + bio->bi_status = errno_to_blk_status(PTR_ERR(split)); + bio_endio(bio); + return true; + } + + bio_chain(split, bio); + submit_bio_noacct(bio); + bio = split; + } + + md_account_bio(mddev, &bio); + bio_set_dev(bio, tmp_dev->rdev->bdev); + bio->bi_iter.bi_sector = bio->bi_iter.bi_sector - + start_sector + data_offset; + + if (unlikely((bio_op(bio) == REQ_OP_DISCARD) && + !bdev_max_discard_sectors(bio->bi_bdev))) { + /* Just ignore it */ + bio_endio(bio); + } else { + if (mddev->gendisk) + trace_block_bio_remap(bio, disk_devt(mddev->gendisk), + bio_sector); + mddev_check_write_zeroes(mddev, bio); + submit_bio_noacct(bio); + } + return true; + +out_of_bounds: + pr_err("md/linear:%s: make_request: Sector %llu out of bounds on dev %pg: %llu sectors, offset %llu\n", + mdname(mddev), + (unsigned long long)bio->bi_iter.bi_sector, + tmp_dev->rdev->bdev, + (unsigned long long)tmp_dev->rdev->sectors, + (unsigned long long)start_sector); + bio_io_error(bio); + return true; +} + +static void linear_status(struct seq_file *seq, struct mddev *mddev) +{ + seq_printf(seq, " %dk rounding", mddev->chunk_sectors / 2); +} + +static void linear_error(struct mddev *mddev, struct md_rdev *rdev) +{ + if (!test_and_set_bit(MD_BROKEN, &mddev->flags)) { + char *md_name = mdname(mddev); + + pr_crit("md/linear%s: Disk failure on %pg detected, failing array.\n", + md_name, rdev->bdev); + } +} + +static void linear_quiesce(struct mddev *mddev, int state) +{ +} + +static struct md_personality linear_personality = { + .name = "linear", + .level = LEVEL_LINEAR, + .owner = THIS_MODULE, + .make_request = linear_make_request, + .run = linear_run, + .free = linear_free, + .status = linear_status, + .hot_add_disk = linear_add, + .size = linear_size, + .quiesce = linear_quiesce, + .error_handler = linear_error, +}; + +static int __init linear_init(void) +{ + return register_md_personality(&linear_personality); +} + +static void linear_exit(void) +{ + unregister_md_personality(&linear_personality); +} + +module_init(linear_init); +module_exit(linear_exit); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Linear device concatenation personality for MD (deprecated)"); +MODULE_ALIAS("md-personality-1"); /* LINEAR - deprecated*/ +MODULE_ALIAS("md-linear"); +MODULE_ALIAS("md-level--1"); diff --git a/drivers/md/md.c b/drivers/md/md.c index f0d007f967f1..465ca2af1e6e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -8124,7 +8124,7 @@ void md_error(struct mddev *mddev, struct md_rdev *rdev) return; mddev->pers->error_handler(mddev, rdev);
- if (mddev->pers->level == 0) + if (mddev->pers->level == 0 || mddev->pers->level == LEVEL_LINEAR) return;
if (mddev->degraded && !test_bit(MD_BROKEN, &mddev->flags)) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index e1ae0f9fad43..cb21df46bab1 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -3566,15 +3566,15 @@ static int ccs_probe(struct i2c_client *client) out_cleanup: ccs_cleanup(sensor);
+out_free_ccs_limits: + kfree(sensor->ccs_limits); + out_release_mdata: kvfree(sensor->mdata.backing);
out_release_sdata: kvfree(sensor->sdata.backing);
-out_free_ccs_limits: - kfree(sensor->ccs_limits); - out_power_off: ccs_power_off(&client->dev); mutex_destroy(&sensor->mutex); diff --git a/drivers/media/i2c/ccs/ccs-data.c b/drivers/media/i2c/ccs/ccs-data.c index 08400edf77ce..2591dba51e17 100644 --- a/drivers/media/i2c/ccs/ccs-data.c +++ b/drivers/media/i2c/ccs/ccs-data.c @@ -10,6 +10,7 @@ #include <linux/limits.h> #include <linux/mm.h> #include <linux/slab.h> +#include <linux/string.h>
#include "ccs-data-defs.h"
@@ -97,7 +98,7 @@ ccs_data_parse_length_specifier(const struct __ccs_data_length_specifier *__len, plen = ((size_t) (__len3->length[0] & ((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT) - 1)) - << 16) + (__len3->length[0] << 8) + __len3->length[1]; + << 16) + (__len3->length[1] << 8) + __len3->length[2]; break; } default: @@ -948,15 +949,15 @@ int ccs_data_parse(struct ccs_data_container *ccsdata, const void *data,
rval = __ccs_data_parse(&bin, ccsdata, data, len, dev, verbose); if (rval) - return rval; + goto out_cleanup;
rval = bin_backing_alloc(&bin); if (rval) - return rval; + goto out_cleanup;
rval = __ccs_data_parse(&bin, ccsdata, data, len, dev, false); if (rval) - goto out_free; + goto out_cleanup;
if (verbose && ccsdata->version) print_ccs_data_version(dev, ccsdata->version); @@ -965,15 +966,16 @@ int ccs_data_parse(struct ccs_data_container *ccsdata, const void *data, rval = -EPROTO; dev_dbg(dev, "parsing mismatch; base %p; now %p; end %p\n", bin.base, bin.now, bin.end); - goto out_free; + goto out_cleanup; }
ccsdata->backing = bin.base;
return 0;
-out_free: +out_cleanup: kvfree(bin.base); + memset(ccsdata, 0, sizeof(*ccsdata));
return rval; } diff --git a/drivers/media/i2c/ds90ub913.c b/drivers/media/i2c/ds90ub913.c index 79bddfee2e2e..9f01950a0ca3 100644 --- a/drivers/media/i2c/ds90ub913.c +++ b/drivers/media/i2c/ds90ub913.c @@ -793,7 +793,6 @@ static void ub913_subdev_uninit(struct ub913_data *priv) v4l2_async_unregister_subdev(&priv->sd); ub913_v4l2_nf_unregister(priv); v4l2_subdev_cleanup(&priv->sd); - fwnode_handle_put(priv->sd.fwnode); media_entity_cleanup(&priv->sd.entity); }
diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c index 725589b3e1c5..b27656f8d2b1 100644 --- a/drivers/media/i2c/ds90ub953.c +++ b/drivers/media/i2c/ds90ub953.c @@ -1288,7 +1288,6 @@ static void ub953_subdev_uninit(struct ub953_data *priv) v4l2_async_unregister_subdev(&priv->sd); ub953_v4l2_notifier_unregister(priv); v4l2_subdev_cleanup(&priv->sd); - fwnode_handle_put(priv->sd.fwnode); media_entity_cleanup(&priv->sd.entity); }
diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index 1b1ff7f7505b..d6b790ee08d6 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -351,6 +351,8 @@
#define UB960_SR_I2C_RX_ID(n) (0xf8 + (n)) /* < UB960_FPD_RX_NPORTS */
+#define UB9702_SR_REFCLK_FREQ 0x3d + /* Indirect register blocks */ #define UB960_IND_TARGET_PAT_GEN 0x00 #define UB960_IND_TARGET_RX_ANA(n) (0x01 + (n)) @@ -1574,16 +1576,24 @@ static int ub960_rxport_wait_locks(struct ub960_data *priv,
ub960_rxport_read16(priv, nport, UB960_RR_RX_FREQ_HIGH, &v);
- ret = ub960_rxport_get_strobe_pos(priv, nport, &strobe_pos); - if (ret) - return ret; + if (priv->hw_data->is_ub9702) { + dev_dbg(dev, "\trx%u: locked, freq %llu Hz\n", + nport, (v * 1000000ULL) >> 8); + } else { + ret = ub960_rxport_get_strobe_pos(priv, nport, + &strobe_pos); + if (ret) + return ret;
- ret = ub960_rxport_get_eq_level(priv, nport, &eq_level); - if (ret) - return ret; + ret = ub960_rxport_get_eq_level(priv, nport, &eq_level); + if (ret) + return ret;
- dev_dbg(dev, "\trx%u: locked, SP: %d, EQ: %u, freq %llu Hz\n", - nport, strobe_pos, eq_level, (v * 1000000ULL) >> 8); + dev_dbg(dev, + "\trx%u: locked, SP: %d, EQ: %u, freq %llu Hz\n", + nport, strobe_pos, eq_level, + (v * 1000000ULL) >> 8); + } }
return 0; @@ -2522,7 +2532,7 @@ static int ub960_configure_ports_for_streaming(struct ub960_data *priv, for (i = 0; i < 8; i++) ub960_rxport_write(priv, nport, UB960_RR_VC_ID_MAP(i), - nport); + (nport << 4) | nport); }
break; @@ -2939,6 +2949,54 @@ static const struct v4l2_subdev_pad_ops ub960_pad_ops = { .set_fmt = ub960_set_fmt, };
+static void ub960_log_status_ub960_sp_eq(struct ub960_data *priv, + unsigned int nport) +{ + struct device *dev = &priv->client->dev; + u8 eq_level; + s8 strobe_pos; + u8 v = 0; + + /* Strobe */ + + ub960_read(priv, UB960_XR_AEQ_CTL1, &v); + + dev_info(dev, "\t%s strobe\n", + (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) ? "Adaptive" : + "Manual"); + + if (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) { + ub960_read(priv, UB960_XR_SFILTER_CFG, &v); + + dev_info(dev, "\tStrobe range [%d, %d]\n", + ((v >> UB960_XR_SFILTER_CFG_SFILTER_MIN_SHIFT) & 0xf) - 7, + ((v >> UB960_XR_SFILTER_CFG_SFILTER_MAX_SHIFT) & 0xf) - 7); + } + + ub960_rxport_get_strobe_pos(priv, nport, &strobe_pos); + + dev_info(dev, "\tStrobe pos %d\n", strobe_pos); + + /* EQ */ + + ub960_rxport_read(priv, nport, UB960_RR_AEQ_BYPASS, &v); + + dev_info(dev, "\t%s EQ\n", + (v & UB960_RR_AEQ_BYPASS_ENABLE) ? "Manual" : + "Adaptive"); + + if (!(v & UB960_RR_AEQ_BYPASS_ENABLE)) { + ub960_rxport_read(priv, nport, UB960_RR_AEQ_MIN_MAX, &v); + + dev_info(dev, "\tEQ range [%u, %u]\n", + (v >> UB960_RR_AEQ_MIN_MAX_AEQ_FLOOR_SHIFT) & 0xf, + (v >> UB960_RR_AEQ_MIN_MAX_AEQ_MAX_SHIFT) & 0xf); + } + + if (ub960_rxport_get_eq_level(priv, nport, &eq_level) == 0) + dev_info(dev, "\tEQ level %u\n", eq_level); +} + static int ub960_log_status(struct v4l2_subdev *sd) { struct ub960_data *priv = sd_to_ub960(sd); @@ -2986,8 +3044,6 @@ static int ub960_log_status(struct v4l2_subdev *sd)
for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { struct ub960_rxport *rxport = priv->rxports[nport]; - u8 eq_level; - s8 strobe_pos; unsigned int i;
dev_info(dev, "RX %u\n", nport); @@ -3023,44 +3079,8 @@ static int ub960_log_status(struct v4l2_subdev *sd) ub960_rxport_read(priv, nport, UB960_RR_CSI_ERR_COUNTER, &v); dev_info(dev, "\tcsi_err_counter %u\n", v);
- /* Strobe */ - - ub960_read(priv, UB960_XR_AEQ_CTL1, &v); - - dev_info(dev, "\t%s strobe\n", - (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) ? "Adaptive" : - "Manual"); - - if (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) { - ub960_read(priv, UB960_XR_SFILTER_CFG, &v); - - dev_info(dev, "\tStrobe range [%d, %d]\n", - ((v >> UB960_XR_SFILTER_CFG_SFILTER_MIN_SHIFT) & 0xf) - 7, - ((v >> UB960_XR_SFILTER_CFG_SFILTER_MAX_SHIFT) & 0xf) - 7); - } - - ub960_rxport_get_strobe_pos(priv, nport, &strobe_pos); - - dev_info(dev, "\tStrobe pos %d\n", strobe_pos); - - /* EQ */ - - ub960_rxport_read(priv, nport, UB960_RR_AEQ_BYPASS, &v); - - dev_info(dev, "\t%s EQ\n", - (v & UB960_RR_AEQ_BYPASS_ENABLE) ? "Manual" : - "Adaptive"); - - if (!(v & UB960_RR_AEQ_BYPASS_ENABLE)) { - ub960_rxport_read(priv, nport, UB960_RR_AEQ_MIN_MAX, &v); - - dev_info(dev, "\tEQ range [%u, %u]\n", - (v >> UB960_RR_AEQ_MIN_MAX_AEQ_FLOOR_SHIFT) & 0xf, - (v >> UB960_RR_AEQ_MIN_MAX_AEQ_MAX_SHIFT) & 0xf); - } - - if (ub960_rxport_get_eq_level(priv, nport, &eq_level) == 0) - dev_info(dev, "\tEQ level %u\n", eq_level); + if (!priv->hw_data->is_ub9702) + ub960_log_status_ub960_sp_eq(priv, nport);
/* GPIOs */ for (i = 0; i < UB960_NUM_BC_GPIOS; i++) { @@ -3834,7 +3854,10 @@ static int ub960_enable_core_hw(struct ub960_data *priv) if (ret) goto err_pd_gpio;
- ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq); + if (priv->hw_data->is_ub9702) + ret = ub960_read(priv, UB9702_SR_REFCLK_FREQ, &refclk_freq); + else + ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq); if (ret) goto err_pd_gpio;
diff --git a/drivers/media/i2c/imx296.c b/drivers/media/i2c/imx296.c index 83149fa729c4..f3bec16b527c 100644 --- a/drivers/media/i2c/imx296.c +++ b/drivers/media/i2c/imx296.c @@ -954,6 +954,8 @@ static int imx296_identify_model(struct imx296 *sensor) return ret; }
+ usleep_range(2000, 5000); + ret = imx296_read(sensor, IMX296_SENSOR_INFO); if (ret < 0) { dev_err(sensor->dev, "failed to read sensor information (%d)\n", diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index da5cb5f45a4f..0dae0438aa80 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -1982,6 +1982,7 @@ static int ov5640_get_light_freq(struct ov5640_dev *sensor) light_freq = 50; } else { /* 60Hz */ + light_freq = 60; } }
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys.c b/drivers/media/pci/intel/ipu6/ipu6-isys.c index 77f9c7319868..8df1d83a74b5 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-isys.c +++ b/drivers/media/pci/intel/ipu6/ipu6-isys.c @@ -1133,6 +1133,7 @@ static int isys_probe(struct auxiliary_device *auxdev, free_fw_msg_bufs: free_fw_msg_bufs(isys); out_remove_pkg_dir_shared_buffer: + cpu_latency_qos_remove_request(&isys->pm_qos); if (!isp->secure_mode) ipu6_cpd_free_pkg_dir(adev); remove_shared_buffer: diff --git a/drivers/media/platform/marvell/mmp-driver.c b/drivers/media/platform/marvell/mmp-driver.c index 3fd4fc1b9c48..d3da7ebb4a2b 100644 --- a/drivers/media/platform/marvell/mmp-driver.c +++ b/drivers/media/platform/marvell/mmp-driver.c @@ -231,13 +231,23 @@ static int mmpcam_probe(struct platform_device *pdev)
mcam_init_clk(mcam);
+ /* + * Register with V4L. + */ + + ret = v4l2_device_register(mcam->dev, &mcam->v4l2_dev); + if (ret) + return ret; + /* * Create a match of the sensor against its OF node. */ ep = fwnode_graph_get_next_endpoint(of_fwnode_handle(pdev->dev.of_node), NULL); - if (!ep) - return -ENODEV; + if (!ep) { + ret = -ENODEV; + goto out_v4l2_device_unregister; + }
v4l2_async_nf_init(&mcam->notifier, &mcam->v4l2_dev);
@@ -246,7 +256,7 @@ static int mmpcam_probe(struct platform_device *pdev) fwnode_handle_put(ep); if (IS_ERR(asd)) { ret = PTR_ERR(asd); - goto out; + goto out_v4l2_device_unregister; }
/* @@ -254,7 +264,7 @@ static int mmpcam_probe(struct platform_device *pdev) */ ret = mccic_register(mcam); if (ret) - goto out; + goto out_v4l2_device_unregister;
/* * Add OF clock provider. @@ -283,6 +293,8 @@ static int mmpcam_probe(struct platform_device *pdev) return 0; out: mccic_shutdown(mcam); +out_v4l2_device_unregister: + v4l2_device_unregister(&mcam->v4l2_dev);
return ret; } @@ -293,6 +305,7 @@ static void mmpcam_remove(struct platform_device *pdev) struct mcam_camera *mcam = &cam->mcam;
mccic_shutdown(mcam); + v4l2_device_unregister(&mcam->v4l2_dev); pm_runtime_force_suspend(mcam->dev); }
diff --git a/drivers/media/platform/nuvoton/npcm-video.c b/drivers/media/platform/nuvoton/npcm-video.c index 4f5d75645b2b..024cd8ee1709 100644 --- a/drivers/media/platform/nuvoton/npcm-video.c +++ b/drivers/media/platform/nuvoton/npcm-video.c @@ -1665,9 +1665,9 @@ static int npcm_video_ece_init(struct npcm_video *video) dev_info(dev, "Support HEXTILE pixel format\n");
ece_pdev = of_find_device_by_node(ece_node); - if (IS_ERR(ece_pdev)) { + if (!ece_pdev) { dev_err(dev, "Failed to find ECE device\n"); - return PTR_ERR(ece_pdev); + return -ENODEV; } of_node_put(ece_node);
diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index 2d27c5167246..807487a1f536 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -506,18 +506,14 @@ static __maybe_unused int venus_runtime_suspend(struct device *dev) void venus_close_common(struct venus_inst *inst) { /* - * First, remove the inst from the ->instances list, so that - * to_instance() will return NULL. - */ - hfi_session_destroy(inst); - /* - * Second, make sure we don't have IRQ/IRQ-thread currently running + * Make sure we don't have IRQ/IRQ-thread currently running * or pending execution, which would race with the inst destruction. */ synchronize_irq(inst->core->irq);
v4l2_m2m_ctx_release(inst->m2m_ctx); v4l2_m2m_release(inst->m2m_dev); + hfi_session_destroy(inst); v4l2_fh_del(&inst->fh); v4l2_fh_exit(&inst->fh); v4l2_ctrl_handler_free(&inst->ctrl_handler); diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c index 7edd49bfe7e5..7f9fa79402df 100644 --- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c +++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c @@ -887,7 +887,7 @@ struct dcmipp_ent_device *dcmipp_bytecap_ent_init(struct device *dev, q->dev = dev;
/* DCMIPP requires 16 bytes aligned buffers */ - ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32) & ~0x0f); + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); if (ret) { dev_err(dev, "Failed to set DMA mask\n"); goto err_mutex_destroy; diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 4fe26e82e3d1..4837d8df9c03 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -1579,6 +1579,40 @@ static void uvc_ctrl_send_slave_event(struct uvc_video_chain *chain, uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes); }
+static void uvc_ctrl_set_handle(struct uvc_fh *handle, struct uvc_control *ctrl, + struct uvc_fh *new_handle) +{ + lockdep_assert_held(&handle->chain->ctrl_mutex); + + if (new_handle) { + if (ctrl->handle) + dev_warn_ratelimited(&handle->stream->dev->udev->dev, + "UVC non compliance: Setting an async control with a pending operation."); + + if (new_handle == ctrl->handle) + return; + + if (ctrl->handle) { + WARN_ON(!ctrl->handle->pending_async_ctrls); + if (ctrl->handle->pending_async_ctrls) + ctrl->handle->pending_async_ctrls--; + } + + ctrl->handle = new_handle; + handle->pending_async_ctrls++; + return; + } + + /* Cannot clear the handle for a control not owned by us.*/ + if (WARN_ON(ctrl->handle != handle)) + return; + + ctrl->handle = NULL; + if (WARN_ON(!handle->pending_async_ctrls)) + return; + handle->pending_async_ctrls--; +} + void uvc_ctrl_status_event(struct uvc_video_chain *chain, struct uvc_control *ctrl, const u8 *data) { @@ -1589,7 +1623,8 @@ void uvc_ctrl_status_event(struct uvc_video_chain *chain, mutex_lock(&chain->ctrl_mutex);
handle = ctrl->handle; - ctrl->handle = NULL; + if (handle) + uvc_ctrl_set_handle(handle, ctrl, NULL);
list_for_each_entry(mapping, &ctrl->info.mappings, list) { s32 value = __uvc_ctrl_get_value(mapping, data); @@ -1640,10 +1675,8 @@ bool uvc_ctrl_status_event_async(struct urb *urb, struct uvc_video_chain *chain, struct uvc_device *dev = chain->dev; struct uvc_ctrl_work *w = &dev->async_ctrl;
- if (list_empty(&ctrl->info.mappings)) { - ctrl->handle = NULL; + if (list_empty(&ctrl->info.mappings)) return false; - }
w->data = data; w->urb = urb; @@ -1673,13 +1706,13 @@ static void uvc_ctrl_send_events(struct uvc_fh *handle, { struct uvc_control_mapping *mapping; struct uvc_control *ctrl; - u32 changes = V4L2_EVENT_CTRL_CH_VALUE; unsigned int i; unsigned int j;
for (i = 0; i < xctrls_count; ++i) { - ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping); + u32 changes = V4L2_EVENT_CTRL_CH_VALUE;
+ ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping); if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) /* Notification will be sent from an Interrupt event. */ continue; @@ -1811,7 +1844,10 @@ int uvc_ctrl_begin(struct uvc_video_chain *chain) }
static int uvc_ctrl_commit_entity(struct uvc_device *dev, - struct uvc_entity *entity, int rollback, struct uvc_control **err_ctrl) + struct uvc_fh *handle, + struct uvc_entity *entity, + int rollback, + struct uvc_control **err_ctrl) { struct uvc_control *ctrl; unsigned int i; @@ -1859,6 +1895,10 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, *err_ctrl = ctrl; return ret; } + + if (!rollback && handle && + ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) + uvc_ctrl_set_handle(handle, ctrl, handle); }
return 0; @@ -1895,8 +1935,8 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
/* Find the control. */ list_for_each_entry(entity, &chain->entities, chain) { - ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback, - &err_ctrl); + ret = uvc_ctrl_commit_entity(chain->dev, handle, entity, + rollback, &err_ctrl); if (ret < 0) { if (ctrls) ctrls->error_idx = @@ -2046,9 +2086,6 @@ int uvc_ctrl_set(struct uvc_fh *handle, mapping->set(mapping, value, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
- if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) - ctrl->handle = handle; - ctrl->dirty = 1; ctrl->modified = 1; return 0; @@ -2377,7 +2414,7 @@ int uvc_ctrl_restore_values(struct uvc_device *dev) ctrl->dirty = 1; }
- ret = uvc_ctrl_commit_entity(dev, entity, 0, NULL); + ret = uvc_ctrl_commit_entity(dev, NULL, entity, 0, NULL); if (ret < 0) return ret; } @@ -2770,6 +2807,26 @@ int uvc_ctrl_init_device(struct uvc_device *dev) return 0; }
+void uvc_ctrl_cleanup_fh(struct uvc_fh *handle) +{ + struct uvc_entity *entity; + + guard(mutex)(&handle->chain->ctrl_mutex); + + if (!handle->pending_async_ctrls) + return; + + list_for_each_entry(entity, &handle->chain->dev->entities, list) { + for (unsigned int i = 0; i < entity->ncontrols; ++i) { + if (entity->controls[i].handle != handle) + continue; + uvc_ctrl_set_handle(handle, &entity->controls[i], NULL); + } + } + + WARN_ON(handle->pending_async_ctrls); +} + /* * Cleanup device controls. */ diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index b3c8411dc05c..31b4b54657fe 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -775,27 +775,14 @@ static const u8 uvc_media_transport_input_guid[16] = UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT; static const u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING;
-static struct uvc_entity *uvc_alloc_new_entity(struct uvc_device *dev, u16 type, - u16 id, unsigned int num_pads, - unsigned int extra_size) +static struct uvc_entity *uvc_alloc_entity(u16 type, u16 id, + unsigned int num_pads, unsigned int extra_size) { struct uvc_entity *entity; unsigned int num_inputs; unsigned int size; unsigned int i;
- /* Per UVC 1.1+ spec 3.7.2, the ID should be non-zero. */ - if (id == 0) { - dev_err(&dev->udev->dev, "Found Unit with invalid ID 0.\n"); - return ERR_PTR(-EINVAL); - } - - /* Per UVC 1.1+ spec 3.7.2, the ID is unique. */ - if (uvc_entity_by_id(dev, id)) { - dev_err(&dev->udev->dev, "Found multiple Units with ID %u\n", id); - return ERR_PTR(-EINVAL); - } - extra_size = roundup(extra_size, sizeof(*entity->pads)); if (num_pads) num_inputs = type & UVC_TERM_OUTPUT ? num_pads : num_pads - 1; @@ -805,7 +792,7 @@ static struct uvc_entity *uvc_alloc_new_entity(struct uvc_device *dev, u16 type, + num_inputs; entity = kzalloc(size, GFP_KERNEL); if (entity == NULL) - return ERR_PTR(-ENOMEM); + return NULL;
entity->id = id; entity->type = type; @@ -917,10 +904,10 @@ static int uvc_parse_vendor_control(struct uvc_device *dev, break; }
- unit = uvc_alloc_new_entity(dev, UVC_VC_EXTENSION_UNIT, - buffer[3], p + 1, 2 * n); - if (IS_ERR(unit)) - return PTR_ERR(unit); + unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3], + p + 1, 2*n); + if (unit == NULL) + return -ENOMEM;
memcpy(unit->guid, &buffer[4], 16); unit->extension.bNumControls = buffer[20]; @@ -1029,10 +1016,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev, return -EINVAL; }
- term = uvc_alloc_new_entity(dev, type | UVC_TERM_INPUT, - buffer[3], 1, n + p); - if (IS_ERR(term)) - return PTR_ERR(term); + term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3], + 1, n + p); + if (term == NULL) + return -ENOMEM;
if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) { term->camera.bControlSize = n; @@ -1088,10 +1075,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev, return 0; }
- term = uvc_alloc_new_entity(dev, type | UVC_TERM_OUTPUT, - buffer[3], 1, 0); - if (IS_ERR(term)) - return PTR_ERR(term); + term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3], + 1, 0); + if (term == NULL) + return -ENOMEM;
memcpy(term->baSourceID, &buffer[7], 1);
@@ -1110,10 +1097,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev, return -EINVAL; }
- unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], - p + 1, 0); - if (IS_ERR(unit)) - return PTR_ERR(unit); + unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0); + if (unit == NULL) + return -ENOMEM;
memcpy(unit->baSourceID, &buffer[5], p);
@@ -1133,9 +1119,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev, return -EINVAL; }
- unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], 2, n); - if (IS_ERR(unit)) - return PTR_ERR(unit); + unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n); + if (unit == NULL) + return -ENOMEM;
memcpy(unit->baSourceID, &buffer[4], 1); unit->processing.wMaxMultiplier = @@ -1162,10 +1148,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev, return -EINVAL; }
- unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], - p + 1, n); - if (IS_ERR(unit)) - return PTR_ERR(unit); + unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n); + if (unit == NULL) + return -ENOMEM;
memcpy(unit->guid, &buffer[4], 16); unit->extension.bNumControls = buffer[20]; @@ -1295,20 +1280,19 @@ static int uvc_gpio_parse(struct uvc_device *dev) struct gpio_desc *gpio_privacy; int irq;
- gpio_privacy = devm_gpiod_get_optional(&dev->udev->dev, "privacy", + gpio_privacy = devm_gpiod_get_optional(&dev->intf->dev, "privacy", GPIOD_IN); if (IS_ERR_OR_NULL(gpio_privacy)) return PTR_ERR_OR_ZERO(gpio_privacy);
irq = gpiod_to_irq(gpio_privacy); if (irq < 0) - return dev_err_probe(&dev->udev->dev, irq, + return dev_err_probe(&dev->intf->dev, irq, "No IRQ for privacy GPIO\n");
- unit = uvc_alloc_new_entity(dev, UVC_EXT_GPIO_UNIT, - UVC_EXT_GPIO_UNIT_ID, 0, 1); - if (IS_ERR(unit)) - return PTR_ERR(unit); + unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1); + if (!unit) + return -ENOMEM;
unit->gpio.gpio_privacy = gpio_privacy; unit->gpio.irq = irq; @@ -1329,15 +1313,27 @@ static int uvc_gpio_parse(struct uvc_device *dev) static int uvc_gpio_init_irq(struct uvc_device *dev) { struct uvc_entity *unit = dev->gpio_unit; + int ret;
if (!unit || unit->gpio.irq < 0) return 0;
- return devm_request_threaded_irq(&dev->udev->dev, unit->gpio.irq, NULL, - uvc_gpio_irq, - IRQF_ONESHOT | IRQF_TRIGGER_FALLING | - IRQF_TRIGGER_RISING, - "uvc_privacy_gpio", dev); + ret = request_threaded_irq(unit->gpio.irq, NULL, uvc_gpio_irq, + IRQF_ONESHOT | IRQF_TRIGGER_FALLING | + IRQF_TRIGGER_RISING, + "uvc_privacy_gpio", dev); + + unit->gpio.initialized = !ret; + + return ret; +} + +static void uvc_gpio_deinit(struct uvc_device *dev) +{ + if (!dev->gpio_unit || !dev->gpio_unit->gpio.initialized) + return; + + free_irq(dev->gpio_unit->gpio.irq, dev); }
/* ------------------------------------------------------------------------ @@ -1934,6 +1930,8 @@ static void uvc_unregister_video(struct uvc_device *dev) { struct uvc_streaming *stream;
+ uvc_gpio_deinit(dev); + list_for_each_entry(stream, &dev->streams, list) { /* Nothing to do here, continue. */ if (!video_is_registered(&stream->vdev)) diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 97c5407f6603..b425306a3b8c 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -652,6 +652,8 @@ static int uvc_v4l2_release(struct file *file)
uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
+ uvc_ctrl_cleanup_fh(handle); + /* Only free resources if this is a privileged handle. */ if (uvc_has_privileges(handle)) uvc_queue_release(&stream->queue); diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index e00f38dd07d9..d2fe01bcd209 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -79,6 +79,27 @@ int uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit, if (likely(ret == size)) return 0;
+ /* + * Some devices return shorter USB control packets than expected if the + * returned value can fit in less bytes. Zero all the bytes that the + * device has not written. + * + * This quirk is applied to all controls, regardless of their data type. + * Most controls are little-endian integers, in which case the missing + * bytes become 0 MSBs. For other data types, a different heuristic + * could be implemented if a device is found needing it. + * + * We exclude UVC_GET_INFO from the quirk. UVC_GET_LEN does not need + * to be excluded because its size is always 1. + */ + if (ret > 0 && query != UVC_GET_INFO) { + memset(data + ret, 0, size - ret); + dev_warn_once(&dev->udev->dev, + "UVC non compliance: %s control %u on unit %u returned %d bytes when we expected %u.\n", + uvc_query_name(query), cs, unit, ret, size); + return 0; + } + if (ret != -EPIPE) { dev_err(&dev->udev->dev, "Failed to query (%s) UVC control %u on unit %u: %d (exp. %u).\n", diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 07f9921d83f2..5690cfd61e23 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -234,6 +234,7 @@ struct uvc_entity { u8 *bmControls; struct gpio_desc *gpio_privacy; int irq; + bool initialized; } gpio; };
@@ -337,7 +338,11 @@ struct uvc_video_chain { struct uvc_entity *processing; /* Processing unit */ struct uvc_entity *selector; /* Selector unit */
- struct mutex ctrl_mutex; /* Protects ctrl.info */ + struct mutex ctrl_mutex; /* + * Protects ctrl.info, + * ctrl.handle and + * uvc_fh.pending_async_ctrls + */
struct v4l2_prio_state prio; /* V4L2 priority state */ u32 caps; /* V4L2 chain-wide caps */ @@ -612,6 +617,7 @@ struct uvc_fh { struct uvc_video_chain *chain; struct uvc_streaming *stream; enum uvc_handle_state state; + unsigned int pending_async_ctrls; };
struct uvc_driver { @@ -797,6 +803,8 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id, int uvc_xu_ctrl_query(struct uvc_video_chain *chain, struct uvc_xu_control_query *xqry);
+void uvc_ctrl_cleanup_fh(struct uvc_fh *handle); + /* Utility functions */ struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts, u8 epaddr); diff --git a/drivers/media/v4l2-core/v4l2-mc.c b/drivers/media/v4l2-core/v4l2-mc.c index 4bb91359e3a9..937d358697e1 100644 --- a/drivers/media/v4l2-core/v4l2-mc.c +++ b/drivers/media/v4l2-core/v4l2-mc.c @@ -329,7 +329,7 @@ int v4l2_create_fwnode_links_to_pad(struct v4l2_subdev *src_sd, if (!(sink->flags & MEDIA_PAD_FL_SINK)) return -EINVAL;
- fwnode_graph_for_each_endpoint(dev_fwnode(src_sd->dev), endpoint) { + fwnode_graph_for_each_endpoint(src_sd->fwnode, endpoint) { struct fwnode_handle *remote_ep; int src_idx, sink_idx, ret; struct media_pad *src; diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index 251465a656d0..bce85a58944a 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -1445,7 +1445,7 @@ int axp20x_device_probe(struct axp20x_dev *axp20x) } }
- ret = mfd_add_devices(axp20x->dev, PLATFORM_DEVID_AUTO, axp20x->cells, + ret = mfd_add_devices(axp20x->dev, PLATFORM_DEVID_NONE, axp20x->cells, axp20x->nr_cells, NULL, 0, NULL);
if (ret) { diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c index f14901660147..4b7d0cb9340f 100644 --- a/drivers/mfd/lpc_ich.c +++ b/drivers/mfd/lpc_ich.c @@ -834,8 +834,9 @@ static const struct pci_device_id lpc_ich_ids[] = { { PCI_VDEVICE(INTEL, 0x2917), LPC_ICH9ME}, { PCI_VDEVICE(INTEL, 0x2918), LPC_ICH9}, { PCI_VDEVICE(INTEL, 0x2919), LPC_ICH9M}, - { PCI_VDEVICE(INTEL, 0x3197), LPC_GLK}, { PCI_VDEVICE(INTEL, 0x2b9c), LPC_COUGARMOUNTAIN}, + { PCI_VDEVICE(INTEL, 0x3197), LPC_GLK}, + { PCI_VDEVICE(INTEL, 0x31e8), LPC_GLK}, { PCI_VDEVICE(INTEL, 0x3a14), LPC_ICH10DO}, { PCI_VDEVICE(INTEL, 0x3a16), LPC_ICH10R}, { PCI_VDEVICE(INTEL, 0x3a18), LPC_ICH10}, diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 48d08eeb2d20..d1188cd12ec6 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -992,7 +992,7 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) mmap_read_lock(current->mm); vma = find_vma(current->mm, ctx->args[i].ptr); if (vma) - pages[i].addr += ctx->args[i].ptr - + pages[i].addr += (ctx->args[i].ptr & PAGE_MASK) - vma->vm_start; mmap_read_unlock(current->mm);
@@ -1019,8 +1019,8 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) (pkt_size - rlen); pages[i].addr = pages[i].addr & PAGE_MASK;
- pg_start = (args & PAGE_MASK) >> PAGE_SHIFT; - pg_end = ((args + len - 1) & PAGE_MASK) >> PAGE_SHIFT; + pg_start = (rpra[i].buf.pv & PAGE_MASK) >> PAGE_SHIFT; + pg_end = ((rpra[i].buf.pv + len - 1) & PAGE_MASK) >> PAGE_SHIFT; pages[i].size = (pg_end - pg_start + 1) * PAGE_SIZE; args = args + mlen; rlen -= mlen; @@ -2344,7 +2344,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
err = fastrpc_device_register(rdev, data, false, domains[domain_id]); if (err) - goto fdev_error; + goto populate_error; break; default: err = -EINVAL; diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 9566837c9848..4b19b8a16b09 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -458,6 +458,8 @@ static unsigned mmc_sdio_get_max_clock(struct mmc_card *card) if (mmc_card_sd_combo(card)) max_dtr = min(max_dtr, mmc_sd_get_max_clock(card));
+ max_dtr = min_not_zero(max_dtr, card->quirk_max_rate); + return max_dtr; }
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index d55d045ef236..e23177ea9d91 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -304,6 +304,7 @@ static struct esdhc_soc_data usdhc_s32g2_data = { | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES | ESDHC_FLAG_SKIP_ERR004536 | ESDHC_FLAG_SKIP_CD_WAKE, + .quirks = SDHCI_QUIRK_NO_LED, };
static struct esdhc_soc_data usdhc_imx7ulp_data = { diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 319f0ebbe652..1fcaaf683d68 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -134,9 +134,18 @@ /* Timeout value to avoid infinite waiting for pwr_irq */ #define MSM_PWR_IRQ_TIMEOUT_MS 5000
+/* Max load for eMMC Vdd supply */ +#define MMC_VMMC_MAX_LOAD_UA 570000 + /* Max load for eMMC Vdd-io supply */ #define MMC_VQMMC_MAX_LOAD_UA 325000
+/* Max load for SD Vdd supply */ +#define SD_VMMC_MAX_LOAD_UA 800000 + +/* Max load for SD Vdd-io supply */ +#define SD_VQMMC_MAX_LOAD_UA 22000 + #define msm_host_readl(msm_host, host, offset) \ msm_host->var_ops->msm_readl_relaxed(host, offset)
@@ -1403,11 +1412,48 @@ static int sdhci_msm_set_pincfg(struct sdhci_msm_host *msm_host, bool level) return ret; }
-static int sdhci_msm_set_vmmc(struct mmc_host *mmc) +static void msm_config_vmmc_regulator(struct mmc_host *mmc, bool hpm) +{ + int load; + + if (!hpm) + load = 0; + else if (!mmc->card) + load = max(MMC_VMMC_MAX_LOAD_UA, SD_VMMC_MAX_LOAD_UA); + else if (mmc_card_mmc(mmc->card)) + load = MMC_VMMC_MAX_LOAD_UA; + else if (mmc_card_sd(mmc->card)) + load = SD_VMMC_MAX_LOAD_UA; + else + return; + + regulator_set_load(mmc->supply.vmmc, load); +} + +static void msm_config_vqmmc_regulator(struct mmc_host *mmc, bool hpm) +{ + int load; + + if (!hpm) + load = 0; + else if (!mmc->card) + load = max(MMC_VQMMC_MAX_LOAD_UA, SD_VQMMC_MAX_LOAD_UA); + else if (mmc_card_sd(mmc->card)) + load = SD_VQMMC_MAX_LOAD_UA; + else + return; + + regulator_set_load(mmc->supply.vqmmc, load); +} + +static int sdhci_msm_set_vmmc(struct sdhci_msm_host *msm_host, + struct mmc_host *mmc, bool hpm) { if (IS_ERR(mmc->supply.vmmc)) return 0;
+ msm_config_vmmc_regulator(mmc, hpm); + return mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, mmc->ios.vdd); }
@@ -1420,6 +1466,8 @@ static int msm_toggle_vqmmc(struct sdhci_msm_host *msm_host, if (msm_host->vqmmc_enabled == level) return 0;
+ msm_config_vqmmc_regulator(mmc, level); + if (level) { /* Set the IO voltage regulator to default voltage level */ if (msm_host->caps_0 & CORE_3_0V_SUPPORT) @@ -1642,7 +1690,8 @@ static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq) }
if (pwr_state) { - ret = sdhci_msm_set_vmmc(mmc); + ret = sdhci_msm_set_vmmc(msm_host, mmc, + pwr_state & REQ_BUS_ON); if (!ret) ret = sdhci_msm_set_vqmmc(msm_host, mmc, pwr_state & REQ_BUS_ON); diff --git a/drivers/mtd/nand/onenand/onenand_base.c b/drivers/mtd/nand/onenand/onenand_base.c index f66385faf631..0dc2ea4fc857 100644 --- a/drivers/mtd/nand/onenand/onenand_base.c +++ b/drivers/mtd/nand/onenand/onenand_base.c @@ -2923,6 +2923,7 @@ static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len, ret = ONENAND_IS_4KB_PAGE(this) ? onenand_mlc_read_ops_nolock(mtd, from, &ops) : onenand_read_ops_nolock(mtd, from, &ops); + *retlen = ops.retlen;
/* Exit OTP access mode */ this->command(mtd, ONENAND_CMD_RESET, 0, 0); diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 30be4ed68fad..ef6a22f372f9 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -1537,7 +1537,7 @@ static int ubi_mtd_param_parse(const char *val, const struct kernel_param *kp) if (token) { int err = kstrtoint(token, 10, &p->ubi_num);
- if (err) { + if (err || p->ubi_num < UBI_DEV_NUM_AUTO) { pr_err("UBI error: bad value for ubi_num parameter: %s\n", token); return -EINVAL; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index fe0e3e2a8117..71e50fc65c14 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c @@ -1441,7 +1441,9 @@ void aq_nic_deinit(struct aq_nic_s *self, bool link_down) aq_ptp_ring_free(self); aq_ptp_free(self);
- if (likely(self->aq_fw_ops->deinit) && link_down) { + /* May be invoked during hot unplug. */ + if (pci_device_is_present(self->pdev) && + likely(self->aq_fw_ops->deinit) && link_down) { mutex_lock(&self->fwreq_mutex); self->aq_fw_ops->deinit(self->aq_hw); mutex_unlock(&self->fwreq_mutex); diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c index 0715ea5bf13e..3b082114f2e5 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c @@ -41,9 +41,12 @@ void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct bcmgenet_priv *priv = netdev_priv(dev); struct device *kdev = &priv->pdev->dev; + u32 phy_wolopts = 0;
- if (dev->phydev) + if (dev->phydev) { phy_ethtool_get_wol(dev->phydev, wol); + phy_wolopts = wol->wolopts; + }
/* MAC is not wake-up capable, return what the PHY does */ if (!device_can_wakeup(kdev)) @@ -51,9 +54,14 @@ void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
/* Overlay MAC capabilities with that of the PHY queried before */ wol->supported |= WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER; - wol->wolopts = priv->wolopts; - memset(wol->sopass, 0, sizeof(wol->sopass)); + wol->wolopts |= priv->wolopts;
+ /* Return the PHY configured magic password */ + if (phy_wolopts & WAKE_MAGICSECURE) + return; + + /* Otherwise the MAC one */ + memset(wol->sopass, 0, sizeof(wol->sopass)); if (wol->wolopts & WAKE_MAGICSECURE) memcpy(wol->sopass, priv->sopass, sizeof(priv->sopass)); } @@ -70,7 +78,7 @@ int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) /* Try Wake-on-LAN from the PHY first */ if (dev->phydev) { ret = phy_ethtool_set_wol(dev->phydev, wol); - if (ret != -EOPNOTSUPP) + if (ret != -EOPNOTSUPP && wol->wolopts) return ret; }
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 9cc8db10a8d6..5ba22fe0995f 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -55,6 +55,7 @@ #include <linux/hwmon.h> #include <linux/hwmon-sysfs.h> #include <linux/crc32poly.h> +#include <linux/dmi.h>
#include <net/checksum.h> #include <net/gso.h> @@ -18192,6 +18193,50 @@ static int tg3_resume(struct device *device)
static SIMPLE_DEV_PM_OPS(tg3_pm_ops, tg3_suspend, tg3_resume);
+/* Systems where ACPI _PTS (Prepare To Sleep) S5 will result in a fatal + * PCIe AER event on the tg3 device if the tg3 device is not, or cannot + * be, powered down. + */ +static const struct dmi_system_id tg3_restart_aer_quirk_table[] = { + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R440"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R540"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R640"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R650"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R740"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R750"), + }, + }, + {} +}; + static void tg3_shutdown(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); @@ -18208,6 +18253,19 @@ static void tg3_shutdown(struct pci_dev *pdev)
if (system_state == SYSTEM_POWER_OFF) tg3_power_down(tp); + else if (system_state == SYSTEM_RESTART && + dmi_first_match(tg3_restart_aer_quirk_table) && + pdev->current_state != PCI_D3cold && + pdev->current_state != PCI_UNKNOWN) { + /* Disable PCIe AER on the tg3 to avoid a fatal + * error during this system restart. + */ + pcie_capability_clear_word(pdev, PCI_EXP_DEVCTL, + PCI_EXP_DEVCTL_CERE | + PCI_EXP_DEVCTL_NFERE | + PCI_EXP_DEVCTL_FERE | + PCI_EXP_DEVCTL_URRE); + }
rtnl_unlock();
diff --git a/drivers/net/ethernet/intel/ice/devlink/devlink.c b/drivers/net/ethernet/intel/ice/devlink/devlink.c index 415445cefdb2..b1efd287b330 100644 --- a/drivers/net/ethernet/intel/ice/devlink/devlink.c +++ b/drivers/net/ethernet/intel/ice/devlink/devlink.c @@ -977,6 +977,9 @@ static int ice_devlink_rate_node_new(struct devlink_rate *rate_node, void **priv
/* preallocate memory for ice_sched_node */ node = devm_kzalloc(ice_hw_to_dev(pi->hw), sizeof(*node), GFP_KERNEL); + if (!node) + return -ENOMEM; + *priv = node;
return 0; diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c index 5d2d7736fd5f..9c9ea4c1b93b 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.c +++ b/drivers/net/ethernet/intel/ice/ice_txrx.c @@ -527,15 +527,14 @@ int ice_setup_rx_ring(struct ice_rx_ring *rx_ring) * @xdp: xdp_buff used as input to the XDP program * @xdp_prog: XDP program to run * @xdp_ring: ring to be used for XDP_TX action - * @rx_buf: Rx buffer to store the XDP action * @eop_desc: Last descriptor in packet to read metadata from * * Returns any of ICE_XDP_{PASS, CONSUMED, TX, REDIR} */ -static void +static u32 ice_run_xdp(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp, struct bpf_prog *xdp_prog, struct ice_tx_ring *xdp_ring, - struct ice_rx_buf *rx_buf, union ice_32b_rx_flex_desc *eop_desc) + union ice_32b_rx_flex_desc *eop_desc) { unsigned int ret = ICE_XDP_PASS; u32 act; @@ -574,7 +573,7 @@ ice_run_xdp(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp, ret = ICE_XDP_CONSUMED; } exit: - ice_set_rx_bufs_act(xdp, rx_ring, ret); + return ret; }
/** @@ -860,10 +859,8 @@ ice_add_xdp_frag(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp, xdp_buff_set_frags_flag(xdp); }
- if (unlikely(sinfo->nr_frags == MAX_SKB_FRAGS)) { - ice_set_rx_bufs_act(xdp, rx_ring, ICE_XDP_CONSUMED); + if (unlikely(sinfo->nr_frags == MAX_SKB_FRAGS)) return -ENOMEM; - }
__skb_fill_page_desc_noacc(sinfo, sinfo->nr_frags++, rx_buf->page, rx_buf->page_offset, size); @@ -924,7 +921,6 @@ ice_get_rx_buf(struct ice_rx_ring *rx_ring, const unsigned int size, struct ice_rx_buf *rx_buf;
rx_buf = &rx_ring->rx_buf[ntc]; - rx_buf->pgcnt = page_count(rx_buf->page); prefetchw(rx_buf->page);
if (!size) @@ -940,6 +936,31 @@ ice_get_rx_buf(struct ice_rx_ring *rx_ring, const unsigned int size, return rx_buf; }
+/** + * ice_get_pgcnts - grab page_count() for gathered fragments + * @rx_ring: Rx descriptor ring to store the page counts on + * + * This function is intended to be called right before running XDP + * program so that the page recycling mechanism will be able to take + * a correct decision regarding underlying pages; this is done in such + * way as XDP program can change the refcount of page + */ +static void ice_get_pgcnts(struct ice_rx_ring *rx_ring) +{ + u32 nr_frags = rx_ring->nr_frags + 1; + u32 idx = rx_ring->first_desc; + struct ice_rx_buf *rx_buf; + u32 cnt = rx_ring->count; + + for (int i = 0; i < nr_frags; i++) { + rx_buf = &rx_ring->rx_buf[idx]; + rx_buf->pgcnt = page_count(rx_buf->page); + + if (++idx == cnt) + idx = 0; + } +} + /** * ice_build_skb - Build skb around an existing buffer * @rx_ring: Rx descriptor ring to transact packets on @@ -1051,12 +1072,12 @@ ice_construct_skb(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp) rx_buf->page_offset + headlen, size, xdp->frame_sz); } else { - /* buffer is unused, change the act that should be taken later - * on; data was copied onto skb's linear part so there's no + /* buffer is unused, restore biased page count in Rx buffer; + * data was copied onto skb's linear part so there's no * need for adjusting page offset and we can reuse this buffer * as-is */ - rx_buf->act = ICE_SKB_CONSUMED; + rx_buf->pagecnt_bias++; }
if (unlikely(xdp_buff_has_frags(xdp))) { @@ -1103,6 +1124,65 @@ ice_put_rx_buf(struct ice_rx_ring *rx_ring, struct ice_rx_buf *rx_buf) rx_buf->page = NULL; }
+/** + * ice_put_rx_mbuf - ice_put_rx_buf() caller, for all frame frags + * @rx_ring: Rx ring with all the auxiliary data + * @xdp: XDP buffer carrying linear + frags part + * @xdp_xmit: XDP_TX/XDP_REDIRECT verdict storage + * @ntc: a current next_to_clean value to be stored at rx_ring + * @verdict: return code from XDP program execution + * + * Walk through gathered fragments and satisfy internal page + * recycle mechanism; we take here an action related to verdict + * returned by XDP program; + */ +static void ice_put_rx_mbuf(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp, + u32 *xdp_xmit, u32 ntc, u32 verdict) +{ + u32 nr_frags = rx_ring->nr_frags + 1; + u32 idx = rx_ring->first_desc; + u32 cnt = rx_ring->count; + u32 post_xdp_frags = 1; + struct ice_rx_buf *buf; + int i; + + if (unlikely(xdp_buff_has_frags(xdp))) + post_xdp_frags += xdp_get_shared_info_from_buff(xdp)->nr_frags; + + for (i = 0; i < post_xdp_frags; i++) { + buf = &rx_ring->rx_buf[idx]; + + if (verdict & (ICE_XDP_TX | ICE_XDP_REDIR)) { + ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz); + *xdp_xmit |= verdict; + } else if (verdict & ICE_XDP_CONSUMED) { + buf->pagecnt_bias++; + } else if (verdict == ICE_XDP_PASS) { + ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz); + } + + ice_put_rx_buf(rx_ring, buf); + + if (++idx == cnt) + idx = 0; + } + /* handle buffers that represented frags released by XDP prog; + * for these we keep pagecnt_bias as-is; refcount from struct page + * has been decremented within XDP prog and we do not have to increase + * the biased refcnt + */ + for (; i < nr_frags; i++) { + buf = &rx_ring->rx_buf[idx]; + ice_put_rx_buf(rx_ring, buf); + if (++idx == cnt) + idx = 0; + } + + xdp->data = NULL; + rx_ring->first_desc = ntc; + rx_ring->nr_frags = 0; +} + /** * ice_clean_rx_irq - Clean completed descriptors from Rx ring - bounce buf * @rx_ring: Rx descriptor ring to transact packets on @@ -1120,15 +1200,13 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget) unsigned int total_rx_bytes = 0, total_rx_pkts = 0; unsigned int offset = rx_ring->rx_offset; struct xdp_buff *xdp = &rx_ring->xdp; - u32 cached_ntc = rx_ring->first_desc; struct ice_tx_ring *xdp_ring = NULL; struct bpf_prog *xdp_prog = NULL; u32 ntc = rx_ring->next_to_clean; + u32 cached_ntu, xdp_verdict; u32 cnt = rx_ring->count; u32 xdp_xmit = 0; - u32 cached_ntu; bool failure; - u32 first;
xdp_prog = READ_ONCE(rx_ring->xdp_prog); if (xdp_prog) { @@ -1190,6 +1268,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget) xdp_prepare_buff(xdp, hard_start, offset, size, !!offset); xdp_buff_clear_frags_flag(xdp); } else if (ice_add_xdp_frag(rx_ring, xdp, rx_buf, size)) { + ice_put_rx_mbuf(rx_ring, xdp, NULL, ntc, ICE_XDP_CONSUMED); break; } if (++ntc == cnt) @@ -1199,15 +1278,15 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget) if (ice_is_non_eop(rx_ring, rx_desc)) continue;
- ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_buf, rx_desc); - if (rx_buf->act == ICE_XDP_PASS) + ice_get_pgcnts(rx_ring); + xdp_verdict = ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_desc); + if (xdp_verdict == ICE_XDP_PASS) goto construct_skb; total_rx_bytes += xdp_get_buff_len(xdp); total_rx_pkts++;
- xdp->data = NULL; - rx_ring->first_desc = ntc; - rx_ring->nr_frags = 0; + ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict); + continue; construct_skb: if (likely(ice_ring_uses_build_skb(rx_ring))) @@ -1217,18 +1296,12 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget) /* exit if we failed to retrieve a buffer */ if (!skb) { rx_ring->ring_stats->rx_stats.alloc_page_failed++; - rx_buf->act = ICE_XDP_CONSUMED; - if (unlikely(xdp_buff_has_frags(xdp))) - ice_set_rx_bufs_act(xdp, rx_ring, - ICE_XDP_CONSUMED); - xdp->data = NULL; - rx_ring->first_desc = ntc; - rx_ring->nr_frags = 0; - break; + xdp_verdict = ICE_XDP_CONSUMED; } - xdp->data = NULL; - rx_ring->first_desc = ntc; - rx_ring->nr_frags = 0; + ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict); + + if (!skb) + break;
stat_err_bits = BIT(ICE_RX_FLEX_DESC_STATUS0_RXE_S); if (unlikely(ice_test_staterr(rx_desc->wb.status_error0, @@ -1257,23 +1330,6 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget) total_rx_pkts++; }
- first = rx_ring->first_desc; - while (cached_ntc != first) { - struct ice_rx_buf *buf = &rx_ring->rx_buf[cached_ntc]; - - if (buf->act & (ICE_XDP_TX | ICE_XDP_REDIR)) { - ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz); - xdp_xmit |= buf->act; - } else if (buf->act & ICE_XDP_CONSUMED) { - buf->pagecnt_bias++; - } else if (buf->act == ICE_XDP_PASS) { - ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz); - } - - ice_put_rx_buf(rx_ring, buf); - if (++cached_ntc >= cnt) - cached_ntc = 0; - } rx_ring->next_to_clean = ntc; /* return up to cleaned_count buffers to hardware */ failure = ice_alloc_rx_bufs(rx_ring, ICE_RX_DESC_UNUSED(rx_ring)); diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h index cb347c852ba9..806bce701df3 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.h +++ b/drivers/net/ethernet/intel/ice/ice_txrx.h @@ -201,7 +201,6 @@ struct ice_rx_buf { struct page *page; unsigned int page_offset; unsigned int pgcnt; - unsigned int act; unsigned int pagecnt_bias; };
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx_lib.h b/drivers/net/ethernet/intel/ice/ice_txrx_lib.h index 79f960c6680d..6cf32b404127 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx_lib.h +++ b/drivers/net/ethernet/intel/ice/ice_txrx_lib.h @@ -5,49 +5,6 @@ #define _ICE_TXRX_LIB_H_ #include "ice.h"
-/** - * ice_set_rx_bufs_act - propagate Rx buffer action to frags - * @xdp: XDP buffer representing frame (linear and frags part) - * @rx_ring: Rx ring struct - * act: action to store onto Rx buffers related to XDP buffer parts - * - * Set action that should be taken before putting Rx buffer from first frag - * to the last. - */ -static inline void -ice_set_rx_bufs_act(struct xdp_buff *xdp, const struct ice_rx_ring *rx_ring, - const unsigned int act) -{ - u32 sinfo_frags = xdp_get_shared_info_from_buff(xdp)->nr_frags; - u32 nr_frags = rx_ring->nr_frags + 1; - u32 idx = rx_ring->first_desc; - u32 cnt = rx_ring->count; - struct ice_rx_buf *buf; - - for (int i = 0; i < nr_frags; i++) { - buf = &rx_ring->rx_buf[idx]; - buf->act = act; - - if (++idx == cnt) - idx = 0; - } - - /* adjust pagecnt_bias on frags freed by XDP prog */ - if (sinfo_frags < rx_ring->nr_frags && act == ICE_XDP_CONSUMED) { - u32 delta = rx_ring->nr_frags - sinfo_frags; - - while (delta) { - if (idx == 0) - idx = cnt - 1; - else - idx--; - buf = &rx_ring->rx_buf[idx]; - buf->pagecnt_bias--; - delta--; - } - } -} - /** * ice_test_staterr - tests bits in Rx descriptor status and error fields * @status_err_n: Rx descriptor status_error0 or status_error1 bits diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c b/drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c index 4f4d58189118..a88c006ea65b 100644 --- a/drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c @@ -150,17 +150,14 @@ octep_get_ethtool_stats(struct net_device *netdev, iface_rx_stats, iface_tx_stats);
- for (q = 0; q < oct->num_oqs; q++) { - struct octep_iq *iq = oct->iq[q]; - struct octep_oq *oq = oct->oq[q]; - - tx_packets += iq->stats.instr_completed; - tx_bytes += iq->stats.bytes_sent; - tx_busy_errors += iq->stats.tx_busy; - - rx_packets += oq->stats.packets; - rx_bytes += oq->stats.bytes; - rx_alloc_errors += oq->stats.alloc_failures; + for (q = 0; q < OCTEP_MAX_QUEUES; q++) { + tx_packets += oct->stats_iq[q].instr_completed; + tx_bytes += oct->stats_iq[q].bytes_sent; + tx_busy_errors += oct->stats_iq[q].tx_busy; + + rx_packets += oct->stats_oq[q].packets; + rx_bytes += oct->stats_oq[q].bytes; + rx_alloc_errors += oct->stats_oq[q].alloc_failures; } i = 0; data[i++] = rx_packets; @@ -198,22 +195,18 @@ octep_get_ethtool_stats(struct net_device *netdev, data[i++] = iface_rx_stats->err_pkts;
/* Per Tx Queue stats */ - for (q = 0; q < oct->num_iqs; q++) { - struct octep_iq *iq = oct->iq[q]; - - data[i++] = iq->stats.instr_posted; - data[i++] = iq->stats.instr_completed; - data[i++] = iq->stats.bytes_sent; - data[i++] = iq->stats.tx_busy; + for (q = 0; q < OCTEP_MAX_QUEUES; q++) { + data[i++] = oct->stats_iq[q].instr_posted; + data[i++] = oct->stats_iq[q].instr_completed; + data[i++] = oct->stats_iq[q].bytes_sent; + data[i++] = oct->stats_iq[q].tx_busy; }
/* Per Rx Queue stats */ - for (q = 0; q < oct->num_oqs; q++) { - struct octep_oq *oq = oct->oq[q]; - - data[i++] = oq->stats.packets; - data[i++] = oq->stats.bytes; - data[i++] = oq->stats.alloc_failures; + for (q = 0; q < OCTEP_MAX_QUEUES; q++) { + data[i++] = oct->stats_oq[q].packets; + data[i++] = oct->stats_oq[q].bytes; + data[i++] = oct->stats_oq[q].alloc_failures; } }
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c index 730aa5632cce..a89f80bac39b 100644 --- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c @@ -822,7 +822,7 @@ static inline int octep_iq_full_check(struct octep_iq *iq) if (unlikely(IQ_INSTR_SPACE(iq) > OCTEP_WAKE_QUEUE_THRESHOLD)) { netif_start_subqueue(iq->netdev, iq->q_no); - iq->stats.restart_cnt++; + iq->stats->restart_cnt++; return 0; }
@@ -960,7 +960,7 @@ static netdev_tx_t octep_start_xmit(struct sk_buff *skb, wmb(); /* Ring Doorbell to notify the NIC of new packets */ writel(iq->fill_cnt, iq->doorbell_reg); - iq->stats.instr_posted += iq->fill_cnt; + iq->stats->instr_posted += iq->fill_cnt; iq->fill_cnt = 0; return NETDEV_TX_OK;
@@ -991,22 +991,19 @@ static netdev_tx_t octep_start_xmit(struct sk_buff *skb, static void octep_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) { - u64 tx_packets, tx_bytes, rx_packets, rx_bytes; struct octep_device *oct = netdev_priv(netdev); + u64 tx_packets, tx_bytes, rx_packets, rx_bytes; int q;
tx_packets = 0; tx_bytes = 0; rx_packets = 0; rx_bytes = 0; - for (q = 0; q < oct->num_oqs; q++) { - struct octep_iq *iq = oct->iq[q]; - struct octep_oq *oq = oct->oq[q]; - - tx_packets += iq->stats.instr_completed; - tx_bytes += iq->stats.bytes_sent; - rx_packets += oq->stats.packets; - rx_bytes += oq->stats.bytes; + for (q = 0; q < OCTEP_MAX_QUEUES; q++) { + tx_packets += oct->stats_iq[q].instr_completed; + tx_bytes += oct->stats_iq[q].bytes_sent; + rx_packets += oct->stats_oq[q].packets; + rx_bytes += oct->stats_oq[q].bytes; } stats->tx_packets = tx_packets; stats->tx_bytes = tx_bytes; diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.h b/drivers/net/ethernet/marvell/octeon_ep/octep_main.h index fee59e0e0138..936b786f4281 100644 --- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.h +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.h @@ -257,11 +257,17 @@ struct octep_device { /* Pointers to Octeon Tx queues */ struct octep_iq *iq[OCTEP_MAX_IQ];
+ /* Per iq stats */ + struct octep_iq_stats stats_iq[OCTEP_MAX_IQ]; + /* Rx queues (OQ: Output Queue) */ u16 num_oqs; /* Pointers to Octeon Rx queues */ struct octep_oq *oq[OCTEP_MAX_OQ];
+ /* Per oq stats */ + struct octep_oq_stats stats_oq[OCTEP_MAX_OQ]; + /* Hardware port number of the PCIe interface */ u16 pcie_port;
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_rx.c b/drivers/net/ethernet/marvell/octeon_ep/octep_rx.c index 8af75cb37c3e..82b6b19e76b4 100644 --- a/drivers/net/ethernet/marvell/octeon_ep/octep_rx.c +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_rx.c @@ -87,7 +87,7 @@ static int octep_oq_refill(struct octep_device *oct, struct octep_oq *oq) page = dev_alloc_page(); if (unlikely(!page)) { dev_err(oq->dev, "refill: rx buffer alloc failed\n"); - oq->stats.alloc_failures++; + oq->stats->alloc_failures++; break; }
@@ -98,7 +98,7 @@ static int octep_oq_refill(struct octep_device *oct, struct octep_oq *oq) "OQ-%d buffer refill: DMA mapping error!\n", oq->q_no); put_page(page); - oq->stats.alloc_failures++; + oq->stats->alloc_failures++; break; } oq->buff_info[refill_idx].page = page; @@ -134,6 +134,7 @@ static int octep_setup_oq(struct octep_device *oct, int q_no) oq->netdev = oct->netdev; oq->dev = &oct->pdev->dev; oq->q_no = q_no; + oq->stats = &oct->stats_oq[q_no]; oq->max_count = CFG_GET_OQ_NUM_DESC(oct->conf); oq->ring_size_mask = oq->max_count - 1; oq->buffer_size = CFG_GET_OQ_BUF_SIZE(oct->conf); @@ -443,7 +444,7 @@ static int __octep_oq_process_rx(struct octep_device *oct, if (!skb) { octep_oq_drop_rx(oq, buff_info, &read_idx, &desc_used); - oq->stats.alloc_failures++; + oq->stats->alloc_failures++; continue; } skb_reserve(skb, data_offset); @@ -494,8 +495,8 @@ static int __octep_oq_process_rx(struct octep_device *oct,
oq->host_read_idx = read_idx; oq->refill_count += desc_used; - oq->stats.packets += pkt; - oq->stats.bytes += rx_bytes; + oq->stats->packets += pkt; + oq->stats->bytes += rx_bytes;
return pkt; } diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_rx.h b/drivers/net/ethernet/marvell/octeon_ep/octep_rx.h index 3b08e2d560dc..b4696c93d0e6 100644 --- a/drivers/net/ethernet/marvell/octeon_ep/octep_rx.h +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_rx.h @@ -186,8 +186,8 @@ struct octep_oq { */ u8 __iomem *pkts_sent_reg;
- /* Statistics for this OQ. */ - struct octep_oq_stats stats; + /* Pointer to statistics for this OQ. */ + struct octep_oq_stats *stats;
/* Packets pending to be processed */ u32 pkts_pending; diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_tx.c b/drivers/net/ethernet/marvell/octeon_ep/octep_tx.c index 06851b78aa28..08ee90013fef 100644 --- a/drivers/net/ethernet/marvell/octeon_ep/octep_tx.c +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_tx.c @@ -81,9 +81,9 @@ int octep_iq_process_completions(struct octep_iq *iq, u16 budget) }
iq->pkts_processed += compl_pkts; - iq->stats.instr_completed += compl_pkts; - iq->stats.bytes_sent += compl_bytes; - iq->stats.sgentry_sent += compl_sg; + iq->stats->instr_completed += compl_pkts; + iq->stats->bytes_sent += compl_bytes; + iq->stats->sgentry_sent += compl_sg; iq->flush_index = fi;
netdev_tx_completed_queue(iq->netdev_q, compl_pkts, compl_bytes); @@ -187,6 +187,7 @@ static int octep_setup_iq(struct octep_device *oct, int q_no) iq->netdev = oct->netdev; iq->dev = &oct->pdev->dev; iq->q_no = q_no; + iq->stats = &oct->stats_iq[q_no]; iq->max_count = CFG_GET_IQ_NUM_DESC(oct->conf); iq->ring_size_mask = iq->max_count - 1; iq->fill_threshold = CFG_GET_IQ_DB_MIN(oct->conf); diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_tx.h b/drivers/net/ethernet/marvell/octeon_ep/octep_tx.h index 875a2c34091f..58fb39dda977 100644 --- a/drivers/net/ethernet/marvell/octeon_ep/octep_tx.h +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_tx.h @@ -170,8 +170,8 @@ struct octep_iq { */ u16 flush_index;
- /* Statistics for this input queue. */ - struct octep_iq_stats stats; + /* Pointer to statistics for this input queue. */ + struct octep_iq_stats *stats;
/* Pointer to the Virtual Base addr of the input ring. */ struct octep_tx_desc_hw *desc_ring; diff --git a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_ethtool.c b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_ethtool.c index 7b21439a315f..d60441928ba9 100644 --- a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_ethtool.c +++ b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_ethtool.c @@ -114,12 +114,9 @@ static void octep_vf_get_ethtool_stats(struct net_device *netdev, iface_tx_stats = &oct->iface_tx_stats; iface_rx_stats = &oct->iface_rx_stats;
- for (q = 0; q < oct->num_oqs; q++) { - struct octep_vf_iq *iq = oct->iq[q]; - struct octep_vf_oq *oq = oct->oq[q]; - - tx_busy_errors += iq->stats.tx_busy; - rx_alloc_errors += oq->stats.alloc_failures; + for (q = 0; q < OCTEP_VF_MAX_QUEUES; q++) { + tx_busy_errors += oct->stats_iq[q].tx_busy; + rx_alloc_errors += oct->stats_oq[q].alloc_failures; } i = 0; data[i++] = rx_alloc_errors; @@ -134,22 +131,18 @@ static void octep_vf_get_ethtool_stats(struct net_device *netdev, data[i++] = iface_rx_stats->dropped_octets_fifo_full;
/* Per Tx Queue stats */ - for (q = 0; q < oct->num_iqs; q++) { - struct octep_vf_iq *iq = oct->iq[q]; - - data[i++] = iq->stats.instr_posted; - data[i++] = iq->stats.instr_completed; - data[i++] = iq->stats.bytes_sent; - data[i++] = iq->stats.tx_busy; + for (q = 0; q < OCTEP_VF_MAX_QUEUES; q++) { + data[i++] = oct->stats_iq[q].instr_posted; + data[i++] = oct->stats_iq[q].instr_completed; + data[i++] = oct->stats_iq[q].bytes_sent; + data[i++] = oct->stats_iq[q].tx_busy; }
/* Per Rx Queue stats */ for (q = 0; q < oct->num_oqs; q++) { - struct octep_vf_oq *oq = oct->oq[q]; - - data[i++] = oq->stats.packets; - data[i++] = oq->stats.bytes; - data[i++] = oq->stats.alloc_failures; + data[i++] = oct->stats_oq[q].packets; + data[i++] = oct->stats_oq[q].bytes; + data[i++] = oct->stats_oq[q].alloc_failures; } }
diff --git a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c index 4c699514fd57..18c922dd5fc6 100644 --- a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c +++ b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c @@ -574,7 +574,7 @@ static int octep_vf_iq_full_check(struct octep_vf_iq *iq) * caused queues to get re-enabled after * being stopped */ - iq->stats.restart_cnt++; + iq->stats->restart_cnt++; fallthrough; case 1: /* Queue left enabled, since IQ is not yet full*/ return 0; @@ -731,7 +731,7 @@ static netdev_tx_t octep_vf_start_xmit(struct sk_buff *skb, /* Flush the hw descriptors before writing to doorbell */ smp_wmb(); writel(iq->fill_cnt, iq->doorbell_reg); - iq->stats.instr_posted += iq->fill_cnt; + iq->stats->instr_posted += iq->fill_cnt; iq->fill_cnt = 0; return NETDEV_TX_OK; } @@ -786,14 +786,11 @@ static void octep_vf_get_stats64(struct net_device *netdev, tx_bytes = 0; rx_packets = 0; rx_bytes = 0; - for (q = 0; q < oct->num_oqs; q++) { - struct octep_vf_iq *iq = oct->iq[q]; - struct octep_vf_oq *oq = oct->oq[q]; - - tx_packets += iq->stats.instr_completed; - tx_bytes += iq->stats.bytes_sent; - rx_packets += oq->stats.packets; - rx_bytes += oq->stats.bytes; + for (q = 0; q < OCTEP_VF_MAX_QUEUES; q++) { + tx_packets += oct->stats_iq[q].instr_completed; + tx_bytes += oct->stats_iq[q].bytes_sent; + rx_packets += oct->stats_oq[q].packets; + rx_bytes += oct->stats_oq[q].bytes; } stats->tx_packets = tx_packets; stats->tx_bytes = tx_bytes; diff --git a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.h b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.h index 5769f62545cd..1a352f41f823 100644 --- a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.h +++ b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.h @@ -246,11 +246,17 @@ struct octep_vf_device { /* Pointers to Octeon Tx queues */ struct octep_vf_iq *iq[OCTEP_VF_MAX_IQ];
+ /* Per iq stats */ + struct octep_vf_iq_stats stats_iq[OCTEP_VF_MAX_IQ]; + /* Rx queues (OQ: Output Queue) */ u16 num_oqs; /* Pointers to Octeon Rx queues */ struct octep_vf_oq *oq[OCTEP_VF_MAX_OQ];
+ /* Per oq stats */ + struct octep_vf_oq_stats stats_oq[OCTEP_VF_MAX_OQ]; + /* Hardware port number of the PCIe interface */ u16 pcie_port;
diff --git a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c index 82821bc28634..d70c8be3cfc4 100644 --- a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c +++ b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c @@ -87,7 +87,7 @@ static int octep_vf_oq_refill(struct octep_vf_device *oct, struct octep_vf_oq *o page = dev_alloc_page(); if (unlikely(!page)) { dev_err(oq->dev, "refill: rx buffer alloc failed\n"); - oq->stats.alloc_failures++; + oq->stats->alloc_failures++; break; }
@@ -98,7 +98,7 @@ static int octep_vf_oq_refill(struct octep_vf_device *oct, struct octep_vf_oq *o "OQ-%d buffer refill: DMA mapping error!\n", oq->q_no); put_page(page); - oq->stats.alloc_failures++; + oq->stats->alloc_failures++; break; } oq->buff_info[refill_idx].page = page; @@ -134,6 +134,7 @@ static int octep_vf_setup_oq(struct octep_vf_device *oct, int q_no) oq->netdev = oct->netdev; oq->dev = &oct->pdev->dev; oq->q_no = q_no; + oq->stats = &oct->stats_oq[q_no]; oq->max_count = CFG_GET_OQ_NUM_DESC(oct->conf); oq->ring_size_mask = oq->max_count - 1; oq->buffer_size = CFG_GET_OQ_BUF_SIZE(oct->conf); @@ -458,8 +459,8 @@ static int __octep_vf_oq_process_rx(struct octep_vf_device *oct,
oq->host_read_idx = read_idx; oq->refill_count += desc_used; - oq->stats.packets += pkt; - oq->stats.bytes += rx_bytes; + oq->stats->packets += pkt; + oq->stats->bytes += rx_bytes;
return pkt; } diff --git a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.h b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.h index fe46838b5200..9e296b7d7e34 100644 --- a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.h +++ b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.h @@ -187,7 +187,7 @@ struct octep_vf_oq { u8 __iomem *pkts_sent_reg;
/* Statistics for this OQ. */ - struct octep_vf_oq_stats stats; + struct octep_vf_oq_stats *stats;
/* Packets pending to be processed */ u32 pkts_pending; diff --git a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_tx.c b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_tx.c index 47a5c054fdb6..8180e5ce3d7e 100644 --- a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_tx.c +++ b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_tx.c @@ -82,9 +82,9 @@ int octep_vf_iq_process_completions(struct octep_vf_iq *iq, u16 budget) }
iq->pkts_processed += compl_pkts; - iq->stats.instr_completed += compl_pkts; - iq->stats.bytes_sent += compl_bytes; - iq->stats.sgentry_sent += compl_sg; + iq->stats->instr_completed += compl_pkts; + iq->stats->bytes_sent += compl_bytes; + iq->stats->sgentry_sent += compl_sg; iq->flush_index = fi;
netif_subqueue_completed_wake(iq->netdev, iq->q_no, compl_pkts, @@ -186,6 +186,7 @@ static int octep_vf_setup_iq(struct octep_vf_device *oct, int q_no) iq->netdev = oct->netdev; iq->dev = &oct->pdev->dev; iq->q_no = q_no; + iq->stats = &oct->stats_iq[q_no]; iq->max_count = CFG_GET_IQ_NUM_DESC(oct->conf); iq->ring_size_mask = iq->max_count - 1; iq->fill_threshold = CFG_GET_IQ_DB_MIN(oct->conf); diff --git a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_tx.h b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_tx.h index f338b975103c..1cede90e3a5f 100644 --- a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_tx.h +++ b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_tx.h @@ -129,7 +129,7 @@ struct octep_vf_iq { u16 flush_index;
/* Statistics for this input queue. */ - struct octep_vf_iq_stats stats; + struct octep_vf_iq_stats *stats;
/* Pointer to the Virtual Base addr of the input ring. */ struct octep_vf_tx_desc_hw *desc_ring; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c index 4822d01123b4..d61a1a9297c9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c @@ -322,17 +322,16 @@ static void mlx5_pps_out(struct work_struct *work) } }
-static void mlx5_timestamp_overflow(struct work_struct *work) +static long mlx5_timestamp_overflow(struct ptp_clock_info *ptp_info) { - struct delayed_work *dwork = to_delayed_work(work); struct mlx5_core_dev *mdev; struct mlx5_timer *timer; struct mlx5_clock *clock; unsigned long flags;
- timer = container_of(dwork, struct mlx5_timer, overflow_work); - clock = container_of(timer, struct mlx5_clock, timer); + clock = container_of(ptp_info, struct mlx5_clock, ptp_info); mdev = container_of(clock, struct mlx5_core_dev, clock); + timer = &clock->timer;
if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) goto out; @@ -343,7 +342,7 @@ static void mlx5_timestamp_overflow(struct work_struct *work) write_sequnlock_irqrestore(&clock->lock, flags);
out: - schedule_delayed_work(&timer->overflow_work, timer->overflow_period); + return timer->overflow_period; }
static int mlx5_ptp_settime_real_time(struct mlx5_core_dev *mdev, @@ -517,6 +516,7 @@ static int mlx5_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) timer->cycles.mult = mult; mlx5_update_clock_info_page(mdev); write_sequnlock_irqrestore(&clock->lock, flags); + ptp_schedule_worker(clock->ptp, timer->overflow_period);
return 0; } @@ -852,6 +852,7 @@ static const struct ptp_clock_info mlx5_ptp_clock_info = { .settime64 = mlx5_ptp_settime, .enable = NULL, .verify = NULL, + .do_aux_work = mlx5_timestamp_overflow, };
static int mlx5_query_mtpps_pin_mode(struct mlx5_core_dev *mdev, u8 pin, @@ -1052,12 +1053,11 @@ static void mlx5_init_overflow_period(struct mlx5_clock *clock) do_div(ns, NSEC_PER_SEC / HZ); timer->overflow_period = ns;
- INIT_DELAYED_WORK(&timer->overflow_work, mlx5_timestamp_overflow); - if (timer->overflow_period) - schedule_delayed_work(&timer->overflow_work, 0); - else + if (!timer->overflow_period) { + timer->overflow_period = HZ; mlx5_core_warn(mdev, - "invalid overflow period, overflow_work is not scheduled\n"); + "invalid overflow period, overflow_work is scheduled once per second\n"); + }
if (clock_info) clock_info->overflow_period = timer->overflow_period; @@ -1172,6 +1172,9 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev)
MLX5_NB_INIT(&clock->pps_nb, mlx5_pps_event, PPS_EVENT); mlx5_eq_notifier_register(mdev, &clock->pps_nb); + + if (clock->ptp) + ptp_schedule_worker(clock->ptp, 0); }
void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) @@ -1188,7 +1191,6 @@ void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) }
cancel_work_sync(&clock->pps_info.out_work); - cancel_delayed_work_sync(&clock->timer.overflow_work);
if (mdev->clock_info) { free_page((unsigned long)mdev->clock_info); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c index baacf662c0ab..ae2849cf4dd4 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c @@ -152,6 +152,8 @@ mlx5hws_bwc_matcher_create(struct mlx5hws_table *table, if (!bwc_matcher) return NULL;
+ atomic_set(&bwc_matcher->num_of_rules, 0); + /* Check if the required match params can be all matched * in single STE, otherwise complex matcher is needed. */ @@ -199,10 +201,12 @@ int mlx5hws_bwc_matcher_destroy_simple(struct mlx5hws_bwc_matcher *bwc_matcher)
int mlx5hws_bwc_matcher_destroy(struct mlx5hws_bwc_matcher *bwc_matcher) { - if (bwc_matcher->num_of_rules) + u32 num_of_rules = atomic_read(&bwc_matcher->num_of_rules); + + if (num_of_rules) mlx5hws_err(bwc_matcher->matcher->tbl->ctx, "BWC matcher destroy: matcher still has %d rules\n", - bwc_matcher->num_of_rules); + num_of_rules);
mlx5hws_bwc_matcher_destroy_simple(bwc_matcher);
@@ -309,7 +313,7 @@ static void hws_bwc_rule_list_add(struct mlx5hws_bwc_rule *bwc_rule, u16 idx) { struct mlx5hws_bwc_matcher *bwc_matcher = bwc_rule->bwc_matcher;
- bwc_matcher->num_of_rules++; + atomic_inc(&bwc_matcher->num_of_rules); bwc_rule->bwc_queue_idx = idx; list_add(&bwc_rule->list_node, &bwc_matcher->rules[idx]); } @@ -318,7 +322,7 @@ static void hws_bwc_rule_list_remove(struct mlx5hws_bwc_rule *bwc_rule) { struct mlx5hws_bwc_matcher *bwc_matcher = bwc_rule->bwc_matcher;
- bwc_matcher->num_of_rules--; + atomic_dec(&bwc_matcher->num_of_rules); list_del_init(&bwc_rule->list_node); }
@@ -704,7 +708,8 @@ hws_bwc_matcher_rehash_size(struct mlx5hws_bwc_matcher *bwc_matcher) * Need to check again if we really need rehash. * If the reason for rehash was size, but not any more - skip rehash. */ - if (!hws_bwc_matcher_rehash_size_needed(bwc_matcher, bwc_matcher->num_of_rules)) + if (!hws_bwc_matcher_rehash_size_needed(bwc_matcher, + atomic_read(&bwc_matcher->num_of_rules))) return 0;
/* Now we're done all the checking - do the rehash: @@ -797,7 +802,7 @@ int mlx5hws_bwc_rule_create_simple(struct mlx5hws_bwc_rule *bwc_rule, }
/* check if number of rules require rehash */ - num_of_rules = bwc_matcher->num_of_rules; + num_of_rules = atomic_read(&bwc_matcher->num_of_rules);
if (unlikely(hws_bwc_matcher_rehash_size_needed(bwc_matcher, num_of_rules))) { mutex_unlock(queue_lock); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.h b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.h index 0b745968e21e..655fa7a22d84 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.h @@ -19,7 +19,7 @@ struct mlx5hws_bwc_matcher { u8 num_of_at; u16 priority; u8 size_log; - u32 num_of_rules; /* atomically accessed */ + atomic_t num_of_rules; struct list_head *rules; };
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c index 1bb3a6f8c3cd..e94f96c0c781 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c @@ -165,14 +165,14 @@ static int hws_matcher_disconnect(struct mlx5hws_matcher *matcher) next->match_ste.rtc_0_id, next->match_ste.rtc_1_id); if (ret) { - mlx5hws_err(tbl->ctx, "Failed to disconnect matcher\n"); - goto matcher_reconnect; + mlx5hws_err(tbl->ctx, "Fatal error, failed to disconnect matcher\n"); + return ret; } } else { ret = mlx5hws_table_connect_to_miss_table(tbl, tbl->default_miss.miss_tbl); if (ret) { - mlx5hws_err(tbl->ctx, "Failed to disconnect last matcher\n"); - goto matcher_reconnect; + mlx5hws_err(tbl->ctx, "Fatal error, failed to disconnect last matcher\n"); + return ret; } }
@@ -180,27 +180,19 @@ static int hws_matcher_disconnect(struct mlx5hws_matcher *matcher) if (prev_ft_id == tbl->ft_id) { ret = mlx5hws_table_update_connected_miss_tables(tbl); if (ret) { - mlx5hws_err(tbl->ctx, "Fatal error, failed to update connected miss table\n"); - goto matcher_reconnect; + mlx5hws_err(tbl->ctx, + "Fatal error, failed to update connected miss table\n"); + return ret; } }
ret = mlx5hws_table_ft_set_default_next_ft(tbl, prev_ft_id); if (ret) { mlx5hws_err(tbl->ctx, "Fatal error, failed to restore matcher ft default miss\n"); - goto matcher_reconnect; + return ret; }
return 0; - -matcher_reconnect: - if (list_empty(&tbl->matchers_list) || !prev) - list_add(&matcher->list_node, &tbl->matchers_list); - else - /* insert after prev matcher */ - list_add(&matcher->list_node, &prev->list_node); - - return ret; }
static void hws_matcher_set_rtc_attr_sz(struct mlx5hws_matcher *matcher, diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c index e1de45fb18ae..2be2889d0646 100644 --- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c +++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c @@ -2242,8 +2242,6 @@ static void am65_cpsw_nuss_remove_tx_chns(struct am65_cpsw_common *common) struct device *dev = common->dev; int i;
- devm_remove_action(dev, am65_cpsw_nuss_free_tx_chns, common); - common->tx_ch_rate_msk = 0; for (i = 0; i < common->tx_ch_num; i++) { struct am65_cpsw_tx_chn *tx_chn = &common->tx_chns[i]; @@ -2265,8 +2263,6 @@ static int am65_cpsw_nuss_ndev_add_tx_napi(struct am65_cpsw_common *common) for (i = 0; i < common->tx_ch_num; i++) { struct am65_cpsw_tx_chn *tx_chn = &common->tx_chns[i];
- netif_napi_add_tx(common->dma_ndev, &tx_chn->napi_tx, - am65_cpsw_nuss_tx_poll); hrtimer_init(&tx_chn->tx_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_PINNED); tx_chn->tx_hrtimer.function = &am65_cpsw_nuss_tx_timer_callback;
@@ -2279,9 +2275,21 @@ static int am65_cpsw_nuss_ndev_add_tx_napi(struct am65_cpsw_common *common) tx_chn->id, tx_chn->irq, ret); goto err; } + + netif_napi_add_tx(common->dma_ndev, &tx_chn->napi_tx, + am65_cpsw_nuss_tx_poll); }
+ return 0; + err: + for (--i ; i >= 0 ; i--) { + struct am65_cpsw_tx_chn *tx_chn = &common->tx_chns[i]; + + netif_napi_del(&tx_chn->napi_tx); + devm_free_irq(dev, tx_chn->irq, tx_chn); + } + return ret; }
@@ -2362,12 +2370,10 @@ static int am65_cpsw_nuss_init_tx_chns(struct am65_cpsw_common *common) goto err; }
+ return 0; + err: - i = devm_add_action(dev, am65_cpsw_nuss_free_tx_chns, common); - if (i) { - dev_err(dev, "Failed to add free_tx_chns action %d\n", i); - return i; - } + am65_cpsw_nuss_free_tx_chns(common);
return ret; } @@ -2395,7 +2401,6 @@ static void am65_cpsw_nuss_remove_rx_chns(struct am65_cpsw_common *common)
rx_chn = &common->rx_chns; flows = rx_chn->flows; - devm_remove_action(dev, am65_cpsw_nuss_free_rx_chns, common);
for (i = 0; i < common->rx_ch_num_flows; i++) { if (!(flows[i].irq < 0)) @@ -2494,7 +2499,7 @@ static int am65_cpsw_nuss_init_rx_chns(struct am65_cpsw_common *common) i, &rx_flow_cfg); if (ret) { dev_err(dev, "Failed to init rx flow%d %d\n", i, ret); - goto err; + goto err_flow; } if (!i) fdqring_id = @@ -2506,14 +2511,12 @@ static int am65_cpsw_nuss_init_rx_chns(struct am65_cpsw_common *common) dev_err(dev, "Failed to get rx dma irq %d\n", flow->irq); ret = flow->irq; - goto err; + goto err_flow; }
snprintf(flow->name, sizeof(flow->name), "%s-rx%d", dev_name(dev), i); - netif_napi_add(common->dma_ndev, &flow->napi_rx, - am65_cpsw_nuss_rx_poll); hrtimer_init(&flow->rx_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_PINNED); flow->rx_hrtimer.function = &am65_cpsw_nuss_rx_timer_callback; @@ -2526,20 +2529,28 @@ static int am65_cpsw_nuss_init_rx_chns(struct am65_cpsw_common *common) dev_err(dev, "failure requesting rx %d irq %u, %d\n", i, flow->irq, ret); flow->irq = -EINVAL; - goto err; + goto err_flow; } + + netif_napi_add(common->dma_ndev, &flow->napi_rx, + am65_cpsw_nuss_rx_poll); }
/* setup classifier to route priorities to flows */ cpsw_ale_classifier_setup_default(common->ale, common->rx_ch_num_flows);
-err: - i = devm_add_action(dev, am65_cpsw_nuss_free_rx_chns, common); - if (i) { - dev_err(dev, "Failed to add free_rx_chns action %d\n", i); - return i; + return 0; + +err_flow: + for (--i; i >= 0 ; i--) { + flow = &rx_chn->flows[i]; + netif_napi_del(&flow->napi_rx); + devm_free_irq(dev, flow->irq, flow); }
+err: + am65_cpsw_nuss_free_rx_chns(common); + return ret; }
@@ -3349,7 +3360,7 @@ static int am65_cpsw_nuss_register_ndevs(struct am65_cpsw_common *common) return ret; ret = am65_cpsw_nuss_init_rx_chns(common); if (ret) - return ret; + goto err_remove_tx;
/* The DMA Channels are not guaranteed to be in a clean state. * Reset and disable them to ensure that they are back to the @@ -3370,7 +3381,7 @@ static int am65_cpsw_nuss_register_ndevs(struct am65_cpsw_common *common)
ret = am65_cpsw_nuss_register_devlink(common); if (ret) - return ret; + goto err_remove_rx;
for (i = 0; i < common->port_num; i++) { port = &common->ports[i]; @@ -3401,6 +3412,10 @@ static int am65_cpsw_nuss_register_ndevs(struct am65_cpsw_common *common) err_cleanup_ndev: am65_cpsw_nuss_cleanup_ndev(common); am65_cpsw_unregister_devlink(common); +err_remove_rx: + am65_cpsw_nuss_remove_rx_chns(common); +err_remove_tx: + am65_cpsw_nuss_remove_tx_chns(common);
return ret; } @@ -3420,6 +3435,8 @@ int am65_cpsw_nuss_update_tx_rx_chns(struct am65_cpsw_common *common, return ret;
ret = am65_cpsw_nuss_init_rx_chns(common); + if (ret) + am65_cpsw_nuss_remove_tx_chns(common);
return ret; } @@ -3678,6 +3695,8 @@ static void am65_cpsw_nuss_remove(struct platform_device *pdev) */ am65_cpsw_nuss_cleanup_ndev(common); am65_cpsw_unregister_devlink(common); + am65_cpsw_nuss_remove_rx_chns(common); + am65_cpsw_nuss_remove_tx_chns(common); am65_cpsw_nuss_phylink_cleanup(common); am65_cpts_release(common->cpts); am65_cpsw_disable_serdes_phy(common); @@ -3739,8 +3758,10 @@ static int am65_cpsw_nuss_resume(struct device *dev) if (ret) return ret; ret = am65_cpsw_nuss_init_rx_chns(common); - if (ret) + if (ret) { + am65_cpsw_nuss_remove_tx_chns(common); return ret; + }
/* If RX IRQ was disabled before suspend, keep it disabled */ for (i = 0; i < common->rx_ch_num_flows; i++) { diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c index ade544bc007d..872e582b7e83 100644 --- a/drivers/net/phy/nxp-c45-tja11xx.c +++ b/drivers/net/phy/nxp-c45-tja11xx.c @@ -1297,6 +1297,8 @@ static int nxp_c45_soft_reset(struct phy_device *phydev) if (ret) return ret;
+ usleep_range(2000, 2050); + return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, VEND1_DEVICE_CONTROL, ret, !(ret & DEVICE_CONTROL_RESET), 20000, diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 148c7bc66c0a..acf96f262488 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -580,7 +580,7 @@ static inline bool tun_not_capable(struct tun_struct *tun) struct net *net = dev_net(tun->dev);
return ((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) || - (gid_valid(tun->group) && !in_egroup_p(tun->group))) && + (gid_valid(tun->group) && !in_egroup_p(tun->group))) && !ns_capable(net->user_ns, CAP_NET_ADMIN); }
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index 46afb95ffabe..a19789b57190 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c @@ -61,7 +61,18 @@ #define IPHETH_USBINTF_PROTO 1
#define IPHETH_IP_ALIGN 2 /* padding at front of URB */ -#define IPHETH_NCM_HEADER_SIZE (12 + 96) /* NCMH + NCM0 */ +/* On iOS devices, NCM headers in RX have a fixed size regardless of DPE count: + * - NTH16 (NCMH): 12 bytes, as per CDC NCM 1.0 spec + * - NDP16 (NCM0): 96 bytes, of which + * - NDP16 fixed header: 8 bytes + * - maximum of 22 DPEs (21 datagrams + trailer), 4 bytes each + */ +#define IPHETH_NDP16_MAX_DPE 22 +#define IPHETH_NDP16_HEADER_SIZE (sizeof(struct usb_cdc_ncm_ndp16) + \ + IPHETH_NDP16_MAX_DPE * \ + sizeof(struct usb_cdc_ncm_dpe16)) +#define IPHETH_NCM_HEADER_SIZE (sizeof(struct usb_cdc_ncm_nth16) + \ + IPHETH_NDP16_HEADER_SIZE) #define IPHETH_TX_BUF_SIZE ETH_FRAME_LEN #define IPHETH_RX_BUF_SIZE_LEGACY (IPHETH_IP_ALIGN + ETH_FRAME_LEN) #define IPHETH_RX_BUF_SIZE_NCM 65536 @@ -207,15 +218,23 @@ static int ipheth_rcvbulk_callback_legacy(struct urb *urb) return ipheth_consume_skb(buf, len, dev); }
+/* In "NCM mode", the iOS device encapsulates RX (phone->computer) traffic + * in NCM Transfer Blocks (similarly to CDC NCM). However, unlike reverse + * tethering (handled by the `cdc_ncm` driver), regular tethering is not + * compliant with the CDC NCM spec, as the device is missing the necessary + * descriptors, and TX (computer->phone) traffic is not encapsulated + * at all. Thus `ipheth` implements a very limited subset of the spec with + * the sole purpose of parsing RX URBs. + */ static int ipheth_rcvbulk_callback_ncm(struct urb *urb) { struct usb_cdc_ncm_nth16 *ncmh; struct usb_cdc_ncm_ndp16 *ncm0; struct usb_cdc_ncm_dpe16 *dpe; struct ipheth_device *dev; + u16 dg_idx, dg_len; int retval = -EINVAL; char *buf; - int len;
dev = urb->context;
@@ -226,40 +245,42 @@ static int ipheth_rcvbulk_callback_ncm(struct urb *urb)
ncmh = urb->transfer_buffer; if (ncmh->dwSignature != cpu_to_le32(USB_CDC_NCM_NTH16_SIGN) || - le16_to_cpu(ncmh->wNdpIndex) >= urb->actual_length) { - dev->net->stats.rx_errors++; - return retval; - } + /* On iOS, NDP16 directly follows NTH16 */ + ncmh->wNdpIndex != cpu_to_le16(sizeof(struct usb_cdc_ncm_nth16))) + goto rx_error;
- ncm0 = urb->transfer_buffer + le16_to_cpu(ncmh->wNdpIndex); - if (ncm0->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN) || - le16_to_cpu(ncmh->wHeaderLength) + le16_to_cpu(ncm0->wLength) >= - urb->actual_length) { - dev->net->stats.rx_errors++; - return retval; - } + ncm0 = urb->transfer_buffer + sizeof(struct usb_cdc_ncm_nth16); + if (ncm0->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN)) + goto rx_error;
dpe = ncm0->dpe16; - while (le16_to_cpu(dpe->wDatagramIndex) != 0 && - le16_to_cpu(dpe->wDatagramLength) != 0) { - if (le16_to_cpu(dpe->wDatagramIndex) >= urb->actual_length || - le16_to_cpu(dpe->wDatagramIndex) + - le16_to_cpu(dpe->wDatagramLength) > urb->actual_length) { + for (int dpe_i = 0; dpe_i < IPHETH_NDP16_MAX_DPE; ++dpe_i, ++dpe) { + dg_idx = le16_to_cpu(dpe->wDatagramIndex); + dg_len = le16_to_cpu(dpe->wDatagramLength); + + /* Null DPE must be present after last datagram pointer entry + * (3.3.1 USB CDC NCM spec v1.0) + */ + if (dg_idx == 0 && dg_len == 0) + return 0; + + if (dg_idx < IPHETH_NCM_HEADER_SIZE || + dg_idx >= urb->actual_length || + dg_len > urb->actual_length - dg_idx) { dev->net->stats.rx_length_errors++; return retval; }
- buf = urb->transfer_buffer + le16_to_cpu(dpe->wDatagramIndex); - len = le16_to_cpu(dpe->wDatagramLength); + buf = urb->transfer_buffer + dg_idx;
- retval = ipheth_consume_skb(buf, len, dev); + retval = ipheth_consume_skb(buf, dg_len, dev); if (retval != 0) return retval; - - dpe++; }
- return 0; +rx_error: + dev->net->stats.rx_errors++; + return retval; }
static void ipheth_rcvbulk_callback(struct urb *urb) diff --git a/drivers/net/vmxnet3/vmxnet3_xdp.c b/drivers/net/vmxnet3/vmxnet3_xdp.c index 1341374a4588..616ecc38d172 100644 --- a/drivers/net/vmxnet3/vmxnet3_xdp.c +++ b/drivers/net/vmxnet3/vmxnet3_xdp.c @@ -28,7 +28,7 @@ vmxnet3_xdp_get_tq(struct vmxnet3_adapter *adapter) if (likely(cpu < tq_number)) tq = &adapter->tx_queue[cpu]; else - tq = &adapter->tx_queue[reciprocal_scale(cpu, tq_number)]; + tq = &adapter->tx_queue[cpu % tq_number];
return tq; } @@ -124,6 +124,7 @@ vmxnet3_xdp_xmit_frame(struct vmxnet3_adapter *adapter, u32 buf_size; u32 dw2;
+ spin_lock_irq(&tq->tx_lock); dw2 = (tq->tx_ring.gen ^ 0x1) << VMXNET3_TXD_GEN_SHIFT; dw2 |= xdpf->len; ctx.sop_txd = tq->tx_ring.base + tq->tx_ring.next2fill; @@ -134,6 +135,7 @@ vmxnet3_xdp_xmit_frame(struct vmxnet3_adapter *adapter,
if (vmxnet3_cmd_ring_desc_avail(&tq->tx_ring) == 0) { tq->stats.tx_ring_full++; + spin_unlock_irq(&tq->tx_lock); return -ENOSPC; }
@@ -142,8 +144,10 @@ vmxnet3_xdp_xmit_frame(struct vmxnet3_adapter *adapter, tbi->dma_addr = dma_map_single(&adapter->pdev->dev, xdpf->data, buf_size, DMA_TO_DEVICE); - if (dma_mapping_error(&adapter->pdev->dev, tbi->dma_addr)) + if (dma_mapping_error(&adapter->pdev->dev, tbi->dma_addr)) { + spin_unlock_irq(&tq->tx_lock); return -EFAULT; + } tbi->map_type |= VMXNET3_MAP_SINGLE; } else { /* XDP buffer from page pool */ page = virt_to_page(xdpf->data); @@ -182,6 +186,7 @@ vmxnet3_xdp_xmit_frame(struct vmxnet3_adapter *adapter, dma_wmb(); gdesc->dword[2] = cpu_to_le32(le32_to_cpu(gdesc->dword[2]) ^ VMXNET3_TXD_GEN); + spin_unlock_irq(&tq->tx_lock);
/* No need to handle the case when tx_num_deferred doesn't reach * threshold. Backend driver at hypervisor side will poll and reset @@ -225,6 +230,7 @@ vmxnet3_xdp_xmit(struct net_device *dev, { struct vmxnet3_adapter *adapter = netdev_priv(dev); struct vmxnet3_tx_queue *tq; + struct netdev_queue *nq; int i;
if (unlikely(test_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state))) @@ -236,6 +242,9 @@ vmxnet3_xdp_xmit(struct net_device *dev, if (tq->stopped) return -ENETDOWN;
+ nq = netdev_get_tx_queue(adapter->netdev, tq->qid); + + __netif_tx_lock(nq, smp_processor_id()); for (i = 0; i < n; i++) { if (vmxnet3_xdp_xmit_frame(adapter, frames[i], tq, true)) { tq->stats.xdp_xmit_err++; @@ -243,6 +252,7 @@ vmxnet3_xdp_xmit(struct net_device *dev, } } tq->stats.xdp_xmit += i; + __netif_tx_unlock(nq);
return i; } diff --git a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c index c9980c0193d1..43ea87e981f4 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c +++ b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c @@ -1562,7 +1562,8 @@ ath12k_htt_print_tx_selfgen_ac_stats_tlv(const void *tag_buf, u16 tag_len, le32_to_cpu(htt_stats_buf->ac_mu_mimo_ndp)); len += print_array_to_buf_index(buf, len, "ac_mu_mimo_brpollX_tried = ", 1, htt_stats_buf->ac_mu_mimo_brpoll, - ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS, "\n\n"); + ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS - 1, + "\n\n");
stats_req->buf_len = len; } @@ -1590,7 +1591,7 @@ ath12k_htt_print_tx_selfgen_ax_stats_tlv(const void *tag_buf, u16 tag_len, le32_to_cpu(htt_stats_buf->ax_mu_mimo_ndp)); len += print_array_to_buf_index(buf, len, "ax_mu_mimo_brpollX_tried = ", 1, htt_stats_buf->ax_mu_mimo_brpoll, - ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS, "\n"); + ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS - 1, "\n"); len += scnprintf(buf + len, buf_len - len, "ax_basic_trigger = %u\n", le32_to_cpu(htt_stats_buf->ax_basic_trigger)); len += scnprintf(buf + len, buf_len - len, "ax_ulmumimo_total_trigger = %u\n", diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index ef2736fb5f53..e8639ad8761a 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -4378,6 +4378,7 @@ static int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (sta) { ahsta = ath12k_sta_to_ahsta(sta); + /* For an ML STA Pairwise key is same for all associated link Stations, * hence do set key for all link STAs which are active. */ @@ -4400,41 +4401,47 @@ static int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (ret) break; } - } else { - arsta = &ahsta->deflink; - arvif = arsta->arvif; - if (WARN_ON(!arvif)) { - ret = -EINVAL; - goto out; - }
- ret = ath12k_mac_set_key(arvif->ar, cmd, arvif, arsta, key); - } - } else { - if (key->link_id >= 0 && key->link_id < IEEE80211_MLD_MAX_NUM_LINKS) { - link_id = key->link_id; - arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]); - } else { - link_id = 0; - arvif = &ahvif->deflink; + return 0; }
- if (!arvif || !arvif->is_created) { - cache = ath12k_ahvif_get_link_cache(ahvif, link_id); - if (!cache) - return -ENOSPC; + arsta = &ahsta->deflink; + arvif = arsta->arvif; + if (WARN_ON(!arvif)) + return -EINVAL;
- ret = ath12k_mac_update_key_cache(cache, cmd, sta, key); + ret = ath12k_mac_set_key(arvif->ar, cmd, arvif, arsta, key); + if (ret) + return ret;
+ return 0; + } + + if (key->link_id >= 0 && key->link_id < IEEE80211_MLD_MAX_NUM_LINKS) { + link_id = key->link_id; + arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]); + } else { + link_id = 0; + arvif = &ahvif->deflink; + } + + if (!arvif || !arvif->is_created) { + cache = ath12k_ahvif_get_link_cache(ahvif, link_id); + if (!cache) + return -ENOSPC; + + ret = ath12k_mac_update_key_cache(cache, cmd, sta, key); + if (ret) return ret; - }
- ret = ath12k_mac_set_key(arvif->ar, cmd, arvif, NULL, key); + return 0; }
-out: + ret = ath12k_mac_set_key(arvif->ar, cmd, arvif, NULL, key); + if (ret) + return ret;
- return ret; + return 0; }
static int diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index da72fd2d541f..20ab9b1eea28 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -540,6 +540,11 @@ void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success) struct ethhdr *eh; u16 type;
+ if (!ifp) { + brcmu_pkt_buf_free_skb(txp); + return; + } + eh = (struct ethhdr *)(txp->data); type = ntohs(eh->h_proto);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c index c1f18e2fe540..1681ad00f82e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c @@ -99,13 +99,13 @@ int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, /* Set board-type to the first string of the machine compatible prop */ root = of_find_node_by_path("/"); if (root && err) { - char *board_type; + char *board_type = NULL; const char *tmp;
- of_property_read_string_index(root, "compatible", 0, &tmp); - /* get rid of '/' in the compatible string to be able to find the FW */ - board_type = devm_kstrdup(dev, tmp, GFP_KERNEL); + if (!of_property_read_string_index(root, "compatible", 0, &tmp)) + board_type = devm_kstrdup(dev, tmp, GFP_KERNEL); + if (!board_type) { of_node_put(root); return 0; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c index d69879e1bd87..d362c4337616 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c @@ -23423,6 +23423,9 @@ wlc_phy_iqcal_gainparams_nphy(struct brcms_phy *pi, u16 core_no, break; }
+ if (WARN_ON(k == NPHY_IQCAL_NUMGAINS)) + return; + params->txgm = tbl_iqcal_gainparams_nphy[band_idx][k][1]; params->pga = tbl_iqcal_gainparams_nphy[band_idx][k][2]; params->pad = tbl_iqcal_gainparams_nphy[band_idx][k][3]; diff --git a/drivers/net/wireless/intel/iwlwifi/Makefile b/drivers/net/wireless/intel/iwlwifi/Makefile index 64c123314245..a3052684b341 100644 --- a/drivers/net/wireless/intel/iwlwifi/Makefile +++ b/drivers/net/wireless/intel/iwlwifi/Makefile @@ -11,7 +11,7 @@ iwlwifi-objs += pcie/ctxt-info.o pcie/ctxt-info-gen3.o iwlwifi-objs += pcie/trans-gen2.o pcie/tx-gen2.o iwlwifi-$(CONFIG_IWLDVM) += cfg/1000.o cfg/2000.o cfg/5000.o cfg/6000.o iwlwifi-$(CONFIG_IWLMVM) += cfg/7000.o cfg/8000.o cfg/9000.o cfg/22000.o -iwlwifi-$(CONFIG_IWLMVM) += cfg/ax210.o cfg/bz.o cfg/sc.o +iwlwifi-$(CONFIG_IWLMVM) += cfg/ax210.o cfg/bz.o cfg/sc.o cfg/dr.o iwlwifi-objs += iwl-dbg-tlv.o iwlwifi-objs += iwl-trans.o
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/dr.c b/drivers/net/wireless/intel/iwlwifi/cfg/dr.c new file mode 100644 index 000000000000..ab7c0f8d54f4 --- /dev/null +++ b/drivers/net/wireless/intel/iwlwifi/cfg/dr.c @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * Copyright (C) 2024 Intel Corporation + */ +#include <linux/module.h> +#include <linux/stringify.h> +#include "iwl-config.h" +#include "iwl-prph.h" +#include "fw/api/txq.h" + +/* Highest firmware API version supported */ +#define IWL_DR_UCODE_API_MAX 96 + +/* Lowest firmware API version supported */ +#define IWL_DR_UCODE_API_MIN 96 + +/* NVM versions */ +#define IWL_DR_NVM_VERSION 0x0a1d + +/* Memory offsets and lengths */ +#define IWL_DR_DCCM_OFFSET 0x800000 /* LMAC1 */ +#define IWL_DR_DCCM_LEN 0x10000 /* LMAC1 */ +#define IWL_DR_DCCM2_OFFSET 0x880000 +#define IWL_DR_DCCM2_LEN 0x8000 +#define IWL_DR_SMEM_OFFSET 0x400000 +#define IWL_DR_SMEM_LEN 0xD0000 + +#define IWL_DR_A_PE_A_FW_PRE "iwlwifi-dr-a0-pe-a0" +#define IWL_BR_A_PET_A_FW_PRE "iwlwifi-br-a0-petc-a0" +#define IWL_BR_A_PE_A_FW_PRE "iwlwifi-br-a0-pe-a0" + +#define IWL_DR_A_PE_A_FW_MODULE_FIRMWARE(api) \ + IWL_DR_A_PE_A_FW_PRE "-" __stringify(api) ".ucode" +#define IWL_BR_A_PET_A_FW_MODULE_FIRMWARE(api) \ + IWL_BR_A_PET_A_FW_PRE "-" __stringify(api) ".ucode" +#define IWL_BR_A_PE_A_FW_MODULE_FIRMWARE(api) \ + IWL_BR_A_PE_A_FW_PRE "-" __stringify(api) ".ucode" + +static const struct iwl_base_params iwl_dr_base_params = { + .eeprom_size = OTP_LOW_IMAGE_SIZE_32K, + .num_of_queues = 512, + .max_tfd_queue_size = 65536, + .shadow_ram_support = true, + .led_compensation = 57, + .wd_timeout = IWL_LONG_WD_TIMEOUT, + .max_event_log_size = 512, + .shadow_reg_enable = true, + .pcie_l1_allowed = true, +}; + +#define IWL_DEVICE_DR_COMMON \ + .ucode_api_max = IWL_DR_UCODE_API_MAX, \ + .ucode_api_min = IWL_DR_UCODE_API_MIN, \ + .led_mode = IWL_LED_RF_STATE, \ + .nvm_hw_section_num = 10, \ + .non_shared_ant = ANT_B, \ + .dccm_offset = IWL_DR_DCCM_OFFSET, \ + .dccm_len = IWL_DR_DCCM_LEN, \ + .dccm2_offset = IWL_DR_DCCM2_OFFSET, \ + .dccm2_len = IWL_DR_DCCM2_LEN, \ + .smem_offset = IWL_DR_SMEM_OFFSET, \ + .smem_len = IWL_DR_SMEM_LEN, \ + .apmg_not_supported = true, \ + .trans.mq_rx_supported = true, \ + .vht_mu_mimo_supported = true, \ + .mac_addr_from_csr = 0x30, \ + .nvm_ver = IWL_DR_NVM_VERSION, \ + .trans.rf_id = true, \ + .trans.gen2 = true, \ + .nvm_type = IWL_NVM_EXT, \ + .dbgc_supported = true, \ + .min_umac_error_event_table = 0xD0000, \ + .d3_debug_data_base_addr = 0x401000, \ + .d3_debug_data_length = 60 * 1024, \ + .mon_smem_regs = { \ + .write_ptr = { \ + .addr = LDBG_M2S_BUF_WPTR, \ + .mask = LDBG_M2S_BUF_WPTR_VAL_MSK, \ + }, \ + .cycle_cnt = { \ + .addr = LDBG_M2S_BUF_WRAP_CNT, \ + .mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, \ + }, \ + }, \ + .trans.umac_prph_offset = 0x300000, \ + .trans.device_family = IWL_DEVICE_FAMILY_DR, \ + .trans.base_params = &iwl_dr_base_params, \ + .min_txq_size = 128, \ + .gp2_reg_addr = 0xd02c68, \ + .min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_EHT, \ + .mon_dram_regs = { \ + .write_ptr = { \ + .addr = DBGC_CUR_DBGBUF_STATUS, \ + .mask = DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK, \ + }, \ + .cycle_cnt = { \ + .addr = DBGC_DBGBUF_WRAP_AROUND, \ + .mask = 0xffffffff, \ + }, \ + .cur_frag = { \ + .addr = DBGC_CUR_DBGBUF_STATUS, \ + .mask = DBGC_CUR_DBGBUF_STATUS_IDX_MSK, \ + }, \ + }, \ + .mon_dbgi_regs = { \ + .write_ptr = { \ + .addr = DBGI_SRAM_FIFO_POINTERS, \ + .mask = DBGI_SRAM_FIFO_POINTERS_WR_PTR_MSK, \ + }, \ + } + +#define IWL_DEVICE_DR \ + IWL_DEVICE_DR_COMMON, \ + .uhb_supported = true, \ + .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \ + .num_rbds = IWL_NUM_RBDS_DR_EHT, \ + .ht_params = &iwl_22000_ht_params + +/* + * This size was picked according to 8 MSDUs inside 512 A-MSDUs in an + * A-MPDU, with additional overhead to account for processing time. + */ +#define IWL_NUM_RBDS_DR_EHT (512 * 16) + +const struct iwl_cfg_trans_params iwl_dr_trans_cfg = { + .device_family = IWL_DEVICE_FAMILY_DR, + .base_params = &iwl_dr_base_params, + .mq_rx_supported = true, + .rf_id = true, + .gen2 = true, + .integrated = true, + .umac_prph_offset = 0x300000, + .xtal_latency = 12000, + .low_latency_xtal = true, + .ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US, +}; + +const char iwl_dr_name[] = "Intel(R) TBD Dr device"; + +const struct iwl_cfg iwl_cfg_dr = { + .fw_name_mac = "dr", + IWL_DEVICE_DR, +}; + +const struct iwl_cfg_trans_params iwl_br_trans_cfg = { + .device_family = IWL_DEVICE_FAMILY_DR, + .base_params = &iwl_dr_base_params, + .mq_rx_supported = true, + .rf_id = true, + .gen2 = true, + .integrated = true, + .umac_prph_offset = 0x300000, + .xtal_latency = 12000, + .low_latency_xtal = true, + .ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US, +}; + +const char iwl_br_name[] = "Intel(R) TBD Br device"; + +const struct iwl_cfg iwl_cfg_br = { + .fw_name_mac = "br", + IWL_DEVICE_DR, +}; + +MODULE_FIRMWARE(IWL_DR_A_PE_A_FW_MODULE_FIRMWARE(IWL_DR_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL_BR_A_PET_A_FW_MODULE_FIRMWARE(IWL_DR_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL_BR_A_PE_A_FW_MODULE_FIRMWARE(IWL_DR_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c index 0bc32291815e..a26c5573d209 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c @@ -108,7 +108,7 @@ static int iwl_acpi_get_dsm_integer(struct device *dev, int rev, int func, size_t expected_size) { union acpi_object *obj; - int ret = 0; + int ret;
obj = iwl_acpi_get_dsm_object(dev, rev, func, NULL, guid); if (IS_ERR(obj)) { @@ -123,8 +123,10 @@ static int iwl_acpi_get_dsm_integer(struct device *dev, int rev, int func, } else if (obj->type == ACPI_TYPE_BUFFER) { __le64 le_value = 0;
- if (WARN_ON_ONCE(expected_size > sizeof(le_value))) - return -EINVAL; + if (WARN_ON_ONCE(expected_size > sizeof(le_value))) { + ret = -EINVAL; + goto out; + }
/* if the buffer size doesn't match the expected size */ if (obj->buffer.length != expected_size) @@ -145,8 +147,9 @@ static int iwl_acpi_get_dsm_integer(struct device *dev, int rev, int func, }
IWL_DEBUG_DEV_RADIO(dev, - "ACPI: DSM method evaluated: func=%d, ret=%d\n", - func, ret); + "ACPI: DSM method evaluated: func=%d, value=%lld\n", + func, *value); + ret = 0; out: ACPI_FREE(obj); return ret; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 17721bb47e25..89744dbedb4a 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -38,6 +38,7 @@ enum iwl_device_family { IWL_DEVICE_FAMILY_AX210, IWL_DEVICE_FAMILY_BZ, IWL_DEVICE_FAMILY_SC, + IWL_DEVICE_FAMILY_DR, };
/* @@ -424,6 +425,8 @@ struct iwl_cfg { #define IWL_CFG_MAC_TYPE_SC2 0x49 #define IWL_CFG_MAC_TYPE_SC2F 0x4A #define IWL_CFG_MAC_TYPE_BZ_W 0x4B +#define IWL_CFG_MAC_TYPE_BR 0x4C +#define IWL_CFG_MAC_TYPE_DR 0x4D
#define IWL_CFG_RF_TYPE_TH 0x105 #define IWL_CFG_RF_TYPE_TH1 0x108 @@ -434,6 +437,7 @@ struct iwl_cfg { #define IWL_CFG_RF_TYPE_GF 0x10D #define IWL_CFG_RF_TYPE_FM 0x112 #define IWL_CFG_RF_TYPE_WH 0x113 +#define IWL_CFG_RF_TYPE_PE 0x114
#define IWL_CFG_RF_ID_TH 0x1 #define IWL_CFG_RF_ID_TH1 0x1 @@ -506,6 +510,8 @@ extern const struct iwl_cfg_trans_params iwl_ma_trans_cfg; extern const struct iwl_cfg_trans_params iwl_bz_trans_cfg; extern const struct iwl_cfg_trans_params iwl_gl_trans_cfg; extern const struct iwl_cfg_trans_params iwl_sc_trans_cfg; +extern const struct iwl_cfg_trans_params iwl_dr_trans_cfg; +extern const struct iwl_cfg_trans_params iwl_br_trans_cfg; extern const char iwl9162_name[]; extern const char iwl9260_name[]; extern const char iwl9260_1_name[]; @@ -551,6 +557,8 @@ extern const char iwl_mtp_name[]; extern const char iwl_sc_name[]; extern const char iwl_sc2_name[]; extern const char iwl_sc2f_name[]; +extern const char iwl_dr_name[]; +extern const char iwl_br_name[]; #if IS_ENABLED(CONFIG_IWLDVM) extern const struct iwl_cfg iwl5300_agn_cfg; extern const struct iwl_cfg iwl5100_agn_cfg; @@ -658,6 +666,8 @@ extern const struct iwl_cfg iwl_cfg_gl; extern const struct iwl_cfg iwl_cfg_sc; extern const struct iwl_cfg iwl_cfg_sc2; extern const struct iwl_cfg iwl_cfg_sc2f; +extern const struct iwl_cfg iwl_cfg_dr; +extern const struct iwl_cfg iwl_cfg_br; #endif /* CONFIG_IWLMVM */
#endif /* __IWL_CONFIG_H__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 8fb2aa282242..9dd0e0a51ce5 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -540,6 +540,9 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0xE340, PCI_ANY_ID, iwl_sc_trans_cfg)}, {IWL_PCI_DEVICE(0xD340, PCI_ANY_ID, iwl_sc_trans_cfg)}, {IWL_PCI_DEVICE(0x6E70, PCI_ANY_ID, iwl_sc_trans_cfg)}, + +/* Dr devices */ + {IWL_PCI_DEVICE(0x272F, PCI_ANY_ID, iwl_dr_trans_cfg)}, #endif /* CONFIG_IWLMVM */
{0} @@ -1182,6 +1185,19 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct iwl_dev_info iwl_dev_info_table[] = { IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, iwl_cfg_sc2f, iwl_sc2f_name), +/* Dr */ + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_DR, IWL_CFG_ANY, + IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + iwl_cfg_dr, iwl_dr_name), + +/* Br */ + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_BR, IWL_CFG_ANY, + IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + iwl_cfg_br, iwl_br_name), #endif /* CONFIG_IWLMVM */ }; EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_dev_info_table); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c index bfdbc15abaa9..928e0b07a9bf 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c @@ -2,9 +2,14 @@ /* Copyright (C) 2020 MediaTek Inc. */
#include <linux/firmware.h> +#include <linux/moduleparam.h> #include "mt7915.h" #include "eeprom.h"
+static bool enable_6ghz; +module_param(enable_6ghz, bool, 0644); +MODULE_PARM_DESC(enable_6ghz, "Enable 6 GHz instead of 5 GHz on hardware that supports both"); + static int mt7915_eeprom_load_precal(struct mt7915_dev *dev) { struct mt76_dev *mdev = &dev->mt76; @@ -170,8 +175,20 @@ static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy) phy->mt76->cap.has_6ghz = true; return; case MT_EE_V2_BAND_SEL_5GHZ_6GHZ: - phy->mt76->cap.has_5ghz = true; - phy->mt76->cap.has_6ghz = true; + if (enable_6ghz) { + phy->mt76->cap.has_6ghz = true; + u8p_replace_bits(&eeprom[MT_EE_WIFI_CONF + band], + MT_EE_V2_BAND_SEL_6GHZ, + MT_EE_WIFI_CONF0_BAND_SEL); + } else { + phy->mt76->cap.has_5ghz = true; + u8p_replace_bits(&eeprom[MT_EE_WIFI_CONF + band], + MT_EE_V2_BAND_SEL_5GHZ, + MT_EE_WIFI_CONF0_BAND_SEL); + } + /* force to buffer mode */ + dev->flash_mode = true; + return; default: phy->mt76->cap.has_2ghz = true; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c index 77d82ccd7307..bc983ab10b0c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c @@ -1239,14 +1239,14 @@ int mt7915_register_device(struct mt7915_dev *dev) if (ret) goto unreg_dev;
- ieee80211_queue_work(mt76_hw(dev), &dev->init_work); - if (phy2) { ret = mt7915_register_ext_phy(dev, phy2); if (ret) goto unreg_thermal; }
+ ieee80211_queue_work(mt76_hw(dev), &dev->init_work); + dev->recovery.hw_init_done = true;
ret = mt7915_init_debugfs(&dev->phy); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c index 8aa4f0203208..e3459295ad88 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c @@ -21,6 +21,9 @@ static const struct usb_device_id mt7921u_device_table[] = { /* Netgear, Inc. [A8000,AXE3000] */ { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9060, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM }, + /* TP-Link TXE50UH */ + { USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0107, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM }, { }, };
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h index c269942b3f4a..af8d17b9e012 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h @@ -197,9 +197,9 @@ enum rtl8821a_h2c_cmd {
/* _MEDIA_STATUS_RPT_PARM_CMD1 */ #define SET_H2CCMD_MSRRPT_PARM_OPMODE(__cmd, __value) \ - u8p_replace_bits(__cmd + 1, __value, BIT(0)) + u8p_replace_bits(__cmd, __value, BIT(0)) #define SET_H2CCMD_MSRRPT_PARM_MACID_IND(__cmd, __value) \ - u8p_replace_bits(__cmd + 1, __value, BIT(1)) + u8p_replace_bits(__cmd, __value, BIT(1))
/* AP_OFFLOAD */ #define SET_H2CCMD_AP_OFFLOAD_ON(__cmd, __value) \ diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index cd09fb6f7b8b..65c7acea41af 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -510,12 +510,12 @@ struct rtw_5g_txpwr_idx { struct rtw_5g_vht_ns_pwr_idx_diff vht_2s_diff; struct rtw_5g_vht_ns_pwr_idx_diff vht_3s_diff; struct rtw_5g_vht_ns_pwr_idx_diff vht_4s_diff; -}; +} __packed;
struct rtw_txpwr_idx { struct rtw_2g_txpwr_idx pwr_idx_2g; struct rtw_5g_txpwr_idx pwr_idx_5g; -}; +} __packed;
struct rtw_channel_params { u8 center_chan; diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c index a19b94d022ee..1d232adbdd7e 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c @@ -903,7 +903,7 @@ static void rtw8703b_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x0); rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x0); rtw_write32_mask(rtwdev, REG_OFDM0_TX_PSD_NOISE, - GENMASK(31, 20), 0x0); + GENMASK(31, 30), 0x0); rtw_write32(rtwdev, REG_BBRX_DFIR, 0x4A880000); rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x19F60000); break; @@ -1198,9 +1198,9 @@ static u8 rtw8703b_iqk_rx_path(struct rtw_dev *rtwdev, rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c); rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c); rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c); - rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x8216000f); + rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x8214030f); rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28110000); - rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x28110000); + rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x82110000); rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000);
/* LOK setting */ @@ -1372,7 +1372,7 @@ void rtw8703b_iqk_fill_a_matrix(struct rtw_dev *rtwdev, const s32 result[]) return;
tmp_rx_iqi |= FIELD_PREP(BIT_MASK_RXIQ_S1_X, result[IQK_S1_RX_X]); - tmp_rx_iqi |= FIELD_PREP(BIT_MASK_RXIQ_S1_Y1, result[IQK_S1_RX_X]); + tmp_rx_iqi |= FIELD_PREP(BIT_MASK_RXIQ_S1_Y1, result[IQK_S1_RX_Y]); rtw_write32(rtwdev, REG_A_RXIQI, tmp_rx_iqi); rtw_write32_mask(rtwdev, REG_RXIQK_MATRIX_LSB_11N, BIT_MASK_RXIQ_S1_Y2, BIT_SET_RXIQ_S1_Y2(result[IQK_S1_RX_Y])); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723x.h b/drivers/net/wireless/realtek/rtw88/rtw8723x.h index e93bfce994bf..a99af527c92c 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8723x.h +++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.h @@ -47,7 +47,7 @@ struct rtw8723xe_efuse { u8 device_id[2]; u8 sub_vendor_id[2]; u8 sub_device_id[2]; -}; +} __packed;
struct rtw8723xu_efuse { u8 res4[48]; /* 0xd0 */ @@ -56,12 +56,12 @@ struct rtw8723xu_efuse { u8 usb_option; /* 0x104 */ u8 res5[2]; /* 0x105 */ u8 mac_addr[ETH_ALEN]; /* 0x107 */ -}; +} __packed;
struct rtw8723xs_efuse { u8 res4[0x4a]; /* 0xd0 */ u8 mac_addr[ETH_ALEN]; /* 0x11a */ -}; +} __packed;
struct rtw8723x_efuse { __le16 rtl_id; @@ -96,7 +96,7 @@ struct rtw8723x_efuse { struct rtw8723xu_efuse u; struct rtw8723xs_efuse s; }; -}; +} __packed;
#define RTW8723X_IQK_ADDA_REG_NUM 16 #define RTW8723X_IQK_MAC8_REG_NUM 3 diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.h b/drivers/net/wireless/realtek/rtw88/rtw8821c.h index 7a33ebd612ed..954e93c8020d 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8821c.h +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h @@ -27,7 +27,7 @@ struct rtw8821cu_efuse { u8 res11[0xcf]; u8 package_type; /* 0x1fb */ u8 res12[0x4]; -}; +} __packed;
struct rtw8821ce_efuse { u8 mac_addr[ETH_ALEN]; /* 0xd0 */ @@ -47,7 +47,8 @@ struct rtw8821ce_efuse { u8 ltr_en:1; u8 res1:2; u8 obff:2; - u8 res2:3; + u8 res2_1:1; + u8 res2_2:2; u8 obff_cap:2; u8 res3:4; u8 res4[3]; @@ -63,7 +64,7 @@ struct rtw8821ce_efuse { u8 res6:1; u8 port_t_power_on_value:5; u8 res7; -}; +} __packed;
struct rtw8821cs_efuse { u8 res4[0x4a]; /* 0xd0 */ @@ -101,7 +102,7 @@ struct rtw8821c_efuse { struct rtw8821cu_efuse u; struct rtw8821cs_efuse s; }; -}; +} __packed;
static inline void _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data) diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.h b/drivers/net/wireless/realtek/rtw88/rtw8822b.h index 0514958fb57c..9fca9ba67c90 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822b.h +++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.h @@ -27,7 +27,7 @@ struct rtw8822bu_efuse { u8 res11[0xcf]; u8 package_type; /* 0x1fb */ u8 res12[0x4]; -}; +} __packed;
struct rtw8822be_efuse { u8 mac_addr[ETH_ALEN]; /* 0xd0 */ @@ -47,7 +47,8 @@ struct rtw8822be_efuse { u8 ltr_en:1; u8 res1:2; u8 obff:2; - u8 res2:3; + u8 res2_1:1; + u8 res2_2:2; u8 obff_cap:2; u8 res3:4; u8 res4[3]; @@ -63,7 +64,7 @@ struct rtw8822be_efuse { u8 res6:1; u8 port_t_power_on_value:5; u8 res7; -}; +} __packed;
struct rtw8822bs_efuse { u8 res4[0x4a]; /* 0xd0 */ @@ -103,7 +104,7 @@ struct rtw8822b_efuse { struct rtw8822bu_efuse u; struct rtw8822bs_efuse s; }; -}; +} __packed;
static inline void _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data) diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.h b/drivers/net/wireless/realtek/rtw88/rtw8822c.h index e2b383d633cd..fc62b67a15f2 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822c.h +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.h @@ -14,7 +14,7 @@ struct rtw8822cu_efuse { u8 res1[3]; u8 mac_addr[ETH_ALEN]; /* 0x157 */ u8 res2[0x3d]; -}; +} __packed;
struct rtw8822cs_efuse { u8 res0[0x4a]; /* 0x120 */ @@ -39,7 +39,8 @@ struct rtw8822ce_efuse { u8 ltr_en:1; u8 res1:2; u8 obff:2; - u8 res2:3; + u8 res2_1:1; + u8 res2_2:2; u8 obff_cap:2; u8 res3:4; u8 class_code[3]; @@ -55,7 +56,7 @@ struct rtw8822ce_efuse { u8 res6:1; u8 port_t_power_on_value:5; u8 res7; -}; +} __packed;
struct rtw8822c_efuse { __le16 rtl_id; @@ -102,7 +103,7 @@ struct rtw8822c_efuse { struct rtw8822cu_efuse u; struct rtw8822cs_efuse s; }; -}; +} __packed;
enum rtw8822c_dpk_agc_phase { RTW_DPK_GAIN_CHECK, diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c index 799230eb5f16..e024061bdbf7 100644 --- a/drivers/net/wireless/realtek/rtw88/sdio.c +++ b/drivers/net/wireless/realtek/rtw88/sdio.c @@ -1192,6 +1192,8 @@ static void rtw_sdio_indicate_tx_status(struct rtw_dev *rtwdev, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_hw *hw = rtwdev->hw;
+ skb_pull(skb, rtwdev->chip->tx_pkt_desc_sz); + /* enqueue to wait for tx report */ if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn); diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index f923bec03d41..c3a027735d0f 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -2516,7 +2516,7 @@ static int rtw89_pci_dphy_delay(struct rtw89_dev *rtwdev) PCIE_DPHY_DLY_25US, PCIE_PHY_GEN1); }
-static void rtw89_pci_power_wake(struct rtw89_dev *rtwdev, bool pwr_up) +static void rtw89_pci_power_wake_ax(struct rtw89_dev *rtwdev, bool pwr_up) { if (pwr_up) rtw89_write32_set(rtwdev, R_AX_HCI_OPT_CTRL, BIT_WAKE_CTRL); @@ -2825,6 +2825,8 @@ static int rtw89_pci_ops_deinit(struct rtw89_dev *rtwdev) { const struct rtw89_pci_info *info = rtwdev->pci_info;
+ rtw89_pci_power_wake(rtwdev, false); + if (rtwdev->chip->chip_id == RTL8852A) { /* ltr sw trigger */ rtw89_write32_set(rtwdev, R_AX_LTR_CTRL_0, B_AX_APP_LTR_IDLE); @@ -2867,7 +2869,7 @@ static int rtw89_pci_ops_mac_pre_init_ax(struct rtw89_dev *rtwdev) return ret; }
- rtw89_pci_power_wake(rtwdev, true); + rtw89_pci_power_wake_ax(rtwdev, true); rtw89_pci_autoload_hang(rtwdev); rtw89_pci_l12_vmain(rtwdev); rtw89_pci_gen2_force_ib(rtwdev); @@ -2912,6 +2914,13 @@ static int rtw89_pci_ops_mac_pre_init_ax(struct rtw89_dev *rtwdev) return 0; }
+static int rtw89_pci_ops_mac_pre_deinit_ax(struct rtw89_dev *rtwdev) +{ + rtw89_pci_power_wake_ax(rtwdev, false); + + return 0; +} + int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev, bool en) { u32 val; @@ -4325,7 +4334,7 @@ const struct rtw89_pci_gen_def rtw89_pci_gen_ax = { B_AX_RDU_INT},
.mac_pre_init = rtw89_pci_ops_mac_pre_init_ax, - .mac_pre_deinit = NULL, + .mac_pre_deinit = rtw89_pci_ops_mac_pre_deinit_ax, .mac_post_init = rtw89_pci_ops_mac_post_init_ax,
.clr_idx_all = rtw89_pci_clr_idx_all_ax, @@ -4343,6 +4352,7 @@ const struct rtw89_pci_gen_def rtw89_pci_gen_ax = { .l1ss_set = rtw89_pci_l1ss_set_ax,
.disable_eq = rtw89_pci_disable_eq_ax, + .power_wake = rtw89_pci_power_wake_ax, }; EXPORT_SYMBOL(rtw89_pci_gen_ax);
diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index b68e2d82eea9..d52db4ca1b99 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -1290,6 +1290,7 @@ struct rtw89_pci_gen_def { void (*l1ss_set)(struct rtw89_dev *rtwdev, bool enable);
void (*disable_eq)(struct rtw89_dev *rtwdev); + void (*power_wake)(struct rtw89_dev *rtwdev, bool pwr_up); };
#define RTW89_PCI_SSID(v, d, ssv, ssd, cust) \ @@ -1805,4 +1806,12 @@ static inline void rtw89_pci_disable_eq(struct rtw89_dev *rtwdev) gen_def->disable_eq(rtwdev); }
+static inline void rtw89_pci_power_wake(struct rtw89_dev *rtwdev, bool pwr_up) +{ + const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_pci_gen_def *gen_def = info->gen_def; + + gen_def->power_wake(rtwdev, pwr_up); +} + #endif diff --git a/drivers/net/wireless/realtek/rtw89/pci_be.c b/drivers/net/wireless/realtek/rtw89/pci_be.c index 34154506f5d4..cd39eebe8186 100644 --- a/drivers/net/wireless/realtek/rtw89/pci_be.c +++ b/drivers/net/wireless/realtek/rtw89/pci_be.c @@ -691,5 +691,6 @@ const struct rtw89_pci_gen_def rtw89_pci_gen_be = { .l1ss_set = rtw89_pci_l1ss_set_be,
.disable_eq = rtw89_pci_disable_eq_be, + .power_wake = _patch_pcie_power_wake_be, }; EXPORT_SYMBOL(rtw89_pci_gen_be); diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index f24aca663cf0..b9171f6ccae0 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -4058,7 +4058,6 @@ static void rtw89_phy_cfo_set_crystal_cap(struct rtw89_dev *rtwdev,
if (!force && cfo->crystal_cap == crystal_cap) return; - crystal_cap = clamp_t(u8, crystal_cap, 0, 127); if (chip->chip_id == RTL8852A || chip->chip_id == RTL8851B) { rtw89_phy_cfo_set_xcap_reg(rtwdev, true, crystal_cap); rtw89_phy_cfo_set_xcap_reg(rtwdev, false, crystal_cap); @@ -4181,7 +4180,7 @@ static void rtw89_phy_cfo_crystal_cap_adjust(struct rtw89_dev *rtwdev, s32 curr_cfo) { struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; - s8 crystal_cap = cfo->crystal_cap; + int crystal_cap = cfo->crystal_cap; s32 cfo_abs = abs(curr_cfo); int sign;
@@ -4202,15 +4201,17 @@ static void rtw89_phy_cfo_crystal_cap_adjust(struct rtw89_dev *rtwdev, } sign = curr_cfo > 0 ? 1 : -1; if (cfo_abs > CFO_TRK_STOP_TH_4) - crystal_cap += 7 * sign; + crystal_cap += 3 * sign; else if (cfo_abs > CFO_TRK_STOP_TH_3) - crystal_cap += 5 * sign; - else if (cfo_abs > CFO_TRK_STOP_TH_2) crystal_cap += 3 * sign; + else if (cfo_abs > CFO_TRK_STOP_TH_2) + crystal_cap += 1 * sign; else if (cfo_abs > CFO_TRK_STOP_TH_1) crystal_cap += 1 * sign; else return; + + crystal_cap = clamp(crystal_cap, 0, 127); rtw89_phy_cfo_set_crystal_cap(rtwdev, (u8)crystal_cap, false); rtw89_debug(rtwdev, RTW89_DBG_CFO, "X_cap{Curr,Default}={0x%x,0x%x}\n", diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h index c683f4d7d29b..bc6912b3a2fb 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.h +++ b/drivers/net/wireless/realtek/rtw89/phy.h @@ -57,7 +57,7 @@ #define CFO_TRK_STOP_TH_4 (30 << 2) #define CFO_TRK_STOP_TH_3 (20 << 2) #define CFO_TRK_STOP_TH_2 (10 << 2) -#define CFO_TRK_STOP_TH_1 (00 << 2) +#define CFO_TRK_STOP_TH_1 (03 << 2) #define CFO_TRK_STOP_TH (2 << 2) #define CFO_SW_COMP_FINE_TUNE (2 << 2) #define CFO_PERIOD_CNT 15 diff --git a/drivers/net/wwan/iosm/iosm_ipc_pcie.c b/drivers/net/wwan/iosm/iosm_ipc_pcie.c index 04517bd3325a..a066977af0be 100644 --- a/drivers/net/wwan/iosm/iosm_ipc_pcie.c +++ b/drivers/net/wwan/iosm/iosm_ipc_pcie.c @@ -6,6 +6,7 @@ #include <linux/acpi.h> #include <linux/bitfield.h> #include <linux/module.h> +#include <linux/suspend.h> #include <net/rtnetlink.h>
#include "iosm_ipc_imem.h" @@ -18,6 +19,7 @@ MODULE_LICENSE("GPL v2"); /* WWAN GUID */ static guid_t wwan_acpi_guid = GUID_INIT(0xbad01b75, 0x22a8, 0x4f48, 0x87, 0x92, 0xbd, 0xde, 0x94, 0x67, 0x74, 0x7d); +static bool pci_registered;
static void ipc_pcie_resources_release(struct iosm_pcie *ipc_pcie) { @@ -448,7 +450,6 @@ static struct pci_driver iosm_ipc_driver = { }, .id_table = iosm_ipc_ids, }; -module_pci_driver(iosm_ipc_driver);
int ipc_pcie_addr_map(struct iosm_pcie *ipc_pcie, unsigned char *data, size_t size, dma_addr_t *mapping, int direction) @@ -530,3 +531,56 @@ void ipc_pcie_kfree_skb(struct iosm_pcie *ipc_pcie, struct sk_buff *skb) IPC_CB(skb)->mapping = 0; dev_kfree_skb(skb); } + +static int pm_notify(struct notifier_block *nb, unsigned long mode, void *_unused) +{ + if (mode == PM_HIBERNATION_PREPARE || mode == PM_RESTORE_PREPARE) { + if (pci_registered) { + pci_unregister_driver(&iosm_ipc_driver); + pci_registered = false; + } + } else if (mode == PM_POST_HIBERNATION || mode == PM_POST_RESTORE) { + if (!pci_registered) { + int ret; + + ret = pci_register_driver(&iosm_ipc_driver); + if (ret) { + pr_err(KBUILD_MODNAME ": unable to re-register PCI driver: %d\n", + ret); + } else { + pci_registered = true; + } + } + } + + return 0; +} + +static struct notifier_block pm_notifier = { + .notifier_call = pm_notify, +}; + +static int __init iosm_ipc_driver_init(void) +{ + int ret; + + ret = pci_register_driver(&iosm_ipc_driver); + if (ret) + return ret; + + pci_registered = true; + + register_pm_notifier(&pm_notifier); + + return 0; +} +module_init(iosm_ipc_driver_init); + +static void __exit iosm_ipc_driver_exit(void) +{ + unregister_pm_notifier(&pm_notifier); + + if (pci_registered) + pci_unregister_driver(&iosm_ipc_driver); +} +module_exit(iosm_ipc_driver_exit); diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 12e7ae1f99e2..46e04b30f642 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1695,7 +1695,13 @@ int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count)
status = nvme_set_features(ctrl, NVME_FEAT_NUM_QUEUES, q_count, NULL, 0, &result); - if (status < 0) + + /* + * It's either a kernel error or the host observed a connection + * lost. In either case it's not possible communicate with the + * controller and thus enter the error code path. + */ + if (status < 0 || status == NVME_SC_HOST_PATH_ERROR) return status;
/* diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index b81af7919e94..682234da2fab 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -2080,7 +2080,8 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) nvme_fc_complete_rq(rq);
check_error: - if (terminate_assoc && ctrl->ctrl.state != NVME_CTRL_RESETTING) + if (terminate_assoc && + nvme_ctrl_state(&ctrl->ctrl) != NVME_CTRL_RESETTING) queue_work(nvme_reset_wq, &ctrl->ioerr_work); }
@@ -2534,6 +2535,8 @@ __nvme_fc_abort_outstanding_ios(struct nvme_fc_ctrl *ctrl, bool start_queues) static void nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg) { + enum nvme_ctrl_state state = nvme_ctrl_state(&ctrl->ctrl); + /* * if an error (io timeout, etc) while (re)connecting, the remote * port requested terminating of the association (disconnect_ls) @@ -2541,7 +2544,7 @@ nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg) * the controller. Abort any ios on the association and let the * create_association error path resolve things. */ - if (ctrl->ctrl.state == NVME_CTRL_CONNECTING) { + if (state == NVME_CTRL_CONNECTING) { __nvme_fc_abort_outstanding_ios(ctrl, true); set_bit(ASSOC_FAILED, &ctrl->flags); dev_warn(ctrl->ctrl.device, @@ -2551,7 +2554,7 @@ nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg) }
/* Otherwise, only proceed if in LIVE state - e.g. on first error */ - if (ctrl->ctrl.state != NVME_CTRL_LIVE) + if (state != NVME_CTRL_LIVE) return;
dev_warn(ctrl->ctrl.device, diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index e2634f437f33..99c2983dbe6c 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -3148,7 +3148,9 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev) * because of high power consumption (> 2 Watt) in s2idle * sleep. Only some boards with Intel CPU are affected. */ - if (dmi_match(DMI_BOARD_NAME, "GMxPXxx") || + if (dmi_match(DMI_BOARD_NAME, "DN50Z-140HC-YD") || + dmi_match(DMI_BOARD_NAME, "GMxPXxx") || + dmi_match(DMI_BOARD_NAME, "GXxMRXx") || dmi_match(DMI_BOARD_NAME, "PH4PG31") || dmi_match(DMI_BOARD_NAME, "PH4PRX1_PH6PRX1") || dmi_match(DMI_BOARD_NAME, "PH6PG01_PH6PG71")) diff --git a/drivers/nvme/host/sysfs.c b/drivers/nvme/host/sysfs.c index b68a9e5f1ea3..3a41b9ab0f13 100644 --- a/drivers/nvme/host/sysfs.c +++ b/drivers/nvme/host/sysfs.c @@ -792,7 +792,7 @@ static umode_t nvme_tls_attrs_are_visible(struct kobject *kobj, return a->mode; }
-const struct attribute_group nvme_tls_attrs_group = { +static const struct attribute_group nvme_tls_attrs_group = { .attrs = nvme_tls_attrs, .is_visible = nvme_tls_attrs_are_visible, }; diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index fa89b0549c36..7b70635373fd 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -915,6 +915,7 @@ static void nvme_execute_identify_ns_nvm(struct nvmet_req *req) goto out; } status = nvmet_copy_to_sgl(req, 0, id, sizeof(*id)); + kfree(id); out: nvmet_req_complete(req, status); } diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index d6494dfc20a7..845540b57e68 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -1790,6 +1790,8 @@ static int __nvmem_cell_entry_write(struct nvmem_cell_entry *cell, void *buf, si return -EINVAL;
if (cell->bit_offset || cell->nbits) { + if (len != BITS_TO_BYTES(cell->nbits) && len != cell->bytes) + return -EINVAL; buf = nvmem_cell_prepare_write_buffer(cell, buf, len); if (IS_ERR(buf)) return PTR_ERR(buf); diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c index 1ba494497698..ca6dd71d8a2e 100644 --- a/drivers/nvmem/imx-ocotp-ele.c +++ b/drivers/nvmem/imx-ocotp-ele.c @@ -71,13 +71,15 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz u32 *buf; void *p; int i; + u8 skipbytes;
- index = offset; - num_bytes = round_up(bytes, 4); - count = num_bytes >> 2; + if (offset + bytes > priv->data->size) + bytes = priv->data->size - offset;
- if (count > ((priv->data->size >> 2) - index)) - count = (priv->data->size >> 2) - index; + index = offset >> 2; + skipbytes = offset - (index << 2); + num_bytes = round_up(bytes + skipbytes, 4); + count = num_bytes >> 2;
p = kzalloc(num_bytes, GFP_KERNEL); if (!p) @@ -100,7 +102,7 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz *buf++ = readl_relaxed(reg + (i << 2)); }
- memcpy(val, (u8 *)p, bytes); + memcpy(val, ((u8 *)p) + skipbytes, bytes);
mutex_unlock(&priv->lock);
@@ -109,6 +111,26 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz return 0; };
+static int imx_ocotp_cell_pp(void *context, const char *id, int index, + unsigned int offset, void *data, size_t bytes) +{ + u8 *buf = data; + int i; + + /* Deal with some post processing of nvmem cell data */ + if (id && !strcmp(id, "mac-address")) + for (i = 0; i < bytes / 2; i++) + swap(buf[i], buf[bytes - i - 1]); + + return 0; +} + +static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem, + struct nvmem_cell_info *cell) +{ + cell->read_post_process = imx_ocotp_cell_pp; +} + static int imx_ele_ocotp_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -131,10 +153,12 @@ static int imx_ele_ocotp_probe(struct platform_device *pdev) priv->config.owner = THIS_MODULE; priv->config.size = priv->data->size; priv->config.reg_read = priv->data->reg_read; - priv->config.word_size = 4; + priv->config.word_size = 1; priv->config.stride = 1; priv->config.priv = priv; priv->config.read_only = true; + priv->config.add_legacy_fixed_of_cells = true; + priv->config.fixup_dt_cell_info = imx_ocotp_fixup_dt_cell_info; mutex_init(&priv->lock);
nvmem = devm_nvmem_register(dev, &priv->config); diff --git a/drivers/nvmem/qcom-spmi-sdam.c b/drivers/nvmem/qcom-spmi-sdam.c index 9aa8f42faa4c..4f1cca6eab71 100644 --- a/drivers/nvmem/qcom-spmi-sdam.c +++ b/drivers/nvmem/qcom-spmi-sdam.c @@ -144,6 +144,7 @@ static int sdam_probe(struct platform_device *pdev) sdam->sdam_config.owner = THIS_MODULE; sdam->sdam_config.add_legacy_fixed_of_cells = true; sdam->sdam_config.stride = 1; + sdam->sdam_config.size = sdam->size; sdam->sdam_config.word_size = 1; sdam->sdam_config.reg_read = sdam_read; sdam->sdam_config.reg_write = sdam_write; diff --git a/drivers/of/address.c b/drivers/of/address.c index 8770004d9b08..5c0663066a7f 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -200,17 +200,15 @@ static u64 of_bus_pci_map(__be32 *addr, const __be32 *range, int na, int ns,
static int __of_address_resource_bounds(struct resource *r, u64 start, u64 size) { - u64 end = start; - if (overflows_type(start, r->start)) return -EOVERFLOW; - if (size && check_add_overflow(end, size - 1, &end)) - return -EOVERFLOW; - if (overflows_type(end, r->end)) - return -EOVERFLOW;
r->start = start; - r->end = end; + + if (!size) + r->end = wrapping_sub(typeof(r->end), r->start, 1); + else if (size && check_add_overflow(r->start, size - 1, &r->end)) + return -EOVERFLOW;
return 0; } diff --git a/drivers/of/base.c b/drivers/of/base.c index 6f5abea2462a..dc57401c72ea 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -894,10 +894,10 @@ struct device_node *of_find_node_opts_by_path(const char *path, const char **opt /* The path could begin with an alias */ if (*path != '/') { int len; - const char *p = separator; + const char *p = strchrnul(path, '/');
- if (!p) - p = strchrnul(path, '/'); + if (separator && separator < p) + p = separator; len = p - path;
/* of_aliases must not be NULL */ @@ -1546,7 +1546,6 @@ int of_parse_phandle_with_args_map(const struct device_node *np, * specifier into the out_args structure, keeping the * bits specified in <list>-map-pass-thru. */ - match_array = map - new_size; for (i = 0; i < new_size; i++) { __be32 val = *(map - new_size + i);
@@ -1555,6 +1554,7 @@ int of_parse_phandle_with_args_map(const struct device_node *np, val |= cpu_to_be32(out_args->args[i]) & pass[i]; }
+ initial_match_array[i] = val; out_args->args[i] = be32_to_cpu(val); } out_args->args_count = list_size = new_size; diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index b47559f11f07..e2da88d7706a 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -263,6 +263,11 @@ void __init fdt_scan_reserved_mem_reg_nodes(void) uname); continue; } + + if (len > t_len) + pr_warn("%s() ignores %d regions in node '%s'\n", + __func__, len / t_len - 1, uname); + base = dt_mem_next_cell(dt_root_addr_cells, &prop); size = dt_mem_next_cell(dt_root_size_cells, &prop);
@@ -410,12 +415,12 @@ static int __init __reserved_mem_alloc_size(unsigned long node, const char *unam
prop = of_get_flat_dt_prop(node, "alignment", &len); if (prop) { - if (len != dt_root_addr_cells * sizeof(__be32)) { + if (len != dt_root_size_cells * sizeof(__be32)) { pr_err("invalid alignment property in '%s' node.\n", uname); return -EINVAL; } - align = dt_mem_next_cell(dt_root_addr_cells, &prop); + align = dt_mem_next_cell(dt_root_size_cells, &prop); }
nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL; diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index f3ac7d46a855..44a617d54b15 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c @@ -222,19 +222,30 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no, if ((flags & PCI_BASE_ADDRESS_MEM_TYPE_64) && (bar & 1)) return -EINVAL;
- reg = PCI_BASE_ADDRESS_0 + (4 * bar); - - if (!(flags & PCI_BASE_ADDRESS_SPACE)) - type = PCIE_ATU_TYPE_MEM; - else - type = PCIE_ATU_TYPE_IO; + /* + * Certain EPF drivers dynamically change the physical address of a BAR + * (i.e. they call set_bar() twice, without ever calling clear_bar(), as + * calling clear_bar() would clear the BAR's PCI address assigned by the + * host). + */ + if (ep->epf_bar[bar]) { + /* + * We can only dynamically change a BAR if the new BAR size and + * BAR flags do not differ from the existing configuration. + */ + if (ep->epf_bar[bar]->barno != bar || + ep->epf_bar[bar]->size != size || + ep->epf_bar[bar]->flags != flags) + return -EINVAL;
- ret = dw_pcie_ep_inbound_atu(ep, func_no, type, epf_bar->phys_addr, bar); - if (ret) - return ret; + /* + * When dynamically changing a BAR, skip writing the BAR reg, as + * that would clear the BAR's PCI address assigned by the host. + */ + goto config_atu; + }
- if (ep->epf_bar[bar]) - return 0; + reg = PCI_BASE_ADDRESS_0 + (4 * bar);
dw_pcie_dbi_ro_wr_en(pci);
@@ -246,9 +257,20 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no, dw_pcie_ep_writel_dbi(ep, func_no, reg + 4, 0); }
- ep->epf_bar[bar] = epf_bar; dw_pcie_dbi_ro_wr_dis(pci);
+config_atu: + if (!(flags & PCI_BASE_ADDRESS_SPACE)) + type = PCIE_ATU_TYPE_MEM; + else + type = PCIE_ATU_TYPE_IO; + + ret = dw_pcie_ep_inbound_atu(ep, func_no, type, epf_bar->phys_addr, bar); + if (ret) + return ret; + + ep->epf_bar[bar] = epf_bar; + return 0; }
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c index 8fa2797d4169..50bc2892a36c 100644 --- a/drivers/pci/endpoint/pci-epf-core.c +++ b/drivers/pci/endpoint/pci-epf-core.c @@ -202,6 +202,7 @@ void pci_epf_remove_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf)
mutex_lock(&epf_pf->lock); clear_bit(epf_vf->vfunc_no, &epf_pf->vfunction_num_map); + epf_vf->epf_pf = NULL; list_del(&epf_vf->list); mutex_unlock(&epf_pf->lock); } diff --git a/drivers/pci/tph.c b/drivers/pci/tph.c index 1e604fbbda65..07de59ca2ebf 100644 --- a/drivers/pci/tph.c +++ b/drivers/pci/tph.c @@ -360,7 +360,7 @@ int pcie_tph_set_st_entry(struct pci_dev *pdev, unsigned int index, u16 tag) return err; }
- set_ctrl_reg_req_en(pdev, pdev->tph_mode); + set_ctrl_reg_req_en(pdev, pdev->tph_req_type);
pci_dbg(pdev, "set steering tag: %s table, index=%d, tag=%#04x\n", (loc == PCI_TPH_LOC_MSIX) ? "MSI-X" : "ST", index, tag); diff --git a/drivers/perf/fsl_imx9_ddr_perf.c b/drivers/perf/fsl_imx9_ddr_perf.c index 3c856d9a4e97..843f163e6c33 100644 --- a/drivers/perf/fsl_imx9_ddr_perf.c +++ b/drivers/perf/fsl_imx9_ddr_perf.c @@ -63,8 +63,21 @@
static DEFINE_IDA(ddr_ida);
+/* + * V1 support 1 read transaction, 1 write transaction and 1 read beats + * event which corresponding respecitively to counter 2, 3 and 4. + */ +#define DDR_PERF_AXI_FILTER_V1 0x1 + +/* + * V2 support 1 read beats and 3 write beats events which corresponding + * respecitively to counter 2-5. + */ +#define DDR_PERF_AXI_FILTER_V2 0x2 + struct imx_ddr_devtype_data { const char *identifier; /* system PMU identifier for userspace */ + unsigned int filter_ver; /* AXI filter version */ };
struct ddr_pmu { @@ -83,24 +96,27 @@ struct ddr_pmu {
static const struct imx_ddr_devtype_data imx91_devtype_data = { .identifier = "imx91", + .filter_ver = DDR_PERF_AXI_FILTER_V1 };
static const struct imx_ddr_devtype_data imx93_devtype_data = { .identifier = "imx93", + .filter_ver = DDR_PERF_AXI_FILTER_V1 };
static const struct imx_ddr_devtype_data imx95_devtype_data = { .identifier = "imx95", + .filter_ver = DDR_PERF_AXI_FILTER_V2 };
-static inline bool is_imx93(struct ddr_pmu *pmu) +static inline bool axi_filter_v1(struct ddr_pmu *pmu) { - return pmu->devtype_data == &imx93_devtype_data; + return pmu->devtype_data->filter_ver == DDR_PERF_AXI_FILTER_V1; }
-static inline bool is_imx95(struct ddr_pmu *pmu) +static inline bool axi_filter_v2(struct ddr_pmu *pmu) { - return pmu->devtype_data == &imx95_devtype_data; + return pmu->devtype_data->filter_ver == DDR_PERF_AXI_FILTER_V2; }
static const struct of_device_id imx_ddr_pmu_dt_ids[] = { @@ -155,7 +171,7 @@ static const struct attribute_group ddr_perf_cpumask_attr_group = { struct imx9_pmu_events_attr { struct device_attribute attr; u64 id; - const void *devtype_data; + const struct imx_ddr_devtype_data *devtype_data; };
static ssize_t ddr_pmu_event_show(struct device *dev, @@ -307,7 +323,8 @@ ddr_perf_events_attrs_is_visible(struct kobject *kobj, if (!eattr->devtype_data) return attr->mode;
- if (eattr->devtype_data != ddr_pmu->devtype_data) + if (eattr->devtype_data != ddr_pmu->devtype_data && + eattr->devtype_data->filter_ver != ddr_pmu->devtype_data->filter_ver) return 0;
return attr->mode; @@ -624,11 +641,11 @@ static int ddr_perf_event_add(struct perf_event *event, int flags) hwc->idx = counter; hwc->state |= PERF_HES_STOPPED;
- if (is_imx93(pmu)) + if (axi_filter_v1(pmu)) /* read trans, write trans, read beat */ imx93_ddr_perf_monitor_config(pmu, event_id, counter, cfg1, cfg2);
- if (is_imx95(pmu)) + if (axi_filter_v2(pmu)) /* write beat, read beat2, read beat1, read beat */ imx95_ddr_perf_monitor_config(pmu, event_id, counter, cfg1, cfg2);
diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c index 1df9cec2873f..515c38de445a 100644 --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c @@ -157,7 +157,7 @@ #define PWPR_REGWE_B BIT(5) /* OEN Register Write Enable, known only in RZ/V2H(P) */
#define PM_MASK 0x03 -#define PFC_MASK 0x07 +#define PFC_MASK 0x0f #define IEN_MASK 0x01 #define IOLH_MASK 0x03 #define SR_MASK 0x01 diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index bbedd980ec67..3ab5878b69d1 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -1272,7 +1272,7 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
ret = platform_get_irq_optional(pdev, 0); if (ret < 0 && ret != -ENXIO) - return ret; + goto err_put_banks; if (ret > 0) drvdata->irq = ret;
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index d09baa3d3d90..ac4f8ab45bdc 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -95,6 +95,7 @@ enum acer_wmi_event_ids { WMID_HOTKEY_EVENT = 0x1, WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5, WMID_GAMING_TURBO_KEY_EVENT = 0x7, + WMID_AC_EVENT = 0x8, };
enum acer_wmi_predator_v4_sys_info_command { @@ -393,6 +394,20 @@ static struct quirk_entry quirk_acer_predator_ph315_53 = { .gpu_fans = 1, };
+static struct quirk_entry quirk_acer_predator_ph16_72 = { + .turbo = 1, + .cpu_fans = 1, + .gpu_fans = 1, + .predator_v4 = 1, +}; + +static struct quirk_entry quirk_acer_predator_pt14_51 = { + .turbo = 1, + .cpu_fans = 1, + .gpu_fans = 1, + .predator_v4 = 1, +}; + static struct quirk_entry quirk_acer_predator_v4 = { .predator_v4 = 1, }; @@ -564,6 +579,15 @@ static const struct dmi_system_id acer_quirks[] __initconst = { }, .driver_data = &quirk_acer_travelmate_2490, }, + { + .callback = dmi_matched, + .ident = "Acer Nitro AN515-58", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Nitro AN515-58"), + }, + .driver_data = &quirk_acer_predator_v4, + }, { .callback = dmi_matched, .ident = "Acer Predator PH315-53", @@ -591,6 +615,15 @@ static const struct dmi_system_id acer_quirks[] __initconst = { }, .driver_data = &quirk_acer_predator_v4, }, + { + .callback = dmi_matched, + .ident = "Acer Predator PH16-72", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Predator PH16-72"), + }, + .driver_data = &quirk_acer_predator_ph16_72, + }, { .callback = dmi_matched, .ident = "Acer Predator PH18-71", @@ -600,6 +633,15 @@ static const struct dmi_system_id acer_quirks[] __initconst = { }, .driver_data = &quirk_acer_predator_v4, }, + { + .callback = dmi_matched, + .ident = "Acer Predator PT14-51", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Predator PT14-51"), + }, + .driver_data = &quirk_acer_predator_pt14_51, + }, { .callback = set_force_caps, .ident = "Acer Aspire Switch 10E SW3-016", @@ -2280,6 +2322,9 @@ static void acer_wmi_notify(union acpi_object *obj, void *context) if (return_value.key_num == 0x5 && has_cap(ACER_CAP_PLATFORM_PROFILE)) acer_thermal_profile_change(); break; + case WMID_AC_EVENT: + /* We ignore AC events here */ + break; default: pr_warn("Unknown function number - %d - %d\n", return_value.function, return_value.key_num); diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c index d881b2cfcdfc..09fff213b091 100644 --- a/drivers/platform/x86/intel/int3472/discrete.c +++ b/drivers/platform/x86/intel/int3472/discrete.c @@ -336,6 +336,9 @@ static int skl_int3472_discrete_probe(struct platform_device *pdev) struct int3472_cldb cldb; int ret;
+ if (!adev) + return -ENODEV; + ret = skl_int3472_fill_cldb(adev, &cldb); if (ret) { dev_err(&pdev->dev, "Couldn't fill CLDB structure\n"); diff --git a/drivers/platform/x86/intel/int3472/tps68470.c b/drivers/platform/x86/intel/int3472/tps68470.c index 1e107fd49f82..81ac4c691963 100644 --- a/drivers/platform/x86/intel/int3472/tps68470.c +++ b/drivers/platform/x86/intel/int3472/tps68470.c @@ -152,6 +152,9 @@ static int skl_int3472_tps68470_probe(struct i2c_client *client) int ret; int i;
+ if (!adev) + return -ENODEV; + n_consumers = skl_int3472_fill_clk_pdata(&client->dev, &clk_pdata); if (n_consumers < 0) return n_consumers; diff --git a/drivers/platform/x86/serdev_helpers.h b/drivers/platform/x86/serdev_helpers.h index bcf3a0c356ea..3bc7fd8e1e19 100644 --- a/drivers/platform/x86/serdev_helpers.h +++ b/drivers/platform/x86/serdev_helpers.h @@ -35,7 +35,7 @@ get_serdev_controller(const char *serial_ctrl_hid, ctrl_adev = acpi_dev_get_first_match_dev(serial_ctrl_hid, serial_ctrl_uid, -1); if (!ctrl_adev) { pr_err("error could not get %s/%s serial-ctrl adev\n", - serial_ctrl_hid, serial_ctrl_uid); + serial_ctrl_hid, serial_ctrl_uid ?: "*"); return ERR_PTR(-ENODEV); }
@@ -43,7 +43,7 @@ get_serdev_controller(const char *serial_ctrl_hid, ctrl_dev = get_device(acpi_get_first_physical_node(ctrl_adev)); if (!ctrl_dev) { pr_err("error could not get %s/%s serial-ctrl physical node\n", - serial_ctrl_hid, serial_ctrl_uid); + serial_ctrl_hid, serial_ctrl_uid ?: "*"); ctrl_dev = ERR_PTR(-ENODEV); goto put_ctrl_adev; } diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index 77a36e7bddd5..1a1edd87122d 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -217,6 +217,11 @@ static int ptp_getcycles64(struct ptp_clock_info *info, struct timespec64 *ts) return info->gettime64(info, ts); }
+static int ptp_enable(struct ptp_clock_info *ptp, struct ptp_clock_request *request, int on) +{ + return -EOPNOTSUPP; +} + static void ptp_aux_kworker(struct kthread_work *work) { struct ptp_clock *ptp = container_of(work, struct ptp_clock, @@ -294,6 +299,9 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, ptp->info->getcrosscycles = ptp->info->getcrosststamp; }
+ if (!ptp->info->enable) + ptp->info->enable = ptp_enable; + if (ptp->info->do_aux_work) { kthread_init_delayed_work(&ptp->aux_work, ptp_aux_kworker); ptp->kworker = kthread_create_worker(0, "ptp%d", ptp->index); diff --git a/drivers/pwm/pwm-microchip-core.c b/drivers/pwm/pwm-microchip-core.c index c1f2287b8e97..12821b4bbf97 100644 --- a/drivers/pwm/pwm-microchip-core.c +++ b/drivers/pwm/pwm-microchip-core.c @@ -327,7 +327,7 @@ static int mchp_core_pwm_apply_locked(struct pwm_chip *chip, struct pwm_device * * mchp_core_pwm_calc_period(). * The period is locked and we cannot change this, so we abort. */ - if (hw_period_steps == MCHPCOREPWM_PERIOD_STEPS_MAX) + if (hw_period_steps > MCHPCOREPWM_PERIOD_STEPS_MAX) return -EINVAL;
prescale = hw_prescale; diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c index 9ae2e831456d..3260dd512491 100644 --- a/drivers/remoteproc/omap_remoteproc.c +++ b/drivers/remoteproc/omap_remoteproc.c @@ -37,6 +37,10 @@
#include <linux/platform_data/dmtimer-omap.h>
+#ifdef CONFIG_ARM_DMA_USE_IOMMU +#include <asm/dma-iommu.h> +#endif + #include "omap_remoteproc.h" #include "remoteproc_internal.h"
@@ -1323,6 +1327,19 @@ static int omap_rproc_probe(struct platform_device *pdev) /* All existing OMAP IPU and DSP processors have an MMU */ rproc->has_iommu = true;
+#ifdef CONFIG_ARM_DMA_USE_IOMMU + /* + * Throw away the ARM DMA mapping that we'll never use, so it doesn't + * interfere with the core rproc->domain and we get the right DMA ops. + */ + if (pdev->dev.archdata.mapping) { + struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(&pdev->dev); + + arm_iommu_detach_device(&pdev->dev); + arm_iommu_release_mapping(mapping); + } +#endif + ret = omap_rproc_of_get_internal_memories(pdev, rproc); if (ret) return ret; diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c index af1abb69d1e3..17f68c25dc29 100644 --- a/drivers/rtc/rtc-zynqmp.c +++ b/drivers/rtc/rtc-zynqmp.c @@ -318,8 +318,8 @@ static int xlnx_rtc_probe(struct platform_device *pdev) return ret; }
- /* Getting the rtc_clk info */ - xrtcdev->rtc_clk = devm_clk_get_optional(&pdev->dev, "rtc_clk"); + /* Getting the rtc info */ + xrtcdev->rtc_clk = devm_clk_get_optional(&pdev->dev, "rtc"); if (IS_ERR(xrtcdev->rtc_clk)) { if (PTR_ERR(xrtcdev->rtc_clk) != -EPROBE_DEFER) dev_warn(&pdev->dev, "Device clock not found.\n"); diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 15066c112817..cb95b7b12051 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -4098,6 +4098,8 @@ struct qla_hw_data { uint32_t npiv_supported :1; uint32_t pci_channel_io_perm_failure :1; uint32_t fce_enabled :1; + uint32_t user_enabled_fce :1; + uint32_t fce_dump_buf_alloced :1; uint32_t fac_supported :1;
uint32_t chip_reset_done :1; diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c index a1545dad0c0c..08273520c777 100644 --- a/drivers/scsi/qla2xxx/qla_dfs.c +++ b/drivers/scsi/qla2xxx/qla_dfs.c @@ -409,26 +409,31 @@ qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
mutex_lock(&ha->fce_mutex);
- seq_puts(s, "FCE Trace Buffer\n"); - seq_printf(s, "In Pointer = %llx\n\n", (unsigned long long)ha->fce_wr); - seq_printf(s, "Base = %llx\n\n", (unsigned long long) ha->fce_dma); - seq_puts(s, "FCE Enable Registers\n"); - seq_printf(s, "%08x %08x %08x %08x %08x %08x\n", - ha->fce_mb[0], ha->fce_mb[2], ha->fce_mb[3], ha->fce_mb[4], - ha->fce_mb[5], ha->fce_mb[6]); - - fce = (uint32_t *) ha->fce; - fce_start = (unsigned long long) ha->fce_dma; - for (cnt = 0; cnt < fce_calc_size(ha->fce_bufs) / 4; cnt++) { - if (cnt % 8 == 0) - seq_printf(s, "\n%llx: ", - (unsigned long long)((cnt * 4) + fce_start)); - else - seq_putc(s, ' '); - seq_printf(s, "%08x", *fce++); - } + if (ha->flags.user_enabled_fce) { + seq_puts(s, "FCE Trace Buffer\n"); + seq_printf(s, "In Pointer = %llx\n\n", (unsigned long long)ha->fce_wr); + seq_printf(s, "Base = %llx\n\n", (unsigned long long)ha->fce_dma); + seq_puts(s, "FCE Enable Registers\n"); + seq_printf(s, "%08x %08x %08x %08x %08x %08x\n", + ha->fce_mb[0], ha->fce_mb[2], ha->fce_mb[3], ha->fce_mb[4], + ha->fce_mb[5], ha->fce_mb[6]); + + fce = (uint32_t *)ha->fce; + fce_start = (unsigned long long)ha->fce_dma; + for (cnt = 0; cnt < fce_calc_size(ha->fce_bufs) / 4; cnt++) { + if (cnt % 8 == 0) + seq_printf(s, "\n%llx: ", + (unsigned long long)((cnt * 4) + fce_start)); + else + seq_putc(s, ' '); + seq_printf(s, "%08x", *fce++); + }
- seq_puts(s, "\nEnd\n"); + seq_puts(s, "\nEnd\n"); + } else { + seq_puts(s, "FCE Trace is currently not enabled\n"); + seq_puts(s, "\techo [ 1 | 0 ] > fce\n"); + }
mutex_unlock(&ha->fce_mutex);
@@ -467,7 +472,7 @@ qla2x00_dfs_fce_release(struct inode *inode, struct file *file) struct qla_hw_data *ha = vha->hw; int rval;
- if (ha->flags.fce_enabled) + if (ha->flags.fce_enabled || !ha->fce) goto out;
mutex_lock(&ha->fce_mutex); @@ -488,11 +493,88 @@ qla2x00_dfs_fce_release(struct inode *inode, struct file *file) return single_release(inode, file); }
+static ssize_t +qla2x00_dfs_fce_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + struct seq_file *s = file->private_data; + struct scsi_qla_host *vha = s->private; + struct qla_hw_data *ha = vha->hw; + char *buf; + int rc = 0; + unsigned long enable; + + if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && + !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) { + ql_dbg(ql_dbg_user, vha, 0xd034, + "this adapter does not support FCE."); + return -EINVAL; + } + + buf = memdup_user_nul(buffer, count); + if (IS_ERR(buf)) { + ql_dbg(ql_dbg_user, vha, 0xd037, + "fail to copy user buffer."); + return PTR_ERR(buf); + } + + enable = kstrtoul(buf, 0, 0); + rc = count; + + mutex_lock(&ha->fce_mutex); + + if (enable) { + if (ha->flags.user_enabled_fce) { + mutex_unlock(&ha->fce_mutex); + goto out_free; + } + ha->flags.user_enabled_fce = 1; + if (!ha->fce) { + rc = qla2x00_alloc_fce_trace(vha); + if (rc) { + ha->flags.user_enabled_fce = 0; + mutex_unlock(&ha->fce_mutex); + goto out_free; + } + + /* adjust fw dump buffer to take into account of this feature */ + if (!ha->flags.fce_dump_buf_alloced) + qla2x00_alloc_fw_dump(vha); + } + + if (!ha->flags.fce_enabled) + qla_enable_fce_trace(vha); + + ql_dbg(ql_dbg_user, vha, 0xd045, "User enabled FCE .\n"); + } else { + if (!ha->flags.user_enabled_fce) { + mutex_unlock(&ha->fce_mutex); + goto out_free; + } + ha->flags.user_enabled_fce = 0; + if (ha->flags.fce_enabled) { + qla2x00_disable_fce_trace(vha, NULL, NULL); + ha->flags.fce_enabled = 0; + } + + qla2x00_free_fce_trace(ha); + /* no need to re-adjust fw dump buffer */ + + ql_dbg(ql_dbg_user, vha, 0xd04f, "User disabled FCE .\n"); + } + + mutex_unlock(&ha->fce_mutex); +out_free: + kfree(buf); + return rc; +} + static const struct file_operations dfs_fce_ops = { .open = qla2x00_dfs_fce_open, .read = seq_read, .llseek = seq_lseek, .release = qla2x00_dfs_fce_release, + .write = qla2x00_dfs_fce_write, };
static int @@ -626,8 +708,6 @@ qla2x00_dfs_setup(scsi_qla_host_t *vha) if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) goto out; - if (!ha->fce) - goto out;
if (qla2x00_dfs_root) goto create_dir; diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index cededfda9d0e..e556f57c91af 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -11,6 +11,9 @@ /* * Global Function Prototypes in qla_init.c source file. */ +int qla2x00_alloc_fce_trace(scsi_qla_host_t *); +void qla2x00_free_fce_trace(struct qla_hw_data *ha); +void qla_enable_fce_trace(scsi_qla_host_t *); extern int qla2x00_initialize_adapter(scsi_qla_host_t *); extern int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 31fc6a0eca3e..79cdfec2bca3 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2681,7 +2681,7 @@ qla83xx_nic_core_fw_load(scsi_qla_host_t *vha) return rval; }
-static void qla_enable_fce_trace(scsi_qla_host_t *vha) +void qla_enable_fce_trace(scsi_qla_host_t *vha) { int rval; struct qla_hw_data *ha = vha->hw; @@ -3717,25 +3717,24 @@ qla24xx_chip_diag(scsi_qla_host_t *vha) return rval; }
-static void -qla2x00_alloc_fce_trace(scsi_qla_host_t *vha) +int qla2x00_alloc_fce_trace(scsi_qla_host_t *vha) { dma_addr_t tc_dma; void *tc; struct qla_hw_data *ha = vha->hw;
if (!IS_FWI2_CAPABLE(ha)) - return; + return -EINVAL;
if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) - return; + return -EINVAL;
if (ha->fce) { ql_dbg(ql_dbg_init, vha, 0x00bd, "%s: FCE Mem is already allocated.\n", __func__); - return; + return -EIO; }
/* Allocate memory for Fibre Channel Event Buffer. */ @@ -3745,7 +3744,7 @@ qla2x00_alloc_fce_trace(scsi_qla_host_t *vha) ql_log(ql_log_warn, vha, 0x00be, "Unable to allocate (%d KB) for FCE.\n", FCE_SIZE / 1024); - return; + return -ENOMEM; }
ql_dbg(ql_dbg_init, vha, 0x00c0, @@ -3754,6 +3753,16 @@ qla2x00_alloc_fce_trace(scsi_qla_host_t *vha) ha->fce_dma = tc_dma; ha->fce = tc; ha->fce_bufs = FCE_NUM_BUFFERS; + return 0; +} + +void qla2x00_free_fce_trace(struct qla_hw_data *ha) +{ + if (!ha->fce) + return; + dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce, ha->fce_dma); + ha->fce = NULL; + ha->fce_dma = 0; }
static void @@ -3844,9 +3853,10 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) if (ha->tgt.atio_ring) mq_size += ha->tgt.atio_q_length * sizeof(request_t);
- qla2x00_alloc_fce_trace(vha); - if (ha->fce) + if (ha->fce) { fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE; + ha->flags.fce_dump_buf_alloced = 1; + } qla2x00_alloc_eft_trace(vha); if (ha->eft) eft_size = EFT_SIZE; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 0cc6a0f77b09..5f9b107ae267 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -868,13 +868,18 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) case 0x1a: /* start stop unit in progress */ case 0x1b: /* sanitize in progress */ case 0x1d: /* configuration in progress */ - case 0x24: /* depopulation in progress */ - case 0x25: /* depopulation restore in progress */ action = ACTION_DELAYED_RETRY; break; case 0x0a: /* ALUA state transition */ action = ACTION_DELAYED_REPREP; break; + /* + * Depopulation might take many hours, + * thus it is not worthwhile to retry. + */ + case 0x24: /* depopulation in progress */ + case 0x25: /* depopulation restore in progress */ + fallthrough; default: action = ACTION_FAIL; break; diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index e8ef27d7ef61..ebbd50ec0cda 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -1030,6 +1030,11 @@ static int test_ready(struct scsi_tape *STp, int do_wait) retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY; break; } + if (STp->first_tur) { + /* Don't set pos_unknown right after device recognition */ + STp->pos_unknown = 0; + STp->first_tur = 0; + }
if (SRpnt != NULL) st_release_request(SRpnt); @@ -4328,6 +4333,7 @@ static int st_probe(struct device *dev) blk_queue_rq_timeout(tpnt->device->request_queue, ST_TIMEOUT); tpnt->long_timeout = ST_LONG_TIMEOUT; tpnt->try_dio = try_direct_io; + tpnt->first_tur = 1;
for (i = 0; i < ST_NBR_MODES; i++) { STm = &(tpnt->modes[i]); diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index 7a68eaba7e81..1aaaf5369a40 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h @@ -170,6 +170,7 @@ struct scsi_tape { unsigned char rew_at_close; /* rewind necessary at close */ unsigned char inited; unsigned char cleaning_req; /* cleaning requested? */ + unsigned char first_tur; /* first TEST UNIT READY */ int block_size; int min_block; int max_block; diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index b3c588b102d9..b8186feccdf5 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1800,6 +1800,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
length = scsi_bufflen(scmnd); payload = (struct vmbus_packet_mpb_array *)&cmd_request->mpb; + payload->range.len = 0; payload_sz = 0;
if (scsi_sg_count(scmnd)) { diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c index 2a1adcb87d4e..f54c966138b5 100644 --- a/drivers/soc/mediatek/mtk-devapc.c +++ b/drivers/soc/mediatek/mtk-devapc.c @@ -273,23 +273,31 @@ static int mtk_devapc_probe(struct platform_device *pdev) return -EINVAL;
devapc_irq = irq_of_parse_and_map(node, 0); - if (!devapc_irq) - return -EINVAL; + if (!devapc_irq) { + ret = -EINVAL; + goto err; + }
ctx->infra_clk = devm_clk_get_enabled(&pdev->dev, "devapc-infra-clock"); - if (IS_ERR(ctx->infra_clk)) - return -EINVAL; + if (IS_ERR(ctx->infra_clk)) { + ret = -EINVAL; + goto err; + }
ret = devm_request_irq(&pdev->dev, devapc_irq, devapc_violation_irq, IRQF_TRIGGER_NONE, "devapc", ctx); if (ret) - return ret; + goto err;
platform_set_drvdata(pdev, ctx);
start_devapc(ctx);
return 0; + +err: + iounmap(ctx->infra_base); + return ret; }
static void mtk_devapc_remove(struct platform_device *pdev) @@ -297,6 +305,7 @@ static void mtk_devapc_remove(struct platform_device *pdev) struct mtk_devapc_context *ctx = platform_get_drvdata(pdev);
stop_devapc(ctx); + iounmap(ctx->infra_base); }
static struct platform_driver mtk_devapc_driver = { diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c index 32c3bc887cef..1560db00a012 100644 --- a/drivers/soc/qcom/llcc-qcom.c +++ b/drivers/soc/qcom/llcc-qcom.c @@ -3004,6 +3004,7 @@ static const struct llcc_slice_config x1e80100_data[] = { .fixed_size = true, .bonus_ways = 0xfff, .cache_mode = 0, + .activate_on_init = true, }, { .usecase_id = LLCC_CAMEXP0, .slice_id = 4, diff --git a/drivers/soc/qcom/smem_state.c b/drivers/soc/qcom/smem_state.c index d9bfac6c54fb..cc5be8019b6a 100644 --- a/drivers/soc/qcom/smem_state.c +++ b/drivers/soc/qcom/smem_state.c @@ -112,7 +112,8 @@ struct qcom_smem_state *qcom_smem_state_get(struct device *dev,
if (args.args_count != 1) { dev_err(dev, "invalid #qcom,smem-state-cells\n"); - return ERR_PTR(-EINVAL); + state = ERR_PTR(-EINVAL); + goto put; }
state = of_node_to_state(args.np); diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 62fadfe44a09..d49c55979bb3 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -796,7 +796,7 @@ static int qcom_socinfo_probe(struct platform_device *pdev) if (!qs->attr.soc_id || !qs->attr.revision) return -ENOMEM;
- if (offsetof(struct socinfo, serial_num) <= item_size) { + if (offsetofend(struct socinfo, serial_num) <= item_size) { qs->attr.serial_number = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%u", le32_to_cpu(info->serial_num)); diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c index d8c53cec7f37..dd5256e5aae1 100644 --- a/drivers/soc/samsung/exynos-pmu.c +++ b/drivers/soc/samsung/exynos-pmu.c @@ -126,7 +126,7 @@ static int tensor_set_bits_atomic(void *ctx, unsigned int offset, u32 val, if (ret) return ret; } - return ret; + return 0; }
static bool tensor_is_atomic(unsigned int reg) diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c index 316bce577081..8887f6bd41c7 100644 --- a/drivers/spi/atmel-quadspi.c +++ b/drivers/spi/atmel-quadspi.c @@ -138,11 +138,15 @@ #define QSPI_WPSR_WPVSRC_MASK GENMASK(15, 8) #define QSPI_WPSR_WPVSRC(src) (((src) << 8) & QSPI_WPSR_WPVSRC)
+#define ATMEL_QSPI_TIMEOUT 1000 /* ms */ + struct atmel_qspi_caps { bool has_qspick; bool has_ricr; };
+struct atmel_qspi_ops; + struct atmel_qspi { void __iomem *regs; void __iomem *mem; @@ -150,13 +154,22 @@ struct atmel_qspi { struct clk *qspick; struct platform_device *pdev; const struct atmel_qspi_caps *caps; + const struct atmel_qspi_ops *ops; resource_size_t mmap_size; u32 pending; + u32 irq_mask; u32 mr; u32 scr; struct completion cmd_completion; };
+struct atmel_qspi_ops { + int (*set_cfg)(struct atmel_qspi *aq, const struct spi_mem_op *op, + u32 *offset); + int (*transfer)(struct spi_mem *mem, const struct spi_mem_op *op, + u32 offset); +}; + struct atmel_qspi_mode { u8 cmd_buswidth; u8 addr_buswidth; @@ -404,10 +417,67 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq, return 0; }
+static int atmel_qspi_wait_for_completion(struct atmel_qspi *aq, u32 irq_mask) +{ + int err = 0; + u32 sr; + + /* Poll INSTRuction End status */ + sr = atmel_qspi_read(aq, QSPI_SR); + if ((sr & irq_mask) == irq_mask) + return 0; + + /* Wait for INSTRuction End interrupt */ + reinit_completion(&aq->cmd_completion); + aq->pending = sr & irq_mask; + aq->irq_mask = irq_mask; + atmel_qspi_write(irq_mask, aq, QSPI_IER); + if (!wait_for_completion_timeout(&aq->cmd_completion, + msecs_to_jiffies(ATMEL_QSPI_TIMEOUT))) + err = -ETIMEDOUT; + atmel_qspi_write(irq_mask, aq, QSPI_IDR); + + return err; +} + +static int atmel_qspi_transfer(struct spi_mem *mem, + const struct spi_mem_op *op, u32 offset) +{ + struct atmel_qspi *aq = spi_controller_get_devdata(mem->spi->controller); + + /* Skip to the final steps if there is no data */ + if (!op->data.nbytes) + return atmel_qspi_wait_for_completion(aq, + QSPI_SR_CMD_COMPLETED); + + /* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */ + (void)atmel_qspi_read(aq, QSPI_IFR); + + /* Send/Receive data */ + if (op->data.dir == SPI_MEM_DATA_IN) { + memcpy_fromio(op->data.buf.in, aq->mem + offset, + op->data.nbytes); + + /* Synchronize AHB and APB accesses again */ + rmb(); + } else { + memcpy_toio(aq->mem + offset, op->data.buf.out, + op->data.nbytes); + + /* Synchronize AHB and APB accesses again */ + wmb(); + } + + /* Release the chip-select */ + atmel_qspi_write(QSPI_CR_LASTXFER, aq, QSPI_CR); + + return atmel_qspi_wait_for_completion(aq, QSPI_SR_CMD_COMPLETED); +} + static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) { struct atmel_qspi *aq = spi_controller_get_devdata(mem->spi->controller); - u32 sr, offset; + u32 offset; int err;
/* @@ -416,46 +486,20 @@ static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) * when the flash memories overrun the controller's memory space. */ if (op->addr.val + op->data.nbytes > aq->mmap_size) - return -ENOTSUPP; + return -EOPNOTSUPP; + + if (op->addr.nbytes > 4) + return -EOPNOTSUPP;
err = pm_runtime_resume_and_get(&aq->pdev->dev); if (err < 0) return err;
- err = atmel_qspi_set_cfg(aq, op, &offset); + err = aq->ops->set_cfg(aq, op, &offset); if (err) goto pm_runtime_put;
- /* Skip to the final steps if there is no data */ - if (op->data.nbytes) { - /* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */ - (void)atmel_qspi_read(aq, QSPI_IFR); - - /* Send/Receive data */ - if (op->data.dir == SPI_MEM_DATA_IN) - memcpy_fromio(op->data.buf.in, aq->mem + offset, - op->data.nbytes); - else - memcpy_toio(aq->mem + offset, op->data.buf.out, - op->data.nbytes); - - /* Release the chip-select */ - atmel_qspi_write(QSPI_CR_LASTXFER, aq, QSPI_CR); - } - - /* Poll INSTRuction End status */ - sr = atmel_qspi_read(aq, QSPI_SR); - if ((sr & QSPI_SR_CMD_COMPLETED) == QSPI_SR_CMD_COMPLETED) - goto pm_runtime_put; - - /* Wait for INSTRuction End interrupt */ - reinit_completion(&aq->cmd_completion); - aq->pending = sr & QSPI_SR_CMD_COMPLETED; - atmel_qspi_write(QSPI_SR_CMD_COMPLETED, aq, QSPI_IER); - if (!wait_for_completion_timeout(&aq->cmd_completion, - msecs_to_jiffies(1000))) - err = -ETIMEDOUT; - atmel_qspi_write(QSPI_SR_CMD_COMPLETED, aq, QSPI_IDR); + err = aq->ops->transfer(mem, op, offset);
pm_runtime_put: pm_runtime_mark_last_busy(&aq->pdev->dev); @@ -599,12 +643,17 @@ static irqreturn_t atmel_qspi_interrupt(int irq, void *dev_id) return IRQ_NONE;
aq->pending |= pending; - if ((aq->pending & QSPI_SR_CMD_COMPLETED) == QSPI_SR_CMD_COMPLETED) + if ((aq->pending & aq->irq_mask) == aq->irq_mask) complete(&aq->cmd_completion);
return IRQ_HANDLED; }
+static const struct atmel_qspi_ops atmel_qspi_ops = { + .set_cfg = atmel_qspi_set_cfg, + .transfer = atmel_qspi_transfer, +}; + static int atmel_qspi_probe(struct platform_device *pdev) { struct spi_controller *ctrl; @@ -629,6 +678,7 @@ static int atmel_qspi_probe(struct platform_device *pdev)
init_completion(&aq->cmd_completion); aq->pdev = pdev; + aq->ops = &atmel_qspi_ops;
/* Map the registers */ aq->regs = devm_platform_ioremap_resource_byname(pdev, "qspi_base"); diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 924b803af440..0050d6253c05 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -165,6 +165,7 @@ struct sci_port { static struct sci_port sci_ports[SCI_NPORTS]; static unsigned long sci_ports_in_use; static struct uart_driver sci_uart_driver; +static bool sci_uart_earlycon;
static inline struct sci_port * to_sci_port(struct uart_port *uart) @@ -3450,6 +3451,7 @@ static int sci_probe_single(struct platform_device *dev, static int sci_probe(struct platform_device *dev) { struct plat_sci_port *p; + struct resource *res; struct sci_port *sp; unsigned int dev_id; int ret; @@ -3479,6 +3481,26 @@ static int sci_probe(struct platform_device *dev) }
sp = &sci_ports[dev_id]; + + /* + * In case: + * - the probed port alias is zero (as the one used by earlycon), and + * - the earlycon is still active (e.g., "earlycon keep_bootcon" in + * bootargs) + * + * defer the probe of this serial. This is a debug scenario and the user + * must be aware of it. + * + * Except when the probed port is the same as the earlycon port. + */ + + res = platform_get_resource(dev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + if (sci_uart_earlycon && sp == &sci_ports[0] && sp->port.mapbase != res->start) + return dev_err_probe(&dev->dev, -EBUSY, "sci_port[0] is used by earlycon!\n"); + platform_set_drvdata(dev, sp);
ret = sci_probe_single(dev, dev_id, p, sp); @@ -3562,7 +3584,7 @@ sh_early_platform_init_buffer("earlyprintk", &sci_driver, early_serial_buf, ARRAY_SIZE(early_serial_buf)); #endif #ifdef CONFIG_SERIAL_SH_SCI_EARLYCON -static struct plat_sci_port port_cfg __initdata; +static struct plat_sci_port port_cfg;
static int __init early_console_setup(struct earlycon_device *device, int type) @@ -3575,6 +3597,7 @@ static int __init early_console_setup(struct earlycon_device *device, port_cfg.type = type; sci_ports[0].cfg = &port_cfg; sci_ports[0].params = sci_probe_regmap(&port_cfg); + sci_uart_earlycon = true; port_cfg.scscr = sci_serial_in(&sci_ports[0].port, SCSCR); sci_serial_out(&sci_ports[0].port, SCSCR, SCSCR_RE | SCSCR_TE | port_cfg.scscr); diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index beb151be4d32..92ec51870d1d 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -287,7 +287,7 @@ static void cdns_uart_handle_rx(void *dev_id, unsigned int isrstatus) continue; }
- if (uart_handle_sysrq_char(port, data)) + if (uart_prepare_sysrq_char(port, data)) continue;
if (is_rxbs_support) { @@ -495,7 +495,7 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id) !(readl(port->membase + CDNS_UART_CR) & CDNS_UART_CR_RX_DIS)) cdns_uart_handle_rx(dev_id, isrstatus);
- uart_port_unlock(port); + uart_unlock_and_check_sysrq(port); return IRQ_HANDLED; }
@@ -1380,9 +1380,7 @@ static void cdns_uart_console_write(struct console *co, const char *s, unsigned int imr, ctrl; int locked = 1;
- if (port->sysrq) - locked = 0; - else if (oops_in_progress) + if (oops_in_progress) locked = uart_port_trylock_irqsave(port, &flags); else uart_port_lock_irqsave(port, &flags); diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index 564341f1a74f..0bd6544e30a6 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c @@ -192,6 +192,20 @@ int set_selection_user(const struct tiocl_selection __user *sel, if (copy_from_user(&v, sel, sizeof(*sel))) return -EFAULT;
+ /* + * TIOCL_SELCLEAR, TIOCL_SELPOINTER and TIOCL_SELMOUSEREPORT are OK to + * use without CAP_SYS_ADMIN as they do not modify the selection. + */ + switch (v.sel_mode) { + case TIOCL_SELCLEAR: + case TIOCL_SELPOINTER: + case TIOCL_SELMOUSEREPORT: + break; + default: + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + } + return set_selection_kernel(&v, tty); }
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 96842ce817af..be5564ed8c01 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -3345,8 +3345,6 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
switch (type) { case TIOCL_SETSEL: - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; return set_selection_user(param, tty); case TIOCL_PASTESEL: if (!capable(CAP_SYS_ADMIN)) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 9c26e8767515..d4a628169a51 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -10292,16 +10292,6 @@ int ufshcd_system_thaw(struct device *dev) EXPORT_SYMBOL_GPL(ufshcd_system_thaw); #endif /* CONFIG_PM_SLEEP */
-/** - * ufshcd_dealloc_host - deallocate Host Bus Adapter (HBA) - * @hba: pointer to Host Bus Adapter (HBA) - */ -void ufshcd_dealloc_host(struct ufs_hba *hba) -{ - scsi_host_put(hba->host); -} -EXPORT_SYMBOL_GPL(ufshcd_dealloc_host); - /** * ufshcd_set_dma_mask - Set dma mask based on the controller * addressing capability @@ -10320,12 +10310,26 @@ static int ufshcd_set_dma_mask(struct ufs_hba *hba) return dma_set_mask_and_coherent(hba->dev, DMA_BIT_MASK(32)); }
+/** + * ufshcd_devres_release - devres cleanup handler, invoked during release of + * hba->dev + * @host: pointer to SCSI host + */ +static void ufshcd_devres_release(void *host) +{ + scsi_host_put(host); +} + /** * ufshcd_alloc_host - allocate Host Bus Adapter (HBA) * @dev: pointer to device handle * @hba_handle: driver private handle * * Return: 0 on success, non-zero value on failure. + * + * NOTE: There is no corresponding ufshcd_dealloc_host() because this function + * keeps track of its allocations using devres and deallocates everything on + * device removal automatically. */ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle) { @@ -10347,6 +10351,13 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle) err = -ENOMEM; goto out_error; } + + err = devm_add_action_or_reset(dev, ufshcd_devres_release, + host); + if (err) + return dev_err_probe(dev, err, + "failed to add ufshcd dealloc action\n"); + host->nr_maps = HCTX_TYPE_POLL + 1; hba = shost_priv(host); hba->host = host; diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index 91e94fe990b4..d305889f450b 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -155,8 +155,9 @@ static int ufs_qcom_ice_program_key(struct ufs_hba *hba, { struct ufs_qcom_host *host = ufshcd_get_variant(hba); union ufs_crypto_cap_entry cap; - bool config_enable = - cfg->config_enable & UFS_CRYPTO_CONFIGURATION_ENABLE; + + if (!(cfg->config_enable & UFS_CRYPTO_CONFIGURATION_ENABLE)) + return qcom_ice_evict_key(host->ice, slot);
/* Only AES-256-XTS has been tested so far. */ cap = hba->crypto_cap_array[cfg->crypto_cap_idx]; @@ -164,14 +165,11 @@ static int ufs_qcom_ice_program_key(struct ufs_hba *hba, cap.key_size != UFS_CRYPTO_KEY_SIZE_256) return -EOPNOTSUPP;
- if (config_enable) - return qcom_ice_program_key(host->ice, - QCOM_ICE_CRYPTO_ALG_AES_XTS, - QCOM_ICE_CRYPTO_KEY_SIZE_256, - cfg->crypto_key, - cfg->data_unit_size, slot); - else - return qcom_ice_evict_key(host->ice, slot); + return qcom_ice_program_key(host->ice, + QCOM_ICE_CRYPTO_ALG_AES_XTS, + QCOM_ICE_CRYPTO_KEY_SIZE_256, + cfg->crypto_key, + cfg->data_unit_size, slot); }
#else diff --git a/drivers/ufs/host/ufshcd-pci.c b/drivers/ufs/host/ufshcd-pci.c index ea39c5d5b8cf..9cfcaad23cf9 100644 --- a/drivers/ufs/host/ufshcd-pci.c +++ b/drivers/ufs/host/ufshcd-pci.c @@ -562,7 +562,6 @@ static void ufshcd_pci_remove(struct pci_dev *pdev) pm_runtime_forbid(&pdev->dev); pm_runtime_get_noresume(&pdev->dev); ufshcd_remove(hba); - ufshcd_dealloc_host(hba); }
/** @@ -605,7 +604,6 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) err = ufshcd_init(hba, mmio_base, pdev->irq); if (err) { dev_err(&pdev->dev, "Initialization failed\n"); - ufshcd_dealloc_host(hba); return err; }
diff --git a/drivers/ufs/host/ufshcd-pltfrm.c b/drivers/ufs/host/ufshcd-pltfrm.c index 505572d4fa87..ffe5d1d2b215 100644 --- a/drivers/ufs/host/ufshcd-pltfrm.c +++ b/drivers/ufs/host/ufshcd-pltfrm.c @@ -465,21 +465,17 @@ int ufshcd_pltfrm_init(struct platform_device *pdev, struct device *dev = &pdev->dev;
mmio_base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(mmio_base)) { - err = PTR_ERR(mmio_base); - goto out; - } + if (IS_ERR(mmio_base)) + return PTR_ERR(mmio_base);
irq = platform_get_irq(pdev, 0); - if (irq < 0) { - err = irq; - goto out; - } + if (irq < 0) + return irq;
err = ufshcd_alloc_host(dev, &hba); if (err) { dev_err(dev, "Allocation failed\n"); - goto out; + return err; }
hba->vops = vops; @@ -488,13 +484,13 @@ int ufshcd_pltfrm_init(struct platform_device *pdev, if (err) { dev_err(dev, "%s: clock parse failed %d\n", __func__, err); - goto dealloc_host; + return err; } err = ufshcd_parse_regulator_info(hba); if (err) { dev_err(dev, "%s: regulator init failed %d\n", __func__, err); - goto dealloc_host; + return err; }
ufshcd_init_lanes_per_dir(hba); @@ -502,25 +498,20 @@ int ufshcd_pltfrm_init(struct platform_device *pdev, err = ufshcd_parse_operating_points(hba); if (err) { dev_err(dev, "%s: OPP parse failed %d\n", __func__, err); - goto dealloc_host; + return err; }
err = ufshcd_init(hba, mmio_base, irq); if (err) { dev_err_probe(dev, err, "Initialization failed with error %d\n", err); - goto dealloc_host; + return err; }
pm_runtime_set_active(dev); pm_runtime_enable(dev);
return 0; - -dealloc_host: - ufshcd_dealloc_host(hba); -out: - return err; } EXPORT_SYMBOL_GPL(ufshcd_pltfrm_init);
@@ -534,7 +525,6 @@ void ufshcd_pltfrm_remove(struct platform_device *pdev)
pm_runtime_get_sync(&pdev->dev); ufshcd_remove(hba); - ufshcd_dealloc_host(hba); pm_runtime_disable(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); } diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index 48dee166e5d8..7b23631f4744 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -245,7 +245,6 @@ static int bot_send_write_request(struct usbg_cmd *cmd) { struct f_uas *fu = cmd->fu; struct se_cmd *se_cmd = &cmd->se_cmd; - struct usb_gadget *gadget = fuas_to_gadget(fu); int ret;
init_completion(&cmd->write_complete); @@ -256,22 +255,6 @@ static int bot_send_write_request(struct usbg_cmd *cmd) return -EINVAL; }
- if (!gadget->sg_supported) { - cmd->data_buf = kmalloc(se_cmd->data_length, GFP_KERNEL); - if (!cmd->data_buf) - return -ENOMEM; - - fu->bot_req_out->buf = cmd->data_buf; - } else { - fu->bot_req_out->buf = NULL; - fu->bot_req_out->num_sgs = se_cmd->t_data_nents; - fu->bot_req_out->sg = se_cmd->t_data_sg; - } - - fu->bot_req_out->complete = usbg_data_write_cmpl; - fu->bot_req_out->length = se_cmd->data_length; - fu->bot_req_out->context = cmd; - ret = usbg_prepare_w_request(cmd, fu->bot_req_out); if (ret) goto cleanup; @@ -973,6 +956,7 @@ static void usbg_data_write_cmpl(struct usb_ep *ep, struct usb_request *req) return;
cleanup: + target_put_sess_cmd(se_cmd); transport_generic_free_cmd(&cmd->se_cmd, 0); }
@@ -1065,7 +1049,7 @@ static void usbg_cmd_work(struct work_struct *work)
out: transport_send_check_condition_and_sense(se_cmd, - TCM_UNSUPPORTED_SCSI_OPCODE, 1); + TCM_UNSUPPORTED_SCSI_OPCODE, 0); }
static struct usbg_cmd *usbg_get_cmd(struct f_uas *fu, @@ -1193,7 +1177,7 @@ static void bot_cmd_work(struct work_struct *work)
out: transport_send_check_condition_and_sense(se_cmd, - TCM_UNSUPPORTED_SCSI_OPCODE, 1); + TCM_UNSUPPORTED_SCSI_OPCODE, 0); }
static int bot_submit_command(struct f_uas *fu, @@ -1969,43 +1953,39 @@ static int tcm_bind(struct usb_configuration *c, struct usb_function *f) bot_intf_desc.bInterfaceNumber = iface; uasp_intf_desc.bInterfaceNumber = iface; fu->iface = iface; - ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bi_desc, - &uasp_bi_ep_comp_desc); + ep = usb_ep_autoconfig(gadget, &uasp_fs_bi_desc); if (!ep) goto ep_fail;
fu->ep_in = ep;
- ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bo_desc, - &uasp_bo_ep_comp_desc); + ep = usb_ep_autoconfig(gadget, &uasp_fs_bo_desc); if (!ep) goto ep_fail; fu->ep_out = ep;
- ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_status_desc, - &uasp_status_in_ep_comp_desc); + ep = usb_ep_autoconfig(gadget, &uasp_fs_status_desc); if (!ep) goto ep_fail; fu->ep_status = ep;
- ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_cmd_desc, - &uasp_cmd_comp_desc); + ep = usb_ep_autoconfig(gadget, &uasp_fs_cmd_desc); if (!ep) goto ep_fail; fu->ep_cmd = ep;
/* Assume endpoint addresses are the same for both speeds */ - uasp_bi_desc.bEndpointAddress = uasp_ss_bi_desc.bEndpointAddress; - uasp_bo_desc.bEndpointAddress = uasp_ss_bo_desc.bEndpointAddress; + uasp_bi_desc.bEndpointAddress = uasp_fs_bi_desc.bEndpointAddress; + uasp_bo_desc.bEndpointAddress = uasp_fs_bo_desc.bEndpointAddress; uasp_status_desc.bEndpointAddress = - uasp_ss_status_desc.bEndpointAddress; - uasp_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress; - - uasp_fs_bi_desc.bEndpointAddress = uasp_ss_bi_desc.bEndpointAddress; - uasp_fs_bo_desc.bEndpointAddress = uasp_ss_bo_desc.bEndpointAddress; - uasp_fs_status_desc.bEndpointAddress = - uasp_ss_status_desc.bEndpointAddress; - uasp_fs_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress; + uasp_fs_status_desc.bEndpointAddress; + uasp_cmd_desc.bEndpointAddress = uasp_fs_cmd_desc.bEndpointAddress; + + uasp_ss_bi_desc.bEndpointAddress = uasp_fs_bi_desc.bEndpointAddress; + uasp_ss_bo_desc.bEndpointAddress = uasp_fs_bo_desc.bEndpointAddress; + uasp_ss_status_desc.bEndpointAddress = + uasp_fs_status_desc.bEndpointAddress; + uasp_ss_cmd_desc.bEndpointAddress = uasp_fs_cmd_desc.bEndpointAddress;
ret = usb_assign_descriptors(f, uasp_fs_function_desc, uasp_hs_function_desc, uasp_ss_function_desc, diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c index 3bf1043cd795..d63c2d266d07 100644 --- a/drivers/vfio/platform/vfio_platform_common.c +++ b/drivers/vfio/platform/vfio_platform_common.c @@ -393,6 +393,11 @@ static ssize_t vfio_platform_read_mmio(struct vfio_platform_region *reg,
count = min_t(size_t, count, reg->size - off);
+ if (off >= reg->size) + return -EINVAL; + + count = min_t(size_t, count, reg->size - off); + if (!reg->ioaddr) { reg->ioaddr = ioremap(reg->addr, reg->size); @@ -477,6 +482,11 @@ static ssize_t vfio_platform_write_mmio(struct vfio_platform_region *reg,
count = min_t(size_t, count, reg->size - off);
+ if (off >= reg->size) + return -EINVAL; + + count = min_t(size_t, count, reg->size - off); + if (!reg->ioaddr) { reg->ioaddr = ioremap(reg->addr, reg->size); diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 390808ce935d..b5b5ca1a44f7 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -478,7 +478,7 @@ static int load_flat_file(struct linux_binprm *bprm, * 28 bits (256 MB) is way more than reasonable in this case. * If some top bits are set we have probable binary corruption. */ - if ((text_len | data_len | bss_len | stack_len | full_data) >> 28) { + if ((text_len | data_len | bss_len | stack_len | relocs | full_data) >> 28) { pr_err("bad header\n"); ret = -ENOEXEC; goto err; diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 185985a337b3..5d2613b16cd2 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1563,6 +1563,7 @@ read_block_for_search(struct btrfs_root *root, struct btrfs_path *p,
if (!p->skip_locking) { btrfs_unlock_up_safe(p, parent_level + 1); + btrfs_maybe_reset_lockdep_class(root, tmp); tmp_locked = true; btrfs_tree_read_lock(tmp); btrfs_release_path(p); @@ -1606,6 +1607,7 @@ read_block_for_search(struct btrfs_root *root, struct btrfs_path *p,
if (!p->skip_locking) { ASSERT(ret == -EAGAIN); + btrfs_maybe_reset_lockdep_class(root, tmp); tmp_locked = true; btrfs_tree_read_lock(tmp); btrfs_release_path(p); diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 14e27473c5bc..4d7c7a296d2d 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -224,7 +224,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, if (args->drop_cache) btrfs_drop_extent_map_range(inode, args->start, args->end - 1, false);
- if (args->start >= inode->disk_i_size && !args->replace_extent) + if (data_race(args->start >= inode->disk_i_size) && !args->replace_extent) modify_tree = 0;
update_refs = (btrfs_root_id(root) != BTRFS_TREE_LOG_OBJECTID); diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 30eceaf829a7..4aca7475fd82 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -1229,6 +1229,18 @@ struct btrfs_ordered_extent *btrfs_split_ordered_extent( */ if (WARN_ON_ONCE(len >= ordered->num_bytes)) return ERR_PTR(-EINVAL); + /* + * If our ordered extent had an error there's no point in continuing. + * The error may have come from a transaction abort done either by this + * task or some other concurrent task, and the transaction abort path + * iterates over all existing ordered extents and sets the flag + * BTRFS_ORDERED_IOERR on them. + */ + if (unlikely(flags & (1U << BTRFS_ORDERED_IOERR))) { + const int fs_error = BTRFS_FS_ERROR(fs_info); + + return fs_error ? ERR_PTR(fs_error) : ERR_PTR(-EIO); + } /* We cannot split partially completed ordered extents. */ if (ordered->bytes_left) { ASSERT(!(flags & ~BTRFS_ORDERED_TYPE_FLAGS)); diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 993b5e803699..5ab51781d0e4 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -1915,8 +1915,11 @@ int btrfs_qgroup_cleanup_dropped_subvolume(struct btrfs_fs_info *fs_info, u64 su /* * It's squota and the subvolume still has numbers needed for future * accounting, in this case we can not delete it. Just skip it. + * + * Or the qgroup is already removed by a qgroup rescan. For both cases we're + * safe to ignore them. */ - if (ret == -EBUSY) + if (ret == -EBUSY || ret == -ENOENT) ret = 0; return ret; } diff --git a/fs/btrfs/raid-stripe-tree.c b/fs/btrfs/raid-stripe-tree.c index 9ffc79f250fb..10781c015ee8 100644 --- a/fs/btrfs/raid-stripe-tree.c +++ b/fs/btrfs/raid-stripe-tree.c @@ -13,12 +13,13 @@ #include "volumes.h" #include "print-tree.h"
-static void btrfs_partially_delete_raid_extent(struct btrfs_trans_handle *trans, +static int btrfs_partially_delete_raid_extent(struct btrfs_trans_handle *trans, struct btrfs_path *path, const struct btrfs_key *oldkey, u64 newlen, u64 frontpad) { - struct btrfs_stripe_extent *extent; + struct btrfs_root *stripe_root = trans->fs_info->stripe_root; + struct btrfs_stripe_extent *extent, *newitem; struct extent_buffer *leaf; int slot; size_t item_size; @@ -27,23 +28,38 @@ static void btrfs_partially_delete_raid_extent(struct btrfs_trans_handle *trans, .type = BTRFS_RAID_STRIPE_KEY, .offset = newlen, }; + int ret;
ASSERT(oldkey->type == BTRFS_RAID_STRIPE_KEY);
leaf = path->nodes[0]; slot = path->slots[0]; item_size = btrfs_item_size(leaf, slot); + + newitem = kzalloc(item_size, GFP_NOFS); + if (!newitem) + return -ENOMEM; + extent = btrfs_item_ptr(leaf, slot, struct btrfs_stripe_extent);
for (int i = 0; i < btrfs_num_raid_stripes(item_size); i++) { struct btrfs_raid_stride *stride = &extent->strides[i]; u64 phys;
- phys = btrfs_raid_stride_physical(leaf, stride); - btrfs_set_raid_stride_physical(leaf, stride, phys + frontpad); + phys = btrfs_raid_stride_physical(leaf, stride) + frontpad; + btrfs_set_stack_raid_stride_physical(&newitem->strides[i], phys); }
- btrfs_set_item_key_safe(trans, path, &newkey); + ret = btrfs_del_item(trans, stripe_root, path); + if (ret) + goto out; + + btrfs_release_path(path); + ret = btrfs_insert_item(trans, stripe_root, &newkey, newitem, item_size); + +out: + kfree(newitem); + return ret; }
int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, u64 length) diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index db8b42f674b7..ab2de2d1b2be 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -4405,8 +4405,18 @@ int btrfs_reloc_cow_block(struct btrfs_trans_handle *trans, WARN_ON(!first_cow && level == 0);
node = rc->backref_cache.path[level]; - BUG_ON(node->bytenr != buf->start && - node->new_bytenr != buf->start); + + /* + * If node->bytenr != buf->start and node->new_bytenr != + * buf->start then we've got the wrong backref node for what we + * expected to see here and the cache is incorrect. + */ + if (unlikely(node->bytenr != buf->start && node->new_bytenr != buf->start)) { + btrfs_err(fs_info, +"bytenr %llu was found but our backref cache was expecting %llu or %llu", + buf->start, node->bytenr, node->new_bytenr); + return -EUCLEAN; + }
btrfs_backref_drop_node_buffer(node); atomic_inc(&cow->refs); diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index dc0b837efd5d..914a22cc950b 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -274,8 +274,10 @@ static noinline int join_transaction(struct btrfs_fs_info *fs_info, cur_trans = fs_info->running_transaction; if (cur_trans) { if (TRANS_ABORTED(cur_trans)) { + const int abort_error = cur_trans->aborted; + spin_unlock(&fs_info->trans_lock); - return cur_trans->aborted; + return abort_error; } if (btrfs_blocked_trans_types[cur_trans->state] & type) { spin_unlock(&fs_info->trans_lock); diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 785fe489ef4b..ae37f0e24c99 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -5690,18 +5690,18 @@ static int ceph_mds_auth_match(struct ceph_mds_client *mdsc, * * All the other cases --> mismatch */ + bool path_matched = true; char *first = strstr(_tpath, auth->match.path); - if (first != _tpath) { - if (free_tpath) - kfree(_tpath); - return 0; + if (first != _tpath || + (tlen > len && _tpath[len] != '/')) { + path_matched = false; }
- if (tlen > len && _tpath[len] != '/') { - if (free_tpath) - kfree(_tpath); + if (free_tpath) + kfree(_tpath); + + if (!path_matched) return 0; - } } }
diff --git a/fs/exec.c b/fs/exec.c index 98cb7ba9983c..b1f6b47ad20e 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1341,7 +1341,28 @@ int begin_new_exec(struct linux_binprm * bprm) set_dumpable(current->mm, SUID_DUMP_USER);
perf_event_exec(); - __set_task_comm(me, kbasename(bprm->filename), true); + + /* + * If the original filename was empty, alloc_bprm() made up a path + * that will probably not be useful to admins running ps or similar. + * Let's fix it up to be something reasonable. + */ + if (bprm->comm_from_dentry) { + /* + * Hold RCU lock to keep the name from being freed behind our back. + * Use acquire semantics to make sure the terminating NUL from + * __d_alloc() is seen. + * + * Note, we're deliberately sloppy here. We don't need to care about + * detecting a concurrent rename and just want a terminated name. + */ + rcu_read_lock(); + __set_task_comm(me, smp_load_acquire(&bprm->file->f_path.dentry->d_name.name), + true); + rcu_read_unlock(); + } else { + __set_task_comm(me, kbasename(bprm->filename), true); + }
/* An exec changes our domain. We are no longer part of the thread group */ @@ -1517,11 +1538,13 @@ static struct linux_binprm *alloc_bprm(int fd, struct filename *filename, int fl if (fd == AT_FDCWD || filename->name[0] == '/') { bprm->filename = filename->name; } else { - if (filename->name[0] == '\0') + if (filename->name[0] == '\0') { bprm->fdpath = kasprintf(GFP_KERNEL, "/dev/fd/%d", fd); - else + bprm->comm_from_dentry = 1; + } else { bprm->fdpath = kasprintf(GFP_KERNEL, "/dev/fd/%d/%s", fd, filename->name); + } if (!bprm->fdpath) goto out_free;
diff --git a/fs/namespace.c b/fs/namespace.c index eac057e56948..cb08db40fc03 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -5037,26 +5037,29 @@ static int statmount_mnt_opts(struct kstatmount *s, struct seq_file *seq) { struct vfsmount *mnt = s->mnt; struct super_block *sb = mnt->mnt_sb; + size_t start = seq->count; int err;
- if (sb->s_op->show_options) { - size_t start = seq->count; + err = security_sb_show_options(seq, sb); + if (err) + return err;
+ if (sb->s_op->show_options) { err = sb->s_op->show_options(seq, mnt->mnt_root); if (err) return err; + }
- if (unlikely(seq_has_overflowed(seq))) - return -EAGAIN; + if (unlikely(seq_has_overflowed(seq))) + return -EAGAIN;
- if (seq->count == start) - return 0; + if (seq->count == start) + return 0;
- /* skip leading comma */ - memmove(seq->buf + start, seq->buf + start + 1, - seq->count - start - 1); - seq->count--; - } + /* skip leading comma */ + memmove(seq->buf + start, seq->buf + start + 1, + seq->count - start - 1); + seq->count--;
return 0; } @@ -5137,39 +5140,45 @@ static int statmount_string(struct kstatmount *s, u64 flag) size_t kbufsize; struct seq_file *seq = &s->seq; struct statmount *sm = &s->sm; - u32 start = seq->count; + u32 start, *offp; + + /* Reserve an empty string at the beginning for any unset offsets */ + if (!seq->count) + seq_putc(seq, 0); + + start = seq->count;
switch (flag) { case STATMOUNT_FS_TYPE: - sm->fs_type = start; + offp = &sm->fs_type; ret = statmount_fs_type(s, seq); break; case STATMOUNT_MNT_ROOT: - sm->mnt_root = start; + offp = &sm->mnt_root; ret = statmount_mnt_root(s, seq); break; case STATMOUNT_MNT_POINT: - sm->mnt_point = start; + offp = &sm->mnt_point; ret = statmount_mnt_point(s, seq); break; case STATMOUNT_MNT_OPTS: - sm->mnt_opts = start; + offp = &sm->mnt_opts; ret = statmount_mnt_opts(s, seq); break; case STATMOUNT_OPT_ARRAY: - sm->opt_array = start; + offp = &sm->opt_array; ret = statmount_opt_array(s, seq); break; case STATMOUNT_OPT_SEC_ARRAY: - sm->opt_sec_array = start; + offp = &sm->opt_sec_array; ret = statmount_opt_sec_array(s, seq); break; case STATMOUNT_FS_SUBTYPE: - sm->fs_subtype = start; + offp = &sm->fs_subtype; statmount_fs_subtype(s, seq); break; case STATMOUNT_SB_SOURCE: - sm->sb_source = start; + offp = &sm->sb_source; ret = statmount_sb_source(s, seq); break; default: @@ -5197,6 +5206,7 @@ static int statmount_string(struct kstatmount *s, u64 flag)
seq->buf[seq->count++] = '\0'; sm->mask |= flag; + *offp = start; return 0; }
diff --git a/fs/netfs/read_collect.c b/fs/netfs/read_collect.c index e8624f5c7fcc..8878b46589ff 100644 --- a/fs/netfs/read_collect.c +++ b/fs/netfs/read_collect.c @@ -258,17 +258,18 @@ static bool netfs_consume_read_data(struct netfs_io_subrequest *subreq, bool was */ if (!subreq->consumed && !prev_donated && - !list_is_first(&subreq->rreq_link, &rreq->subrequests) && - subreq->start == prev->start + prev->len) { + !list_is_first(&subreq->rreq_link, &rreq->subrequests)) { prev = list_prev_entry(subreq, rreq_link); - WRITE_ONCE(prev->next_donated, prev->next_donated + subreq->len); - subreq->start += subreq->len; - subreq->len = 0; - subreq->transferred = 0; - trace_netfs_donate(rreq, subreq, prev, subreq->len, - netfs_trace_donate_to_prev); - trace_netfs_sreq(subreq, netfs_sreq_trace_donate_to_prev); - goto remove_subreq_locked; + if (subreq->start == prev->start + prev->len) { + WRITE_ONCE(prev->next_donated, prev->next_donated + subreq->len); + subreq->start += subreq->len; + subreq->len = 0; + subreq->transferred = 0; + trace_netfs_donate(rreq, subreq, prev, subreq->len, + netfs_trace_donate_to_prev); + trace_netfs_sreq(subreq, netfs_sreq_trace_donate_to_prev); + goto remove_subreq_locked; + } }
/* If we can't donate down the chain, donate up the chain instead. */ diff --git a/fs/netfs/read_pgpriv2.c b/fs/netfs/read_pgpriv2.c index 54d5004fec18..e72f5e674834 100644 --- a/fs/netfs/read_pgpriv2.c +++ b/fs/netfs/read_pgpriv2.c @@ -181,16 +181,17 @@ void netfs_pgpriv2_write_to_the_cache(struct netfs_io_request *rreq) break;
folioq_unmark3(folioq, slot); - if (!folioq->marks3) { + while (!folioq->marks3) { folioq = folioq->next; if (!folioq) - break; + goto end_of_queue; }
slot = __ffs(folioq->marks3); folio = folioq_folio(folioq, slot); }
+end_of_queue: netfs_issue_write(wreq, &wreq->io_streams[1]); smp_wmb(); /* Write lists before ALL_QUEUED. */ set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags); diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig index 0eb20012792f..d3f76101ad4b 100644 --- a/fs/nfs/Kconfig +++ b/fs/nfs/Kconfig @@ -170,7 +170,8 @@ config ROOT_NFS
config NFS_FSCACHE bool "Provide NFS client caching support" - depends on NFS_FS=m && NETFS_SUPPORT || NFS_FS=y && NETFS_SUPPORT=y + depends on NFS_FS + select NETFS_SUPPORT select FSCACHE help Say Y here if you want NFS data to be cached locally on disc through diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index f78115c6c2c1..a1cfe4cc60c4 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -847,6 +847,9 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs4_pnfs_ds *ds; u32 ds_idx;
+ if (NFS_SERVER(pgio->pg_inode)->flags & + (NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR)) + pgio->pg_maxretrans = io_maxretrans; retry: pnfs_generic_pg_check_layout(pgio, req); /* Use full layout for now */ @@ -860,6 +863,8 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio, if (!pgio->pg_lseg) goto out_nolseg; } + /* Reset wb_nio, since getting layout segment was successful */ + req->wb_nio = 0;
ds = ff_layout_get_ds_for_read(pgio, &ds_idx); if (!ds) { @@ -876,14 +881,24 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio, pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].rsize;
pgio->pg_mirror_idx = ds_idx; - - if (NFS_SERVER(pgio->pg_inode)->flags & - (NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR)) - pgio->pg_maxretrans = io_maxretrans; return; out_nolseg: - if (pgio->pg_error < 0) - return; + if (pgio->pg_error < 0) { + if (pgio->pg_error != -EAGAIN) + return; + /* Retry getting layout segment if lower layer returned -EAGAIN */ + if (pgio->pg_maxretrans && req->wb_nio++ > pgio->pg_maxretrans) { + if (NFS_SERVER(pgio->pg_inode)->flags & NFS_MOUNT_SOFTERR) + pgio->pg_error = -ETIMEDOUT; + else + pgio->pg_error = -EIO; + return; + } + pgio->pg_error = 0; + /* Sleep for 1 second before retrying */ + ssleep(1); + goto retry; + } out_mds: trace_pnfs_mds_fallback_pg_init_read(pgio->pg_inode, 0, NFS4_MAX_UINT64, IOMODE_READ, diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 53fac037611c..e8adf62d3484 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -5760,15 +5760,14 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) struct nfs4_stateowner *so = resp->cstate.replay_owner; struct svc_rqst *rqstp = resp->rqstp; const struct nfsd4_operation *opdesc = op->opdesc; - int post_err_offset; + unsigned int op_status_offset; nfsd4_enc encoder; - __be32 *p;
- p = xdr_reserve_space(xdr, 8); - if (!p) + if (xdr_stream_encode_u32(xdr, op->opnum) != XDR_UNIT) + goto release; + op_status_offset = xdr->buf->len; + if (!xdr_reserve_space(xdr, XDR_UNIT)) goto release; - *p++ = cpu_to_be32(op->opnum); - post_err_offset = xdr->buf->len;
if (op->opnum == OP_ILLEGAL) goto status; @@ -5809,20 +5808,21 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) * bug if we had to do this on a non-idempotent op: */ warn_on_nonidempotent_op(op); - xdr_truncate_encode(xdr, post_err_offset); + xdr_truncate_encode(xdr, op_status_offset + XDR_UNIT); } if (so) { - int len = xdr->buf->len - post_err_offset; + int len = xdr->buf->len - (op_status_offset + XDR_UNIT);
so->so_replay.rp_status = op->status; so->so_replay.rp_buflen = len; - read_bytes_from_xdr_buf(xdr->buf, post_err_offset, + read_bytes_from_xdr_buf(xdr->buf, op_status_offset + XDR_UNIT, so->so_replay.rp_buf, len); } status: op->status = nfsd4_map_status(op->status, resp->cstate.minorversion); - *p = op->status; + write_bytes_to_xdr_buf(xdr->buf, op_status_offset, + &op->status, XDR_UNIT); release: if (opdesc && opdesc->op_release) opdesc->op_release(&op->u); diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 23f3a75edd50..81abb58dcbd8 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c @@ -1188,7 +1188,7 @@ int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, if (size) { if (phys && blkphy << blkbits == phys + size) { /* The current extent goes on */ - size += n << blkbits; + size += (u64)n << blkbits; } else { /* Terminate the current extent */ ret = fiemap_fill_next_extent( @@ -1201,14 +1201,14 @@ int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, flags = FIEMAP_EXTENT_MERGED; logical = blkoff << blkbits; phys = blkphy << blkbits; - size = n << blkbits; + size = (u64)n << blkbits; } } else { /* Start a new extent */ flags = FIEMAP_EXTENT_MERGED; logical = blkoff << blkbits; phys = blkphy << blkbits; - size = n << blkbits; + size = (u64)n << blkbits; } blkoff += n; } diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index c79b4291777f..1e87554f6f41 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -2340,7 +2340,7 @@ static int ocfs2_verify_volume(struct ocfs2_dinode *di, mlog(ML_ERROR, "found superblock with incorrect block " "size bits: found %u, should be 9, 10, 11, or 12\n", blksz_bits); - } else if ((1 << le32_to_cpu(blksz_bits)) != blksz) { + } else if ((1 << blksz_bits) != blksz) { mlog(ML_ERROR, "found superblock with incorrect block " "size: found %u, should be %u\n", 1 << blksz_bits, blksz); } else if (le16_to_cpu(di->id2.i_super.s_major_rev_level) != diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c index d4c5fdcfa1e4..f5cf2255dc09 100644 --- a/fs/ocfs2/symlink.c +++ b/fs/ocfs2/symlink.c @@ -65,7 +65,7 @@ static int ocfs2_fast_symlink_read_folio(struct file *f, struct folio *folio)
if (status < 0) { mlog_errno(status); - return status; + goto out; }
fe = (struct ocfs2_dinode *) bh->b_data; @@ -76,9 +76,10 @@ static int ocfs2_fast_symlink_read_folio(struct file *f, struct folio *folio) memcpy(kaddr, link, len + 1); kunmap_atomic(kaddr); SetPageUptodate(page); +out: unlock_page(page); brelse(bh); - return 0; + return status; }
const struct address_space_operations ocfs2_fast_symlink_aops = { diff --git a/fs/pidfs.c b/fs/pidfs.c index 618abb1fa1b8..96d8aeeebb43 100644 --- a/fs/pidfs.c +++ b/fs/pidfs.c @@ -190,6 +190,37 @@ static long pidfd_info(struct task_struct *task, unsigned int cmd, unsigned long return 0; }
+static bool pidfs_ioctl_valid(unsigned int cmd) +{ + switch (cmd) { + case FS_IOC_GETVERSION: + case PIDFD_GET_CGROUP_NAMESPACE: + case PIDFD_GET_IPC_NAMESPACE: + case PIDFD_GET_MNT_NAMESPACE: + case PIDFD_GET_NET_NAMESPACE: + case PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE: + case PIDFD_GET_TIME_NAMESPACE: + case PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE: + case PIDFD_GET_UTS_NAMESPACE: + case PIDFD_GET_USER_NAMESPACE: + case PIDFD_GET_PID_NAMESPACE: + return true; + } + + /* Extensible ioctls require some more careful checks. */ + switch (_IOC_NR(cmd)) { + case _IOC_NR(PIDFD_GET_INFO): + /* + * Try to prevent performing a pidfd ioctl when someone + * erronously mistook the file descriptor for a pidfd. + * This is not perfect but will catch most cases. + */ + return (_IOC_TYPE(cmd) == _IOC_TYPE(PIDFD_GET_INFO)); + } + + return false; +} + static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct task_struct *task __free(put_task) = NULL; @@ -198,6 +229,9 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) struct ns_common *ns_common = NULL; struct pid_namespace *pid_ns;
+ if (!pidfs_ioctl_valid(cmd)) + return -ENOIOCTLCMD; + task = get_pid_task(pid, PIDTYPE_PID); if (!task) return -ESRCH; diff --git a/fs/proc/array.c b/fs/proc/array.c index 55ed3510d2bb..d6a0369caa93 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -500,7 +500,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, * a program is not able to use ptrace(2) in that case. It is * safe because the task has stopped executing permanently. */ - if (permitted && (task->flags & (PF_EXITING|PF_DUMPCORE))) { + if (permitted && (task->flags & (PF_EXITING|PF_DUMPCORE|PF_POSTCOREDUMP))) { if (try_get_task_stack(task)) { eip = KSTK_EIP(task); esp = KSTK_ESP(task); diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 6e63abe461fd..cf53503e001e 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -326,7 +326,7 @@ struct smb_version_operations { int (*handle_cancelled_mid)(struct mid_q_entry *, struct TCP_Server_Info *); void (*downgrade_oplock)(struct TCP_Server_Info *server, struct cifsInodeInfo *cinode, __u32 oplock, - unsigned int epoch, bool *purge_cache); + __u16 epoch, bool *purge_cache); /* process transaction2 response */ bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *, char *, int); @@ -521,12 +521,12 @@ struct smb_version_operations { /* if we can do cache read operations */ bool (*is_read_op)(__u32); /* set oplock level for the inode */ - void (*set_oplock_level)(struct cifsInodeInfo *, __u32, unsigned int, - bool *); + void (*set_oplock_level)(struct cifsInodeInfo *cinode, __u32 oplock, __u16 epoch, + bool *purge_cache); /* create lease context buffer for CREATE request */ char * (*create_lease_buf)(u8 *lease_key, u8 oplock); /* parse lease context buffer and return oplock/epoch info */ - __u8 (*parse_lease_buf)(void *buf, unsigned int *epoch, char *lkey); + __u8 (*parse_lease_buf)(void *buf, __u16 *epoch, char *lkey); ssize_t (*copychunk_range)(const unsigned int, struct cifsFileInfo *src_file, struct cifsFileInfo *target_file, @@ -1422,7 +1422,7 @@ struct cifs_fid { __u8 create_guid[16]; __u32 access; struct cifs_pending_open *pending_open; - unsigned int epoch; + __u16 epoch; #ifdef CONFIG_CIFS_DEBUG2 __u64 mid; #endif /* CIFS_DEBUG2 */ @@ -1455,7 +1455,7 @@ struct cifsFileInfo { bool oplock_break_cancelled:1; bool status_file_deleted:1; /* file has been deleted */ bool offload:1; /* offload final part of _put to a wq */ - unsigned int oplock_epoch; /* epoch from the lease break */ + __u16 oplock_epoch; /* epoch from the lease break */ __u32 oplock_level; /* oplock/lease level from the lease break */ int count; spinlock_t file_info_lock; /* protects four flag/count fields above */ @@ -1552,7 +1552,7 @@ struct cifsInodeInfo { spinlock_t open_file_lock; /* protects openFileList */ __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */ unsigned int oplock; /* oplock/lease level we have */ - unsigned int epoch; /* used to track lease state changes */ + __u16 epoch; /* used to track lease state changes */ #define CIFS_INODE_PENDING_OPLOCK_BREAK (0) /* oplock break in progress */ #define CIFS_INODE_PENDING_WRITERS (1) /* Writes in progress */ #define CIFS_INODE_FLAG_UNUSED (2) /* Unused flag */ diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c index 864b194dbaa0..1822493dd084 100644 --- a/fs/smb/client/dir.c +++ b/fs/smb/client/dir.c @@ -627,7 +627,7 @@ int cifs_mknod(struct mnt_idmap *idmap, struct inode *inode, goto mknod_out; }
- trace_smb3_mknod_enter(xid, tcon->ses->Suid, tcon->tid, full_path); + trace_smb3_mknod_enter(xid, tcon->tid, tcon->ses->Suid, full_path);
rc = tcon->ses->server->ops->make_node(xid, inode, direntry, tcon, full_path, mode, @@ -635,9 +635,9 @@ int cifs_mknod(struct mnt_idmap *idmap, struct inode *inode,
mknod_out: if (rc) - trace_smb3_mknod_err(xid, tcon->ses->Suid, tcon->tid, rc); + trace_smb3_mknod_err(xid, tcon->tid, tcon->ses->Suid, rc); else - trace_smb3_mknod_done(xid, tcon->ses->Suid, tcon->tid); + trace_smb3_mknod_done(xid, tcon->tid, tcon->ses->Suid);
free_dentry_path(page); free_xid(xid); diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c index db3695eddcf9..c70f4961c4eb 100644 --- a/fs/smb/client/smb1ops.c +++ b/fs/smb/client/smb1ops.c @@ -377,7 +377,7 @@ coalesce_t2(char *second_buf, struct smb_hdr *target_hdr) static void cifs_downgrade_oplock(struct TCP_Server_Info *server, struct cifsInodeInfo *cinode, __u32 oplock, - unsigned int epoch, bool *purge_cache) + __u16 epoch, bool *purge_cache) { cifs_set_oplock_level(cinode, oplock); } diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c index b935c1a62d10..7dfd3eb3847b 100644 --- a/fs/smb/client/smb2inode.c +++ b/fs/smb/client/smb2inode.c @@ -298,8 +298,8 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, goto finished; } num_rqst++; - trace_smb3_query_info_compound_enter(xid, ses->Suid, - tcon->tid, full_path); + trace_smb3_query_info_compound_enter(xid, tcon->tid, + ses->Suid, full_path); break; case SMB2_OP_POSIX_QUERY_INFO: rqst[num_rqst].rq_iov = &vars->qi_iov; @@ -334,18 +334,18 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, goto finished; } num_rqst++; - trace_smb3_posix_query_info_compound_enter(xid, ses->Suid, - tcon->tid, full_path); + trace_smb3_posix_query_info_compound_enter(xid, tcon->tid, + ses->Suid, full_path); break; case SMB2_OP_DELETE: - trace_smb3_delete_enter(xid, ses->Suid, tcon->tid, full_path); + trace_smb3_delete_enter(xid, tcon->tid, ses->Suid, full_path); break; case SMB2_OP_MKDIR: /* * Directories are created through parameters in the * SMB2_open() call. */ - trace_smb3_mkdir_enter(xid, ses->Suid, tcon->tid, full_path); + trace_smb3_mkdir_enter(xid, tcon->tid, ses->Suid, full_path); break; case SMB2_OP_RMDIR: rqst[num_rqst].rq_iov = &vars->si_iov[0]; @@ -363,7 +363,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, goto finished; smb2_set_next_command(tcon, &rqst[num_rqst]); smb2_set_related(&rqst[num_rqst++]); - trace_smb3_rmdir_enter(xid, ses->Suid, tcon->tid, full_path); + trace_smb3_rmdir_enter(xid, tcon->tid, ses->Suid, full_path); break; case SMB2_OP_SET_EOF: rqst[num_rqst].rq_iov = &vars->si_iov[0]; @@ -398,7 +398,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, goto finished; } num_rqst++; - trace_smb3_set_eof_enter(xid, ses->Suid, tcon->tid, full_path); + trace_smb3_set_eof_enter(xid, tcon->tid, ses->Suid, full_path); break; case SMB2_OP_SET_INFO: rqst[num_rqst].rq_iov = &vars->si_iov[0]; @@ -429,8 +429,8 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, goto finished; } num_rqst++; - trace_smb3_set_info_compound_enter(xid, ses->Suid, - tcon->tid, full_path); + trace_smb3_set_info_compound_enter(xid, tcon->tid, + ses->Suid, full_path); break; case SMB2_OP_RENAME: rqst[num_rqst].rq_iov = &vars->si_iov[0]; @@ -469,7 +469,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, goto finished; } num_rqst++; - trace_smb3_rename_enter(xid, ses->Suid, tcon->tid, full_path); + trace_smb3_rename_enter(xid, tcon->tid, ses->Suid, full_path); break; case SMB2_OP_HARDLINK: rqst[num_rqst].rq_iov = &vars->si_iov[0]; @@ -496,7 +496,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, goto finished; smb2_set_next_command(tcon, &rqst[num_rqst]); smb2_set_related(&rqst[num_rqst++]); - trace_smb3_hardlink_enter(xid, ses->Suid, tcon->tid, full_path); + trace_smb3_hardlink_enter(xid, tcon->tid, ses->Suid, full_path); break; case SMB2_OP_SET_REPARSE: rqst[num_rqst].rq_iov = vars->io_iov; @@ -523,8 +523,8 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, goto finished; } num_rqst++; - trace_smb3_set_reparse_compound_enter(xid, ses->Suid, - tcon->tid, full_path); + trace_smb3_set_reparse_compound_enter(xid, tcon->tid, + ses->Suid, full_path); break; case SMB2_OP_GET_REPARSE: rqst[num_rqst].rq_iov = vars->io_iov; @@ -549,8 +549,8 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, goto finished; } num_rqst++; - trace_smb3_get_reparse_compound_enter(xid, ses->Suid, - tcon->tid, full_path); + trace_smb3_get_reparse_compound_enter(xid, tcon->tid, + ses->Suid, full_path); break; case SMB2_OP_QUERY_WSL_EA: rqst[num_rqst].rq_iov = &vars->ea_iov; @@ -663,11 +663,11 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, } SMB2_query_info_free(&rqst[num_rqst++]); if (rc) - trace_smb3_query_info_compound_err(xid, ses->Suid, - tcon->tid, rc); + trace_smb3_query_info_compound_err(xid, tcon->tid, + ses->Suid, rc); else - trace_smb3_query_info_compound_done(xid, ses->Suid, - tcon->tid); + trace_smb3_query_info_compound_done(xid, tcon->tid, + ses->Suid); break; case SMB2_OP_POSIX_QUERY_INFO: idata = in_iov[i].iov_base; @@ -690,15 +690,15 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
SMB2_query_info_free(&rqst[num_rqst++]); if (rc) - trace_smb3_posix_query_info_compound_err(xid, ses->Suid, - tcon->tid, rc); + trace_smb3_posix_query_info_compound_err(xid, tcon->tid, + ses->Suid, rc); else - trace_smb3_posix_query_info_compound_done(xid, ses->Suid, - tcon->tid); + trace_smb3_posix_query_info_compound_done(xid, tcon->tid, + ses->Suid); break; case SMB2_OP_DELETE: if (rc) - trace_smb3_delete_err(xid, ses->Suid, tcon->tid, rc); + trace_smb3_delete_err(xid, tcon->tid, ses->Suid, rc); else { /* * If dentry (hence, inode) is NULL, lease break is going to @@ -706,59 +706,59 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, */ if (inode) cifs_mark_open_handles_for_deleted_file(inode, full_path); - trace_smb3_delete_done(xid, ses->Suid, tcon->tid); + trace_smb3_delete_done(xid, tcon->tid, ses->Suid); } break; case SMB2_OP_MKDIR: if (rc) - trace_smb3_mkdir_err(xid, ses->Suid, tcon->tid, rc); + trace_smb3_mkdir_err(xid, tcon->tid, ses->Suid, rc); else - trace_smb3_mkdir_done(xid, ses->Suid, tcon->tid); + trace_smb3_mkdir_done(xid, tcon->tid, ses->Suid); break; case SMB2_OP_HARDLINK: if (rc) - trace_smb3_hardlink_err(xid, ses->Suid, tcon->tid, rc); + trace_smb3_hardlink_err(xid, tcon->tid, ses->Suid, rc); else - trace_smb3_hardlink_done(xid, ses->Suid, tcon->tid); + trace_smb3_hardlink_done(xid, tcon->tid, ses->Suid); SMB2_set_info_free(&rqst[num_rqst++]); break; case SMB2_OP_RENAME: if (rc) - trace_smb3_rename_err(xid, ses->Suid, tcon->tid, rc); + trace_smb3_rename_err(xid, tcon->tid, ses->Suid, rc); else - trace_smb3_rename_done(xid, ses->Suid, tcon->tid); + trace_smb3_rename_done(xid, tcon->tid, ses->Suid); SMB2_set_info_free(&rqst[num_rqst++]); break; case SMB2_OP_RMDIR: if (rc) - trace_smb3_rmdir_err(xid, ses->Suid, tcon->tid, rc); + trace_smb3_rmdir_err(xid, tcon->tid, ses->Suid, rc); else - trace_smb3_rmdir_done(xid, ses->Suid, tcon->tid); + trace_smb3_rmdir_done(xid, tcon->tid, ses->Suid); SMB2_set_info_free(&rqst[num_rqst++]); break; case SMB2_OP_SET_EOF: if (rc) - trace_smb3_set_eof_err(xid, ses->Suid, tcon->tid, rc); + trace_smb3_set_eof_err(xid, tcon->tid, ses->Suid, rc); else - trace_smb3_set_eof_done(xid, ses->Suid, tcon->tid); + trace_smb3_set_eof_done(xid, tcon->tid, ses->Suid); SMB2_set_info_free(&rqst[num_rqst++]); break; case SMB2_OP_SET_INFO: if (rc) - trace_smb3_set_info_compound_err(xid, ses->Suid, - tcon->tid, rc); + trace_smb3_set_info_compound_err(xid, tcon->tid, + ses->Suid, rc); else - trace_smb3_set_info_compound_done(xid, ses->Suid, - tcon->tid); + trace_smb3_set_info_compound_done(xid, tcon->tid, + ses->Suid); SMB2_set_info_free(&rqst[num_rqst++]); break; case SMB2_OP_SET_REPARSE: if (rc) { - trace_smb3_set_reparse_compound_err(xid, ses->Suid, - tcon->tid, rc); + trace_smb3_set_reparse_compound_err(xid, tcon->tid, + ses->Suid, rc); } else { - trace_smb3_set_reparse_compound_done(xid, ses->Suid, - tcon->tid); + trace_smb3_set_reparse_compound_done(xid, tcon->tid, + ses->Suid); } SMB2_ioctl_free(&rqst[num_rqst++]); break; @@ -771,18 +771,18 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, rbuf = reparse_buf_ptr(iov); if (IS_ERR(rbuf)) { rc = PTR_ERR(rbuf); - trace_smb3_set_reparse_compound_err(xid, ses->Suid, - tcon->tid, rc); + trace_smb3_get_reparse_compound_err(xid, tcon->tid, + ses->Suid, rc); } else { idata->reparse.tag = le32_to_cpu(rbuf->ReparseTag); - trace_smb3_set_reparse_compound_done(xid, ses->Suid, - tcon->tid); + trace_smb3_get_reparse_compound_done(xid, tcon->tid, + ses->Suid); } memset(iov, 0, sizeof(*iov)); resp_buftype[i + 1] = CIFS_NO_BUFFER; } else { - trace_smb3_set_reparse_compound_err(xid, ses->Suid, - tcon->tid, rc); + trace_smb3_get_reparse_compound_err(xid, tcon->tid, + ses->Suid, rc); } SMB2_ioctl_free(&rqst[num_rqst++]); break; @@ -799,11 +799,11 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, } } if (!rc) { - trace_smb3_query_wsl_ea_compound_done(xid, ses->Suid, - tcon->tid); + trace_smb3_query_wsl_ea_compound_done(xid, tcon->tid, + ses->Suid); } else { - trace_smb3_query_wsl_ea_compound_err(xid, ses->Suid, - tcon->tid, rc); + trace_smb3_query_wsl_ea_compound_err(xid, tcon->tid, + ses->Suid, rc); } SMB2_query_info_free(&rqst[num_rqst++]); break; diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 9790ff2cc5b3..a588f6b3f3b6 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -3904,22 +3904,22 @@ static long smb3_fallocate(struct file *file, struct cifs_tcon *tcon, int mode, static void smb2_downgrade_oplock(struct TCP_Server_Info *server, struct cifsInodeInfo *cinode, __u32 oplock, - unsigned int epoch, bool *purge_cache) + __u16 epoch, bool *purge_cache) { server->ops->set_oplock_level(cinode, oplock, 0, NULL); }
static void smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, - unsigned int epoch, bool *purge_cache); + __u16 epoch, bool *purge_cache);
static void smb3_downgrade_oplock(struct TCP_Server_Info *server, struct cifsInodeInfo *cinode, __u32 oplock, - unsigned int epoch, bool *purge_cache) + __u16 epoch, bool *purge_cache) { unsigned int old_state = cinode->oplock; - unsigned int old_epoch = cinode->epoch; + __u16 old_epoch = cinode->epoch; unsigned int new_state;
if (epoch > old_epoch) { @@ -3939,7 +3939,7 @@ smb3_downgrade_oplock(struct TCP_Server_Info *server,
static void smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, - unsigned int epoch, bool *purge_cache) + __u16 epoch, bool *purge_cache) { oplock &= 0xFF; cinode->lease_granted = false; @@ -3963,7 +3963,7 @@ smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
static void smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, - unsigned int epoch, bool *purge_cache) + __u16 epoch, bool *purge_cache) { char message[5] = {0}; unsigned int new_oplock = 0; @@ -4000,7 +4000,7 @@ smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
static void smb3_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, - unsigned int epoch, bool *purge_cache) + __u16 epoch, bool *purge_cache) { unsigned int old_oplock = cinode->oplock;
@@ -4114,7 +4114,7 @@ smb3_create_lease_buf(u8 *lease_key, u8 oplock) }
static __u8 -smb2_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key) +smb2_parse_lease_buf(void *buf, __u16 *epoch, char *lease_key) { struct create_lease *lc = (struct create_lease *)buf;
@@ -4125,7 +4125,7 @@ smb2_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key) }
static __u8 -smb3_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key) +smb3_parse_lease_buf(void *buf, __u16 *epoch, char *lease_key) { struct create_lease_v2 *lc = (struct create_lease_v2 *)buf;
@@ -5077,6 +5077,7 @@ int __cifs_sfu_make_node(unsigned int xid, struct inode *inode, { struct TCP_Server_Info *server = tcon->ses->server; struct cifs_open_parms oparms; + struct cifs_open_info_data idata; struct cifs_io_parms io_parms = {}; struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_fid fid; @@ -5146,10 +5147,20 @@ int __cifs_sfu_make_node(unsigned int xid, struct inode *inode, CREATE_OPTION_SPECIAL, ACL_NO_MODE); oparms.fid = &fid;
- rc = server->ops->open(xid, &oparms, &oplock, NULL); + rc = server->ops->open(xid, &oparms, &oplock, &idata); if (rc) goto out;
+ /* + * Check if the server honored ATTR_SYSTEM flag by CREATE_OPTION_SPECIAL + * option. If not then server does not support ATTR_SYSTEM and newly + * created file is not SFU compatible, which means that the call failed. + */ + if (!(le32_to_cpu(idata.fi.Attributes) & ATTR_SYSTEM)) { + rc = -EOPNOTSUPP; + goto out_close; + } + if (type_len + data_len > 0) { io_parms.pid = current->tgid; io_parms.tcon = tcon; @@ -5164,8 +5175,18 @@ int __cifs_sfu_make_node(unsigned int xid, struct inode *inode, iov, ARRAY_SIZE(iov)-1); }
+out_close: server->ops->close(xid, tcon, &fid);
+ /* + * If CREATE was successful but either setting ATTR_SYSTEM failed or + * writing type/data information failed then remove the intermediate + * object created by CREATE. Otherwise intermediate empty object stay + * on the server. + */ + if (rc) + server->ops->unlink(xid, tcon, full_path, cifs_sb, NULL); + out: kfree(symname_utf16); return rc; diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c index 0577556f0a41..10eca164c838 100644 --- a/fs/smb/client/smb2pdu.c +++ b/fs/smb/client/smb2pdu.c @@ -2329,7 +2329,7 @@ parse_posix_ctxt(struct create_context *cc, struct smb2_file_all_info *info,
int smb2_parse_contexts(struct TCP_Server_Info *server, struct kvec *rsp_iov, - unsigned int *epoch, + __u16 *epoch, char *lease_key, __u8 *oplock, struct smb2_file_all_info *buf, struct create_posix_rsp *posix) diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h index 09349fa8da03..51d890f74e36 100644 --- a/fs/smb/client/smb2proto.h +++ b/fs/smb/client/smb2proto.h @@ -282,7 +282,7 @@ extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *, enum securityEnum); int smb2_parse_contexts(struct TCP_Server_Info *server, struct kvec *rsp_iov, - unsigned int *epoch, + __u16 *epoch, char *lease_key, __u8 *oplock, struct smb2_file_all_info *buf, struct create_posix_rsp *posix); diff --git a/fs/smb/server/transport_ipc.c b/fs/smb/server/transport_ipc.c index befaf42b84cc..e9aa92d02789 100644 --- a/fs/smb/server/transport_ipc.c +++ b/fs/smb/server/transport_ipc.c @@ -626,6 +626,9 @@ ksmbd_ipc_spnego_authen_request(const char *spnego_blob, int blob_len) struct ksmbd_spnego_authen_request *req; struct ksmbd_spnego_authen_response *resp;
+ if (blob_len > KSMBD_IPC_MAX_PAYLOAD) + return NULL; + msg = ipc_msg_alloc(sizeof(struct ksmbd_spnego_authen_request) + blob_len + 1); if (!msg) @@ -805,6 +808,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle struct ksmbd_rpc_command *req; struct ksmbd_rpc_command *resp;
+ if (payload_sz > KSMBD_IPC_MAX_PAYLOAD) + return NULL; + msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command) + payload_sz + 1); if (!msg) return NULL; @@ -853,6 +859,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle struct ksmbd_rpc_command *req; struct ksmbd_rpc_command *resp;
+ if (payload_sz > KSMBD_IPC_MAX_PAYLOAD) + return NULL; + msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command) + payload_sz + 1); if (!msg) return NULL; diff --git a/fs/xfs/xfs_exchrange.c b/fs/xfs/xfs_exchrange.c index 265c42449893..56803863b26c 100644 --- a/fs/xfs/xfs_exchrange.c +++ b/fs/xfs/xfs_exchrange.c @@ -326,22 +326,6 @@ xfs_exchrange_mappings( * successfully but before locks are dropped. */
-/* Verify that we have security clearance to perform this operation. */ -static int -xfs_exchange_range_verify_area( - struct xfs_exchrange *fxr) -{ - int ret; - - ret = remap_verify_area(fxr->file1, fxr->file1_offset, fxr->length, - true); - if (ret) - return ret; - - return remap_verify_area(fxr->file2, fxr->file2_offset, fxr->length, - true); -} - /* * Performs necessary checks before doing a range exchange, having stabilized * mutable inode attributes via i_rwsem. @@ -352,11 +336,13 @@ xfs_exchange_range_checks( unsigned int alloc_unit) { struct inode *inode1 = file_inode(fxr->file1); + loff_t size1 = i_size_read(inode1); struct inode *inode2 = file_inode(fxr->file2); + loff_t size2 = i_size_read(inode2); uint64_t allocmask = alloc_unit - 1; int64_t test_len; uint64_t blen; - loff_t size1, size2, tmp; + loff_t tmp; int error;
/* Don't touch certain kinds of inodes */ @@ -365,24 +351,25 @@ xfs_exchange_range_checks( if (IS_SWAPFILE(inode1) || IS_SWAPFILE(inode2)) return -ETXTBSY;
- size1 = i_size_read(inode1); - size2 = i_size_read(inode2); - /* Ranges cannot start after EOF. */ if (fxr->file1_offset > size1 || fxr->file2_offset > size2) return -EINVAL;
- /* - * If the caller said to exchange to EOF, we set the length of the - * request large enough to cover everything to the end of both files. - */ if (fxr->flags & XFS_EXCHANGE_RANGE_TO_EOF) { + /* + * If the caller said to exchange to EOF, we set the length of + * the request large enough to cover everything to the end of + * both files. + */ fxr->length = max_t(int64_t, size1 - fxr->file1_offset, size2 - fxr->file2_offset); - - error = xfs_exchange_range_verify_area(fxr); - if (error) - return error; + } else { + /* + * Otherwise we require both ranges to end within EOF. + */ + if (fxr->file1_offset + fxr->length > size1 || + fxr->file2_offset + fxr->length > size2) + return -EINVAL; }
/* @@ -398,15 +385,6 @@ xfs_exchange_range_checks( check_add_overflow(fxr->file2_offset, fxr->length, &tmp)) return -EINVAL;
- /* - * We require both ranges to end within EOF, unless we're exchanging - * to EOF. - */ - if (!(fxr->flags & XFS_EXCHANGE_RANGE_TO_EOF) && - (fxr->file1_offset + fxr->length > size1 || - fxr->file2_offset + fxr->length > size2)) - return -EINVAL; - /* * Make sure we don't hit any file size limits. If we hit any size * limits such that test_length was adjusted, we abort the whole @@ -744,6 +722,7 @@ xfs_exchange_range( { struct inode *inode1 = file_inode(fxr->file1); struct inode *inode2 = file_inode(fxr->file2); + loff_t check_len = fxr->length; int ret;
BUILD_BUG_ON(XFS_EXCHANGE_RANGE_ALL_FLAGS & @@ -776,14 +755,18 @@ xfs_exchange_range( return -EBADF;
/* - * If we're not exchanging to EOF, we can check the areas before - * stabilizing both files' i_size. + * If we're exchanging to EOF we can't calculate the length until taking + * the iolock. Pass a 0 length to remap_verify_area similar to the + * FICLONE and FICLONERANGE ioctls that support cloning to EOF as well. */ - if (!(fxr->flags & XFS_EXCHANGE_RANGE_TO_EOF)) { - ret = xfs_exchange_range_verify_area(fxr); - if (ret) - return ret; - } + if (fxr->flags & XFS_EXCHANGE_RANGE_TO_EOF) + check_len = 0; + ret = remap_verify_area(fxr->file1, fxr->file1_offset, check_len, true); + if (ret) + return ret; + ret = remap_verify_area(fxr->file2, fxr->file2_offset, check_len, true); + if (ret) + return ret;
/* Update cmtime if the fd/inode don't forbid it. */ if (!(fxr->file1->f_mode & FMODE_NOCMTIME) && !IS_NOCMTIME(inode1)) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index c8ad2606f928..1ff514b6c035 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1404,8 +1404,11 @@ xfs_inactive( goto out;
/* Try to clean out the cow blocks if there are any. */ - if (xfs_inode_has_cow_data(ip)) - xfs_reflink_cancel_cow_range(ip, 0, NULLFILEOFF, true); + if (xfs_inode_has_cow_data(ip)) { + error = xfs_reflink_cancel_cow_range(ip, 0, NULLFILEOFF, true); + if (error) + goto out; + }
if (VFS_I(ip)->i_nlink != 0) { /* diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 50fa3ef89f6c..d61460309a78 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -976,10 +976,8 @@ xfs_dax_write_iomap_end( if (!xfs_is_cow_inode(ip)) return 0;
- if (!written) { - xfs_reflink_cancel_cow_range(ip, pos, length, true); - return 0; - } + if (!written) + return xfs_reflink_cancel_cow_range(ip, pos, length, true);
return xfs_reflink_end_cow(ip, pos, written); } diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index e3fa43291f44..1e2b25e204cb 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -2001,8 +2001,11 @@ struct drm_connector { struct drm_encoder *encoder;
#define MAX_ELD_BYTES 128 - /** @eld: EDID-like data, if present */ + /** @eld: EDID-like data, if present, protected by @eld_mutex */ uint8_t eld[MAX_ELD_BYTES]; + /** @eld_mutex: protection for concurrenct access to @eld */ + struct mutex eld_mutex; + /** @latency_present: AV delay info from ELD, if found */ bool latency_present[2]; /** diff --git a/include/drm/drm_utils.h b/include/drm/drm_utils.h index 70775748d243..15fa9b6865f4 100644 --- a/include/drm/drm_utils.h +++ b/include/drm/drm_utils.h @@ -12,8 +12,12 @@
#include <linux/types.h>
+struct drm_edid; + int drm_get_panel_orientation_quirk(int width, int height);
+int drm_get_panel_min_brightness_quirk(const struct drm_edid *edid); + signed long drm_timeout_abs_to_jiffies(int64_t timeout_nsec);
#endif diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index e6c00e860951..3305c849abd6 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -42,7 +42,9 @@ struct linux_binprm { * Set when errors can no longer be returned to the * original userspace. */ - point_of_no_return:1; + point_of_no_return:1, + /* Set when "comm" must come from the dentry. */ + comm_from_dentry:1; struct file *executable; /* Executable to pass to the interpreter */ struct file *interpreter; struct file *file; diff --git a/include/linux/call_once.h b/include/linux/call_once.h new file mode 100644 index 000000000000..6261aa0b3fb0 --- /dev/null +++ b/include/linux/call_once.h @@ -0,0 +1,45 @@ +#ifndef _LINUX_CALL_ONCE_H +#define _LINUX_CALL_ONCE_H + +#include <linux/types.h> +#include <linux/mutex.h> + +#define ONCE_NOT_STARTED 0 +#define ONCE_RUNNING 1 +#define ONCE_COMPLETED 2 + +struct once { + atomic_t state; + struct mutex lock; +}; + +static inline void __once_init(struct once *once, const char *name, + struct lock_class_key *key) +{ + atomic_set(&once->state, ONCE_NOT_STARTED); + __mutex_init(&once->lock, name, key); +} + +#define once_init(once) \ +do { \ + static struct lock_class_key __key; \ + __once_init((once), #once, &__key); \ +} while (0) + +static inline void call_once(struct once *once, void (*cb)(struct once *)) +{ + /* Pairs with atomic_set_release() below. */ + if (atomic_read_acquire(&once->state) == ONCE_COMPLETED) + return; + + guard(mutex)(&once->lock); + WARN_ON(atomic_read(&once->state) == ONCE_RUNNING); + if (atomic_read(&once->state) != ONCE_NOT_STARTED) + return; + + atomic_set(&once->state, ONCE_RUNNING); + cb(once); + atomic_set_release(&once->state, ONCE_COMPLETED); +} + +#endif /* _LINUX_CALL_ONCE_H */ diff --git a/include/linux/hrtimer_defs.h b/include/linux/hrtimer_defs.h index c3b4b7ed7c16..84a5045f80f3 100644 --- a/include/linux/hrtimer_defs.h +++ b/include/linux/hrtimer_defs.h @@ -125,6 +125,7 @@ struct hrtimer_cpu_base { ktime_t softirq_expires_next; struct hrtimer *softirq_next_timer; struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES]; + call_single_data_t csd; } ____cacheline_aligned;
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h index ed945f42e064..0ea8c9887429 100644 --- a/include/linux/jiffies.h +++ b/include/linux/jiffies.h @@ -537,7 +537,7 @@ static __always_inline unsigned long msecs_to_jiffies(const unsigned int m) * * Return: jiffies value */ -#define secs_to_jiffies(_secs) ((_secs) * HZ) +#define secs_to_jiffies(_secs) (unsigned long)((_secs) * HZ)
extern unsigned long __usecs_to_jiffies(const unsigned int u); #if !(USEC_PER_SEC % HZ) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 401439bb21e3..b0b38744c4b0 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -963,6 +963,15 @@ static inline struct kvm_io_bus *kvm_get_bus(struct kvm *kvm, enum kvm_bus idx) static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i) { int num_vcpus = atomic_read(&kvm->online_vcpus); + + /* + * Explicitly verify the target vCPU is online, as the anti-speculation + * logic only limits the CPU's ability to speculate, e.g. given a "bad" + * index, clamping the index to 0 would return vCPU0, not NULL. + */ + if (i >= num_vcpus) + return NULL; + i = array_index_nospec(i, num_vcpus);
/* Pairs with smp_wmb() in kvm_vm_ioctl_create_vcpu. */ diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index ea48eb879a0f..fed666c5bd16 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -691,7 +691,6 @@ struct mlx5_timer { struct timecounter tc; u32 nominal_c_mult; unsigned long overflow_period; - struct delayed_work overflow_work; };
struct mlx5_clock { diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h index 365e119bebaa..783e2a336861 100644 --- a/include/linux/platform_data/x86/asus-wmi.h +++ b/include/linux/platform_data/x86/asus-wmi.h @@ -184,6 +184,11 @@ static const struct dmi_system_id asus_use_hid_led_dmi_ids[] = { DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Flow"), }, }, + { + .matches = { + DMI_MATCH(DMI_PRODUCT_FAMILY, "ProArt P16"), + }, + }, { .matches = { DMI_MATCH(DMI_BOARD_NAME, "GA403U"), diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 1e6324f0d4ef..24e48af7e8f7 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -851,7 +851,7 @@ static inline int qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch, }
static inline void _bstats_update(struct gnet_stats_basic_sync *bstats, - __u64 bytes, __u32 packets) + __u64 bytes, __u64 packets) { u64_stats_update_begin(&bstats->syncp); u64_stats_add(&bstats->bytes, bytes); diff --git a/include/rv/da_monitor.h b/include/rv/da_monitor.h index 9705b2a98e49..510c88bfabd4 100644 --- a/include/rv/da_monitor.h +++ b/include/rv/da_monitor.h @@ -14,6 +14,7 @@ #include <rv/automata.h> #include <linux/rv.h> #include <linux/bug.h> +#include <linux/sched.h>
#ifdef CONFIG_RV_REACTORS
@@ -324,10 +325,13 @@ static inline struct da_monitor *da_get_monitor_##name(struct task_struct *tsk) static void da_monitor_reset_all_##name(void) \ { \ struct task_struct *g, *p; \ + int cpu; \ \ read_lock(&tasklist_lock); \ for_each_process_thread(g, p) \ da_monitor_reset_##name(da_get_monitor_##name(p)); \ + for_each_present_cpu(cpu) \ + da_monitor_reset_##name(da_get_monitor_##name(idle_task(cpu))); \ read_unlock(&tasklist_lock); \ } \ \ diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h index 27c23873c881..ee4030f2e99d 100644 --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h @@ -218,6 +218,7 @@ EM(rxrpc_conn_get_conn_input, "GET inp-conn") \ EM(rxrpc_conn_get_idle, "GET idle ") \ EM(rxrpc_conn_get_poke_abort, "GET pk-abort") \ + EM(rxrpc_conn_get_poke_secured, "GET secured ") \ EM(rxrpc_conn_get_poke_timer, "GET poke ") \ EM(rxrpc_conn_get_service_conn, "GET svc-conn") \ EM(rxrpc_conn_new_client, "NEW client ") \ diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index efe5de6ce208..aaa4f3bc688b 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -411,13 +411,20 @@ struct drm_amdgpu_gem_userptr { /* GFX12 and later: */ #define AMDGPU_TILING_GFX12_SWIZZLE_MODE_SHIFT 0 #define AMDGPU_TILING_GFX12_SWIZZLE_MODE_MASK 0x7 -/* These are DCC recompression setting for memory management: */ +/* These are DCC recompression settings for memory management: */ #define AMDGPU_TILING_GFX12_DCC_MAX_COMPRESSED_BLOCK_SHIFT 3 #define AMDGPU_TILING_GFX12_DCC_MAX_COMPRESSED_BLOCK_MASK 0x3 /* 0:64B, 1:128B, 2:256B */ #define AMDGPU_TILING_GFX12_DCC_NUMBER_TYPE_SHIFT 5 #define AMDGPU_TILING_GFX12_DCC_NUMBER_TYPE_MASK 0x7 /* CB_COLOR0_INFO.NUMBER_TYPE */ #define AMDGPU_TILING_GFX12_DCC_DATA_FORMAT_SHIFT 8 #define AMDGPU_TILING_GFX12_DCC_DATA_FORMAT_MASK 0x3f /* [0:4]:CB_COLOR0_INFO.FORMAT, [5]:MM */ +/* When clearing the buffer or moving it from VRAM to GTT, don't compress and set DCC metadata + * to uncompressed. Set when parts of an allocation bypass DCC and read raw data. */ +#define AMDGPU_TILING_GFX12_DCC_WRITE_COMPRESS_DISABLE_SHIFT 14 +#define AMDGPU_TILING_GFX12_DCC_WRITE_COMPRESS_DISABLE_MASK 0x1 +/* bit gap */ +#define AMDGPU_TILING_GFX12_SCANOUT_SHIFT 63 +#define AMDGPU_TILING_GFX12_SCANOUT_MASK 0x1
/* Set/Get helpers for tiling flags. */ #define AMDGPU_TILING_SET(field, value) \ diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h index a4206723f503..5a199f3d4a26 100644 --- a/include/uapi/linux/input-event-codes.h +++ b/include/uapi/linux/input-event-codes.h @@ -519,6 +519,7 @@ #define KEY_NOTIFICATION_CENTER 0x1bc /* Show/hide the notification center */ #define KEY_PICKUP_PHONE 0x1bd /* Answer incoming call */ #define KEY_HANGUP_PHONE 0x1be /* Decline incoming call */ +#define KEY_LINK_PHONE 0x1bf /* AL Phone Syncing */
#define KEY_DEL_EOL 0x1c0 #define KEY_DEL_EOS 0x1c1 diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h index 34810f6ae2b5..78747b24bd0f 100644 --- a/include/uapi/linux/iommufd.h +++ b/include/uapi/linux/iommufd.h @@ -868,6 +868,7 @@ enum iommu_hwpt_pgfault_perm { * @pasid: Process Address Space ID * @grpid: Page Request Group Index * @perm: Combination of enum iommu_hwpt_pgfault_perm + * @__reserved: Must be 0. * @addr: Fault address * @length: a hint of how much data the requestor is expecting to fetch. For * example, if the PRI initiator knows it is going to do a 10MB @@ -883,7 +884,8 @@ struct iommu_hwpt_pgfault { __u32 pasid; __u32 grpid; __u32 perm; - __u64 addr; + __u32 __reserved; + __aligned_u64 addr; __u32 length; __u32 cookie; }; diff --git a/include/uapi/linux/raid/md_p.h b/include/uapi/linux/raid/md_p.h index 5a43c23f53bf..ff47b6f0ba0f 100644 --- a/include/uapi/linux/raid/md_p.h +++ b/include/uapi/linux/raid/md_p.h @@ -233,7 +233,7 @@ struct mdp_superblock_1 { char set_name[32]; /* set and interpreted by user-space */
__le64 ctime; /* lo 40 bits are seconds, top 24 are microseconds or 0*/ - __le32 level; /* 0,1,4,5 */ + __le32 level; /* 0,1,4,5, -1 (linear) */ __le32 layout; /* only for raid5 and raid10 currently */ __le64 size; /* used size of component devices, in 512byte sectors */
diff --git a/include/uapi/linux/raid/md_u.h b/include/uapi/linux/raid/md_u.h index 7be89a4906e7..a893010735fb 100644 --- a/include/uapi/linux/raid/md_u.h +++ b/include/uapi/linux/raid/md_u.h @@ -103,6 +103,8 @@ typedef struct mdu_array_info_s {
} mdu_array_info_t;
+#define LEVEL_LINEAR (-1) + /* we need a value for 'no level specified' and 0 * means 'raid0', so we need something else. This is * for internal use only diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h index e594abe5d05f..f0c6111160e7 100644 --- a/include/ufs/ufs.h +++ b/include/ufs/ufs.h @@ -386,8 +386,8 @@ enum {
/* Possible values for dExtendedUFSFeaturesSupport */ enum { - UFS_DEV_LOW_TEMP_NOTIF = BIT(4), - UFS_DEV_HIGH_TEMP_NOTIF = BIT(5), + UFS_DEV_HIGH_TEMP_NOTIF = BIT(4), + UFS_DEV_LOW_TEMP_NOTIF = BIT(5), UFS_DEV_EXT_TEMP_NOTIF = BIT(6), UFS_DEV_HPB_SUPPORT = BIT(7), UFS_DEV_WRITE_BOOSTER_SUP = BIT(8), diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 74e5b9960c54..82b2d2b25c23 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -1297,7 +1297,6 @@ static inline void ufshcd_rmwl(struct ufs_hba *hba, u32 mask, u32 val, u32 reg) void ufshcd_enable_irq(struct ufs_hba *hba); void ufshcd_disable_irq(struct ufs_hba *hba); int ufshcd_alloc_host(struct device *, struct ufs_hba **); -void ufshcd_dealloc_host(struct ufs_hba *); int ufshcd_hba_enable(struct ufs_hba *hba); int ufshcd_init(struct ufs_hba *, void __iomem *, unsigned int); int ufshcd_link_recovery(struct ufs_hba *hba); diff --git a/io_uring/net.c b/io_uring/net.c index c6cd38cc5dc4..b01bf900e3b9 100644 --- a/io_uring/net.c +++ b/io_uring/net.c @@ -1709,6 +1709,11 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags) int ret; bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
+ if (unlikely(req->flags & REQ_F_FAIL)) { + ret = -ECONNRESET; + goto out; + } + file_flags = force_nonblock ? O_NONBLOCK : 0;
ret = __sys_connect_file(req->file, &io->addr, connect->addr_len, diff --git a/io_uring/poll.c b/io_uring/poll.c index bced9edd5233..2c28c4c93071 100644 --- a/io_uring/poll.c +++ b/io_uring/poll.c @@ -273,6 +273,8 @@ static int io_poll_check_events(struct io_kiocb *req, struct io_tw_state *ts) return IOU_POLL_REISSUE; } } + if (unlikely(req->cqe.res & EPOLLERR)) + req_set_fail(req); if (req->apoll_events & EPOLLONESHOT) return IOU_POLL_DONE;
@@ -315,8 +317,10 @@ void io_poll_task_func(struct io_kiocb *req, struct io_tw_state *ts)
ret = io_poll_check_events(req, ts); if (ret == IOU_POLL_NO_ACTION) { + io_kbuf_recycle(req, 0); return; } else if (ret == IOU_POLL_REQUEUE) { + io_kbuf_recycle(req, 0); __io_poll_execute(req, 0); return; } diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 77f56674aaa9..4f02345b764f 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -18803,7 +18803,7 @@ static int do_check(struct bpf_verifier_env *env) * match caller reference state when it exits. */ err = check_resource_leak(env, exception_exit, !env->cur_state->curframe, - "BPF_EXIT instruction"); + "BPF_EXIT instruction in main prog"); if (err) return err;
diff --git a/kernel/locking/test-ww_mutex.c b/kernel/locking/test-ww_mutex.c index 5d58b2c0ef98..bcb1b9fea588 100644 --- a/kernel/locking/test-ww_mutex.c +++ b/kernel/locking/test-ww_mutex.c @@ -404,7 +404,7 @@ static inline u32 prandom_u32_below(u32 ceil) static int *get_random_order(int count) { int *order; - int n, r, tmp; + int n, r;
order = kmalloc_array(count, sizeof(*order), GFP_KERNEL); if (!order) @@ -415,11 +415,8 @@ static int *get_random_order(int count)
for (n = count - 1; n > 1; n--) { r = prandom_u32_below(n + 1); - if (r != n) { - tmp = order[n]; - order[n] = order[r]; - order[r] = tmp; - } + if (r != n) + swap(order[n], order[r]); }
return order; diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index f446a06b4da8..07668433644b 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -523,7 +523,7 @@ static struct latched_seq clear_seq = { /* record buffer */ #define LOG_ALIGN __alignof__(unsigned long) #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) -#define LOG_BUF_LEN_MAX (u32)(1 << 31) +#define LOG_BUF_LEN_MAX ((u32)1 << 31) static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN); static char *log_buf = __log_buf; static u32 log_buf_len = __LOG_BUF_LEN; diff --git a/kernel/sched/core.c b/kernel/sched/core.c index e0fd8069c60e..ffceb5ff4c5c 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -766,13 +766,15 @@ static void update_rq_clock_task(struct rq *rq, s64 delta) #endif #ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING if (static_key_false((¶virt_steal_rq_enabled))) { - steal = paravirt_steal_clock(cpu_of(rq)); + u64 prev_steal; + + steal = prev_steal = paravirt_steal_clock(cpu_of(rq)); steal -= rq->prev_steal_time_rq;
if (unlikely(steal > delta)) steal = delta;
- rq->prev_steal_time_rq += steal; + rq->prev_steal_time_rq = prev_steal; delta -= steal; } #endif diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 8800679b508d..7d0a05660e5e 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -5372,6 +5372,15 @@ static __always_inline void return_cfs_rq_runtime(struct cfs_rq *cfs_rq); static void set_delayed(struct sched_entity *se) { se->sched_delayed = 1; + + /* + * Delayed se of cfs_rq have no tasks queued on them. + * Do not adjust h_nr_runnable since dequeue_entities() + * will account it for blocked tasks. + */ + if (!entity_is_task(se)) + return; + for_each_sched_entity(se) { struct cfs_rq *cfs_rq = cfs_rq_of(se);
@@ -5384,6 +5393,16 @@ static void set_delayed(struct sched_entity *se) static void clear_delayed(struct sched_entity *se) { se->sched_delayed = 0; + + /* + * Delayed se of cfs_rq have no tasks queued on them. + * Do not adjust h_nr_runnable since a dequeue has + * already accounted for it or an enqueue of a task + * below it will account for it in enqueue_task_fair(). + */ + if (!entity_is_task(se)) + return; + for_each_sched_entity(se) { struct cfs_rq *cfs_rq = cfs_rq_of(se);
diff --git a/kernel/seccomp.c b/kernel/seccomp.c index 385d48293a5f..0cd1f8b5a102 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c @@ -749,6 +749,15 @@ static bool seccomp_is_const_allow(struct sock_fprog_kern *fprog, if (WARN_ON_ONCE(!fprog)) return false;
+ /* Our single exception to filtering. */ +#ifdef __NR_uretprobe +#ifdef SECCOMP_ARCH_COMPAT + if (sd->arch == SECCOMP_ARCH_NATIVE) +#endif + if (sd->nr == __NR_uretprobe) + return true; +#endif + for (pc = 0; pc < fprog->len; pc++) { struct sock_filter *insn = &fprog->filter[pc]; u16 code = insn->code; @@ -1023,6 +1032,9 @@ static inline void seccomp_log(unsigned long syscall, long signr, u32 action, */ static const int mode1_syscalls[] = { __NR_seccomp_read, __NR_seccomp_write, __NR_seccomp_exit, __NR_seccomp_sigreturn, +#ifdef __NR_uretprobe + __NR_uretprobe, +#endif -1, /* negative terminated */ };
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 030426c8c944..36dd2f5c30da 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -58,6 +58,8 @@ #define HRTIMER_ACTIVE_SOFT (HRTIMER_ACTIVE_HARD << MASK_SHIFT) #define HRTIMER_ACTIVE_ALL (HRTIMER_ACTIVE_SOFT | HRTIMER_ACTIVE_HARD)
+static void retrigger_next_event(void *arg); + /* * The timer bases: * @@ -111,7 +113,8 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = .clockid = CLOCK_TAI, .get_time = &ktime_get_clocktai, }, - } + }, + .csd = CSD_INIT(retrigger_next_event, NULL) };
static const int hrtimer_clock_to_base_table[MAX_CLOCKS] = { @@ -124,6 +127,14 @@ static const int hrtimer_clock_to_base_table[MAX_CLOCKS] = { [CLOCK_TAI] = HRTIMER_BASE_TAI, };
+static inline bool hrtimer_base_is_online(struct hrtimer_cpu_base *base) +{ + if (!IS_ENABLED(CONFIG_HOTPLUG_CPU)) + return true; + else + return likely(base->online); +} + /* * Functions and macros which are different for UP/SMP systems are kept in a * single place @@ -183,27 +194,54 @@ struct hrtimer_clock_base *lock_hrtimer_base(const struct hrtimer *timer, }
/* - * We do not migrate the timer when it is expiring before the next - * event on the target cpu. When high resolution is enabled, we cannot - * reprogram the target cpu hardware and we would cause it to fire - * late. To keep it simple, we handle the high resolution enabled and - * disabled case similar. + * Check if the elected target is suitable considering its next + * event and the hotplug state of the current CPU. + * + * If the elected target is remote and its next event is after the timer + * to queue, then a remote reprogram is necessary. However there is no + * guarantee the IPI handling the operation would arrive in time to meet + * the high resolution deadline. In this case the local CPU becomes a + * preferred target, unless it is offline. + * + * High and low resolution modes are handled the same way for simplicity. * * Called with cpu_base->lock of target cpu held. */ -static int -hrtimer_check_target(struct hrtimer *timer, struct hrtimer_clock_base *new_base) +static bool hrtimer_suitable_target(struct hrtimer *timer, struct hrtimer_clock_base *new_base, + struct hrtimer_cpu_base *new_cpu_base, + struct hrtimer_cpu_base *this_cpu_base) { ktime_t expires;
+ /* + * The local CPU clockevent can be reprogrammed. Also get_target_base() + * guarantees it is online. + */ + if (new_cpu_base == this_cpu_base) + return true; + + /* + * The offline local CPU can't be the default target if the + * next remote target event is after this timer. Keep the + * elected new base. An IPI will we issued to reprogram + * it as a last resort. + */ + if (!hrtimer_base_is_online(this_cpu_base)) + return true; + expires = ktime_sub(hrtimer_get_expires(timer), new_base->offset); - return expires < new_base->cpu_base->expires_next; + + return expires >= new_base->cpu_base->expires_next; }
-static inline -struct hrtimer_cpu_base *get_target_base(struct hrtimer_cpu_base *base, - int pinned) +static inline struct hrtimer_cpu_base *get_target_base(struct hrtimer_cpu_base *base, int pinned) { + if (!hrtimer_base_is_online(base)) { + int cpu = cpumask_any_and(cpu_online_mask, housekeeping_cpumask(HK_TYPE_TIMER)); + + return &per_cpu(hrtimer_bases, cpu); + } + #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) if (static_branch_likely(&timers_migration_enabled) && !pinned) return &per_cpu(hrtimer_bases, get_nohz_timer_target()); @@ -254,8 +292,8 @@ switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base, raw_spin_unlock(&base->cpu_base->lock); raw_spin_lock(&new_base->cpu_base->lock);
- if (new_cpu_base != this_cpu_base && - hrtimer_check_target(timer, new_base)) { + if (!hrtimer_suitable_target(timer, new_base, new_cpu_base, + this_cpu_base)) { raw_spin_unlock(&new_base->cpu_base->lock); raw_spin_lock(&base->cpu_base->lock); new_cpu_base = this_cpu_base; @@ -264,8 +302,7 @@ switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base, } WRITE_ONCE(timer->base, new_base); } else { - if (new_cpu_base != this_cpu_base && - hrtimer_check_target(timer, new_base)) { + if (!hrtimer_suitable_target(timer, new_base, new_cpu_base, this_cpu_base)) { new_cpu_base = this_cpu_base; goto again; } @@ -716,8 +753,6 @@ static inline int hrtimer_is_hres_enabled(void) return hrtimer_hres_enabled; }
-static void retrigger_next_event(void *arg); - /* * Switch to high resolution mode */ @@ -1206,6 +1241,7 @@ static int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, u64 delta_ns, const enum hrtimer_mode mode, struct hrtimer_clock_base *base) { + struct hrtimer_cpu_base *this_cpu_base = this_cpu_ptr(&hrtimer_bases); struct hrtimer_clock_base *new_base; bool force_local, first;
@@ -1217,9 +1253,15 @@ static int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, * and enforce reprogramming after it is queued no matter whether * it is the new first expiring timer again or not. */ - force_local = base->cpu_base == this_cpu_ptr(&hrtimer_bases); + force_local = base->cpu_base == this_cpu_base; force_local &= base->cpu_base->next_timer == timer;
+ /* + * Don't force local queuing if this enqueue happens on a unplugged + * CPU after hrtimer_cpu_dying() has been invoked. + */ + force_local &= this_cpu_base->online; + /* * Remove an active timer from the queue. In case it is not queued * on the current CPU, make sure that remove_hrtimer() updates the @@ -1249,8 +1291,27 @@ static int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, }
first = enqueue_hrtimer(timer, new_base, mode); - if (!force_local) - return first; + if (!force_local) { + /* + * If the current CPU base is online, then the timer is + * never queued on a remote CPU if it would be the first + * expiring timer there. + */ + if (hrtimer_base_is_online(this_cpu_base)) + return first; + + /* + * Timer was enqueued remote because the current base is + * already offline. If the timer is the first to expire, + * kick the remote CPU to reprogram the clock event. + */ + if (first) { + struct hrtimer_cpu_base *new_cpu_base = new_base->cpu_base; + + smp_call_function_single_async(new_cpu_base->cpu, &new_cpu_base->csd); + } + return 0; + }
/* * Timer was forced to stay on the current CPU to avoid diff --git a/kernel/time/timer_migration.c b/kernel/time/timer_migration.c index 066c9ddca4ec..0707f1ef05f7 100644 --- a/kernel/time/timer_migration.c +++ b/kernel/time/timer_migration.c @@ -1677,6 +1677,9 @@ static int tmigr_setup_groups(unsigned int cpu, unsigned int node)
} while (i < tmigr_hierarchy_levels);
+ /* Assert single root */ + WARN_ON_ONCE(!err && !group->parent && !list_is_singular(&tmigr_level_list[top])); + while (i > 0) { group = stack[--i];
@@ -1718,7 +1721,12 @@ static int tmigr_setup_groups(unsigned int cpu, unsigned int node) WARN_ON_ONCE(top == 0);
lvllist = &tmigr_level_list[top]; - if (group->num_children == 1 && list_is_singular(lvllist)) { + + /* + * Newly created root level should have accounted the upcoming + * CPU's child group and pre-accounted the old root. + */ + if (group->num_children == 2 && list_is_singular(lvllist)) { /* * The target CPU must never do the prepare work, except * on early boot when the boot CPU is the target. Otherwise diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 60210fb5b211..6b888699f916 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -4398,8 +4398,13 @@ rb_reserve_next_event(struct trace_buffer *buffer, int nr_loops = 0; int add_ts_default;
- /* ring buffer does cmpxchg, make sure it is safe in NMI context */ - if (!IS_ENABLED(CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG) && + /* + * ring buffer does cmpxchg as well as atomic64 operations + * (which some archs use locking for atomic64), make sure this + * is safe in NMI context + */ + if ((!IS_ENABLED(CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG) || + IS_ENABLED(CONFIG_GENERIC_ATOMIC64)) && (unlikely(in_nmi()))) { return NULL; } @@ -7059,7 +7064,7 @@ static int __rb_map_vma(struct ring_buffer_per_cpu *cpu_buffer, }
while (p < nr_pages) { - struct page *page = virt_to_page((void *)cpu_buffer->subbuf_ids[s]); + struct page *page; int off = 0;
if (WARN_ON_ONCE(s >= nr_subbufs)) { @@ -7067,6 +7072,8 @@ static int __rb_map_vma(struct ring_buffer_per_cpu *cpu_buffer, goto out; }
+ page = virt_to_page((void *)cpu_buffer->subbuf_ids[s]); + for (; off < (1 << (subbuf_order)); off++, page++) { if (p >= nr_pages) break; diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 5504b5e4e7b4..d81fcf51b196 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -198,7 +198,7 @@ int trace_graph_entry(struct ftrace_graph_ent *trace, * returning from the function. */ if (ftrace_graph_notrace_addr(trace->func)) { - *task_var |= TRACE_GRAPH_NOTRACE_BIT; + *task_var |= TRACE_GRAPH_NOTRACE; /* * Need to return 1 to have the return called * that will clear the NOTRACE bit. diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c index b9f96c77527d..23cbc24ed292 100644 --- a/kernel/trace/trace_osnoise.c +++ b/kernel/trace/trace_osnoise.c @@ -1229,6 +1229,8 @@ static void trace_sched_migrate_callback(void *data, struct task_struct *p, int } }
+static bool monitor_enabled; + static int register_migration_monitor(void) { int ret = 0; @@ -1237,16 +1239,25 @@ static int register_migration_monitor(void) * Timerlat thread migration check is only required when running timerlat in user-space. * Thus, enable callback only if timerlat is set with no workload. */ - if (timerlat_enabled() && !test_bit(OSN_WORKLOAD, &osnoise_options)) + if (timerlat_enabled() && !test_bit(OSN_WORKLOAD, &osnoise_options)) { + if (WARN_ON_ONCE(monitor_enabled)) + return 0; + ret = register_trace_sched_migrate_task(trace_sched_migrate_callback, NULL); + if (!ret) + monitor_enabled = true; + }
return ret; }
static void unregister_migration_monitor(void) { - if (timerlat_enabled() && !test_bit(OSN_WORKLOAD, &osnoise_options)) - unregister_trace_sched_migrate_task(trace_sched_migrate_callback, NULL); + if (!monitor_enabled) + return; + + unregister_trace_sched_migrate_task(trace_sched_migrate_callback, NULL); + monitor_enabled = false; } #else static int register_migration_monitor(void) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index f3d723705879..bc725add84f4 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1504,7 +1504,7 @@ config LOCKDEP_SMALL config LOCKDEP_BITS int "Bitsize for MAX_LOCKDEP_ENTRIES" depends on LOCKDEP && !LOCKDEP_SMALL - range 10 30 + range 10 24 default 15 help Try increasing this value if you hit "BUG: MAX_LOCKDEP_ENTRIES too low!" message. @@ -1520,7 +1520,7 @@ config LOCKDEP_CHAINS_BITS config LOCKDEP_STACK_TRACE_BITS int "Bitsize for MAX_STACK_TRACE_ENTRIES" depends on LOCKDEP && !LOCKDEP_SMALL - range 10 30 + range 10 26 default 19 help Try increasing this value if you hit "BUG: MAX_STACK_TRACE_ENTRIES too low!" message. @@ -1528,7 +1528,7 @@ config LOCKDEP_STACK_TRACE_BITS config LOCKDEP_STACK_TRACE_HASH_BITS int "Bitsize for STACK_TRACE_HASH_SIZE" depends on LOCKDEP && !LOCKDEP_SMALL - range 10 30 + range 10 26 default 14 help Try increasing this value if you need large STACK_TRACE_HASH_SIZE. @@ -1536,7 +1536,7 @@ config LOCKDEP_STACK_TRACE_HASH_BITS config LOCKDEP_CIRCULAR_QUEUE_BITS int "Bitsize for elements in circular_queue struct" depends on LOCKDEP - range 10 30 + range 10 26 default 12 help Try increasing this value if you hit "lockdep bfs error:-1" warning due to __cq_enqueue() failure. diff --git a/lib/atomic64.c b/lib/atomic64.c index caf895789a1e..1a72bba36d24 100644 --- a/lib/atomic64.c +++ b/lib/atomic64.c @@ -25,15 +25,15 @@ * Ensure each lock is in a separate cacheline. */ static union { - raw_spinlock_t lock; + arch_spinlock_t lock; char pad[L1_CACHE_BYTES]; } atomic64_lock[NR_LOCKS] __cacheline_aligned_in_smp = { [0 ... (NR_LOCKS - 1)] = { - .lock = __RAW_SPIN_LOCK_UNLOCKED(atomic64_lock.lock), + .lock = __ARCH_SPIN_LOCK_UNLOCKED, }, };
-static inline raw_spinlock_t *lock_addr(const atomic64_t *v) +static inline arch_spinlock_t *lock_addr(const atomic64_t *v) { unsigned long addr = (unsigned long) v;
@@ -45,12 +45,14 @@ static inline raw_spinlock_t *lock_addr(const atomic64_t *v) s64 generic_atomic64_read(const atomic64_t *v) { unsigned long flags; - raw_spinlock_t *lock = lock_addr(v); + arch_spinlock_t *lock = lock_addr(v); s64 val;
- raw_spin_lock_irqsave(lock, flags); + local_irq_save(flags); + arch_spin_lock(lock); val = v->counter; - raw_spin_unlock_irqrestore(lock, flags); + arch_spin_unlock(lock); + local_irq_restore(flags); return val; } EXPORT_SYMBOL(generic_atomic64_read); @@ -58,11 +60,13 @@ EXPORT_SYMBOL(generic_atomic64_read); void generic_atomic64_set(atomic64_t *v, s64 i) { unsigned long flags; - raw_spinlock_t *lock = lock_addr(v); + arch_spinlock_t *lock = lock_addr(v);
- raw_spin_lock_irqsave(lock, flags); + local_irq_save(flags); + arch_spin_lock(lock); v->counter = i; - raw_spin_unlock_irqrestore(lock, flags); + arch_spin_unlock(lock); + local_irq_restore(flags); } EXPORT_SYMBOL(generic_atomic64_set);
@@ -70,11 +74,13 @@ EXPORT_SYMBOL(generic_atomic64_set); void generic_atomic64_##op(s64 a, atomic64_t *v) \ { \ unsigned long flags; \ - raw_spinlock_t *lock = lock_addr(v); \ + arch_spinlock_t *lock = lock_addr(v); \ \ - raw_spin_lock_irqsave(lock, flags); \ + local_irq_save(flags); \ + arch_spin_lock(lock); \ v->counter c_op a; \ - raw_spin_unlock_irqrestore(lock, flags); \ + arch_spin_unlock(lock); \ + local_irq_restore(flags); \ } \ EXPORT_SYMBOL(generic_atomic64_##op);
@@ -82,12 +88,14 @@ EXPORT_SYMBOL(generic_atomic64_##op); s64 generic_atomic64_##op##_return(s64 a, atomic64_t *v) \ { \ unsigned long flags; \ - raw_spinlock_t *lock = lock_addr(v); \ + arch_spinlock_t *lock = lock_addr(v); \ s64 val; \ \ - raw_spin_lock_irqsave(lock, flags); \ + local_irq_save(flags); \ + arch_spin_lock(lock); \ val = (v->counter c_op a); \ - raw_spin_unlock_irqrestore(lock, flags); \ + arch_spin_unlock(lock); \ + local_irq_restore(flags); \ return val; \ } \ EXPORT_SYMBOL(generic_atomic64_##op##_return); @@ -96,13 +104,15 @@ EXPORT_SYMBOL(generic_atomic64_##op##_return); s64 generic_atomic64_fetch_##op(s64 a, atomic64_t *v) \ { \ unsigned long flags; \ - raw_spinlock_t *lock = lock_addr(v); \ + arch_spinlock_t *lock = lock_addr(v); \ s64 val; \ \ - raw_spin_lock_irqsave(lock, flags); \ + local_irq_save(flags); \ + arch_spin_lock(lock); \ val = v->counter; \ v->counter c_op a; \ - raw_spin_unlock_irqrestore(lock, flags); \ + arch_spin_unlock(lock); \ + local_irq_restore(flags); \ return val; \ } \ EXPORT_SYMBOL(generic_atomic64_fetch_##op); @@ -131,14 +141,16 @@ ATOMIC64_OPS(xor, ^=) s64 generic_atomic64_dec_if_positive(atomic64_t *v) { unsigned long flags; - raw_spinlock_t *lock = lock_addr(v); + arch_spinlock_t *lock = lock_addr(v); s64 val;
- raw_spin_lock_irqsave(lock, flags); + local_irq_save(flags); + arch_spin_lock(lock); val = v->counter - 1; if (val >= 0) v->counter = val; - raw_spin_unlock_irqrestore(lock, flags); + arch_spin_unlock(lock); + local_irq_restore(flags); return val; } EXPORT_SYMBOL(generic_atomic64_dec_if_positive); @@ -146,14 +158,16 @@ EXPORT_SYMBOL(generic_atomic64_dec_if_positive); s64 generic_atomic64_cmpxchg(atomic64_t *v, s64 o, s64 n) { unsigned long flags; - raw_spinlock_t *lock = lock_addr(v); + arch_spinlock_t *lock = lock_addr(v); s64 val;
- raw_spin_lock_irqsave(lock, flags); + local_irq_save(flags); + arch_spin_lock(lock); val = v->counter; if (val == o) v->counter = n; - raw_spin_unlock_irqrestore(lock, flags); + arch_spin_unlock(lock); + local_irq_restore(flags); return val; } EXPORT_SYMBOL(generic_atomic64_cmpxchg); @@ -161,13 +175,15 @@ EXPORT_SYMBOL(generic_atomic64_cmpxchg); s64 generic_atomic64_xchg(atomic64_t *v, s64 new) { unsigned long flags; - raw_spinlock_t *lock = lock_addr(v); + arch_spinlock_t *lock = lock_addr(v); s64 val;
- raw_spin_lock_irqsave(lock, flags); + local_irq_save(flags); + arch_spin_lock(lock); val = v->counter; v->counter = new; - raw_spin_unlock_irqrestore(lock, flags); + arch_spin_unlock(lock); + local_irq_restore(flags); return val; } EXPORT_SYMBOL(generic_atomic64_xchg); @@ -175,14 +191,16 @@ EXPORT_SYMBOL(generic_atomic64_xchg); s64 generic_atomic64_fetch_add_unless(atomic64_t *v, s64 a, s64 u) { unsigned long flags; - raw_spinlock_t *lock = lock_addr(v); + arch_spinlock_t *lock = lock_addr(v); s64 val;
- raw_spin_lock_irqsave(lock, flags); + local_irq_save(flags); + arch_spin_lock(lock); val = v->counter; if (val != u) v->counter += a; - raw_spin_unlock_irqrestore(lock, flags); + arch_spin_unlock(lock); + local_irq_restore(flags);
return val; } diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 047397136f15..db9bf663661c 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -1863,11 +1863,11 @@ static inline int mab_no_null_split(struct maple_big_node *b_node, * Return: The first split location. The middle split is set in @mid_split. */ static inline int mab_calc_split(struct ma_state *mas, - struct maple_big_node *bn, unsigned char *mid_split, unsigned long min) + struct maple_big_node *bn, unsigned char *mid_split) { unsigned char b_end = bn->b_end; int split = b_end / 2; /* Assume equal split. */ - unsigned char slot_min, slot_count = mt_slots[bn->type]; + unsigned char slot_count = mt_slots[bn->type];
/* * To support gap tracking, all NULL entries are kept together and a node cannot @@ -1900,18 +1900,7 @@ static inline int mab_calc_split(struct ma_state *mas, split = b_end / 3; *mid_split = split * 2; } else { - slot_min = mt_min_slots[bn->type]; - *mid_split = 0; - /* - * Avoid having a range less than the slot count unless it - * causes one node to be deficient. - * NOTE: mt_min_slots is 1 based, b_end and split are zero. - */ - while ((split < slot_count - 1) && - ((bn->pivot[split] - min) < slot_count - 1) && - (b_end - split > slot_min)) - split++; }
/* Avoid ending a node on a NULL entry */ @@ -2377,7 +2366,7 @@ static inline struct maple_enode static inline unsigned char mas_mab_to_node(struct ma_state *mas, struct maple_big_node *b_node, struct maple_enode **left, struct maple_enode **right, struct maple_enode **middle, - unsigned char *mid_split, unsigned long min) + unsigned char *mid_split) { unsigned char split = 0; unsigned char slot_count = mt_slots[b_node->type]; @@ -2390,7 +2379,7 @@ static inline unsigned char mas_mab_to_node(struct ma_state *mas, if (b_node->b_end < slot_count) { split = b_node->b_end; } else { - split = mab_calc_split(mas, b_node, mid_split, min); + split = mab_calc_split(mas, b_node, mid_split); *right = mas_new_ma_node(mas, b_node); }
@@ -2877,7 +2866,7 @@ static void mas_spanning_rebalance(struct ma_state *mas, mast->bn->b_end--; mast->bn->type = mte_node_type(mast->orig_l->node); split = mas_mab_to_node(mas, mast->bn, &left, &right, &middle, - &mid_split, mast->orig_l->min); + &mid_split); mast_set_split_parents(mast, left, middle, right, split, mid_split); mast_cp_to_nodes(mast, left, middle, right, split, mid_split); @@ -3365,7 +3354,7 @@ static void mas_split(struct ma_state *mas, struct maple_big_node *b_node) if (mas_push_data(mas, height, &mast, false)) break;
- split = mab_calc_split(mas, b_node, &mid_split, prev_l_mas.min); + split = mab_calc_split(mas, b_node, &mid_split); mast_split_data(&mast, mas, split); /* * Usually correct, mab_mas_cp in the above call overwrites diff --git a/mm/compaction.c b/mm/compaction.c index a2b16b08cbbf..384e4672998e 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -630,7 +630,8 @@ static unsigned long isolate_freepages_block(struct compact_control *cc, if (PageCompound(page)) { const unsigned int order = compound_order(page);
- if (blockpfn + (1UL << order) <= end_pfn) { + if ((order <= MAX_PAGE_ORDER) && + (blockpfn + (1UL << order) <= end_pfn)) { blockpfn += (1UL << order) - 1; page += (1UL << order) - 1; nr_scanned += (1UL << order) - 1; diff --git a/mm/gup.c b/mm/gup.c index 3b75e631f369..569a4d82012d 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -2323,13 +2323,13 @@ static void pofs_unpin(struct pages_or_folios *pofs) /* * Returns the number of collected folios. Return value is always >= 0. */ -static unsigned long collect_longterm_unpinnable_folios( +static void collect_longterm_unpinnable_folios( struct list_head *movable_folio_list, struct pages_or_folios *pofs) { - unsigned long i, collected = 0; struct folio *prev_folio = NULL; bool drain_allow = true; + unsigned long i;
for (i = 0; i < pofs->nr_entries; i++) { struct folio *folio = pofs_get_folio(pofs, i); @@ -2341,8 +2341,6 @@ static unsigned long collect_longterm_unpinnable_folios( if (folio_is_longterm_pinnable(folio)) continue;
- collected++; - if (folio_is_device_coherent(folio)) continue;
@@ -2364,8 +2362,6 @@ static unsigned long collect_longterm_unpinnable_folios( NR_ISOLATED_ANON + folio_is_file_lru(folio), folio_nr_pages(folio)); } - - return collected; }
/* @@ -2442,11 +2438,9 @@ static long check_and_migrate_movable_pages_or_folios(struct pages_or_folios *pofs) { LIST_HEAD(movable_folio_list); - unsigned long collected;
- collected = collect_longterm_unpinnable_folios(&movable_folio_list, - pofs); - if (!collected) + collect_longterm_unpinnable_folios(&movable_folio_list, pofs); + if (list_empty(&movable_folio_list)) return 0;
return migrate_longterm_unpinnable_folios(&movable_folio_list, pofs); diff --git a/mm/hugetlb.c b/mm/hugetlb.c index eaaec19caa7c..b2294dc1dd6e 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1394,8 +1394,7 @@ static unsigned long available_huge_pages(struct hstate *h)
static struct folio *dequeue_hugetlb_folio_vma(struct hstate *h, struct vm_area_struct *vma, - unsigned long address, int avoid_reserve, - long chg) + unsigned long address, long chg) { struct folio *folio = NULL; struct mempolicy *mpol; @@ -1411,10 +1410,6 @@ static struct folio *dequeue_hugetlb_folio_vma(struct hstate *h, if (!vma_has_reserves(vma, chg) && !available_huge_pages(h)) goto err;
- /* If reserves cannot be used, ensure enough pages are in the pool */ - if (avoid_reserve && !available_huge_pages(h)) - goto err; - gfp_mask = htlb_alloc_mask(h); nid = huge_node(vma, address, gfp_mask, &mpol, &nodemask);
@@ -1430,7 +1425,7 @@ static struct folio *dequeue_hugetlb_folio_vma(struct hstate *h, folio = dequeue_hugetlb_folio_nodemask(h, gfp_mask, nid, nodemask);
- if (folio && !avoid_reserve && vma_has_reserves(vma, chg)) { + if (folio && vma_has_reserves(vma, chg)) { folio_set_hugetlb_restore_reserve(folio); h->resv_huge_pages--; } @@ -3007,17 +3002,6 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma, gbl_chg = hugepage_subpool_get_pages(spool, 1); if (gbl_chg < 0) goto out_end_reservation; - - /* - * Even though there was no reservation in the region/reserve - * map, there could be reservations associated with the - * subpool that can be used. This would be indicated if the - * return value of hugepage_subpool_get_pages() is zero. - * However, if avoid_reserve is specified we still avoid even - * the subpool reservations. - */ - if (avoid_reserve) - gbl_chg = 1; }
/* If this allocation is not consuming a reservation, charge it now. @@ -3040,7 +3024,7 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma, * from the global free pool (global change). gbl_chg == 0 indicates * a reservation exists for the allocation. */ - folio = dequeue_hugetlb_folio_vma(h, vma, addr, avoid_reserve, gbl_chg); + folio = dequeue_hugetlb_folio_vma(h, vma, addr, gbl_chg); if (!folio) { spin_unlock_irq(&hugetlb_lock); folio = alloc_buddy_hugetlb_folio_with_mpol(h, vma, addr); @@ -3289,7 +3273,7 @@ static void __init gather_bootmem_prealloc(void) .thread_fn = gather_bootmem_prealloc_parallel, .fn_arg = NULL, .start = 0, - .size = num_node_state(N_MEMORY), + .size = nr_node_ids, .align = 1, .min_chunk = 1, .max_threads = num_node_state(N_MEMORY), diff --git a/mm/kfence/core.c b/mm/kfence/core.c index 67fc321db79b..102048821c22 100644 --- a/mm/kfence/core.c +++ b/mm/kfence/core.c @@ -21,6 +21,7 @@ #include <linux/log2.h> #include <linux/memblock.h> #include <linux/moduleparam.h> +#include <linux/nodemask.h> #include <linux/notifier.h> #include <linux/panic_notifier.h> #include <linux/random.h> @@ -1084,6 +1085,7 @@ void *__kfence_alloc(struct kmem_cache *s, size_t size, gfp_t flags) * properties (e.g. reside in DMAable memory). */ if ((flags & GFP_ZONEMASK) || + ((flags & __GFP_THISNODE) && num_online_nodes() > 1) || (s->flags & (SLAB_CACHE_DMA | SLAB_CACHE_DMA32))) { atomic_long_inc(&counters[KFENCE_COUNTER_SKIP_INCOMPAT]); return NULL; diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 820ba3b5cbfc..bb7d61fc4da3 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -1689,7 +1689,7 @@ static void kmemleak_scan(void) unsigned long phys = object->pointer;
if (PHYS_PFN(phys) < min_low_pfn || - PHYS_PFN(phys + object->size) >= max_low_pfn) + PHYS_PFN(phys + object->size) > max_low_pfn) __paint_it(object, KMEMLEAK_BLACK); }
diff --git a/mm/vmscan.c b/mm/vmscan.c index b1ec5ece067e..c22175120f5d 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1053,7 +1053,7 @@ static unsigned int shrink_folio_list(struct list_head *folio_list, struct folio_batch free_folios; LIST_HEAD(ret_folios); LIST_HEAD(demote_folios); - unsigned int nr_reclaimed = 0; + unsigned int nr_reclaimed = 0, nr_demoted = 0; unsigned int pgactivate = 0; bool do_demote_pass; struct swap_iocb *plug = NULL; @@ -1522,8 +1522,9 @@ static unsigned int shrink_folio_list(struct list_head *folio_list, /* 'folio_list' is always empty here */
/* Migrate folios selected for demotion */ - stat->nr_demoted = demote_folio_list(&demote_folios, pgdat); - nr_reclaimed += stat->nr_demoted; + nr_demoted = demote_folio_list(&demote_folios, pgdat); + nr_reclaimed += nr_demoted; + stat->nr_demoted += nr_demoted; /* Folios that could not be demoted are still in @demote_folios */ if (!list_empty(&demote_folios)) { /* Folios which weren't demoted go back on @folio_list */ diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 3d2553dcdb1b..46ea0bee2259 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -710,12 +710,12 @@ static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu) { switch (chan->scid) { case L2CAP_CID_ATT: - if (mtu < L2CAP_LE_MIN_MTU) + if (mtu && mtu < L2CAP_LE_MIN_MTU) return false; break;
default: - if (mtu < L2CAP_DEFAULT_MIN_MTU) + if (mtu && mtu < L2CAP_DEFAULT_MIN_MTU) return false; }
@@ -1888,7 +1888,8 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, chan = l2cap_chan_create(); if (!chan) { sk_free(sk); - sock->sk = NULL; + if (sock) + sock->sk = NULL; return NULL; }
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index de47ad999d7b..71dda10f6a24 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -5519,10 +5519,16 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, { struct mgmt_rp_remove_adv_monitor rp; struct mgmt_pending_cmd *cmd = data; - struct mgmt_cp_remove_adv_monitor *cp = cmd->param; + struct mgmt_cp_remove_adv_monitor *cp; + + if (status == -ECANCELED || + cmd != pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev)) + return;
hci_dev_lock(hdev);
+ cp = cmd->param; + rp.monitor_handle = cp->monitor_handle;
if (!status) @@ -5540,6 +5546,10 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, static int mgmt_remove_adv_monitor_sync(struct hci_dev *hdev, void *data) { struct mgmt_pending_cmd *cmd = data; + + if (cmd != pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev)) + return -ECANCELED; + struct mgmt_cp_remove_adv_monitor *cp = cmd->param; u16 handle = __le16_to_cpu(cp->monitor_handle);
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c index 34bee42e1247..7609ce2b2c5e 100644 --- a/net/ethtool/ioctl.c +++ b/net/ethtool/ioctl.c @@ -993,7 +993,7 @@ static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev, return rc;
/* Nonzero ring with RSS only makes sense if NIC adds them together */ - if (cmd == ETHTOOL_SRXCLSRLINS && info.flow_type & FLOW_RSS && + if (cmd == ETHTOOL_SRXCLSRLINS && info.fs.flow_type & FLOW_RSS && !ops->cap_rss_rxnfc_adds && ethtool_get_flow_spec_ring(info.fs.ring_cookie)) return -EINVAL; diff --git a/net/ethtool/rss.c b/net/ethtool/rss.c index 7cb106b590ab..58df9ad02ce8 100644 --- a/net/ethtool/rss.c +++ b/net/ethtool/rss.c @@ -107,6 +107,8 @@ rss_prepare_ctx(const struct rss_req_info *request, struct net_device *dev, u32 total_size, indir_bytes; u8 *rss_config;
+ data->no_key_fields = !dev->ethtool_ops->rxfh_per_ctx_key; + ctx = xa_load(&dev->ethtool->rss_ctx, request->rss_context); if (!ctx) return -ENOENT; @@ -153,7 +155,6 @@ rss_prepare_data(const struct ethnl_req_info *req_base, if (!ops->cap_rss_ctx_supported && !ops->create_rxfh_context) return -EOPNOTSUPP;
- data->no_key_fields = !ops->rxfh_per_ctx_key; return rss_prepare_ctx(request, dev, data, info); }
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index c472c9a57cf6..a9bb9ce5438e 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1141,9 +1141,9 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4, const int hlen = skb_network_header_len(skb) + sizeof(struct udphdr);
- if (hlen + cork->gso_size > cork->fragsize) { + if (hlen + min(datalen, cork->gso_size) > cork->fragsize) { kfree_skb(skb); - return -EINVAL; + return -EMSGSIZE; } if (datalen > cork->gso_size * UDP_MAX_SEGMENTS) { kfree_skb(skb); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index b974116152dd..3a3c7639d1d6 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1389,9 +1389,9 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6, const int hlen = skb_network_header_len(skb) + sizeof(struct udphdr);
- if (hlen + cork->gso_size > cork->fragsize) { + if (hlen + min(datalen, cork->gso_size) > cork->fragsize) { kfree_skb(skb); - return -EINVAL; + return -EMSGSIZE; } if (datalen > cork->gso_size * UDP_MAX_SEGMENTS) { kfree_skb(skb); diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c index bf276eaf9330..7891a537bddd 100644 --- a/net/ncsi/ncsi-manage.c +++ b/net/ncsi/ncsi-manage.c @@ -1385,6 +1385,12 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) nd->state = ncsi_dev_state_probe_package; break; case ncsi_dev_state_probe_package: + if (ndp->package_probe_id >= 8) { + /* Last package probed, finishing */ + ndp->flags |= NCSI_DEV_PROBED; + break; + } + ndp->pending_req_num = 1;
nca.type = NCSI_PKT_CMD_SP; @@ -1501,13 +1507,8 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) if (ret) goto error;
- /* Probe next package */ + /* Probe next package after receiving response */ ndp->package_probe_id++; - if (ndp->package_probe_id >= 8) { - /* Probe finished */ - ndp->flags |= NCSI_DEV_PROBED; - break; - } nd->state = ncsi_dev_state_probe_package; ndp->active_package = NULL; break; diff --git a/net/nfc/nci/hci.c b/net/nfc/nci/hci.c index de175318a3a0..082ab66f120b 100644 --- a/net/nfc/nci/hci.c +++ b/net/nfc/nci/hci.c @@ -542,6 +542,8 @@ static u8 nci_hci_create_pipe(struct nci_dev *ndev, u8 dest_host,
pr_debug("pipe created=%d\n", pipe);
+ if (pipe >= NCI_HCI_MAX_PIPES) + pipe = NCI_HCI_INVALID_PIPE; return pipe; }
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 72c65d938a15..a4a668b88a8f 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -701,11 +701,9 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) struct net_device *dev; ax25_address *source; ax25_uid_assoc *user; + int err = -EINVAL; int n;
- if (!sock_flag(sk, SOCK_ZAPPED)) - return -EINVAL; - if (addr_len != sizeof(struct sockaddr_rose) && addr_len != sizeof(struct full_sockaddr_rose)) return -EINVAL;
@@ -718,8 +716,15 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS) return -EINVAL;
- if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) - return -EADDRNOTAVAIL; + lock_sock(sk); + + if (!sock_flag(sk, SOCK_ZAPPED)) + goto out_release; + + err = -EADDRNOTAVAIL; + dev = rose_dev_get(&addr->srose_addr); + if (!dev) + goto out_release;
source = &addr->srose_call;
@@ -730,7 +735,8 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) } else { if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) { dev_put(dev); - return -EACCES; + err = -EACCES; + goto out_release; } rose->source_call = *source; } @@ -753,8 +759,10 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) rose_insert_socket(sk);
sock_reset_flag(sk, SOCK_ZAPPED); - - return 0; + err = 0; +out_release: + release_sock(sk); + return err; }
static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags) diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index d0fd37bdcfe9..6b036c0564c7 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h @@ -567,6 +567,7 @@ enum rxrpc_call_flag { RXRPC_CALL_EXCLUSIVE, /* The call uses a once-only connection */ RXRPC_CALL_RX_IS_IDLE, /* recvmsg() is idle - send an ACK */ RXRPC_CALL_RECVMSG_READ_ALL, /* recvmsg() read all of the received data */ + RXRPC_CALL_CONN_CHALLENGING, /* The connection is being challenged */ };
/* @@ -587,7 +588,6 @@ enum rxrpc_call_state { RXRPC_CALL_CLIENT_AWAIT_REPLY, /* - client awaiting reply */ RXRPC_CALL_CLIENT_RECV_REPLY, /* - client receiving reply phase */ RXRPC_CALL_SERVER_PREALLOC, /* - service preallocation */ - RXRPC_CALL_SERVER_SECURING, /* - server securing request connection */ RXRPC_CALL_SERVER_RECV_REQUEST, /* - server receiving request */ RXRPC_CALL_SERVER_ACK_REQUEST, /* - server pending ACK of request */ RXRPC_CALL_SERVER_SEND_REPLY, /* - server sending reply */ diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c index f9e983a12c14..e379a2a9375a 100644 --- a/net/rxrpc/call_object.c +++ b/net/rxrpc/call_object.c @@ -22,7 +22,6 @@ const char *const rxrpc_call_states[NR__RXRPC_CALL_STATES] = { [RXRPC_CALL_CLIENT_AWAIT_REPLY] = "ClAwtRpl", [RXRPC_CALL_CLIENT_RECV_REPLY] = "ClRcvRpl", [RXRPC_CALL_SERVER_PREALLOC] = "SvPrealc", - [RXRPC_CALL_SERVER_SECURING] = "SvSecure", [RXRPC_CALL_SERVER_RECV_REQUEST] = "SvRcvReq", [RXRPC_CALL_SERVER_ACK_REQUEST] = "SvAckReq", [RXRPC_CALL_SERVER_SEND_REPLY] = "SvSndRpl", @@ -453,17 +452,16 @@ void rxrpc_incoming_call(struct rxrpc_sock *rx, call->cong_tstamp = skb->tstamp;
__set_bit(RXRPC_CALL_EXPOSED, &call->flags); - rxrpc_set_call_state(call, RXRPC_CALL_SERVER_SECURING); + rxrpc_set_call_state(call, RXRPC_CALL_SERVER_RECV_REQUEST);
spin_lock(&conn->state_lock);
switch (conn->state) { case RXRPC_CONN_SERVICE_UNSECURED: case RXRPC_CONN_SERVICE_CHALLENGING: - rxrpc_set_call_state(call, RXRPC_CALL_SERVER_SECURING); + __set_bit(RXRPC_CALL_CONN_CHALLENGING, &call->flags); break; case RXRPC_CONN_SERVICE: - rxrpc_set_call_state(call, RXRPC_CALL_SERVER_RECV_REQUEST); break;
case RXRPC_CONN_ABORTED: diff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c index 2a1396cd892f..c4eb7986efdd 100644 --- a/net/rxrpc/conn_event.c +++ b/net/rxrpc/conn_event.c @@ -222,10 +222,8 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn) */ static void rxrpc_call_is_secure(struct rxrpc_call *call) { - if (call && __rxrpc_call_state(call) == RXRPC_CALL_SERVER_SECURING) { - rxrpc_set_call_state(call, RXRPC_CALL_SERVER_RECV_REQUEST); + if (call && __test_and_clear_bit(RXRPC_CALL_CONN_CHALLENGING, &call->flags)) rxrpc_notify_socket(call); - } }
/* @@ -266,6 +264,7 @@ static int rxrpc_process_event(struct rxrpc_connection *conn, * we've already received the packet, put it on the * front of the queue. */ + sp->conn = rxrpc_get_connection(conn, rxrpc_conn_get_poke_secured); skb->mark = RXRPC_SKB_MARK_SERVICE_CONN_SECURED; rxrpc_get_skb(skb, rxrpc_skb_get_conn_secured); skb_queue_head(&conn->local->rx_queue, skb); @@ -431,14 +430,16 @@ void rxrpc_input_conn_event(struct rxrpc_connection *conn, struct sk_buff *skb) if (test_and_clear_bit(RXRPC_CONN_EV_ABORT_CALLS, &conn->events)) rxrpc_abort_calls(conn);
- switch (skb->mark) { - case RXRPC_SKB_MARK_SERVICE_CONN_SECURED: - if (conn->state != RXRPC_CONN_SERVICE) - break; + if (skb) { + switch (skb->mark) { + case RXRPC_SKB_MARK_SERVICE_CONN_SECURED: + if (conn->state != RXRPC_CONN_SERVICE) + break;
- for (loop = 0; loop < RXRPC_MAXCALLS; loop++) - rxrpc_call_is_secure(conn->channels[loop].call); - break; + for (loop = 0; loop < RXRPC_MAXCALLS; loop++) + rxrpc_call_is_secure(conn->channels[loop].call); + break; + } }
/* Process delayed ACKs whose time has come. */ diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c index 694c4df7a1a3..88b4aab5a091 100644 --- a/net/rxrpc/conn_object.c +++ b/net/rxrpc/conn_object.c @@ -67,6 +67,7 @@ struct rxrpc_connection *rxrpc_alloc_connection(struct rxrpc_net *rxnet, INIT_WORK(&conn->destructor, rxrpc_clean_up_connection); INIT_LIST_HEAD(&conn->proc_link); INIT_LIST_HEAD(&conn->link); + INIT_LIST_HEAD(&conn->attend_link); mutex_init(&conn->security_lock); mutex_init(&conn->tx_data_alloc_lock); skb_queue_head_init(&conn->rx_queue); diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c index 16d49a861dbb..6a075a7c190d 100644 --- a/net/rxrpc/input.c +++ b/net/rxrpc/input.c @@ -573,7 +573,7 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb rxrpc_propose_delay_ACK(call, sp->hdr.serial, rxrpc_propose_ack_input_data); } - if (notify) { + if (notify && !test_bit(RXRPC_CALL_CONN_CHALLENGING, &call->flags)) { trace_rxrpc_notify_socket(call->debug_id, sp->hdr.serial); rxrpc_notify_socket(call); } diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c index 6abb8eec1b2b..708a1484dada 100644 --- a/net/rxrpc/sendmsg.c +++ b/net/rxrpc/sendmsg.c @@ -655,7 +655,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) } else { switch (rxrpc_call_state(call)) { case RXRPC_CALL_CLIENT_AWAIT_CONN: - case RXRPC_CALL_SERVER_SECURING: + case RXRPC_CALL_SERVER_RECV_REQUEST: if (p.command == RXRPC_CMD_SEND_ABORT) break; fallthrough; diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c index b50b2c2cc09b..e6bfd39ff339 100644 --- a/net/sched/sch_fifo.c +++ b/net/sched/sch_fifo.c @@ -40,6 +40,9 @@ static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc *sch, { unsigned int prev_backlog;
+ if (unlikely(READ_ONCE(sch->limit) == 0)) + return qdisc_drop(skb, sch, to_free); + if (likely(sch->q.qlen < READ_ONCE(sch->limit))) return qdisc_enqueue_tail(skb, sch);
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 71ec9986ed37..fdd79d3ccd8c 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -749,9 +749,9 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch) if (err != NET_XMIT_SUCCESS) { if (net_xmit_drop_count(err)) qdisc_qstats_drop(sch); - qdisc_tree_reduce_backlog(sch, 1, pkt_len); sch->qstats.backlog -= pkt_len; sch->q.qlen--; + qdisc_tree_reduce_backlog(sch, 1, pkt_len); } goto tfifo_dequeue; } diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c index 43c3f1c971b8..c524421ec652 100644 --- a/net/tipc/crypto.c +++ b/net/tipc/crypto.c @@ -2293,8 +2293,8 @@ static bool tipc_crypto_key_rcv(struct tipc_crypto *rx, struct tipc_msg *hdr) keylen = ntohl(*((__be32 *)(data + TIPC_AEAD_ALG_NAME)));
/* Verify the supplied size values */ - if (unlikely(size != keylen + sizeof(struct tipc_aead_key) || - keylen > TIPC_AEAD_KEY_SIZE_MAX)) { + if (unlikely(keylen > TIPC_AEAD_KEY_SIZE_MAX || + size != keylen + sizeof(struct tipc_aead_key))) { pr_debug("%s: invalid MSG_CRYPTO key size\n", rx->name); goto exit; } diff --git a/rust/kernel/init.rs b/rust/kernel/init.rs index 347049df556b..c962029f96e1 100644 --- a/rust/kernel/init.rs +++ b/rust/kernel/init.rs @@ -854,7 +854,7 @@ pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized { /// use kernel::{types::Opaque, init::pin_init_from_closure}; /// #[repr(C)] /// struct RawFoo([u8; 16]); - /// extern { + /// extern "C" { /// fn init_foo(_: *mut RawFoo); /// } /// diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index 1d13cecc7cc7..04faf15ed316 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -130,7 +130,6 @@ KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast) KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare KBUILD_CFLAGS += $(call cc-disable-warning, unaligned-access) KBUILD_CFLAGS += -Wno-enum-compare-conditional -KBUILD_CFLAGS += -Wno-enum-enum-conversion endif
endif @@ -154,6 +153,10 @@ KBUILD_CFLAGS += -Wno-missing-field-initializers KBUILD_CFLAGS += -Wno-type-limits KBUILD_CFLAGS += -Wno-shift-negative-value
+ifdef CONFIG_CC_IS_CLANG +KBUILD_CFLAGS += -Wno-enum-enum-conversion +endif + ifdef CONFIG_CC_IS_GCC KBUILD_CFLAGS += -Wno-maybe-uninitialized endif diff --git a/scripts/gdb/linux/cpus.py b/scripts/gdb/linux/cpus.py index 2f11c4f9c345..13eb8b3901b8 100644 --- a/scripts/gdb/linux/cpus.py +++ b/scripts/gdb/linux/cpus.py @@ -167,7 +167,7 @@ def get_current_task(cpu): var_ptr = gdb.parse_and_eval("&pcpu_hot.current_task") return per_cpu(var_ptr, cpu).dereference() elif utils.is_target_arch("aarch64"): - current_task_addr = gdb.parse_and_eval("$SP_EL0") + current_task_addr = gdb.parse_and_eval("(unsigned long)$SP_EL0") if (current_task_addr >> 63) != 0: current_task = current_task_addr.cast(task_ptr_type) return current_task.dereference() diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs index 0d00ac3723b5..4fd6b6ab3e32 100644 --- a/scripts/generate_rust_target.rs +++ b/scripts/generate_rust_target.rs @@ -165,6 +165,18 @@ fn has(&self, option: &str) -> bool { let option = "CONFIG_".to_owned() + option; self.0.contains_key(&option) } + + /// Is the rustc version at least `major.minor.patch`? + fn rustc_version_atleast(&self, major: u32, minor: u32, patch: u32) -> bool { + let check_version = 100000 * major + 100 * minor + patch; + let actual_version = self + .0 + .get("CONFIG_RUSTC_VERSION") + .unwrap() + .parse::<u32>() + .unwrap(); + check_version <= actual_version + } }
fn main() { @@ -182,6 +194,9 @@ fn main() { } } else if cfg.has("X86_64") { ts.push("arch", "x86_64"); + if cfg.rustc_version_atleast(1, 86, 0) { + ts.push("rustc-abi", "x86-softfloat"); + } ts.push( "data-layout", "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", @@ -215,6 +230,9 @@ fn main() { panic!("32-bit x86 only works under UML"); } ts.push("arch", "x86"); + if cfg.rustc_version_atleast(1, 86, 0) { + ts.push("rustc-abi", "x86-softfloat"); + } ts.push( "data-layout", "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128", diff --git a/security/keys/trusted-keys/trusted_dcp.c b/security/keys/trusted-keys/trusted_dcp.c index e908c53a803c..7b6eb655df0c 100644 --- a/security/keys/trusted-keys/trusted_dcp.c +++ b/security/keys/trusted-keys/trusted_dcp.c @@ -201,12 +201,16 @@ static int trusted_dcp_seal(struct trusted_key_payload *p, char *datablob) { struct dcp_blob_fmt *b = (struct dcp_blob_fmt *)p->blob; int blen, ret; - u8 plain_blob_key[AES_KEYSIZE_128]; + u8 *plain_blob_key;
blen = calc_blob_len(p->key_len); if (blen > MAX_BLOB_SIZE) return -E2BIG;
+ plain_blob_key = kmalloc(AES_KEYSIZE_128, GFP_KERNEL); + if (!plain_blob_key) + return -ENOMEM; + b->fmt_version = DCP_BLOB_VERSION; get_random_bytes(b->nonce, AES_KEYSIZE_128); get_random_bytes(plain_blob_key, AES_KEYSIZE_128); @@ -229,7 +233,8 @@ static int trusted_dcp_seal(struct trusted_key_payload *p, char *datablob) ret = 0;
out: - memzero_explicit(plain_blob_key, sizeof(plain_blob_key)); + memzero_explicit(plain_blob_key, AES_KEYSIZE_128); + kfree(plain_blob_key);
return ret; } @@ -238,7 +243,7 @@ static int trusted_dcp_unseal(struct trusted_key_payload *p, char *datablob) { struct dcp_blob_fmt *b = (struct dcp_blob_fmt *)p->blob; int blen, ret; - u8 plain_blob_key[AES_KEYSIZE_128]; + u8 *plain_blob_key = NULL;
if (b->fmt_version != DCP_BLOB_VERSION) { pr_err("DCP blob has bad version: %i, expected %i\n", @@ -256,6 +261,12 @@ static int trusted_dcp_unseal(struct trusted_key_payload *p, char *datablob) goto out; }
+ plain_blob_key = kmalloc(AES_KEYSIZE_128, GFP_KERNEL); + if (!plain_blob_key) { + ret = -ENOMEM; + goto out; + } + ret = decrypt_blob_key(b->blob_key, plain_blob_key); if (ret) { pr_err("Unable to decrypt blob key: %i\n", ret); @@ -271,7 +282,10 @@ static int trusted_dcp_unseal(struct trusted_key_payload *p, char *datablob)
ret = 0; out: - memzero_explicit(plain_blob_key, sizeof(plain_blob_key)); + if (plain_blob_key) { + memzero_explicit(plain_blob_key, AES_KEYSIZE_128); + kfree(plain_blob_key); + }
return ret; } diff --git a/security/safesetid/securityfs.c b/security/safesetid/securityfs.c index 25310468bcdd..8e1ffd70b18a 100644 --- a/security/safesetid/securityfs.c +++ b/security/safesetid/securityfs.c @@ -143,6 +143,9 @@ static ssize_t handle_policy_update(struct file *file, char *buf, *p, *end; int err;
+ if (len >= KMALLOC_MAX_SIZE) + return -EINVAL; + pol = kmalloc(sizeof(struct setid_ruleset), GFP_KERNEL); if (!pol) return -ENOMEM; diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 5c7b059a332a..972664962e8f 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c @@ -2665,7 +2665,7 @@ ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head,
if (head->w.avail >= head->writebuf_size - 1) { const int len = head->writebuf_size * 2; - char *cp = kzalloc(len, GFP_NOFS); + char *cp = kzalloc(len, GFP_NOFS | __GFP_NOWARN);
if (!cp) { error = -ENOMEM; diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c index 84393f4f429d..8923813ce424 100644 --- a/sound/pci/hda/hda_auto_parser.c +++ b/sound/pci/hda/hda_auto_parser.c @@ -80,7 +80,11 @@ static int compare_input_type(const void *ap, const void *bp)
/* In case one has boost and the other one has not, pick the one with boost first. */ - return (int)(b->has_boost_on_pin - a->has_boost_on_pin); + if (a->has_boost_on_pin != b->has_boost_on_pin) + return (int)(b->has_boost_on_pin - a->has_boost_on_pin); + + /* Keep the original order */ + return a->order - b->order; }
/* Reorder the surround channels @@ -400,6 +404,8 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, reorder_outputs(cfg->speaker_outs, cfg->speaker_pins);
/* sort inputs in the order of AUTO_PIN_* type */ + for (i = 0; i < cfg->num_inputs; i++) + cfg->inputs[i].order = i; sort(cfg->inputs, cfg->num_inputs, sizeof(cfg->inputs[0]), compare_input_type, NULL);
diff --git a/sound/pci/hda/hda_auto_parser.h b/sound/pci/hda/hda_auto_parser.h index 579b11beac71..87af3d8c02f7 100644 --- a/sound/pci/hda/hda_auto_parser.h +++ b/sound/pci/hda/hda_auto_parser.h @@ -37,6 +37,7 @@ struct auto_pin_cfg_item { unsigned int is_headset_mic:1; unsigned int is_headphone_mic:1; /* Mic-only in headphone jack */ unsigned int has_boost_on_pin:1; + int order; };
struct auto_pin_cfg; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 2d523b53b3d7..6c352602987b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -7485,6 +7485,16 @@ static void alc287_fixup_lenovo_thinkpad_with_alc1318(struct hda_codec *codec, spec->gen.pcm_playback_hook = alc287_alc1318_playback_pcm_hook; }
+/* + * Clear COEF 0x0d (PCBEEP passthrough) bit 0x40 where BIOS sets it wrongly + * at PM resume + */ +static void alc283_fixup_dell_hp_resume(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + if (action == HDA_FIXUP_ACT_INIT) + alc_write_coef_idx(codec, 0xd, 0x2800); +}
enum { ALC269_FIXUP_GPIO2, @@ -7785,6 +7795,7 @@ enum { ALC269_FIXUP_VAIO_VJFH52_MIC_NO_PRESENCE, ALC233_FIXUP_MEDION_MTL_SPK, ALC294_FIXUP_BASS_SPEAKER_15, + ALC283_FIXUP_DELL_HP_RESUME, };
/* A special fixup for Lenovo C940 and Yoga Duet 7; @@ -10117,6 +10128,10 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc294_fixup_bass_speaker_15, }, + [ALC283_FIXUP_DELL_HP_RESUME] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc283_fixup_dell_hp_resume, + }, };
static const struct hda_quirk alc269_fixup_tbl[] = { @@ -10177,6 +10192,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0604, "Dell Venue 11 Pro 7130", ALC283_FIXUP_DELL_HP_RESUME), SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X), @@ -10389,6 +10405,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8870, "HP ZBook Fury 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8873, "HP ZBook Studio 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x887a, "HP Laptop 15s-eq2xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x887c, "HP Laptop 14s-fq1xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), SND_PCI_QUIRK(0x103c, 0x888a, "HP ENVY x360 Convertible 15-eu0xxx", ALC245_FIXUP_HP_X360_MUTE_LEDS), SND_PCI_QUIRK(0x103c, 0x888d, "HP ZBook Power 15.6 inch G8 Mobile Workstation PC", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8895, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED), @@ -10889,7 +10906,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), HDA_CODEC_QUIRK(0x17aa, 0x386e, "Legion Y9000X 2022 IAH7", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x17aa, 0x386e, "Yoga Pro 7 14ARP8", ALC285_FIXUP_SPEAKER2_TO_DAC1), - HDA_CODEC_QUIRK(0x17aa, 0x386f, "Legion Pro 7 16ARX8H", ALC287_FIXUP_TAS2781_I2C), + HDA_CODEC_QUIRK(0x17aa, 0x38a8, "Legion Pro 7 16ARX8H", ALC287_FIXUP_TAS2781_I2C), /* this must match before PCI SSID 17aa:386f below */ SND_PCI_QUIRK(0x17aa, 0x386f, "Legion Pro 7i 16IAX7", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x17aa, 0x3870, "Lenovo Yoga 7 14ARB7", ALC287_FIXUP_YOGA7_14ARB7_I2C), SND_PCI_QUIRK(0x17aa, 0x3877, "Lenovo Legion 7 Slim 16ARHA7", ALC287_FIXUP_CS35L41_I2C_2), @@ -10964,6 +10981,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), SND_PCI_QUIRK(0x17aa, 0x9e56, "Lenovo ZhaoYang CF4620Z", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1849, 0x0269, "Positivo Master C6400", ALC269VB_FIXUP_ASUS_ZENBOOK), SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK), SND_PCI_QUIRK(0x1849, 0xa233, "Positivo Master C6300", ALC269_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x1854, 0x0440, "LG CQ6", ALC256_FIXUP_HEADPHONE_AMP_VOL), diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig index c7590d4989bb..803521178279 100644 --- a/sound/soc/amd/Kconfig +++ b/sound/soc/amd/Kconfig @@ -105,7 +105,7 @@ config SND_SOC_AMD_ACP6x config SND_SOC_AMD_YC_MACH tristate "AMD YC support for DMIC" select SND_SOC_DMIC - depends on SND_SOC_AMD_ACP6x + depends on SND_SOC_AMD_ACP6x && ACPI help This option enables machine driver for Yellow Carp platform using dmic. ACP IP has PDM Decoder block with DMA controller. diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index ecf57a6cb7c3..b16587d8f97a 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -304,6 +304,34 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "83AS"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83L3"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83N6"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83Q2"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83Q3"), + } + }, { .driver_data = &acp6x_card, .matches = { diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 5554ad4e7c78..65e55c46fb06 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -641,9 +641,10 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { .callback = sof_sdw_quirk_cb, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "380E") + DMI_MATCH(DMI_PRODUCT_NAME, "83HM") }, - .driver_data = (void *)(SOC_SDW_SIDECAR_AMPS), + .driver_data = (void *)(SOC_SDW_SIDECAR_AMPS | + SOC_SDW_CODEC_MIC), }, { .callback = sof_sdw_quirk_cb, diff --git a/sound/soc/renesas/rz-ssi.c b/sound/soc/renesas/rz-ssi.c index 6b442b101415..b7874dd42b2a 100644 --- a/sound/soc/renesas/rz-ssi.c +++ b/sound/soc/renesas/rz-ssi.c @@ -414,8 +414,12 @@ static int rz_ssi_stop(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) rz_ssi_reg_mask_setl(ssi, SSICR, SSICR_TEN | SSICR_REN, 0);
/* Cancel all remaining DMA transactions */ - if (rz_ssi_is_dma_enabled(ssi)) - dmaengine_terminate_async(strm->dma_ch); + if (rz_ssi_is_dma_enabled(ssi)) { + if (ssi->playback.dma_ch) + dmaengine_terminate_async(ssi->playback.dma_ch); + if (ssi->capture.dma_ch) + dmaengine_terminate_async(ssi->capture.dma_ch); + }
rz_ssi_set_idle(ssi);
@@ -522,6 +526,8 @@ static int rz_ssi_pio_send(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) sample_space = strm->fifo_sample_size; ssifsr = rz_ssi_reg_readl(ssi, SSIFSR); sample_space -= (ssifsr >> SSIFSR_TDC_SHIFT) & SSIFSR_TDC_MASK; + if (sample_space < 0) + return -EINVAL;
/* Only add full frames at a time */ while (frames_left && (sample_space >= runtime->channels)) { diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 1150455619aa..88b3ad5a2552 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -38,7 +38,6 @@ static inline int _soc_pcm_ret(struct snd_soc_pcm_runtime *rtd, switch (ret) { case -EPROBE_DEFER: case -ENOTSUPP: - case -EINVAL: break; default: dev_err(rtd->dev, @@ -986,7 +985,13 @@ static int __soc_pcm_prepare(struct snd_soc_pcm_runtime *rtd, }
out: - return soc_pcm_ret(rtd, ret); + /* + * Don't use soc_pcm_ret() on .prepare callback to lower error log severity + * + * We don't want to log an error since we do not want to give userspace a way to do a + * denial-of-service attack on the syslog / diskspace. + */ + return ret; }
/* PCM prepare ops for non-DPCM streams */ @@ -998,6 +1003,13 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) snd_soc_dpcm_mutex_lock(rtd); ret = __soc_pcm_prepare(rtd, substream); snd_soc_dpcm_mutex_unlock(rtd); + + /* + * Don't use soc_pcm_ret() on .prepare callback to lower error log severity + * + * We don't want to log an error since we do not want to give userspace a way to do a + * denial-of-service attack on the syslog / diskspace. + */ return ret; }
@@ -2539,7 +2551,13 @@ int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream) be->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE; }
- return soc_pcm_ret(fe, ret); + /* + * Don't use soc_pcm_ret() on .prepare callback to lower error log severity + * + * We don't want to log an error since we do not want to give userspace a way to do a + * denial-of-service attack on the syslog / diskspace. + */ + return ret; }
static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) @@ -2579,7 +2597,13 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); snd_soc_dpcm_mutex_unlock(fe);
- return soc_pcm_ret(fe, ret); + /* + * Don't use soc_pcm_ret() on .prepare callback to lower error log severity + * + * We don't want to log an error since we do not want to give userspace a way to do a + * denial-of-service attack on the syslog / diskspace. + */ + return ret; }
static int dpcm_run_update_shutdown(struct snd_soc_pcm_runtime *fe, int stream) diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 0db2a3e554fb..da12aabc1bb8 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -503,6 +503,12 @@ int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream, int ret; int i;
+ if (!w) { + dev_err(cpu_dai->dev, "%s widget not found, check amp link num in the topology\n", + cpu_dai->name); + return -EINVAL; + } + ops = hda_dai_get_ops(substream, cpu_dai); if (!ops) { dev_err(cpu_dai->dev, "DAI widget ops not set\n"); @@ -582,6 +588,12 @@ int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream, */ for_each_rtd_cpu_dais(rtd, i, dai) { w = snd_soc_dai_get_widget(dai, substream->stream); + if (!w) { + dev_err(cpu_dai->dev, + "%s widget not found, check amp link num in the topology\n", + dai->name); + return -EINVAL; + } ipc4_copier = widget_to_copier(w); memcpy(&ipc4_copier->dma_config_tlv[cpu_dai_id], dma_config_tlv, sizeof(*dma_config_tlv)); diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index f991785f727e..be689f6e10c8 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -63,6 +63,11 @@ static int sdw_params_stream(struct device *dev, struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(d, params_data->substream->stream); struct snd_sof_dai_config_data data = { 0 };
+ if (!w) { + dev_err(dev, "%s widget not found, check amp link num in the topology\n", + d->name); + return -EINVAL; + } data.dai_index = (params_data->link_id << 8) | d->id; data.dai_data = params_data->alh_stream_id; data.dai_node_id = data.dai_data; diff --git a/tools/perf/bench/epoll-wait.c b/tools/perf/bench/epoll-wait.c index ef5c4257844d..20fe4f72b4af 100644 --- a/tools/perf/bench/epoll-wait.c +++ b/tools/perf/bench/epoll-wait.c @@ -420,7 +420,12 @@ static int cmpworker(const void *p1, const void *p2)
struct worker *w1 = (struct worker *) p1; struct worker *w2 = (struct worker *) p2; - return w1->tid > w2->tid; + + if (w1->tid > w2->tid) + return 1; + if (w1->tid < w2->tid) + return -1; + return 0; }
int bench_epoll_wait(int argc, const char **argv) diff --git a/tools/testing/selftests/bpf/progs/exceptions_fail.c b/tools/testing/selftests/bpf/progs/exceptions_fail.c index fe0f3fa5aab6..8a0fdff89927 100644 --- a/tools/testing/selftests/bpf/progs/exceptions_fail.c +++ b/tools/testing/selftests/bpf/progs/exceptions_fail.c @@ -131,7 +131,7 @@ int reject_subprog_with_lock(void *ctx) }
SEC("?tc") -__failure __msg("BPF_EXIT instruction cannot be used inside bpf_rcu_read_lock-ed region") +__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_rcu_read_lock-ed region") int reject_with_rcu_read_lock(void *ctx) { bpf_rcu_read_lock(); @@ -147,7 +147,7 @@ __noinline static int throwing_subprog(struct __sk_buff *ctx) }
SEC("?tc") -__failure __msg("BPF_EXIT instruction cannot be used inside bpf_rcu_read_lock-ed region") +__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_rcu_read_lock-ed region") int reject_subprog_with_rcu_read_lock(void *ctx) { bpf_rcu_read_lock(); diff --git a/tools/testing/selftests/bpf/progs/preempt_lock.c b/tools/testing/selftests/bpf/progs/preempt_lock.c index 885377e83607..5269571cf7b5 100644 --- a/tools/testing/selftests/bpf/progs/preempt_lock.c +++ b/tools/testing/selftests/bpf/progs/preempt_lock.c @@ -6,7 +6,7 @@ #include "bpf_experimental.h"
SEC("?tc") -__failure __msg("BPF_EXIT instruction cannot be used inside bpf_preempt_disable-ed region") +__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region") int preempt_lock_missing_1(struct __sk_buff *ctx) { bpf_preempt_disable(); @@ -14,7 +14,7 @@ int preempt_lock_missing_1(struct __sk_buff *ctx) }
SEC("?tc") -__failure __msg("BPF_EXIT instruction cannot be used inside bpf_preempt_disable-ed region") +__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region") int preempt_lock_missing_2(struct __sk_buff *ctx) { bpf_preempt_disable(); @@ -23,7 +23,7 @@ int preempt_lock_missing_2(struct __sk_buff *ctx) }
SEC("?tc") -__failure __msg("BPF_EXIT instruction cannot be used inside bpf_preempt_disable-ed region") +__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region") int preempt_lock_missing_3(struct __sk_buff *ctx) { bpf_preempt_disable(); @@ -33,7 +33,7 @@ int preempt_lock_missing_3(struct __sk_buff *ctx) }
SEC("?tc") -__failure __msg("BPF_EXIT instruction cannot be used inside bpf_preempt_disable-ed region") +__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region") int preempt_lock_missing_3_minus_2(struct __sk_buff *ctx) { bpf_preempt_disable(); @@ -55,7 +55,7 @@ static __noinline void preempt_enable(void) }
SEC("?tc") -__failure __msg("BPF_EXIT instruction cannot be used inside bpf_preempt_disable-ed region") +__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region") int preempt_lock_missing_1_subprog(struct __sk_buff *ctx) { preempt_disable(); @@ -63,7 +63,7 @@ int preempt_lock_missing_1_subprog(struct __sk_buff *ctx) }
SEC("?tc") -__failure __msg("BPF_EXIT instruction cannot be used inside bpf_preempt_disable-ed region") +__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region") int preempt_lock_missing_2_subprog(struct __sk_buff *ctx) { preempt_disable(); @@ -72,7 +72,7 @@ int preempt_lock_missing_2_subprog(struct __sk_buff *ctx) }
SEC("?tc") -__failure __msg("BPF_EXIT instruction cannot be used inside bpf_preempt_disable-ed region") +__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_preempt_disable-ed region") int preempt_lock_missing_2_minus_1_subprog(struct __sk_buff *ctx) { preempt_disable(); diff --git a/tools/testing/selftests/bpf/progs/verifier_spin_lock.c b/tools/testing/selftests/bpf/progs/verifier_spin_lock.c index 3f679de73229..25599eac9a70 100644 --- a/tools/testing/selftests/bpf/progs/verifier_spin_lock.c +++ b/tools/testing/selftests/bpf/progs/verifier_spin_lock.c @@ -187,7 +187,7 @@ l0_%=: r6 = r0; \
SEC("cgroup/skb") __description("spin_lock: test6 missing unlock") -__failure __msg("BPF_EXIT instruction cannot be used inside bpf_spin_lock-ed region") +__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_spin_lock-ed region") __failure_unpriv __msg_unpriv("") __naked void spin_lock_test6_missing_unlock(void) { diff --git a/tools/testing/selftests/drivers/net/hw/rss_ctx.py b/tools/testing/selftests/drivers/net/hw/rss_ctx.py index ca8a7edff3dd..27e24e20749f 100755 --- a/tools/testing/selftests/drivers/net/hw/rss_ctx.py +++ b/tools/testing/selftests/drivers/net/hw/rss_ctx.py @@ -252,6 +252,7 @@ def test_rss_queue_reconfigure(cfg, main_ctx=True): try: # this targets queue 4, which doesn't exist ntuple2 = ethtool_create(cfg, "-N", flow) + defer(ethtool, f"-N {cfg.ifname} delete {ntuple2}") except CmdExitFailure: pass else: @@ -260,6 +261,7 @@ def test_rss_queue_reconfigure(cfg, main_ctx=True): ethtool(f"-X {cfg.ifname} {ctx_ref} weight 1 0 1 0") # ntuple rule therefore targets queues 1 and 3 ntuple2 = ethtool_create(cfg, "-N", flow) + defer(ethtool, f"-N {cfg.ifname} delete {ntuple2}") # should replace existing filter ksft_eq(ntuple, ntuple2) _send_traffic_check(cfg, port, ctx_ref, { 'target': (1, 3), diff --git a/tools/testing/selftests/net/ipsec.c b/tools/testing/selftests/net/ipsec.c index be4a30a0d02a..9b44a091802c 100644 --- a/tools/testing/selftests/net/ipsec.c +++ b/tools/testing/selftests/net/ipsec.c @@ -227,7 +227,8 @@ static int rtattr_pack(struct nlmsghdr *nh, size_t req_sz,
attr->rta_len = RTA_LENGTH(size); attr->rta_type = rta_type; - memcpy(RTA_DATA(attr), payload, size); + if (payload) + memcpy(RTA_DATA(attr), payload, size);
return 0; } diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c index 414addef9a45..d240d02fa443 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_connect.c +++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c @@ -1302,7 +1302,7 @@ int main_loop(void) return ret;
if (cfg_truncate > 0) { - xdisconnect(fd); + shutdown(fd, SHUT_WR); } else if (--cfg_repeat > 0) { xdisconnect(fd);
diff --git a/tools/testing/selftests/net/udpgso.c b/tools/testing/selftests/net/udpgso.c index 3f2fca02fec5..36ff28af4b19 100644 --- a/tools/testing/selftests/net/udpgso.c +++ b/tools/testing/selftests/net/udpgso.c @@ -102,6 +102,19 @@ struct testcase testcases_v4[] = { .gso_len = CONST_MSS_V4, .r_num_mss = 1, }, + { + /* datalen <= MSS < gso_len: will fall back to no GSO */ + .tlen = CONST_MSS_V4, + .gso_len = CONST_MSS_V4 + 1, + .r_num_mss = 0, + .r_len_last = CONST_MSS_V4, + }, + { + /* MSS < datalen < gso_len: fail */ + .tlen = CONST_MSS_V4 + 1, + .gso_len = CONST_MSS_V4 + 2, + .tfail = true, + }, { /* send a single MSS + 1B */ .tlen = CONST_MSS_V4 + 1, @@ -205,6 +218,19 @@ struct testcase testcases_v6[] = { .gso_len = CONST_MSS_V6, .r_num_mss = 1, }, + { + /* datalen <= MSS < gso_len: will fall back to no GSO */ + .tlen = CONST_MSS_V6, + .gso_len = CONST_MSS_V6 + 1, + .r_num_mss = 0, + .r_len_last = CONST_MSS_V6, + }, + { + /* MSS < datalen < gso_len: fail */ + .tlen = CONST_MSS_V6 + 1, + .gso_len = CONST_MSS_V6 + 2, + .tfail = true + }, { /* send a single MSS + 1B */ .tlen = CONST_MSS_V6 + 1, diff --git a/tools/tracing/rtla/src/osnoise.c b/tools/tracing/rtla/src/osnoise.c index 245e9344932b..699a83f538a8 100644 --- a/tools/tracing/rtla/src/osnoise.c +++ b/tools/tracing/rtla/src/osnoise.c @@ -867,7 +867,7 @@ int osnoise_set_workload(struct osnoise_context *context, bool onoff)
retval = osnoise_options_set_option("OSNOISE_WORKLOAD", onoff); if (retval < 0) - return -1; + return -2;
context->opt_workload = onoff;
diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c index 4403cc4eba30..90b33b0c4391 100644 --- a/tools/tracing/rtla/src/timerlat_hist.c +++ b/tools/tracing/rtla/src/timerlat_hist.c @@ -1100,12 +1100,15 @@ timerlat_hist_apply_config(struct osnoise_tool *tool, struct timerlat_hist_param } }
- if (params->user_hist) { - retval = osnoise_set_workload(tool->context, 0); - if (retval) { - err_msg("Failed to set OSNOISE_WORKLOAD option\n"); - goto out_err; - } + /* + * Set workload according to type of thread if the kernel supports it. + * On kernels without support, user threads will have already failed + * on missing timerlat_fd, and kernel threads do not need it. + */ + retval = osnoise_set_workload(tool->context, params->kernel_workload); + if (retval < -1) { + err_msg("Failed to set OSNOISE_WORKLOAD option\n"); + goto out_err; }
return 0; @@ -1146,9 +1149,12 @@ static struct osnoise_tool }
static int stop_tracing; +static struct trace_instance *hist_inst = NULL; static void stop_hist(int sig) { stop_tracing = 1; + if (hist_inst) + trace_instance_stop(hist_inst); }
/* @@ -1195,6 +1201,12 @@ int timerlat_hist_main(int argc, char *argv[]) }
trace = &tool->trace; + /* + * Save trace instance into global variable so that SIGINT can stop + * the timerlat tracer. + * Otherwise, rtla could loop indefinitely when overloaded. + */ + hist_inst = trace;
retval = enable_timerlat(trace); if (retval) { @@ -1363,7 +1375,7 @@ int timerlat_hist_main(int argc, char *argv[])
return_value = 0;
- if (trace_is_off(&tool->trace, &record->trace)) { + if (trace_is_off(&tool->trace, &record->trace) && !stop_tracing) { printf("rtla timerlat hit stop tracing\n");
if (!params->no_aa) diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c index 059b468981e4..139eb58336c3 100644 --- a/tools/tracing/rtla/src/timerlat_top.c +++ b/tools/tracing/rtla/src/timerlat_top.c @@ -851,12 +851,15 @@ timerlat_top_apply_config(struct osnoise_tool *top, struct timerlat_top_params * } }
- if (params->user_top) { - retval = osnoise_set_workload(top->context, 0); - if (retval) { - err_msg("Failed to set OSNOISE_WORKLOAD option\n"); - goto out_err; - } + /* + * Set workload according to type of thread if the kernel supports it. + * On kernels without support, user threads will have already failed + * on missing timerlat_fd, and kernel threads do not need it. + */ + retval = osnoise_set_workload(top->context, params->kernel_workload); + if (retval < -1) { + err_msg("Failed to set OSNOISE_WORKLOAD option\n"); + goto out_err; }
if (isatty(STDOUT_FILENO) && !params->quiet) @@ -900,9 +903,12 @@ static struct osnoise_tool }
static int stop_tracing; +static struct trace_instance *top_inst = NULL; static void stop_top(int sig) { stop_tracing = 1; + if (top_inst) + trace_instance_stop(top_inst); }
/* @@ -950,6 +956,13 @@ int timerlat_top_main(int argc, char *argv[]) }
trace = &top->trace; + /* + * Save trace instance into global variable so that SIGINT can stop + * the timerlat tracer. + * Otherwise, rtla could loop indefinitely when overloaded. + */ + top_inst = trace; +
retval = enable_timerlat(trace); if (retval) { @@ -1131,7 +1144,7 @@ int timerlat_top_main(int argc, char *argv[])
return_value = 0;
- if (trace_is_off(&top->trace, &record->trace)) { + if (trace_is_off(&top->trace, &record->trace) && !stop_tracing) { printf("rtla timerlat hit stop tracing\n");
if (!params->no_aa) diff --git a/tools/tracing/rtla/src/trace.c b/tools/tracing/rtla/src/trace.c index 170a706248ab..440323a997c6 100644 --- a/tools/tracing/rtla/src/trace.c +++ b/tools/tracing/rtla/src/trace.c @@ -196,6 +196,14 @@ int trace_instance_start(struct trace_instance *trace) return tracefs_trace_on(trace->inst); }
+/* + * trace_instance_stop - stop tracing a given rtla instance + */ +int trace_instance_stop(struct trace_instance *trace) +{ + return tracefs_trace_off(trace->inst); +} + /* * trace_events_free - free a list of trace events */ diff --git a/tools/tracing/rtla/src/trace.h b/tools/tracing/rtla/src/trace.h index c7c92dc9a18a..76e1b77291ba 100644 --- a/tools/tracing/rtla/src/trace.h +++ b/tools/tracing/rtla/src/trace.h @@ -21,6 +21,7 @@ struct trace_instance {
int trace_instance_init(struct trace_instance *trace, char *tool_name); int trace_instance_start(struct trace_instance *trace); +int trace_instance_stop(struct trace_instance *trace); void trace_instance_destroy(struct trace_instance *trace);
struct trace_seq *get_trace_seq(void);
Please revert the commit titled "vfio/platform: check the bounds of read/write syscalls" from all the latest stable releases (6.13.3, 6.12.14, 6.6.78).
The backport was already included in the releases two weeks ago and the new one doubles up the existing check. The full list of fixed versions (back to 5.4) is correctly mentioned in the associated CVE: https://www.cve.org/CVERecord/?id=CVE-2025-21687
Best regards, snu
On Mon, Feb 17, 2025 at 12:41:58PM +0000, Stefan Nürnberger wrote:
Please revert the commit titled "vfio/platform: check the bounds of read/write syscalls" from all the latest stable releases (6.13.3, 6.12.14, 6.6.78).
Ah, the joys of patch :(
The backport was already included in the releases two weeks ago and the new one doubles up the existing check. The full list of fixed versions (back to 5.4) is correctly mentioned in the associated CVE: https://www.cve.org/CVERecord/?id=CVE-2025-21687
And that CVE record now shows the duplicates as well, remember, we keep them up to date when new stable kernels are released.
I'll go revert this for the next round of kernels, but it's not really a problem with checking the same thing twice, so nothing is broken.
thanks,
greg k-h
linux-stable-mirror@lists.linaro.org