Merge 5.16-rc3 into char-misc-next
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 29 Nov 2021 07:00:54 +0000 (08:00 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 29 Nov 2021 07:00:54 +0000 (08:00 +0100)
We need the char/misc fixes in here as well.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
721 files changed:
.mailmap
Documentation/admin-guide/laptops/thinkpad-acpi.rst
Documentation/admin-guide/sysctl/kernel.rst
Documentation/arm/marvell.rst
Documentation/bpf/index.rst
Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.yaml
Documentation/doc-guide/sphinx.rst
Documentation/filesystems/autofs.rst
Documentation/filesystems/cifs/ksmbd.rst
Documentation/i2c/smbus-protocol.rst
Documentation/networking/ipvs-sysctl.rst
Documentation/networking/timestamping.rst
Documentation/power/energy-model.rst
Documentation/process/changes.rst
Documentation/process/submitting-patches.rst
Documentation/trace/ftrace.rst
Documentation/translations/it_IT/doc-guide/sphinx.rst
Documentation/translations/it_IT/process/changes.rst
Documentation/translations/zh_CN/doc-guide/sphinx.rst
Documentation/translations/zh_CN/process/management-style.rst
MAINTAINERS
Makefile
arch/Kconfig
arch/alpha/kernel/syscalls/syscall.tbl
arch/arc/include/asm/cacheflush.h
arch/arm/Kconfig
arch/arm/boot/dts/bcm2711.dtsi
arch/arm/boot/dts/bcm5301x.dtsi
arch/arm/include/asm/cacheflush.h
arch/arm/mach-socfpga/core.h
arch/arm/mach-socfpga/platsmp.c
arch/arm64/boot/dts/exynos/exynosautov9.dtsi
arch/arm64/include/asm/ftrace.h
arch/arm64/include/asm/pgalloc.h
arch/arm64/include/asm/stacktrace.h
arch/arm64/include/asm/uaccess.h
arch/arm64/kernel/ftrace.c
arch/arm64/kernel/stacktrace.c
arch/arm64/kvm/arm.c
arch/hexagon/include/asm/timer-regs.h [deleted file]
arch/hexagon/include/asm/timex.h
arch/hexagon/kernel/.gitignore [new file with mode: 0644]
arch/hexagon/kernel/time.c
arch/hexagon/lib/io.c
arch/ia64/kernel/syscalls/syscall.tbl
arch/m68k/include/asm/cacheflush_mm.h
arch/m68k/kernel/syscalls/syscall.tbl
arch/m68k/kernel/traps.c
arch/microblaze/kernel/syscalls/syscall.tbl
arch/mips/Kconfig
arch/mips/bcm63xx/clk.c
arch/mips/boot/compressed/Makefile
arch/mips/generic/yamon-dt.c
arch/mips/include/asm/cacheflush.h
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/proc.c
arch/mips/kernel/syscalls/syscall_n32.tbl
arch/mips/kernel/syscalls/syscall_n64.tbl
arch/mips/kernel/syscalls/syscall_o32.tbl
arch/mips/kvm/mips.c
arch/mips/lantiq/clk.c
arch/nds32/include/asm/cacheflush.h
arch/nios2/include/asm/cacheflush.h
arch/parisc/configs/generic-32bit_defconfig
arch/parisc/include/asm/assembly.h
arch/parisc/include/asm/cacheflush.h
arch/parisc/include/asm/jump_label.h
arch/parisc/include/asm/rt_sigframe.h
arch/parisc/kernel/entry.S
arch/parisc/kernel/signal.c
arch/parisc/kernel/signal32.h
arch/parisc/kernel/syscall.S
arch/parisc/kernel/syscalls/syscall.tbl
arch/parisc/kernel/vmlinux.lds.S
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/head_32.h
arch/powerpc/kernel/head_8xx.S
arch/powerpc/kernel/signal.h
arch/powerpc/kernel/signal_32.c
arch/powerpc/kernel/signal_64.c
arch/powerpc/kernel/syscalls/syscall.tbl
arch/powerpc/kernel/watchdog.c
arch/powerpc/kvm/book3s_hv_builtin.c
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/kvm/powerpc.c
arch/powerpc/mm/nohash/kaslr_booke.c
arch/powerpc/mm/nohash/tlb.c
arch/powerpc/mm/numa.c
arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
arch/powerpc/platforms/pseries/iommu.c
arch/powerpc/sysdev/xive/Kconfig
arch/powerpc/sysdev/xive/common.c
arch/riscv/Makefile
arch/riscv/configs/defconfig
arch/riscv/configs/rv32_defconfig
arch/riscv/kvm/vcpu.c
arch/riscv/kvm/vcpu_sbi.c
arch/riscv/kvm/vm.c
arch/s390/Kconfig
arch/s390/Makefile
arch/s390/boot/startup.c
arch/s390/include/asm/kexec.h
arch/s390/kernel/crash_dump.c
arch/s390/kernel/ipl.c
arch/s390/kernel/machine_kexec_file.c
arch/s390/kernel/setup.c
arch/s390/kernel/syscalls/syscall.tbl
arch/s390/kernel/traps.c
arch/s390/kernel/vdso32/Makefile
arch/s390/kernel/vdso64/Makefile
arch/s390/kvm/kvm-s390.c
arch/sh/include/asm/cacheflush.h
arch/sh/kernel/syscalls/syscall.tbl
arch/sparc/kernel/signal_32.c
arch/sparc/kernel/syscalls/syscall.tbl
arch/sparc/kernel/windows.c
arch/x86/Kconfig
arch/x86/entry/vsyscall/vsyscall_64.c
arch/x86/events/intel/core.c
arch/x86/events/intel/uncore_snbep.c
arch/x86/hyperv/hv_init.c
arch/x86/include/asm/fpu/api.h
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/xen/hypercall.h
arch/x86/include/asm/xen/hypervisor.h
arch/x86/kernel/cpu/mshyperv.c
arch/x86/kernel/cpu/sgx/main.c
arch/x86/kernel/process.c
arch/x86/kernel/setup.c
arch/x86/kernel/vm86_32.c
arch/x86/kvm/cpuid.c
arch/x86/kvm/hyperv.c
arch/x86/kvm/mmu/mmu.c
arch/x86/kvm/svm/sev.c
arch/x86/kvm/svm/svm.h
arch/x86/kvm/vmx/nested.c
arch/x86/kvm/vmx/vmx.h
arch/x86/kvm/x86.c
arch/x86/kvm/x86.h
arch/x86/kvm/xen.c
arch/xtensa/include/asm/cacheflush.h
arch/xtensa/kernel/syscalls/syscall.tbl
block/bdev.c
block/blk-cgroup.c
block/blk-core.c
block/blk-flush.c
block/blk-mq.c
block/blk-mq.h
block/blk-sysfs.c
block/blk.h
block/elevator.c
block/genhd.c
block/ioprio.c
drivers/acpi/cppc_acpi.c
drivers/acpi/glue.c
drivers/acpi/internal.h
drivers/acpi/property.c
drivers/acpi/scan.c
drivers/android/binder.c
drivers/ata/ahci.c
drivers/ata/libahci.c
drivers/ata/libata-core.c
drivers/ata/libata-sata.c
drivers/block/virtio_blk.c
drivers/block/zram/zram_drv.c
drivers/cpufreq/intel_pstate.c
drivers/firmware/arm_scmi/base.c
drivers/firmware/arm_scmi/scmi_pm_domain.c
drivers/firmware/arm_scmi/sensors.c
drivers/firmware/arm_scmi/virtio.c
drivers/firmware/arm_scmi/voltage.c
drivers/firmware/smccc/soc_id.c
drivers/gpio/Kconfig
drivers/gpio/gpio-virtio.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
drivers/gpu/drm/amd/amdgpu/navi10_ih.c
drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c
drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c
drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c
drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
drivers/gpu/drm/amd/amdgpu/nv.c
drivers/gpu/drm/amd/amdgpu/soc15.c
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
drivers/gpu/drm/amd/amdkfd/kfd_priv.h
drivers/gpu/drm/amd/amdkfd/kfd_svm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
drivers/gpu/drm/amd/include/amd_shared.h
drivers/gpu/drm/amd/pm/amdgpu_dpm.c
drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.h
drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
drivers/gpu/drm/drm_gem_cma_helper.c
drivers/gpu/drm/hyperv/hyperv_drm_drv.c
drivers/gpu/drm/i915/display/icl_dsi.c
drivers/gpu/drm/i915/gt/intel_gt_pm.c
drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c
drivers/gpu/drm/nouveau/nvkm/subdev/acr/gm200.c
drivers/gpu/drm/nouveau/nvkm/subdev/acr/gp102.c
drivers/gpu/drm/scheduler/sched_main.c
drivers/gpu/drm/sun4i/Kconfig
drivers/gpu/drm/vc4/vc4_bo.c
drivers/gpu/drm/xen/xen_drm_front.c
drivers/hid/hid-asus.c
drivers/hid/hid-ft260.c
drivers/hid/hid-ids.h
drivers/hid/hid-input.c
drivers/hid/hid-magicmouse.c
drivers/hid/hid-multitouch.c
drivers/hid/hid-nintendo.c
drivers/hid/hid-thrustmaster.c
drivers/hid/intel-ish-hid/ishtp-fw-loader.c
drivers/hid/intel-ish-hid/ishtp-hid-client.c
drivers/hid/intel-ish-hid/ishtp/bus.c
drivers/hid/wacom_wac.c
drivers/hid/wacom_wac.h
drivers/hv/hv_balloon.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-virtio.c
drivers/infiniband/core/nldev.c
drivers/infiniband/core/verbs.c
drivers/infiniband/hw/hfi1/verbs.c
drivers/infiniband/hw/mlx4/main.c
drivers/input/misc/xen-kbdfront.c
drivers/iommu/amd/iommu_v2.c
drivers/iommu/intel/cap_audit.c
drivers/iommu/intel/iommu.c
drivers/iommu/rockchip-iommu.c
drivers/media/cec/core/cec-adap.c
drivers/media/common/videobuf2/videobuf2-dma-sg.c
drivers/media/i2c/hi846.c
drivers/media/v4l2-core/v4l2-compat-ioctl32.c
drivers/memory/mtk-smi.c
drivers/mmc/host/mmc_spi.c
drivers/mmc/host/sdhci-esdhc-imx.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h
drivers/net/Kconfig
drivers/net/amt.c
drivers/net/dsa/microchip/ksz8795.c
drivers/net/dsa/microchip/ksz9477.c
drivers/net/dsa/microchip/ksz_common.c
drivers/net/dsa/microchip/ksz_common.h
drivers/net/dsa/qca8k.c
drivers/net/ethernet/aquantia/atlantic/aq_ring.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
drivers/net/ethernet/asix/ax88796c_main.h
drivers/net/ethernet/asix/ax88796c_spi.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
drivers/net/ethernet/dec/tulip/de4x5.c
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
drivers/net/ethernet/intel/e100.c
drivers/net/ethernet/intel/i40e/i40e.h
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
drivers/net/ethernet/intel/iavf/iavf.h
drivers/net/ethernet/intel/iavf/iavf_ethtool.c
drivers/net/ethernet/intel/iavf/iavf_main.c
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
drivers/net/ethernet/intel/ice/ice_lib.c
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/lantiq_etop.c
drivers/net/ethernet/marvell/mvmdio.c
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
drivers/net/ethernet/marvell/prestera/prestera_switchdev.c
drivers/net/ethernet/mellanox/mlx5/core/cmd.c
drivers/net/ethernet/mellanox/mlx5/core/cq.c
drivers/net/ethernet/mellanox/mlx5/core/debugfs.c
drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.h
drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h
drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c
drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_matcher.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/microchip/lan743x_main.c
drivers/net/ethernet/mscc/ocelot.c
drivers/net/ethernet/mscc/ocelot_vcap.c
drivers/net/ethernet/netronome/nfp/nfp_net.h
drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
drivers/net/ethernet/ni/nixge.c
drivers/net/ethernet/qlogic/qed/qed_int.c
drivers/net/ethernet/realtek/r8169_main.c
drivers/net/ethernet/sis/sis900.c
drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
drivers/net/ethernet/stmicro/stmmac/stmmac.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
drivers/net/hamradio/6pack.c
drivers/net/hamradio/mkiss.c
drivers/net/ipa/ipa_cmd.c
drivers/net/ipa/ipa_cmd.h
drivers/net/ipa/ipa_endpoint.c
drivers/net/ipa/ipa_main.c
drivers/net/ipa/ipa_modem.c
drivers/net/ipa/ipa_resource.c
drivers/net/ipa/ipa_smp2p.c
drivers/net/ipa/ipa_smp2p.h
drivers/net/mdio/mdio-aspeed.c
drivers/net/phy/phylink.c
drivers/net/slip/slip.h
drivers/net/tun.c
drivers/net/usb/r8152.c
drivers/net/usb/smsc95xx.c
drivers/net/virtio_net.c
drivers/nfc/virtual_ncidev.c
drivers/nvme/host/core.c
drivers/nvme/host/fabrics.c
drivers/nvme/host/tcp.c
drivers/nvme/target/io-cmd-file.c
drivers/nvme/target/tcp.c
drivers/pinctrl/pinctrl-amd.c
drivers/pinctrl/pinctrl-apple-gpio.c
drivers/pinctrl/qcom/Kconfig
drivers/pinctrl/qcom/pinctrl-sdm845.c
drivers/pinctrl/qcom/pinctrl-sm8350.c
drivers/pinctrl/ralink/pinctrl-mt7620.c
drivers/pinctrl/tegra/pinctrl-tegra.c
drivers/pinctrl/tegra/pinctrl-tegra194.c
drivers/platform/chrome/cros_ec_ishtp.c
drivers/platform/mellanox/mlxreg-lc.c
drivers/platform/x86/Kconfig
drivers/platform/x86/dell/Kconfig
drivers/platform/x86/hp_accel.c
drivers/platform/x86/intel/ishtp_eclite.c
drivers/platform/x86/samsung-laptop.c
drivers/platform/x86/think-lmi.c
drivers/platform/x86/think-lmi.h
drivers/platform/x86/thinkpad_acpi.c
drivers/powercap/dtpm_cpu.c
drivers/ptp/ptp_clockmatrix.c
drivers/ptp/ptp_ocp.c
drivers/s390/block/dasd_devmap.c
drivers/s390/char/raw3270.c
drivers/s390/cio/chp.c
drivers/scsi/mpt3sas/mpt3sas_base.c
drivers/scsi/mpt3sas/mpt3sas_base.h
drivers/scsi/mpt3sas/mpt3sas_scsih.c
drivers/scsi/qla2xxx/qla_edif.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/scsi_transport_iscsi.c
drivers/scsi/ufs/ufs-mediatek.c
drivers/scsi/ufs/ufshcd.c
drivers/scsi/ufs/ufshpb.c
drivers/scsi/virtio_scsi.c
drivers/spi/spi-cadence-quadspi.c
drivers/spi/spi-fsl-lpspi.c
drivers/spi/spi-geni-qcom.c
drivers/spi/spi.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/fbtft/fb_ssd1351.c
drivers/staging/fbtft/fbtft-core.c
drivers/staging/greybus/audio_helper.c
drivers/staging/netlogic/Kconfig [deleted file]
drivers/staging/netlogic/Makefile [deleted file]
drivers/staging/netlogic/TODO [deleted file]
drivers/staging/netlogic/platform_net.c [deleted file]
drivers/staging/netlogic/platform_net.h [deleted file]
drivers/staging/netlogic/xlr_net.c [deleted file]
drivers/staging/netlogic/xlr_net.h [deleted file]
drivers/staging/r8188eu/core/rtw_mlme_ext.c
drivers/staging/r8188eu/os_dep/ioctl_linux.c
drivers/staging/r8188eu/os_dep/mlme_linux.c
drivers/staging/rtl8192e/rtl8192e/rtl_core.c
drivers/target/target_core_fabric_configfs.c
drivers/target/target_core_spc.c
drivers/tee/optee/ffa_abi.c
drivers/thermal/intel/int340x_thermal/Kconfig
drivers/thermal/thermal_core.c
drivers/tty/hvc/hvc_xen.c
drivers/usb/chipidea/ci_hdrc_imx.c
drivers/usb/core/hub.c
drivers/usb/dwc2/gadget.c
drivers/usb/dwc2/hcd_queue.c
drivers/usb/dwc3/core.c
drivers/usb/dwc3/core.h
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/udc/udc-xilinx.c
drivers/usb/host/xhci-tegra.c
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/typec/tcpm/fusb302.c
drivers/usb/typec/tipd/core.c
drivers/vdpa/vdpa_sim/vdpa_sim.c
drivers/vhost/vdpa.c
drivers/vhost/vsock.c
drivers/video/console/sticon.c
drivers/video/fbdev/efifb.c
drivers/video/fbdev/simplefb.c
drivers/video/fbdev/xen-fbfront.c
drivers/virtio/virtio_ring.c
drivers/xen/Kconfig
drivers/xen/pvcalls-front.c
drivers/xen/xenbus/xenbus_probe.c
drivers/xen/xenbus/xenbus_probe_frontend.c
fs/attr.c
fs/btrfs/async-thread.c
fs/btrfs/disk-io.c
fs/btrfs/ioctl.c
fs/btrfs/lzo.c
fs/btrfs/scrub.c
fs/btrfs/volumes.c
fs/cifs/cifs_swn.c
fs/cifs/cifsfs.h
fs/cifs/cifsproto.h
fs/cifs/connect.c
fs/cifs/dfs_cache.c
fs/cifs/sess.c
fs/cifs/smb2pdu.c
fs/erofs/utils.c
fs/fuse/dev.c
fs/gfs2/bmap.c
fs/gfs2/file.c
fs/gfs2/glock.c
fs/gfs2/super.c
fs/inode.c
fs/io_uring.c
fs/iomap/buffered-io.c
fs/ksmbd/smb2pdu.c
fs/nfs/inode.c
fs/nfs/nfs42proc.c
fs/nfs/nfs42xdr.c
fs/nfs/nfs4state.c
fs/nfs/nfstrace.h
fs/nfsd/nfs4xdr.c
fs/ntfs/Kconfig
fs/proc/vmcore.c
fs/pstore/Kconfig
fs/pstore/blk.c
fs/udf/dir.c
fs/udf/namei.c
fs/udf/super.c
fs/xfs/libxfs/xfs_attr.c
fs/xfs/xfs_icache.c
fs/xfs/xfs_inode.h
include/asm-generic/cacheflush.h
include/linux/acpi.h
include/linux/bpf.h
include/linux/cacheflush.h [new file with mode: 0644]
include/linux/fs.h
include/linux/highmem.h
include/linux/hugetlb_cgroup.h
include/linux/intel-ish-client-if.h
include/linux/ipc_namespace.h
include/linux/kvm_host.h
include/linux/kvm_types.h
include/linux/mlx5/eswitch.h
include/linux/mm_types.h
include/linux/mod_devicetable.h
include/linux/page-flags.h
include/linux/pagemap.h
include/linux/percpu.h
include/linux/printk.h
include/linux/ptp_classify.h
include/linux/sched/signal.h
include/linux/sched/task.h
include/linux/sdb.h [deleted file]
include/linux/skbuff.h
include/linux/trace_events.h
include/linux/virtio.h
include/linux/virtio_net.h
include/net/ip6_fib.h
include/net/ipv6_stubs.h
include/net/nfc/nci_core.h
include/net/nl802154.h
include/net/page_pool.h
include/rdma/rdma_netlink.h
include/soc/mscc/ocelot_vcap.h
include/trace/events/rpcgss.h
include/xen/xenbus.h
init/Kconfig
ipc/shm.c
ipc/util.c
kernel/bpf/cgroup.c
kernel/bpf/helpers.c
kernel/bpf/syscall.c
kernel/bpf/verifier.c
kernel/cpu.c
kernel/entry/syscall_user_dispatch.c
kernel/events/core.c
kernel/locking/rwsem.c
kernel/power/hibernate.c
kernel/power/user.c
kernel/printk/printk.c
kernel/sched/core.c
kernel/signal.c
kernel/trace/bpf_trace.c
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_events.c
kernel/trace/trace_events_hist.c
kernel/trace/trace_uprobe.c
lib/Kconfig.debug
lib/nmi_backtrace.c
lib/test_kasan.c
lib/zstd/Makefile
lib/zstd/common/compiler.h
lib/zstd/compress/zstd_compress_superblock.c
lib/zstd/compress/zstd_opt.c
mm/Kconfig
mm/damon/dbgfs.c
mm/highmem.c
mm/hugetlb.c
mm/memcontrol.c
mm/shmem.c
mm/slab.c
mm/slab.h
mm/slob.c
mm/slub.c
mm/swap.c
mm/util.c
net/8021q/vlan.c
net/8021q/vlan_dev.c
net/core/devlink.c
net/core/filter.c
net/core/neighbour.c
net/core/page_pool.c
net/core/sock.c
net/ethtool/ioctl.c
net/ipv4/bpf_tcp_ca.c
net/ipv4/devinet.c
net/ipv4/nexthop.c
net/ipv4/tcp.c
net/ipv4/tcp_cubic.c
net/ipv4/udp.c
net/ipv6/af_inet6.c
net/ipv6/esp6.c
net/ipv6/ip6_output.c
net/ipv6/route.c
net/mac80211/cfg.c
net/mac80211/iface.c
net/mac80211/led.h
net/mac80211/rx.c
net/mac80211/tx.c
net/mac80211/util.c
net/mac80211/wme.c
net/mptcp/options.c
net/mptcp/protocol.c
net/mptcp/protocol.h
net/ncsi/ncsi-cmd.c
net/netfilter/ipvs/ip_vs_core.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_flow_table_offload.c
net/netfilter/nft_payload.c
net/netfilter/xt_IDLETIMER.c
net/nfc/core.c
net/nfc/nci/core.c
net/sched/act_mirred.c
net/sched/sch_ets.c
net/smc/af_smc.c
net/smc/smc_close.c
net/smc/smc_core.c
net/sunrpc/xprtsock.c
net/tipc/crypto.c
net/tipc/link.c
net/tls/tls_main.c
net/tls/tls_sw.c
net/unix/af_unix.c
net/wireless/nl80211.c
net/wireless/nl80211.h
net/wireless/util.c
net/xdp/xsk_buff_pool.c
samples/Kconfig
samples/Makefile
samples/bpf/hbm_kern.h
samples/bpf/xdp_redirect_cpu_user.c
samples/bpf/xdp_sample_user.c
samples/ftrace/Makefile
samples/ftrace/ftrace-direct-multi.c
scripts/mod/devicetable-offsets.c
scripts/mod/file2alias.c
security/selinux/ss/hashtab.c
sound/hda/intel-dsp-config.c
sound/pci/cmipci.c
sound/pci/ctxfi/ctamixer.c
sound/pci/ctxfi/ctdaio.c
sound/pci/ctxfi/ctresource.c
sound/pci/ctxfi/ctresource.h
sound/pci/ctxfi/ctsrc.c
sound/pci/hda/patch_realtek.c
sound/soc/codecs/cs35l41.c
sound/soc/codecs/lpass-rx-macro.c
sound/soc/codecs/rt1011.c
sound/soc/codecs/rt1011.h
sound/soc/codecs/rt5682-i2c.c
sound/soc/codecs/rt5682.c
sound/soc/codecs/rt5682.h
sound/soc/codecs/rt9120.c
sound/soc/codecs/wcd934x.c
sound/soc/codecs/wcd938x.c
sound/soc/codecs/wm_adsp.c
sound/soc/intel/boards/sof_sdw.c
sound/soc/intel/common/soc-acpi-intel-adl-match.c
sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
sound/soc/mediatek/mt8173/mt8173-rt5650.c
sound/soc/qcom/qdsp6/audioreach.h
sound/soc/qcom/qdsp6/q6adm.c
sound/soc/qcom/qdsp6/q6asm-dai.c
sound/soc/qcom/qdsp6/q6prm.c
sound/soc/qcom/qdsp6/q6routing.c
sound/soc/sh/rcar/dma.c
sound/soc/soc-dapm.c
sound/soc/soc-topology.c
sound/soc/sof/Kconfig
sound/soc/sof/control.c
sound/soc/sof/intel/hda-bus.c
sound/soc/sof/intel/hda-dsp.c
sound/soc/sof/intel/hda.c
sound/soc/stm/stm32_i2s.c
sound/usb/pcm.c
sound/xen/xen_snd_front.c
tools/arch/x86/include/asm/cpufeatures.h
tools/arch/x86/include/uapi/asm/kvm.h
tools/bpf/runqslower/Makefile
tools/build/feature/test-all.c
tools/include/uapi/linux/if_link.h
tools/include/uapi/linux/kvm.h
tools/lib/bpf/bpf_gen_internal.h
tools/lib/bpf/gen_loader.c
tools/lib/bpf/libbpf.c
tools/perf/Makefile.config
tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl
tools/perf/bench/sched-messaging.c
tools/perf/builtin-report.c
tools/perf/tests/event_update.c
tools/perf/tests/sample-parsing.c
tools/perf/tests/wp.c
tools/perf/ui/hist.c
tools/perf/util/arm-spe.c
tools/perf/util/evsel.c
tools/perf/util/header.c
tools/perf/util/hist.c
tools/perf/util/hist.h
tools/perf/util/parse-events.c
tools/perf/util/sort.c
tools/perf/util/sort.h
tools/perf/util/util.c
tools/perf/util/util.h
tools/testing/selftests/bpf/Makefile
tools/testing/selftests/bpf/prog_tests/helper_restricted.c [new file with mode: 0644]
tools/testing/selftests/bpf/progs/test_helper_restricted.c [new file with mode: 0644]
tools/testing/selftests/bpf/test_verifier.c
tools/testing/selftests/bpf/verifier/helper_restricted.c [new file with mode: 0644]
tools/testing/selftests/bpf/verifier/map_in_map.c
tools/testing/selftests/gpio/Makefile
tools/testing/selftests/gpio/gpio-mockup-cdev.c
tools/testing/selftests/kvm/.gitignore
tools/testing/selftests/kvm/access_tracking_perf_test.c
tools/testing/selftests/kvm/demand_paging_test.c
tools/testing/selftests/kvm/dirty_log_perf_test.c
tools/testing/selftests/kvm/dirty_log_test.c
tools/testing/selftests/kvm/include/perf_test_util.h
tools/testing/selftests/kvm/include/test_util.h
tools/testing/selftests/kvm/kvm_page_table_test.c
tools/testing/selftests/kvm/lib/elf.c
tools/testing/selftests/kvm/lib/kvm_util.c
tools/testing/selftests/kvm/lib/perf_test_util.c
tools/testing/selftests/kvm/lib/test_util.c
tools/testing/selftests/kvm/memslot_modification_stress_test.c
tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c
tools/testing/selftests/net/Makefile
tools/testing/selftests/net/fib_nexthops.sh
tools/testing/selftests/net/forwarding/config
tools/testing/selftests/net/forwarding/tc_actions.sh
tools/testing/selftests/net/gre_gso.sh
tools/testing/selftests/net/tls.c
tools/testing/selftests/netfilter/Makefile
tools/testing/selftests/netfilter/conntrack_vrf.sh [new file with mode: 0755]
tools/testing/selftests/netfilter/nft_nat.sh
tools/testing/selftests/netfilter/nft_queue.sh
tools/testing/selftests/tc-testing/tc-tests/actions/bpf.json
tools/testing/selftests/tc-testing/tc-tests/qdiscs/mq.json
virt/kvm/kvm_main.c

index 14314e3..6277bb2 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -71,6 +71,9 @@ Chao Yu <chao@kernel.org> <chao2.yu@samsung.com>
 Chao Yu <chao@kernel.org> <yuchao0@huawei.com>
 Chris Chiu <chris.chiu@canonical.com> <chiu@endlessm.com>
 Chris Chiu <chris.chiu@canonical.com> <chiu@endlessos.org>
+Christian Borntraeger <borntraeger@linux.ibm.com> <borntraeger@de.ibm.com>
+Christian Borntraeger <borntraeger@linux.ibm.com> <cborntra@de.ibm.com>
+Christian Borntraeger <borntraeger@linux.ibm.com> <borntrae@de.ibm.com>
 Christophe Ricard <christophe.ricard@gmail.com>
 Christoph Hellwig <hch@lst.de>
 Colin Ian King <colin.king@intel.com> <colin.king@canonical.com>
index 6721a80..475eb0e 100644 (file)
@@ -1520,15 +1520,15 @@ This sysfs attribute controls the keyboard "face" that will be shown on the
 Lenovo X1 Carbon 2nd gen (2014)'s adaptive keyboard. The value can be read
 and set.
 
-- 1 = Home mode
-- 2 = Web-browser mode
-- 3 = Web-conference mode
-- 4 = Function mode
-- 5 = Layflat mode
+- 0 = Home mode
+- 1 = Web-browser mode
+- 2 = Web-conference mode
+- 3 = Function mode
+- 4 = Layflat mode
 
 For more details about which buttons will appear depending on the mode, please
 review the laptop's user guide:
-http://www.lenovo.com/shop/americas/content/user_guides/x1carbon_2_ug_en.pdf
+https://download.lenovo.com/ibmdl/pub/pc/pccbbs/mobiles_pdf/x1carbon_2_ug_en.pdf
 
 Battery charge control
 ----------------------
index 4261620..0e486f4 100644 (file)
@@ -1099,7 +1099,7 @@ task_delayacct
 ===============
 
 Enables/disables task delay accounting (see
-:doc:`accounting/delay-accounting.rst`). Enabling this feature incurs
+Documentation/accounting/delay-accounting.rst. Enabling this feature incurs
 a small amount of overhead in the scheduler but is useful for debugging
 and performance tuning. It is required by some tools such as iotop.
 
index 8323c79..9485a5a 100644 (file)
@@ -104,6 +104,8 @@ Discovery family
 
                 Not supported by the Linux kernel.
 
+  Homepage:
+        https://web.archive.org/web/20110924171043/http://www.marvell.com/embedded-processors/discovery-innovation/
   Core:
        Feroceon 88fr571-vd ARMv5 compatible
 
@@ -120,6 +122,7 @@ EBU Armada family
         - 88F6707
         - 88F6W11
 
+    - Product infos:   https://web.archive.org/web/20141002083258/http://www.marvell.com/embedded-processors/armada-370/
     - Product Brief:   https://web.archive.org/web/20121115063038/http://www.marvell.com/embedded-processors/armada-300/assets/Marvell_ARMADA_370_SoC.pdf
     - Hardware Spec:   https://web.archive.org/web/20140617183747/http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA370-datasheet.pdf
     - Functional Spec: https://web.archive.org/web/20140617183701/http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA370-FunctionalSpec-datasheet.pdf
@@ -127,9 +130,29 @@ EBU Armada family
   Core:
        Sheeva ARMv7 compatible PJ4B
 
+  Armada XP Flavors:
+        - MV78230
+        - MV78260
+        - MV78460
+
+    NOTE:
+       not to be confused with the non-SMP 78xx0 SoCs
+
+    - Product infos:   https://web.archive.org/web/20150101215721/http://www.marvell.com/embedded-processors/armada-xp/
+    - Product Brief:   https://web.archive.org/web/20121021173528/http://www.marvell.com/embedded-processors/armada-xp/assets/Marvell-ArmadaXP-SoC-product%20brief.pdf
+    - Functional Spec: https://web.archive.org/web/20180829171131/http://www.marvell.com/embedded-processors/armada-xp/assets/ARMADA-XP-Functional-SpecDatasheet.pdf
+    - Hardware Specs:
+        - https://web.archive.org/web/20141127013651/http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78230_OS.PDF
+        - https://web.archive.org/web/20141222000224/http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78260_OS.PDF
+        - https://web.archive.org/web/20141222000230/http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78460_OS.PDF
+
+  Core:
+       Sheeva ARMv7 compatible Dual-core or Quad-core PJ4B-MP
+
   Armada 375 Flavors:
        - 88F6720
 
+    - Product infos: https://web.archive.org/web/20140108032402/http://www.marvell.com/embedded-processors/armada-375/
     - Product Brief: https://web.archive.org/web/20131216023516/http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA_375_SoC-01_product_brief.pdf
 
   Core:
@@ -162,29 +185,6 @@ EBU Armada family
   Core:
        ARM Cortex-A9
 
-  Armada XP Flavors:
-        - MV78230
-        - MV78260
-        - MV78460
-
-    NOTE:
-       not to be confused with the non-SMP 78xx0 SoCs
-
-    Product Brief:
-       https://web.archive.org/web/20121021173528/http://www.marvell.com/embedded-processors/armada-xp/assets/Marvell-ArmadaXP-SoC-product%20brief.pdf
-
-    Functional Spec:
-       https://web.archive.org/web/20180829171131/http://www.marvell.com/embedded-processors/armada-xp/assets/ARMADA-XP-Functional-SpecDatasheet.pdf
-
-    - Hardware Specs:
-
-        - https://web.archive.org/web/20141127013651/http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78230_OS.PDF
-        - https://web.archive.org/web/20141222000224/http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78260_OS.PDF
-        - https://web.archive.org/web/20141222000230/http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78460_OS.PDF
-
-  Core:
-       Sheeva ARMv7 compatible Dual-core or Quad-core PJ4B-MP
-
   Linux kernel mach directory:
        arch/arm/mach-mvebu
   Linux kernel plat directory:
@@ -436,7 +436,7 @@ Berlin family (Multimedia Solutions)
   - Flavors:
        - 88DE3010, Armada 1000 (no Linux support)
                - Core:         Marvell PJ1 (ARMv5TE), Dual-core
-               - Product Brief:        http://www.marvell.com.cn/digital-entertainment/assets/armada_1000_pb.pdf
+               - Product Brief:        https://web.archive.org/web/20131103162620/http://www.marvell.com/digital-entertainment/assets/armada_1000_pb.pdf
        - 88DE3005, Armada 1500 Mini
                - Design name:  BG2CD
                - Core:         ARM Cortex-A9, PL310 L2CC
index 37f273a..610450f 100644 (file)
@@ -15,7 +15,7 @@ that goes into great technical depth about the BPF Architecture.
 libbpf
 ======
 
-Documentation/bpf/libbpf/libbpf.rst is a userspace library for loading and interacting with bpf programs.
+Documentation/bpf/libbpf/index.rst is a userspace library for loading and interacting with bpf programs.
 
 BPF Type Format (BTF)
 =====================
index 29b9447..fe0c89e 100644 (file)
@@ -17,9 +17,10 @@ properties:
     oneOf:
       - enum:
           - fsl,imx7ulp-lpi2c
-          - fsl,imx8qm-lpi2c
       - items:
-          - const: fsl,imx8qxp-lpi2c
+          - enum:
+              - fsl,imx8qxp-lpi2c
+              - fsl,imx8qm-lpi2c
           - const: fsl,imx7ulp-lpi2c
 
   reg:
index ec3e71f..e445cb1 100644 (file)
@@ -27,7 +27,7 @@ Sphinx Install
 ==============
 
 The ReST markups currently used by the Documentation/ files are meant to be
-built with ``Sphinx`` version 1.3 or higher.
+built with ``Sphinx`` version 1.7 or higher.
 
 There's a script that checks for the Sphinx requirements. Please see
 :ref:`sphinx-pre-install` for further details.
@@ -43,10 +43,6 @@ or ``virtualenv``, depending on how your distribution packaged Python 3.
 
 .. note::
 
-   #) Sphinx versions below 1.5 don't work properly with Python's
-      docutils version 0.13.1 or higher. So, if you're willing to use
-      those versions, you should run ``pip install 'docutils==0.12'``.
-
    #) It is recommended to use the RTD theme for html output. Depending
       on the Sphinx version, it should be installed separately,
       with ``pip install sphinx_rtd_theme``.
@@ -55,13 +51,13 @@ or ``virtualenv``, depending on how your distribution packaged Python 3.
       those expressions are written using LaTeX notation. It needs texlive
       installed with amsfonts and amsmath in order to evaluate them.
 
-In summary, if you want to install Sphinx version 1.7.9, you should do::
+In summary, if you want to install Sphinx version 2.4.4, you should do::
 
-       $ virtualenv sphinx_1.7.9
-       $ . sphinx_1.7.9/bin/activate
-       (sphinx_1.7.9) $ pip install -r Documentation/sphinx/requirements.txt
+       $ virtualenv sphinx_2.4.4
+       $ . sphinx_2.4.4/bin/activate
+       (sphinx_2.4.4) $ pip install -r Documentation/sphinx/requirements.txt
 
-After running ``. sphinx_1.7.9/bin/activate``, the prompt will change,
+After running ``. sphinx_2.4.4/bin/activate``, the prompt will change,
 in order to indicate that you're using the new environment. If you
 open a new shell, you need to rerun this command to enter again at
 the virtual environment before building the documentation.
@@ -81,7 +77,7 @@ output.
 PDF and LaTeX builds
 --------------------
 
-Such builds are currently supported only with Sphinx versions 1.4 and higher.
+Such builds are currently supported only with Sphinx versions 2.4 and higher.
 
 For PDF and LaTeX output, you'll also need ``XeLaTeX`` version 3.14159265.
 
@@ -104,8 +100,8 @@ command line options for your distro::
        You should run:
 
                sudo dnf install -y texlive-luatex85
-               /usr/bin/virtualenv sphinx_1.7.9
-               . sphinx_1.7.9/bin/activate
+               /usr/bin/virtualenv sphinx_2.4.4
+               . sphinx_2.4.4/bin/activate
                pip install -r Documentation/sphinx/requirements.txt
 
        Can't build as 1 mandatory dependency is missing at ./scripts/sphinx-pre-install line 468.
index 681c6a4..4f49027 100644 (file)
@@ -35,7 +35,7 @@ This document describes only the kernel module and the interactions
 required with any user-space program.  Subsequent text refers to this
 as the "automount daemon" or simply "the daemon".
 
-"autofs" is a Linux kernel module with provides the "autofs"
+"autofs" is a Linux kernel module which provides the "autofs"
 filesystem type.  Several "autofs" filesystems can be mounted and they
 can each be managed separately, or all managed by the same daemon.
 
index a132615..b0d354f 100644 (file)
@@ -50,11 +50,11 @@ ksmbd.mountd (user space daemon)
 --------------------------------
 
 ksmbd.mountd is userspace process to, transfer user account and password that
-are registered using ksmbd.adduser(part of utils for user space). Further it
+are registered using ksmbd.adduser (part of utils for user space). Further it
 allows sharing information parameters that parsed from smb.conf to ksmbd in
 kernel. For the execution part it has a daemon which is continuously running
 and connected to the kernel interface using netlink socket, it waits for the
-requests(dcerpc and share/user info). It handles RPC calls (at a minimum few
+requests (dcerpc and share/user info). It handles RPC calls (at a minimum few
 dozen) that are most important for file server from NetShareEnum and
 NetServerGetInfo. Complete DCE/RPC response is prepared from the user space
 and passed over to the associated kernel thread for the client.
@@ -154,11 +154,11 @@ Each layer
 1. Enable all component prints
        # sudo ksmbd.control -d "all"
 
-2. Enable one of components(smb, auth, vfs, oplock, ipc, conn, rdma)
+2. Enable one of components (smb, auth, vfs, oplock, ipc, conn, rdma)
        # sudo ksmbd.control -d "smb"
 
-3. Show what prints are enable.
-       # cat/sys/class/ksmbd-control/debug
+3. Show what prints are enabled.
+       # cat /sys/class/ksmbd-control/debug
          [smb] auth vfs oplock ipc conn [rdma]
 
 4. Disable prints:
index 9e07e6b..00d8e17 100644 (file)
@@ -36,6 +36,8 @@ Key to symbols
 
 =============== =============================================================
 S               Start condition
+Sr              Repeated start condition, used to switch from write to
+                read mode.
 P               Stop condition
 Rd/Wr (1 bit)   Read/Write bit. Rd equals 1, Wr equals 0.
 A, NA (1 bit)   Acknowledge (ACK) and Not Acknowledge (NACK) bit
@@ -100,7 +102,7 @@ Implemented by i2c_smbus_read_byte_data()
 This reads a single byte from a device, from a designated register.
 The register is specified through the Comm byte::
 
-  S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P
+  S Addr Wr [A] Comm [A] Sr Addr Rd [A] [Data] NA P
 
 Functionality flag: I2C_FUNC_SMBUS_READ_BYTE_DATA
 
@@ -114,7 +116,7 @@ This operation is very like Read Byte; again, data is read from a
 device, from a designated register that is specified through the Comm
 byte. But this time, the data is a complete word (16 bits)::
 
-  S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
+  S Addr Wr [A] Comm [A] Sr Addr Rd [A] [DataLow] A [DataHigh] NA P
 
 Functionality flag: I2C_FUNC_SMBUS_READ_WORD_DATA
 
@@ -164,7 +166,7 @@ This command selects a device register (through the Comm byte), sends
 16 bits of data to it, and reads 16 bits of data in return::
 
   S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A]
-                               S Addr Rd [A] [DataLow] A [DataHigh] NA P
+                              Sr Addr Rd [A] [DataLow] A [DataHigh] NA P
 
 Functionality flag: I2C_FUNC_SMBUS_PROC_CALL
 
@@ -181,7 +183,7 @@ of data is specified by the device in the Count byte.
 ::
 
   S Addr Wr [A] Comm [A]
-             S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P
+            Sr Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P
 
 Functionality flag: I2C_FUNC_SMBUS_READ_BLOCK_DATA
 
@@ -212,7 +214,7 @@ This command selects a device register (through the Comm byte), sends
 1 to 31 bytes of data to it, and reads 1 to 31 bytes of data in return::
 
   S Addr Wr [A] Comm [A] Count [A] Data [A] ...
-                               S Addr Rd [A] [Count] A [Data] ... A P
+                              Sr Addr Rd [A] [Count] A [Data] ... A P
 
 Functionality flag: I2C_FUNC_SMBUS_BLOCK_PROC_CALL
 
@@ -300,7 +302,7 @@ This command reads a block of bytes from a device, from a
 designated register that is specified through the Comm byte::
 
   S Addr Wr [A] Comm [A]
-             S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
+            Sr Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
 
 Functionality flag: I2C_FUNC_SMBUS_READ_I2C_BLOCK
 
index 95ef56d..387fda8 100644 (file)
@@ -37,8 +37,7 @@ conn_reuse_mode - INTEGER
 
        0: disable any special handling on port reuse. The new
        connection will be delivered to the same real server that was
-       servicing the previous connection. This will effectively
-       disable expire_nodest_conn.
+       servicing the previous connection.
 
        bit 1: enable rescheduling of new connections when it is safe.
        That is, whenever expire_nodest_conn and for TCP sockets, when
index a722eb3..80b1335 100644 (file)
@@ -486,8 +486,8 @@ of packets.
 Drivers are free to use a more permissive configuration than the requested
 configuration. It is expected that drivers should only implement directly the
 most generic mode that can be supported. For example if the hardware can
-support HWTSTAMP_FILTER_V2_EVENT, then it should generally always upscale
-HWTSTAMP_FILTER_V2_L2_SYNC_MESSAGE, and so forth, as HWTSTAMP_FILTER_V2_EVENT
+support HWTSTAMP_FILTER_PTP_V2_EVENT, then it should generally always upscale
+HWTSTAMP_FILTER_PTP_V2_L2_SYNC, and so forth, as HWTSTAMP_FILTER_PTP_V2_EVENT
 is more generic (and more useful to applications).
 
 A driver which supports hardware time stamping shall update the struct
index 8a2788a..5ac62a7 100644 (file)
@@ -84,6 +84,16 @@ CONFIG_ENERGY_MODEL must be enabled to use the EM framework.
 2.2 Registration of performance domains
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+Registration of 'advanced' EM
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The 'advanced' EM gets it's name due to the fact that the driver is allowed
+to provide more precised power model. It's not limited to some implemented math
+formula in the framework (like it's in 'simple' EM case). It can better reflect
+the real power measurements performed for each performance state. Thus, this
+registration method should be preferred in case considering EM static power
+(leakage) is important.
+
 Drivers are expected to register performance domains into the EM framework by
 calling the following API::
 
@@ -103,6 +113,18 @@ to: return warning/error, stop working or panic.
 See Section 3. for an example of driver implementing this
 callback, or Section 2.4 for further documentation on this API
 
+Registration of 'simple' EM
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The 'simple' EM is registered using the framework helper function
+cpufreq_register_em_with_opp(). It implements a power model which is tight to
+math formula::
+
+       Power = C * V^2 * f
+
+The EM which is registered using this method might not reflect correctly the
+physics of a real device, e.g. when static power (leakage) is important.
+
 
 2.3 Accessing performance domains
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -138,6 +160,10 @@ or in Section 2.4
 3. Example driver
 -----------------
 
+The CPUFreq framework supports dedicated callback for registering
+the EM for a given CPU(s) 'policy' object: cpufreq_driver::register_em().
+That callback has to be implemented properly for a given driver,
+because the framework would call it at the right time during setup.
 This section provides a simple example of a CPUFreq driver registering a
 performance domain in the Energy Model framework using the (fake) 'foo'
 protocol. The driver implements an est_power() function to be provided to the
@@ -167,25 +193,22 @@ EM framework::
   20           return 0;
   21   }
   22
-  23   static int foo_cpufreq_init(struct cpufreq_policy *policy)
+  23   static void foo_cpufreq_register_em(struct cpufreq_policy *policy)
   24   {
   25           struct em_data_callback em_cb = EM_DATA_CB(est_power);
   26           struct device *cpu_dev;
-  27           int nr_opp, ret;
+  27           int nr_opp;
   28
   29           cpu_dev = get_cpu_device(cpumask_first(policy->cpus));
   30
-  31           /* Do the actual CPUFreq init work ... */
-  32           ret = do_foo_cpufreq_init(policy);
-  33           if (ret)
-  34                   return ret;
-  35
-  36           /* Find the number of OPPs for this policy */
-  37           nr_opp = foo_get_nr_opp(policy);
+  31           /* Find the number of OPPs for this policy */
+  32           nr_opp = foo_get_nr_opp(policy);
+  33
+  34           /* And register the new performance domain */
+  35           em_dev_register_perf_domain(cpu_dev, nr_opp, &em_cb, policy->cpus,
+  36                                       true);
+  37   }
   38
-  39           /* And register the new performance domain */
-  40           em_dev_register_perf_domain(cpu_dev, nr_opp, &em_cb, policy->cpus,
-  41                                       true);
-  42
-  43           return 0;
-  44   }
+  39   static struct cpufreq_driver foo_cpufreq_driver = {
+  40           .register_em = foo_cpufreq_register_em,
+  41   };
index e35ab74..b398b85 100644 (file)
@@ -54,7 +54,7 @@ mcelog                 0.6              mcelog --version
 iptables               1.4.2            iptables -V
 openssl & libcrypto    1.0.0            openssl version
 bc                     1.06.95          bc --version
-Sphinx\ [#f1]_        1.3              sphinx-build --version
+Sphinx\ [#f1]_         1.7              sphinx-build --version
 ====================== ===============  ========================================
 
 .. [#f1] Sphinx is needed only to build the Kernel documentation
index a0cc969..da085d6 100644 (file)
@@ -22,8 +22,8 @@ use it, it will make your life as a kernel developer and in general much
 easier.
 
 Some subsystems and maintainer trees have additional information about
-their workflow and expectations, see :ref:`Documentation/process/maintainer
-handbooks <maintainer_handbooks_main>`.
+their workflow and expectations, see
+:ref:`Documentation/process/maintainer-handbooks.rst <maintainer_handbooks_main>`.
 
 Obtain a current source tree
 ----------------------------
index 4e5b26f..b3166c4 100644 (file)
@@ -2442,11 +2442,10 @@ Or this simple script!
   #!/bin/bash
 
   tracefs=`sed -ne 's/^tracefs \(.*\) tracefs.*/\1/p' /proc/mounts`
-  echo nop > $tracefs/tracing/current_tracer
-  echo 0 > $tracefs/tracing/tracing_on
-  echo $$ > $tracefs/tracing/set_ftrace_pid
-  echo function > $tracefs/tracing/current_tracer
-  echo 1 > $tracefs/tracing/tracing_on
+  echo 0 > $tracefs/tracing_on
+  echo $$ > $tracefs/set_ftrace_pid
+  echo function > $tracefs/current_tracer
+  echo 1 > $tracefs/tracing_on
   exec "$@"
 
 
index 0046d75..9762452 100644 (file)
@@ -35,7 +35,7 @@ Installazione Sphinx
 ====================
 
 I marcatori ReST utilizzati nei file in Documentation/ sono pensati per essere
-processati da ``Sphinx`` nella versione 1.3 o superiore.
+processati da ``Sphinx`` nella versione 1.7 o superiore.
 
 Esiste uno script che verifica i requisiti Sphinx. Per ulteriori dettagli
 consultate :ref:`it_sphinx-pre-install`.
@@ -53,11 +53,6 @@ pacchettizzato dalla vostra distribuzione.
 
 .. note::
 
-   #) Le versioni di Sphinx inferiori alla 1.5 non funzionano bene
-      con il pacchetto Python docutils versione 0.13.1 o superiore.
-      Se volete usare queste versioni, allora dovere eseguire
-      ``pip install 'docutils==0.12'``.
-
    #) Viene raccomandato l'uso del tema RTD per la documentazione in HTML.
       A seconda della versione di Sphinx, potrebbe essere necessaria
       l'installazione tramite il comando ``pip install sphinx_rtd_theme``.
@@ -67,13 +62,13 @@ pacchettizzato dalla vostra distribuzione.
       utilizzando LaTeX. Per una corretta interpretazione, è necessario aver
       installato texlive con i pacchetti amdfonts e amsmath.
 
-Riassumendo, se volete installare la versione 1.7.9 di Sphinx dovete eseguire::
+Riassumendo, se volete installare la versione 2.4.4 di Sphinx dovete eseguire::
 
-       $ virtualenv sphinx_1.7.9
-       $ . sphinx_1.7.9/bin/activate
-       (sphinx_1.7.9) $ pip install -r Documentation/sphinx/requirements.txt
+       $ virtualenv sphinx_2.4.4
+       $ . sphinx_2.4.4/bin/activate
+       (sphinx_2.4.4) $ pip install -r Documentation/sphinx/requirements.txt
 
-Dopo aver eseguito ``. sphinx_1.7.9/bin/activate``, il prompt cambierà per
+Dopo aver eseguito ``. sphinx_2.4.4/bin/activate``, il prompt cambierà per
 indicare che state usando il nuovo ambiente. Se aprite un nuova sessione,
 prima di generare la documentazione, dovrete rieseguire questo comando per
 rientrare nell'ambiente virtuale.
@@ -94,7 +89,7 @@ Generazione in PDF e LaTeX
 --------------------------
 
 Al momento, la generazione di questi documenti è supportata solo dalle
-versioni di Sphinx superiori alla 1.4.
+versioni di Sphinx superiori alla 2.4.
 
 Per la generazione di PDF e LaTeX, avrete bisogno anche del pacchetto
 ``XeLaTeX`` nella versione 3.14159265
@@ -119,8 +114,8 @@ l'installazione::
        You should run:
 
                sudo dnf install -y texlive-luatex85
-               /usr/bin/virtualenv sphinx_1.7.9
-               . sphinx_1.7.9/bin/activate
+               /usr/bin/virtualenv sphinx_2.4.4
+               . sphinx_2.4.4/bin/activate
                pip install -r Documentation/sphinx/requirements.txt
 
        Can't build as 1 mandatory dependency is missing at ./scripts/sphinx-pre-install line 468.
index 87d0818..dc71933 100644 (file)
@@ -57,7 +57,7 @@ mcelog                 0.6                mcelog --version
 iptables               1.4.2              iptables -V
 openssl & libcrypto    1.0.0              openssl version
 bc                     1.06.95            bc --version
-Sphinx\ [#f1]_         1.3                sphinx-build --version
+Sphinx\ [#f1]_         1.7                sphinx-build --version
 ====================== =================  ========================================
 
 .. [#f1] Sphinx è necessario solo per produrre la documentazione del Kernel
index 951595c..23eac67 100644 (file)
@@ -26,7 +26,7 @@ reStructuredText文件可能包含包含来自源文件的结构化文档注释
 安装Sphinx
 ==========
 
-Documentation/ 下的ReST文件现在使用sphinx1.3或更高版本构建。
+Documentation/ 下的ReST文件现在使用sphinx1.7或更高版本构建。
 
 这有一个脚本可以检查Sphinx的依赖项。更多详细信息见
 :ref:`sphinx-pre-install_zh` 。
@@ -40,22 +40,19 @@ Documentation/ 下的ReST文件现在使用sphinx1.3或更高版本构建。
 
 .. note::
 
-   #) 低于1.5版本的Sphinx无法与Python的0.13.1或更高版本docutils一起正常工作。
-      如果您想使用这些版本,那么应该运行 ``pip install 'docutils==0.12'`` 。
-
    #) html输出建议使用RTD主题。根据Sphinx版本的不同,它应该用
       ``pip install sphinx_rtd_theme`` 单独安装。
 
    #) 一些ReST页面包含数学表达式。由于Sphinx的工作方式,这些表达式是使用 LaTeX
       编写的。它需要安装amsfonts和amsmath宏包,以便显示。
 
-总之,如您要安装Sphinx 1.7.9版本,应执行::
+总之,如您要安装Sphinx 2.4.4版本,应执行::
 
-       $ virtualenv sphinx_1.7.9
-       $ . sphinx_1.7.9/bin/activate
-       (sphinx_1.7.9) $ pip install -r Documentation/sphinx/requirements.txt
+       $ virtualenv sphinx_2.4.4
+       $ . sphinx_2.4.4/bin/activate
+       (sphinx_2.4.4) $ pip install -r Documentation/sphinx/requirements.txt
 
-在运行 ``. sphinx_1.7.9/bin/activate`` 之后,提示符将变化,以指示您正在使用新
+在运行 ``. sphinx_2.4.4/bin/activate`` 之后,提示符将变化,以指示您正在使用新
 环境。如果您打开了一个新的shell,那么在构建文档之前,您需要重新运行此命令以再
 次进入虚拟环境中。
 
@@ -71,7 +68,7 @@ Documentation/ 下的ReST文件现在使用sphinx1.3或更高版本构建。
 PDF和LaTeX构建
 --------------
 
-目前只有Sphinx 1.4及更高版本才支持这种构建。
+目前只有Sphinx 2.4及更高版本才支持这种构建。
 
 对于PDF和LaTeX输出,还需要 ``XeLaTeX`` 3.14159265版本。(译注:此版本号真实
 存在)
@@ -93,8 +90,8 @@ PDF和LaTeX构建
        You should run:
 
                sudo dnf install -y texlive-luatex85
-               /usr/bin/virtualenv sphinx_1.7.9
-               . sphinx_1.7.9/bin/activate
+               /usr/bin/virtualenv sphinx_2.4.4
+               . sphinx_2.4.4/bin/activate
                pip install -r Documentation/sphinx/requirements.txt
 
        Can't build as 1 mandatory dependency is missing at ./scripts/sphinx-pre-install line 468.
index c6a5bb2..8053ae4 100644 (file)
@@ -36,14 +36,14 @@ Linux内核管理风格
 每个人都认为管理者做决定,而且决策很重要。决定越大越痛苦,管理者就必须越高级。
 这很明显,但事实并非如此。
 
¸¸æ\88\8fç\9a\84å\90\8då­\97是 **避免** 做出决定。尤其是,如果有人告诉你“选择(a)或(b),
\9c\80é\87\8dè¦\81ç\9a\84是 **避免** 做出决定。尤其是,如果有人告诉你“选择(a)或(b),
 我们真的需要你来做决定”,你就是陷入麻烦的管理者。你管理的人比你更了解细节,
 所以如果他们来找你做技术决策,你完蛋了。你显然没有能力为他们做这个决定。
 
 (推论:如果你管理的人不比你更了解细节,你也会被搞砸,尽管原因完全不同。
 也就是说,你的工作是错的,他们应该管理你的才智)
 
\89\80以游æ\88\8fç\9a\84å\90\8då­\97是 **避免** 做出决定,至少是那些大而痛苦的决定。做一些小的
\89\80以æ\9c\80é\87\8dè¦\81ç\9a\84是 **避免** 做出决定,至少是那些大而痛苦的决定。做一些小的
 和非结果性的决定是很好的,并且使您看起来好像知道自己在做什么,所以内核管理者
 需要做的是将那些大的和痛苦的决定变成那些没有人真正关心的小事情。
 
index f9b50d1..0533c00 100644 (file)
@@ -2263,6 +2263,15 @@ L:       linux-iio@vger.kernel.org
 S:     Maintained
 F:     drivers/counter/microchip-tcb-capture.c
 
+ARM/MILBEAUT ARCHITECTURE
+M:     Taichi Sugaya <sugaya.taichi@socionext.com>
+M:     Takao Orito <orito.takao@socionext.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     arch/arm/boot/dts/milbeaut*
+F:     arch/arm/mach-milbeaut/
+N:     milbeaut
+
 ARM/MIOA701 MACHINE SUPPORT
 M:     Robert Jarzmik <robert.jarzmik@free.fr>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -2729,10 +2738,11 @@ S:      Maintained
 F:     drivers/memory/*emif*
 
 ARM/TEXAS INSTRUMENT KEYSTONE ARCHITECTURE
+M:     Nishanth Menon <nm@ti.com>
 M:     Santosh Shilimkar <ssantosh@kernel.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
 F:     arch/arm/boot/dts/keystone-*
 F:     arch/arm/mach-keystone/
 
@@ -3570,13 +3580,14 @@ L:      netdev@vger.kernel.org
 S:     Supported
 F:     drivers/net/ethernet/broadcom/b44.*
 
-BROADCOM B53 ETHERNET SWITCH DRIVER
+BROADCOM B53/SF2 ETHERNET SWITCH DRIVER
 M:     Florian Fainelli <f.fainelli@gmail.com>
 L:     netdev@vger.kernel.org
 L:     openwrt-devel@lists.openwrt.org (subscribers-only)
 S:     Supported
 F:     Documentation/devicetree/bindings/net/dsa/brcm,b53.yaml
 F:     drivers/net/dsa/b53/*
+F:     drivers/net/dsa/bcm_sf2*
 F:     include/linux/dsa/brcm.h
 F:     include/linux/platform_data/b53.h
 
@@ -3733,7 +3744,7 @@ F:        drivers/scsi/bnx2i/
 BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER
 M:     Ariel Elior <aelior@marvell.com>
 M:     Sudarsana Kalluru <skalluru@marvell.com>
-M:     GR-everest-linux-l2@marvell.com
+M:     Manish Chopra <manishc@marvell.com>
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     drivers/net/ethernet/broadcom/bnx2x/
@@ -10447,7 +10458,7 @@ F:      arch/riscv/include/uapi/asm/kvm*
 F:     arch/riscv/kvm/
 
 KERNEL VIRTUAL MACHINE for s390 (KVM/s390)
-M:     Christian Borntraeger <borntraeger@de.ibm.com>
+M:     Christian Borntraeger <borntraeger@linux.ibm.com>
 M:     Janosch Frank <frankja@linux.ibm.com>
 R:     David Hildenbrand <david@redhat.com>
 R:     Claudio Imbrenda <imbrenda@linux.ibm.com>
@@ -15595,7 +15606,7 @@ F:      drivers/scsi/qedi/
 
 QLOGIC QL4xxx ETHERNET DRIVER
 M:     Ariel Elior <aelior@marvell.com>
-M:     GR-everest-linux-l2@marvell.com
+M:     Manish Chopra <manishc@marvell.com>
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     drivers/net/ethernet/qlogic/qed/
@@ -16575,7 +16586,7 @@ F:      drivers/video/fbdev/savage/
 S390
 M:     Heiko Carstens <hca@linux.ibm.com>
 M:     Vasily Gorbik <gor@linux.ibm.com>
-M:     Christian Borntraeger <borntraeger@de.ibm.com>
+M:     Christian Borntraeger <borntraeger@linux.ibm.com>
 R:     Alexander Gordeev <agordeev@linux.ibm.com>
 L:     linux-s390@vger.kernel.org
 S:     Supported
@@ -18485,6 +18496,7 @@ F:      include/uapi/linux/pkt_sched.h
 F:     include/uapi/linux/tc_act/
 F:     include/uapi/linux/tc_ematch/
 F:     net/sched/
+F:     tools/testing/selftests/tc-testing
 
 TC90522 MEDIA DRIVER
 M:     Akihiro Tsukada <tskd08@gmail.com>
@@ -19033,11 +19045,12 @@ F:    drivers/mmc/host/tifm_sd.c
 F:     include/linux/tifm.h
 
 TI KEYSTONE MULTICORE NAVIGATOR DRIVERS
+M:     Nishanth Menon <nm@ti.com>
 M:     Santosh Shilimkar <ssantosh@kernel.org>
 L:     linux-kernel@vger.kernel.org
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
 F:     drivers/soc/ti/*
 
 TI LM49xxx FAMILY ASoC CODEC DRIVERS
@@ -20319,7 +20332,8 @@ F:      arch/x86/include/asm/vmware.h
 F:     arch/x86/kernel/cpu/vmware.c
 
 VMWARE PVRDMA DRIVER
-M:     Adit Ranadive <aditr@vmware.com>
+M:     Bryan Tan <bryantan@vmware.com>
+M:     Vishnu Dasa <vdasa@vmware.com>
 M:     VMware PV-Drivers <pv-drivers@vmware.com>
 L:     linux-rdma@vger.kernel.org
 S:     Maintained
index 9e12c14..0a6ecc8 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,8 +2,8 @@
 VERSION = 5
 PATCHLEVEL = 16
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
-NAME = Trick or Treat
+EXTRAVERSION = -rc3
+NAME = Gobble Gobble
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
index 26b8ed1..d3c4ab2 100644 (file)
@@ -991,6 +991,16 @@ config HAVE_ARCH_COMPAT_MMAP_BASES
          and vice-versa 32-bit applications to call 64-bit mmap().
          Required for applications doing different bitness syscalls.
 
+config PAGE_SIZE_LESS_THAN_64KB
+       def_bool y
+       depends on !ARM64_64K_PAGES
+       depends on !IA64_PAGE_SIZE_64KB
+       depends on !PAGE_SIZE_64KB
+       depends on !PARISC_PAGE_SIZE_64KB
+       depends on !PPC_64K_PAGES
+       depends on !PPC_256K_PAGES
+       depends on !PAGE_SIZE_256KB
+
 # This allows to use a set of generic functions to determine mmap base
 # address by giving priority to top-down scheme only if the process
 # is not in legacy mode (compat task, unlimited stack size or
index e4a041c..ca5a322 100644 (file)
 556    common  landlock_restrict_self          sys_landlock_restrict_self
 # 557 reserved for memfd_secret
 558    common  process_mrelease                sys_process_mrelease
+559    common  futex_waitv                     sys_futex_waitv
index e8c2c74..e201b4b 100644 (file)
@@ -36,7 +36,6 @@ void __flush_dcache_page(phys_addr_t paddr, unsigned long vaddr);
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 
 void flush_dcache_page(struct page *page);
-void flush_dcache_folio(struct folio *folio);
 
 void dma_cache_wback_inv(phys_addr_t start, unsigned long sz);
 void dma_cache_inv(phys_addr_t start, unsigned long sz);
index f0f9e8b..c2724d9 100644 (file)
@@ -1463,6 +1463,7 @@ config HIGHMEM
        bool "High Memory Support"
        depends on MMU
        select KMAP_LOCAL
+       select KMAP_LOCAL_NON_LINEAR_PTE_ARRAY
        help
          The address space of ARM processors is only 4 Gigabytes large
          and it has to accommodate user address space, kernel address
index 3b60297..9e01dbc 100644 (file)
                        #address-cells = <3>;
                        #interrupt-cells = <1>;
                        #size-cells = <2>;
-                       interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+                       interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "pcie", "msi";
                        interrupt-map-mask = <0x0 0x0 0x0 0x7>;
                        interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 143
+                                                       IRQ_TYPE_LEVEL_HIGH>,
+                                       <0 0 0 2 &gicv2 GIC_SPI 144
+                                                       IRQ_TYPE_LEVEL_HIGH>,
+                                       <0 0 0 3 &gicv2 GIC_SPI 145
+                                                       IRQ_TYPE_LEVEL_HIGH>,
+                                       <0 0 0 4 &gicv2 GIC_SPI 146
                                                        IRQ_TYPE_LEVEL_HIGH>;
                        msi-controller;
                        msi-parent = <&pcie0>;
index d4f3550..f69d2af 100644 (file)
 
                        gpio-controller;
                        #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
                };
 
                pcie0: pcie@12000 {
        i2c0: i2c@18009000 {
                compatible = "brcm,iproc-i2c";
                reg = <0x18009000 0x50>;
-               interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
                clock-frequency = <100000>;
index e68fb87..5e56288 100644 (file)
@@ -290,7 +290,6 @@ extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr
  */
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 extern void flush_dcache_page(struct page *);
-void flush_dcache_folio(struct folio *folio);
 
 #define ARCH_IMPLEMENTS_FLUSH_KERNEL_VMAP_RANGE 1
 static inline void flush_kernel_vmap_range(void *addr, int size)
index fc2608b..18f0119 100644 (file)
@@ -33,7 +33,7 @@ extern void __iomem *sdr_ctl_base_addr;
 u32 socfpga_sdram_self_refresh(u32 sdr_base);
 extern unsigned int socfpga_sdram_self_refresh_sz;
 
-extern char secondary_trampoline, secondary_trampoline_end;
+extern char secondary_trampoline[], secondary_trampoline_end[];
 
 extern unsigned long socfpga_cpu1start_addr;
 
index fbb80b8..201191c 100644 (file)
 
 static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
-       int trampoline_size = &secondary_trampoline_end - &secondary_trampoline;
+       int trampoline_size = secondary_trampoline_end - secondary_trampoline;
 
        if (socfpga_cpu1start_addr) {
                /* This will put CPU #1 into reset. */
                writel(RSTMGR_MPUMODRST_CPU1,
                       rst_manager_base_addr + SOCFPGA_RSTMGR_MODMPURST);
 
-               memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size);
+               memcpy(phys_to_virt(0), secondary_trampoline, trampoline_size);
 
                writel(__pa_symbol(secondary_startup),
                       sys_manager_base_addr + (socfpga_cpu1start_addr & 0x000000ff));
@@ -45,12 +45,12 @@ static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle)
 
 static int socfpga_a10_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
-       int trampoline_size = &secondary_trampoline_end - &secondary_trampoline;
+       int trampoline_size = secondary_trampoline_end - secondary_trampoline;
 
        if (socfpga_cpu1start_addr) {
                writel(RSTMGR_MPUMODRST_CPU1, rst_manager_base_addr +
                       SOCFPGA_A10_RSTMGR_MODMPURST);
-               memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size);
+               memcpy(phys_to_virt(0), secondary_trampoline, trampoline_size);
 
                writel(__pa_symbol(secondary_startup),
                       sys_manager_base_addr + (socfpga_cpu1start_addr & 0x00000fff));
index 3e47273..a960c0b 100644 (file)
                        pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>;
                        phys = <&ufs_0_phy>;
                        phy-names = "ufs-phy";
-                       samsung,sysreg = <&syscon_fsys2>;
-                       samsung,ufs-shareability-reg-offset = <0x710>;
+                       samsung,sysreg = <&syscon_fsys2 0x710>;
                        status = "disabled";
                };
        };
index 347b0cc..1494cfa 100644 (file)
 
 #define HAVE_FUNCTION_GRAPH_FP_TEST
 
+/*
+ * HAVE_FUNCTION_GRAPH_RET_ADDR_PTR means that the architecture can provide a
+ * "return address pointer" which can be used to uniquely identify a return
+ * address which has been overwritten.
+ *
+ * On arm64 we use the address of the caller's frame record, which remains the
+ * same for the lifetime of the instrumented function, unlike the return
+ * address in the LR.
+ */
+#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
+
 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
 #define ARCH_SUPPORTS_FTRACE_OPS 1
 #else
index 8433a20..2372244 100644 (file)
@@ -76,7 +76,7 @@ static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t ptep,
 static inline void
 pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
 {
-       VM_BUG_ON(mm != &init_mm);
+       VM_BUG_ON(mm && mm != &init_mm);
        __pmd_populate(pmdp, __pa(ptep), PMD_TYPE_TABLE | PMD_TABLE_UXN);
 }
 
index a4e046e..6564a01 100644 (file)
@@ -47,9 +47,6 @@ struct stack_info {
  * @prev_type:   The type of stack this frame record was on, or a synthetic
  *               value of STACK_TYPE_UNKNOWN. This is used to detect a
  *               transition from one stack to another.
- *
- * @graph:       When FUNCTION_GRAPH_TRACER is selected, holds the index of a
- *               replacement lr value in the ftrace graph stack.
  */
 struct stackframe {
        unsigned long fp;
@@ -57,9 +54,6 @@ struct stackframe {
        DECLARE_BITMAP(stacks_done, __NR_STACK_TYPES);
        unsigned long prev_fp;
        enum stack_type prev_type;
-#ifdef CONFIG_FUNCTION_GRAPH_TRACER
-       int graph;
-#endif
 #ifdef CONFIG_KRETPROBES
        struct llist_node *kr_cur;
 #endif
index 6e2e0b7..3a5ff5e 100644 (file)
@@ -281,12 +281,22 @@ do {                                                                      \
        (x) = (__force __typeof__(*(ptr)))__gu_val;                     \
 } while (0)
 
+/*
+ * We must not call into the scheduler between uaccess_ttbr0_enable() and
+ * uaccess_ttbr0_disable(). As `x` and `ptr` could contain blocking functions,
+ * we must evaluate these outside of the critical section.
+ */
 #define __raw_get_user(x, ptr, err)                                    \
 do {                                                                   \
+       __typeof__(*(ptr)) __user *__rgu_ptr = (ptr);                   \
+       __typeof__(x) __rgu_val;                                        \
        __chk_user_ptr(ptr);                                            \
+                                                                       \
        uaccess_ttbr0_enable();                                         \
-       __raw_get_mem("ldtr", x, ptr, err);                             \
+       __raw_get_mem("ldtr", __rgu_val, __rgu_ptr, err);               \
        uaccess_ttbr0_disable();                                        \
+                                                                       \
+       (x) = __rgu_val;                                                \
 } while (0)
 
 #define __get_user_error(x, ptr, err)                                  \
@@ -310,14 +320,22 @@ do {                                                                      \
 
 #define get_user       __get_user
 
+/*
+ * We must not call into the scheduler between __uaccess_enable_tco_async() and
+ * __uaccess_disable_tco_async(). As `dst` and `src` may contain blocking
+ * functions, we must evaluate these outside of the critical section.
+ */
 #define __get_kernel_nofault(dst, src, type, err_label)                        \
 do {                                                                   \
+       __typeof__(dst) __gkn_dst = (dst);                              \
+       __typeof__(src) __gkn_src = (src);                              \
        int __gkn_err = 0;                                              \
                                                                        \
        __uaccess_enable_tco_async();                                   \
-       __raw_get_mem("ldr", *((type *)(dst)),                          \
-                     (__force type *)(src), __gkn_err);                \
+       __raw_get_mem("ldr", *((type *)(__gkn_dst)),                    \
+                     (__force type *)(__gkn_src), __gkn_err);          \
        __uaccess_disable_tco_async();                                  \
+                                                                       \
        if (unlikely(__gkn_err))                                        \
                goto err_label;                                         \
 } while (0)
@@ -351,11 +369,19 @@ do {                                                                      \
        }                                                               \
 } while (0)
 
+/*
+ * We must not call into the scheduler between uaccess_ttbr0_enable() and
+ * uaccess_ttbr0_disable(). As `x` and `ptr` could contain blocking functions,
+ * we must evaluate these outside of the critical section.
+ */
 #define __raw_put_user(x, ptr, err)                                    \
 do {                                                                   \
-       __chk_user_ptr(ptr);                                            \
+       __typeof__(*(ptr)) __user *__rpu_ptr = (ptr);                   \
+       __typeof__(*(ptr)) __rpu_val = (x);                             \
+       __chk_user_ptr(__rpu_ptr);                                      \
+                                                                       \
        uaccess_ttbr0_enable();                                         \
-       __raw_put_mem("sttr", x, ptr, err);                             \
+       __raw_put_mem("sttr", __rpu_val, __rpu_ptr, err);               \
        uaccess_ttbr0_disable();                                        \
 } while (0)
 
@@ -380,14 +406,22 @@ do {                                                                      \
 
 #define put_user       __put_user
 
+/*
+ * We must not call into the scheduler between __uaccess_enable_tco_async() and
+ * __uaccess_disable_tco_async(). As `dst` and `src` may contain blocking
+ * functions, we must evaluate these outside of the critical section.
+ */
 #define __put_kernel_nofault(dst, src, type, err_label)                        \
 do {                                                                   \
+       __typeof__(dst) __pkn_dst = (dst);                              \
+       __typeof__(src) __pkn_src = (src);                              \
        int __pkn_err = 0;                                              \
                                                                        \
        __uaccess_enable_tco_async();                                   \
-       __raw_put_mem("str", *((type *)(src)),                          \
-                     (__force type *)(dst), __pkn_err);                \
+       __raw_put_mem("str", *((type *)(__pkn_src)),                    \
+                     (__force type *)(__pkn_dst), __pkn_err);          \
        __uaccess_disable_tco_async();                                  \
+                                                                       \
        if (unlikely(__pkn_err))                                        \
                goto err_label;                                         \
 } while(0)
index fc62dfe..4506c4a 100644 (file)
@@ -244,8 +244,6 @@ void arch_ftrace_update_code(int command)
  * on the way back to parent. For this purpose, this function is called
  * in _mcount() or ftrace_caller() to replace return address (*parent) on
  * the call stack to return_to_handler.
- *
- * Note that @frame_pointer is used only for sanity check later.
  */
 void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent,
                           unsigned long frame_pointer)
@@ -263,8 +261,10 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent,
         */
        old = *parent;
 
-       if (!function_graph_enter(old, self_addr, frame_pointer, NULL))
+       if (!function_graph_enter(old, self_addr, frame_pointer,
+           (void *)frame_pointer)) {
                *parent = return_hooker;
+       }
 }
 
 #ifdef CONFIG_DYNAMIC_FTRACE
index c30624f..94f83cd 100644 (file)
@@ -38,9 +38,6 @@ void start_backtrace(struct stackframe *frame, unsigned long fp,
 {
        frame->fp = fp;
        frame->pc = pc;
-#ifdef CONFIG_FUNCTION_GRAPH_TRACER
-       frame->graph = 0;
-#endif
 #ifdef CONFIG_KRETPROBES
        frame->kr_cur = NULL;
 #endif
@@ -116,20 +113,23 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
        frame->prev_fp = fp;
        frame->prev_type = info.type;
 
+       frame->pc = ptrauth_strip_insn_pac(frame->pc);
+
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
        if (tsk->ret_stack &&
-               (ptrauth_strip_insn_pac(frame->pc) == (unsigned long)return_to_handler)) {
-               struct ftrace_ret_stack *ret_stack;
+               (frame->pc == (unsigned long)return_to_handler)) {
+               unsigned long orig_pc;
                /*
                 * This is a case where function graph tracer has
                 * modified a return address (LR) in a stack frame
                 * to hook a function return.
                 * So replace it to an original value.
                 */
-               ret_stack = ftrace_graph_get_ret_stack(tsk, frame->graph++);
-               if (WARN_ON_ONCE(!ret_stack))
+               orig_pc = ftrace_graph_ret_addr(tsk, NULL, frame->pc,
+                                               (void *)frame->fp);
+               if (WARN_ON_ONCE(frame->pc == orig_pc))
                        return -EINVAL;
-               frame->pc = ret_stack->ret;
+               frame->pc = orig_pc;
        }
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 #ifdef CONFIG_KRETPROBES
@@ -137,8 +137,6 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
                frame->pc = kretprobe_find_ret_addr(tsk, (void *)frame->fp, &frame->kr_cur);
 #endif
 
-       frame->pc = ptrauth_strip_insn_pac(frame->pc);
-
        return 0;
 }
 NOKPROBE_SYMBOL(unwind_frame);
index 2f03cbf..e4727dc 100644 (file)
@@ -223,7 +223,14 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
                r = 1;
                break;
        case KVM_CAP_NR_VCPUS:
-               r = num_online_cpus();
+               /*
+                * ARM64 treats KVM_CAP_NR_CPUS differently from all other
+                * architectures, as it does not always bound it to
+                * KVM_CAP_MAX_VCPUS. It should not matter much because
+                * this is just an advisory value.
+                */
+               r = min_t(unsigned int, num_online_cpus(),
+                         kvm_arm_default_max_vcpus());
                break;
        case KVM_CAP_MAX_VCPUS:
        case KVM_CAP_MAX_VCPU_ID:
diff --git a/arch/hexagon/include/asm/timer-regs.h b/arch/hexagon/include/asm/timer-regs.h
deleted file mode 100644 (file)
index ee6c614..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Timer support for Hexagon
- *
- * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- */
-
-#ifndef _ASM_TIMER_REGS_H
-#define _ASM_TIMER_REGS_H
-
-/*  This stuff should go into a platform specific file  */
-#define TCX0_CLK_RATE          19200
-#define TIMER_ENABLE           0
-#define TIMER_CLR_ON_MATCH     1
-
-/*
- * 8x50 HDD Specs 5-8.  Simulator co-sim not fixed until
- * release 1.1, and then it's "adjustable" and probably not defaulted.
- */
-#define RTOS_TIMER_INT         3
-#ifdef CONFIG_HEXAGON_COMET
-#define RTOS_TIMER_REGS_ADDR   0xAB000000UL
-#endif
-#define SLEEP_CLK_RATE         32000
-
-#endif
index 8d4ec76..dfe69e1 100644 (file)
@@ -7,11 +7,10 @@
 #define _ASM_TIMEX_H
 
 #include <asm-generic/timex.h>
-#include <asm/timer-regs.h>
 #include <asm/hexagon_vm.h>
 
 /* Using TCX0 as our clock.  CLOCK_TICK_RATE scheduled to be removed. */
-#define CLOCK_TICK_RATE              TCX0_CLK_RATE
+#define CLOCK_TICK_RATE              19200
 
 #define ARCH_HAS_READ_CURRENT_TIMER
 
diff --git a/arch/hexagon/kernel/.gitignore b/arch/hexagon/kernel/.gitignore
new file mode 100644 (file)
index 0000000..c5f676c
--- /dev/null
@@ -0,0 +1 @@
+vmlinux.lds
index feffe52..febc957 100644 (file)
 #include <linux/of_irq.h>
 #include <linux/module.h>
 
-#include <asm/timer-regs.h>
 #include <asm/hexagon_vm.h>
 
+#define TIMER_ENABLE           BIT(0)
+
 /*
  * For the clocksource we need:
  *     pcycle frequency (600MHz)
@@ -33,6 +34,13 @@ cycles_t     pcycle_freq_mhz;
 cycles_t       thread_freq_mhz;
 cycles_t       sleep_clk_freq;
 
+/*
+ * 8x50 HDD Specs 5-8.  Simulator co-sim not fixed until
+ * release 1.1, and then it's "adjustable" and probably not defaulted.
+ */
+#define RTOS_TIMER_INT         3
+#define RTOS_TIMER_REGS_ADDR   0xAB000000UL
+
 static struct resource rtos_timer_resources[] = {
        {
                .start  = RTOS_TIMER_REGS_ADDR,
@@ -80,7 +88,7 @@ static int set_next_event(unsigned long delta, struct clock_event_device *evt)
        iowrite32(0, &rtos_timer->clear);
 
        iowrite32(delta, &rtos_timer->match);
-       iowrite32(1 << TIMER_ENABLE, &rtos_timer->enable);
+       iowrite32(TIMER_ENABLE, &rtos_timer->enable);
        return 0;
 }
 
index d35d69d..55f7539 100644 (file)
@@ -27,6 +27,7 @@ void __raw_readsw(const void __iomem *addr, void *data, int len)
                *dst++ = *src;
 
 }
+EXPORT_SYMBOL(__raw_readsw);
 
 /*
  * __raw_writesw - read words a short at a time
@@ -47,6 +48,7 @@ void __raw_writesw(void __iomem *addr, const void *data, int len)
 
 
 }
+EXPORT_SYMBOL(__raw_writesw);
 
 /*  Pretty sure len is pre-adjusted for the length of the access already */
 void __raw_readsl(const void __iomem *addr, void *data, int len)
@@ -62,6 +64,7 @@ void __raw_readsl(const void __iomem *addr, void *data, int len)
 
 
 }
+EXPORT_SYMBOL(__raw_readsl);
 
 void __raw_writesl(void __iomem *addr, const void *data, int len)
 {
@@ -76,3 +79,4 @@ void __raw_writesl(void __iomem *addr, const void *data, int len)
 
 
 }
+EXPORT_SYMBOL(__raw_writesl);
index 6fea184..707ae12 100644 (file)
 446    common  landlock_restrict_self          sys_landlock_restrict_self
 # 447 reserved for memfd_secret
 448    common  process_mrelease                sys_process_mrelease
+449    common  futex_waitv                     sys_futex_waitv
index 8ab4662..1ac55e7 100644 (file)
@@ -250,7 +250,6 @@ static inline void __flush_page_to_ram(void *vaddr)
 
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 #define flush_dcache_page(page)                __flush_page_to_ram(page_address(page))
-void flush_dcache_folio(struct folio *folio);
 #define flush_dcache_mmap_lock(mapping)                do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)      do { } while (0)
 #define flush_icache_page(vma, page)   __flush_page_to_ram(page_address(page))
index 7976dff..45bc32a 100644 (file)
 446    common  landlock_restrict_self          sys_landlock_restrict_self
 # 447 reserved for memfd_secret
 448    common  process_mrelease                sys_process_mrelease
+449    common  futex_waitv                     sys_futex_waitv
index 99058a6..34d6458 100644 (file)
@@ -1145,7 +1145,7 @@ asmlinkage void set_esp0(unsigned long ssp)
  */
 asmlinkage void fpsp040_die(void)
 {
-       force_fatal_sig(SIGSEGV);
+       force_exit_sig(SIGSEGV);
 }
 
 #ifdef CONFIG_M68KFPU_EMU
index 6b0e113..2204bde 100644 (file)
 446    common  landlock_restrict_self          sys_landlock_restrict_self
 # 447 reserved for memfd_secret
 448    common  process_mrelease                sys_process_mrelease
+449    common  futex_waitv                     sys_futex_waitv
index de60ad1..0215dc1 100644 (file)
@@ -3097,7 +3097,7 @@ config STACKTRACE_SUPPORT
 config PGTABLE_LEVELS
        int
        default 4 if PAGE_SIZE_4KB && MIPS_VA_BITS_48
-       default 3 if 64BIT && !PAGE_SIZE_64KB
+       default 3 if 64BIT && (!PAGE_SIZE_64KB || MIPS_VA_BITS_48)
        default 2
 
 config MIPS_AUTO_PFN_OFFSET
index 5a3e325..1c91064 100644 (file)
@@ -381,6 +381,12 @@ void clk_disable(struct clk *clk)
 
 EXPORT_SYMBOL(clk_disable);
 
+struct clk *clk_get_parent(struct clk *clk)
+{
+       return NULL;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
 unsigned long clk_get_rate(struct clk *clk)
 {
        if (!clk)
index 2861a05..f27cf31 100644 (file)
@@ -52,7 +52,7 @@ endif
 
 vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o
 
-vmlinuzobjs-$(CONFIG_KERNEL_ZSTD) += $(obj)/bswapdi.o
+vmlinuzobjs-$(CONFIG_KERNEL_ZSTD) += $(obj)/bswapdi.o $(obj)/ashldi3.o
 
 targets := $(notdir $(vmlinuzobjs-y))
 
index a3aa22c..a07a5ed 100644 (file)
@@ -75,7 +75,7 @@ static unsigned int __init gen_fdt_mem_array(
 __init int yamon_dt_append_memory(void *fdt,
                                  const struct yamon_mem_region *regions)
 {
-       unsigned long phys_memsize, memsize;
+       unsigned long phys_memsize = 0, memsize;
        __be32 mem_array[2 * MAX_MEM_ARRAY_ENTRIES];
        unsigned int mem_entries;
        int i, err, mem_off;
index f207388..b3dc9c5 100644 (file)
@@ -61,8 +61,6 @@ static inline void flush_dcache_page(struct page *page)
                SetPageDcacheDirty(page);
 }
 
-void flush_dcache_folio(struct folio *folio);
-
 #define flush_dcache_mmap_lock(mapping)                do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)      do { } while (0)
 
index ac0e2cf..24a529c 100644 (file)
@@ -1734,8 +1734,6 @@ static inline void decode_cpucfg(struct cpuinfo_mips *c)
 
 static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
 {
-       decode_configs(c);
-
        /* All Loongson processors covered here define ExcCode 16 as GSExc. */
        c->options |= MIPS_CPU_GSEXCEX;
 
@@ -1796,6 +1794,8 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
                panic("Unknown Loongson Processor ID!");
                break;
        }
+
+       decode_configs(c);
 }
 #else
 static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) { }
index 376a6e2..9f47a88 100644 (file)
@@ -185,7 +185,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                seq_puts(m, " tx39_cache");
        if (cpu_has_octeon_cache)
                seq_puts(m, " octeon_cache");
-       if (cpu_has_fpu)
+       if (raw_cpu_has_fpu)
                seq_puts(m, " fpu");
        if (cpu_has_32fpr)
                seq_puts(m, " 32fpr");
index 70e32de..72d02d3 100644 (file)
 446    n32     landlock_restrict_self          sys_landlock_restrict_self
 # 447 reserved for memfd_secret
 448    n32     process_mrelease                sys_process_mrelease
+449    n32     futex_waitv                     sys_futex_waitv
index 1ca7bc3..e2c481f 100644 (file)
 446    n64     landlock_restrict_self          sys_landlock_restrict_self
 # 447 reserved for memfd_secret
 448    n64     process_mrelease                sys_process_mrelease
+449    n64     futex_waitv                     sys_futex_waitv
index a61c35e..3714c97 100644 (file)
 446    o32     landlock_restrict_self          sys_landlock_restrict_self
 # 447 reserved for memfd_secret
 448    o32     process_mrelease                sys_process_mrelease
+449    o32     futex_waitv                     sys_futex_waitv
index 562aa87..aa20d07 100644 (file)
@@ -1067,7 +1067,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
                r = 1;
                break;
        case KVM_CAP_NR_VCPUS:
-               r = num_online_cpus();
+               r = min_t(unsigned int, num_online_cpus(), KVM_MAX_VCPUS);
                break;
        case KVM_CAP_MAX_VCPUS:
                r = KVM_MAX_VCPUS;
index dd819e3..4916ccc 100644 (file)
@@ -158,6 +158,12 @@ void clk_deactivate(struct clk *clk)
 }
 EXPORT_SYMBOL(clk_deactivate);
 
+struct clk *clk_get_parent(struct clk *clk)
+{
+       return NULL;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
 static inline u32 get_counter_resolution(void)
 {
        u32 res;
index 3fc0bb7..c2a222e 100644 (file)
@@ -27,7 +27,6 @@ void flush_cache_vunmap(unsigned long start, unsigned long end);
 
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 void flush_dcache_page(struct page *page);
-void flush_dcache_folio(struct folio *folio);
 void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
                       unsigned long vaddr, void *dst, void *src, int len);
 void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
index 1999561..d0b71dd 100644 (file)
@@ -29,7 +29,6 @@ extern void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr,
        unsigned long pfn);
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 void flush_dcache_page(struct page *page);
-void flush_dcache_folio(struct folio *folio);
 
 extern void flush_icache_range(unsigned long start, unsigned long end);
 extern void flush_icache_page(struct vm_area_struct *vma, struct page *page);
index d6fd8fa..53061cb 100644 (file)
@@ -231,6 +231,7 @@ CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC_T10DIF=y
 CONFIG_FONTS=y
+CONFIG_PRINTK_TIME=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_MEMORY_INIT=y
index 7085df0..6d13ae2 100644 (file)
@@ -3,38 +3,19 @@
  * Copyright (C) 1999 Hewlett-Packard (Frank Rowand)
  * Copyright (C) 1999 Philipp Rumpf <prumpf@tux.org>
  * Copyright (C) 1999 SuSE GmbH
+ * Copyright (C) 2021 Helge Deller <deller@gmx.de>
  */
 
 #ifndef _PARISC_ASSEMBLY_H
 #define _PARISC_ASSEMBLY_H
 
-#define CALLEE_FLOAT_FRAME_SIZE        80
-
 #ifdef CONFIG_64BIT
-#define LDREG  ldd
-#define STREG  std
-#define LDREGX  ldd,s
-#define LDREGM ldd,mb
-#define STREGM std,ma
-#define SHRREG shrd
-#define SHLREG shld
-#define ANDCM   andcm,*
-#define        COND(x) * ## x
 #define RP_OFFSET      16
 #define FRAME_SIZE     128
 #define CALLEE_REG_FRAME_SIZE  144
 #define REG_SZ         8
 #define ASM_ULONG_INSN .dword
 #else  /* CONFIG_64BIT */
-#define LDREG  ldw
-#define STREG  stw
-#define LDREGX  ldwx,s
-#define LDREGM ldwm
-#define STREGM stwm
-#define SHRREG shr
-#define SHLREG shlw
-#define ANDCM   andcm
-#define COND(x)        x
 #define RP_OFFSET      20
 #define FRAME_SIZE     64
 #define CALLEE_REG_FRAME_SIZE  128
@@ -45,6 +26,7 @@
 /* Frame alignment for 32- and 64-bit */
 #define FRAME_ALIGN     64
 
+#define CALLEE_FLOAT_FRAME_SIZE        80
 #define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE)
 
 #ifdef CONFIG_PA20
 
 #ifdef __ASSEMBLY__
 
+#ifdef CONFIG_64BIT
+#define LDREG  ldd
+#define STREG  std
+#define LDREGX  ldd,s
+#define LDREGM ldd,mb
+#define STREGM std,ma
+#define SHRREG shrd
+#define SHLREG shld
+#define ANDCM   andcm,*
+#define        COND(x) * ## x
+#else  /* CONFIG_64BIT */
+#define LDREG  ldw
+#define STREG  stw
+#define LDREGX  ldwx,s
+#define LDREGM ldwm
+#define STREGM stwm
+#define SHRREG shr
+#define SHLREG shlw
+#define ANDCM   andcm
+#define COND(x)        x
+#endif
+
 #ifdef CONFIG_64BIT
 /* the 64-bit pa gnu assembler unfortunately defaults to .level 1.1 or 2.0 so
  * work around that for now... */
        extrd,u \r, 63-(\sa), 64-(\sa), \t
        .endm
 
+       /* Extract unsigned for 32- and 64-bit
+        * The extru instruction leaves the most significant 32 bits of the
+        * target register in an undefined state on PA 2.0 systems. */
+       .macro extru_safe r, p, len, t
+#ifdef CONFIG_64BIT
+       extrd,u \r, 32+(\p), \len, \t
+#else
+       extru   \r, \p, \len, \t
+#endif
+       .endm
+
        /* load 32-bit 'value' into 'reg' compensating for the ldil
         * sign-extension when running in wide mode.
         * WARNING!! neither 'value' nor 'reg' can be expressions
index da0cd4b..859b8a3 100644 (file)
@@ -50,7 +50,6 @@ void invalidate_kernel_vmap_range(void *vaddr, int size);
 
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 void flush_dcache_page(struct page *page);
-void flush_dcache_folio(struct folio *folio);
 
 #define flush_dcache_mmap_lock(mapping)                xa_lock_irq(&mapping->i_pages)
 #define flush_dcache_mmap_unlock(mapping)      xa_unlock_irq(&mapping->i_pages)
index 7efb1aa..af2a598 100644 (file)
@@ -5,6 +5,7 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/types.h>
+#include <linux/stringify.h>
 #include <asm/assembly.h>
 
 #define JUMP_LABEL_NOP_SIZE 4
index 4b9e3d7..2b3010a 100644 (file)
@@ -2,7 +2,7 @@
 #ifndef _ASM_PARISC_RT_SIGFRAME_H
 #define _ASM_PARISC_RT_SIGFRAME_H
 
-#define SIGRETURN_TRAMP 3
+#define SIGRETURN_TRAMP 4
 #define SIGRESTARTBLOCK_TRAMP 5 
 #define TRAMP_SIZE (SIGRETURN_TRAMP + SIGRESTARTBLOCK_TRAMP)
 
index 88c188a..6e9cdb2 100644 (file)
         */
        .macro          L2_ptep pmd,pte,index,va,fault
 #if CONFIG_PGTABLE_LEVELS == 3
-       extru           \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index
+       extru_safe      \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index
 #else
-# if defined(CONFIG_64BIT)
-       extrd,u         \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
-  #else
-  # if PAGE_SIZE > 4096
-       extru           \va,31-ASM_PGDIR_SHIFT,32-ASM_PGDIR_SHIFT,\index
-  # else
-       extru           \va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
-  # endif
-# endif
+       extru_safe      \va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
 #endif
        dep             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
 #if CONFIG_PGTABLE_LEVELS < 3
        bb,>=,n         \pmd,_PxD_PRESENT_BIT,\fault
        dep             %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
        SHLREG          \pmd,PxD_VALUE_SHIFT,\pmd
-       extru           \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
+       extru_safe      \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
        dep             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
        shladd          \index,BITS_PER_PTE_ENTRY,\pmd,\pmd /* pmd is now pte */
        .endm
index bbfe23c..46b1050 100644 (file)
@@ -288,21 +288,22 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
           already in userspace. The first words of tramp are used to
           save the previous sigrestartblock trampoline that might be
           on the stack. We start the sigreturn trampoline at 
-          SIGRESTARTBLOCK_TRAMP. */
+          SIGRESTARTBLOCK_TRAMP+X. */
        err |= __put_user(in_syscall ? INSN_LDI_R25_1 : INSN_LDI_R25_0,
                        &frame->tramp[SIGRESTARTBLOCK_TRAMP+0]);
-       err |= __put_user(INSN_BLE_SR2_R0, 
+       err |= __put_user(INSN_LDI_R20, 
                        &frame->tramp[SIGRESTARTBLOCK_TRAMP+1]);
-       err |= __put_user(INSN_LDI_R20,
+       err |= __put_user(INSN_BLE_SR2_R0, 
                        &frame->tramp[SIGRESTARTBLOCK_TRAMP+2]);
+       err |= __put_user(INSN_NOP, &frame->tramp[SIGRESTARTBLOCK_TRAMP+3]);
 
-       start = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP+0];
-       end = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP+3];
+       start = (unsigned long) &frame->tramp[0];
+       end = (unsigned long) &frame->tramp[TRAMP_SIZE];
        flush_user_dcache_range_asm(start, end);
        flush_user_icache_range_asm(start, end);
 
        /* TRAMP Words 0-4, Length 5 = SIGRESTARTBLOCK_TRAMP
-        * TRAMP Words 5-7, Length 3 = SIGRETURN_TRAMP
+        * TRAMP Words 5-9, Length 4 = SIGRETURN_TRAMP
         * So the SIGRETURN_TRAMP is at the end of SIGRESTARTBLOCK_TRAMP
         */
        rp = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP];
index a5bdbb5..f166250 100644 (file)
@@ -36,7 +36,7 @@ struct compat_regfile {
         compat_int_t rf_sar;
 };
 
-#define COMPAT_SIGRETURN_TRAMP 3
+#define COMPAT_SIGRETURN_TRAMP 4
 #define COMPAT_SIGRESTARTBLOCK_TRAMP 5
 #define COMPAT_TRAMP_SIZE (COMPAT_SIGRETURN_TRAMP + \
                                COMPAT_SIGRESTARTBLOCK_TRAMP)
index 4fb3b6a..d2497b3 100644 (file)
@@ -566,7 +566,7 @@ lws_compare_and_swap:
        ldo     R%lws_lock_start(%r20), %r28
 
        /* Extract eight bits from r26 and hash lock (Bits 3-11) */
-       extru  %r26, 28, 8, %r20
+       extru_safe  %r26, 28, 8, %r20
 
        /* Find lock to use, the hash is either one of 0 to
           15, multiplied by 16 (keep it 16-byte aligned)
@@ -751,7 +751,7 @@ cas2_lock_start:
        ldo     R%lws_lock_start(%r20), %r28
 
        /* Extract eight bits from r26 and hash lock (Bits 3-11) */
-       extru  %r26, 28, 8, %r20
+       extru_safe  %r26, 28, 8, %r20
 
        /* Find lock to use, the hash is either one of 0 to
           15, multiplied by 16 (keep it 16-byte aligned)
index bf751e0..358c000 100644 (file)
 446    common  landlock_restrict_self          sys_landlock_restrict_self
 # 447 reserved for memfd_secret
 448    common  process_mrelease                sys_process_mrelease
+449    common  futex_waitv                     sys_futex_waitv
index 3d208af..2769eb9 100644 (file)
@@ -57,8 +57,6 @@ SECTIONS
 {
        . = KERNEL_BINARY_TEXT_START;
 
-       _stext = .;     /* start of kernel text, includes init code & data */
-
        __init_begin = .;
        HEAD_TEXT_SECTION
        MLONGCALL_DISCARD(INIT_TEXT_SECTION(8))
@@ -82,6 +80,7 @@ SECTIONS
        /* freed after init ends here */
 
        _text = .;              /* Text and read-only data */
+       _stext = .;
        MLONGCALL_KEEP(INIT_TEXT_SECTION(8))
        .text ALIGN(PAGE_SIZE) : {
                TEXT_TEXT
index 0e3640e..5fa68c2 100644 (file)
@@ -196,3 +196,6 @@ clean-files := vmlinux.lds
 # Force dependency (incbin is bad)
 $(obj)/vdso32_wrapper.o : $(obj)/vdso32/vdso32.so.dbg
 $(obj)/vdso64_wrapper.o : $(obj)/vdso64/vdso64.so.dbg
+
+# for cleaning
+subdir- += vdso32 vdso64
index 6b1ec9e..349c4a8 100644 (file)
@@ -202,11 +202,11 @@ vmap_stack_overflow:
        mfspr   r1, SPRN_SPRG_THREAD
        lwz     r1, TASK_CPU - THREAD(r1)
        slwi    r1, r1, 3
-       addis   r1, r1, emergency_ctx@ha
+       addis   r1, r1, emergency_ctx-PAGE_OFFSET@ha
 #else
-       lis     r1, emergency_ctx@ha
+       lis     r1, emergency_ctx-PAGE_OFFSET@ha
 #endif
-       lwz     r1, emergency_ctx@l(r1)
+       lwz     r1, emergency_ctx-PAGE_OFFSET@l(r1)
        addi    r1, r1, THREAD_SIZE - INT_FRAME_SIZE
        EXCEPTION_PROLOG_2 0 vmap_stack_overflow
        prepare_transfer_to_handler
index 2d59688..0d073b9 100644 (file)
@@ -733,6 +733,7 @@ _GLOBAL(mmu_pin_tlb)
 #ifdef CONFIG_PIN_TLB_DATA
        LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET)
        LOAD_REG_IMMEDIATE(r7, MI_SVALID | MI_PS8MEG | _PMD_ACCESSED)
+       li      r8, 0
 #ifdef CONFIG_PIN_TLB_IMMR
        li      r0, 3
 #else
@@ -741,26 +742,26 @@ _GLOBAL(mmu_pin_tlb)
        mtctr   r0
        cmpwi   r4, 0
        beq     4f
-       LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_RO | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT)
        LOAD_REG_ADDR(r9, _sinittext)
 
 2:     ori     r0, r6, MD_EVALID
+       ori     r12, r8, 0xf0 | _PAGE_RO | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT
        mtspr   SPRN_MD_CTR, r5
        mtspr   SPRN_MD_EPN, r0
        mtspr   SPRN_MD_TWC, r7
-       mtspr   SPRN_MD_RPN, r8
+       mtspr   SPRN_MD_RPN, r12
        addi    r5, r5, 0x100
        addis   r6, r6, SZ_8M@h
        addis   r8, r8, SZ_8M@h
        cmplw   r6, r9
        bdnzt   lt, 2b
-
-4:     LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_DIRTY | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT)
+4:
 2:     ori     r0, r6, MD_EVALID
+       ori     r12, r8, 0xf0 | _PAGE_DIRTY | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT
        mtspr   SPRN_MD_CTR, r5
        mtspr   SPRN_MD_EPN, r0
        mtspr   SPRN_MD_TWC, r7
-       mtspr   SPRN_MD_RPN, r8
+       mtspr   SPRN_MD_RPN, r12
        addi    r5, r5, 0x100
        addis   r6, r6, SZ_8M@h
        addis   r8, r8, SZ_8M@h
@@ -781,7 +782,7 @@ _GLOBAL(mmu_pin_tlb)
 #endif
 #if defined(CONFIG_PIN_TLB_IMMR) || defined(CONFIG_PIN_TLB_DATA)
        lis     r0, (MD_RSV4I | MD_TWAM)@h
-       mtspr   SPRN_MI_CTR, r0
+       mtspr   SPRN_MD_CTR, r0
 #endif
        mtspr   SPRN_SRR1, r10
        mtspr   SPRN_SRR0, r11
index 1f07317..618aecc 100644 (file)
@@ -25,8 +25,14 @@ static inline int __get_user_sigset(sigset_t *dst, const sigset_t __user *src)
 
        return __get_user(dst->sig[0], (u64 __user *)&src->sig[0]);
 }
-#define unsafe_get_user_sigset(dst, src, label) \
-       unsafe_get_user((dst)->sig[0], (u64 __user *)&(src)->sig[0], label)
+#define unsafe_get_user_sigset(dst, src, label) do {                   \
+       sigset_t *__dst = dst;                                          \
+       const sigset_t __user *__src = src;                             \
+       int i;                                                          \
+                                                                       \
+       for (i = 0; i < _NSIG_WORDS; i++)                               \
+               unsafe_get_user(__dst->sig[i], &__src->sig[i], label);  \
+} while (0)
 
 #ifdef CONFIG_VSX
 extern unsigned long copy_vsx_to_user(void __user *to,
index 00a9c9c..3e053e2 100644 (file)
@@ -1063,7 +1063,7 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx,
         * We kill the task with a SIGSEGV in this situation.
         */
        if (do_setcontext(new_ctx, regs, 0)) {
-               force_fatal_sig(SIGSEGV);
+               force_exit_sig(SIGSEGV);
                return -EFAULT;
        }
 
index ef51853..d1e1fc0 100644 (file)
@@ -704,7 +704,7 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx,
         */
 
        if (__get_user_sigset(&set, &new_ctx->uc_sigmask)) {
-               force_fatal_sig(SIGSEGV);
+               force_exit_sig(SIGSEGV);
                return -EFAULT;
        }
        set_current_blocked(&set);
@@ -713,7 +713,7 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx,
                return -EFAULT;
        if (__unsafe_restore_sigcontext(current, NULL, 0, &new_ctx->uc_mcontext)) {
                user_read_access_end();
-               force_fatal_sig(SIGSEGV);
+               force_exit_sig(SIGSEGV);
                return -EFAULT;
        }
        user_read_access_end();
index 7bef917..15109af 100644 (file)
 446    common  landlock_restrict_self          sys_landlock_restrict_self
 # 447 reserved for memfd_secret
 448    common  process_mrelease                sys_process_mrelease
+449    common  futex_waitv                     sys_futex_waitv
index f9ea0e5..3fa6d24 100644 (file)
@@ -187,6 +187,12 @@ static void watchdog_smp_panic(int cpu, u64 tb)
        if (sysctl_hardlockup_all_cpu_backtrace)
                trigger_allbutself_cpu_backtrace();
 
+       /*
+        * Force flush any remote buffers that might be stuck in IRQ context
+        * and therefore could not run their irq_work.
+        */
+       printk_trigger_flush();
+
        if (hardlockup_panic)
                nmi_panic(NULL, "Hard LOCKUP");
 
index fcf4760..70b7a8f 100644 (file)
@@ -695,6 +695,7 @@ static void flush_guest_tlb(struct kvm *kvm)
                                       "r" (0) : "memory");
                }
                asm volatile("ptesync": : :"memory");
+               // POWER9 congruence-class TLBIEL leaves ERAT. Flush it now.
                asm volatile(PPC_RADIX_INVALIDATE_ERAT_GUEST : : :"memory");
        } else {
                for (set = 0; set < kvm->arch.tlb_sets; ++set) {
@@ -705,7 +706,9 @@ static void flush_guest_tlb(struct kvm *kvm)
                        rb += PPC_BIT(51);      /* increment set number */
                }
                asm volatile("ptesync": : :"memory");
-               asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT : : :"memory");
+               // POWER9 congruence-class TLBIEL leaves ERAT. Flush it now.
+               if (cpu_has_feature(CPU_FTR_ARCH_300))
+                       asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT : : :"memory");
        }
 }
 
index eb776d0..32a4b4d 100644 (file)
@@ -2005,7 +2005,7 @@ hcall_real_table:
        .globl  hcall_real_table_end
 hcall_real_table_end:
 
-_GLOBAL(kvmppc_h_set_xdabr)
+_GLOBAL_TOC(kvmppc_h_set_xdabr)
 EXPORT_SYMBOL_GPL(kvmppc_h_set_xdabr)
        andi.   r0, r5, DABRX_USER | DABRX_KERNEL
        beq     6f
@@ -2015,7 +2015,7 @@ EXPORT_SYMBOL_GPL(kvmppc_h_set_xdabr)
 6:     li      r3, H_PARAMETER
        blr
 
-_GLOBAL(kvmppc_h_set_dabr)
+_GLOBAL_TOC(kvmppc_h_set_dabr)
 EXPORT_SYMBOL_GPL(kvmppc_h_set_dabr)
        li      r5, DABRX_USER | DABRX_KERNEL
 3:
index 35e9ccc..a72920f 100644 (file)
@@ -641,9 +641,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
                 * implementations just count online CPUs.
                 */
                if (hv_enabled)
-                       r = num_present_cpus();
+                       r = min_t(unsigned int, num_present_cpus(), KVM_MAX_VCPUS);
                else
-                       r = num_online_cpus();
+                       r = min_t(unsigned int, num_online_cpus(), KVM_MAX_VCPUS);
                break;
        case KVM_CAP_MAX_VCPUS:
                r = KVM_MAX_VCPUS;
index 8fc49b1..6ec9789 100644 (file)
@@ -314,7 +314,7 @@ static unsigned long __init kaslr_choose_location(void *dt_ptr, phys_addr_t size
                pr_warn("KASLR: No safe seed for randomizing the kernel base.\n");
 
        ram = min_t(phys_addr_t, __max_low_memory, size);
-       ram = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM, true, false);
+       ram = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM, true, true);
        linear_sz = min_t(unsigned long, ram, SZ_512M);
 
        /* If the linear size is smaller than 64M, do not randmize */
index 89353d4..647bf45 100644 (file)
@@ -645,7 +645,7 @@ static void early_init_this_mmu(void)
 
                if (map)
                        linear_map_top = map_mem_in_cams(linear_map_top,
-                                                        num_cams, true, true);
+                                                        num_cams, false, true);
        }
 #endif
 
@@ -766,7 +766,7 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
                num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
 
                linear_sz = map_mem_in_cams(first_memblock_size, num_cams,
-                                           false, true);
+                                           true, true);
 
                ppc64_rma_size = min_t(u64, linear_sz, 0x40000000);
        } else
index 6f14c8f..59d3cfc 100644 (file)
@@ -376,9 +376,9 @@ static void initialize_form2_numa_distance_lookup_table(void)
 {
        int i, j;
        struct device_node *root;
-       const __u8 *numa_dist_table;
+       const __u8 *form2_distances;
        const __be32 *numa_lookup_index;
-       int numa_dist_table_length;
+       int form2_distances_length;
        int max_numa_index, distance_index;
 
        if (firmware_has_feature(FW_FEATURE_OPAL))
@@ -392,45 +392,41 @@ static void initialize_form2_numa_distance_lookup_table(void)
        max_numa_index = of_read_number(&numa_lookup_index[0], 1);
 
        /* first element of the array is the size and is encode-int */
-       numa_dist_table = of_get_property(root, "ibm,numa-distance-table", NULL);
-       numa_dist_table_length = of_read_number((const __be32 *)&numa_dist_table[0], 1);
+       form2_distances = of_get_property(root, "ibm,numa-distance-table", NULL);
+       form2_distances_length = of_read_number((const __be32 *)&form2_distances[0], 1);
        /* Skip the size which is encoded int */
-       numa_dist_table += sizeof(__be32);
+       form2_distances += sizeof(__be32);
 
-       pr_debug("numa_dist_table_len = %d, numa_dist_indexes_len = %d\n",
-                numa_dist_table_length, max_numa_index);
+       pr_debug("form2_distances_len = %d, numa_dist_indexes_len = %d\n",
+                form2_distances_length, max_numa_index);
 
        for (i = 0; i < max_numa_index; i++)
                /* +1 skip the max_numa_index in the property */
                numa_id_index_table[i] = of_read_number(&numa_lookup_index[i + 1], 1);
 
 
-       if (numa_dist_table_length != max_numa_index * max_numa_index) {
+       if (form2_distances_length != max_numa_index * max_numa_index) {
                WARN(1, "Wrong NUMA distance information\n");
-               /* consider everybody else just remote. */
-               for (i = 0;  i < max_numa_index; i++) {
-                       for (j = 0; j < max_numa_index; j++) {
-                               int nodeA = numa_id_index_table[i];
-                               int nodeB = numa_id_index_table[j];
-
-                               if (nodeA == nodeB)
-                                       numa_distance_table[nodeA][nodeB] = LOCAL_DISTANCE;
-                               else
-                                       numa_distance_table[nodeA][nodeB] = REMOTE_DISTANCE;
-                       }
-               }
+               form2_distances = NULL; // don't use it
        }
-
        distance_index = 0;
        for (i = 0;  i < max_numa_index; i++) {
                for (j = 0; j < max_numa_index; j++) {
                        int nodeA = numa_id_index_table[i];
                        int nodeB = numa_id_index_table[j];
-
-                       numa_distance_table[nodeA][nodeB] = numa_dist_table[distance_index++];
-                       pr_debug("dist[%d][%d]=%d ", nodeA, nodeB, numa_distance_table[nodeA][nodeB]);
+                       int dist;
+
+                       if (form2_distances)
+                               dist = form2_distances[distance_index++];
+                       else if (nodeA == nodeB)
+                               dist = LOCAL_DISTANCE;
+                       else
+                               dist = REMOTE_DISTANCE;
+                       numa_distance_table[nodeA][nodeB] = dist;
+                       pr_debug("dist[%d][%d]=%d ", nodeA, nodeB, dist);
                }
        }
+
        of_node_put(root);
 }
 
index bb789f3..a38372f 100644 (file)
@@ -186,7 +186,6 @@ err:
 static int mcu_remove(struct i2c_client *client)
 {
        struct mcu *mcu = i2c_get_clientdata(client);
-       int ret;
 
        kthread_stop(shutdown_thread);
 
index 49b4015..8f998e5 100644 (file)
@@ -1094,15 +1094,6 @@ static phys_addr_t ddw_memory_hotplug_max(void)
        phys_addr_t max_addr = memory_hotplug_max();
        struct device_node *memory;
 
-       /*
-        * The "ibm,pmemory" can appear anywhere in the address space.
-        * Assuming it is still backed by page structs, set the upper limit
-        * for the huge DMA window as MAX_PHYSMEM_BITS.
-        */
-       if (of_find_node_by_type(NULL, "ibm,pmemory"))
-               return (sizeof(phys_addr_t) * 8 <= MAX_PHYSMEM_BITS) ?
-                       (phys_addr_t) -1 : (1ULL << MAX_PHYSMEM_BITS);
-
        for_each_node_by_type(memory, "memory") {
                unsigned long start, size;
                int n_mem_addr_cells, n_mem_size_cells, len;
@@ -1238,7 +1229,6 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
        u32 ddw_avail[DDW_APPLICABLE_SIZE];
        struct dma_win *window;
        struct property *win64;
-       bool ddw_enabled = false;
        struct failed_ddw_pdn *fpdn;
        bool default_win_removed = false, direct_mapping = false;
        bool pmem_present;
@@ -1253,7 +1243,6 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
 
        if (find_existing_ddw(pdn, &dev->dev.archdata.dma_offset, &len)) {
                direct_mapping = (len >= max_ram_len);
-               ddw_enabled = true;
                goto out_unlock;
        }
 
@@ -1367,8 +1356,10 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
                len = order_base_2(query.largest_available_block << page_shift);
                win_name = DMA64_PROPNAME;
        } else {
-               direct_mapping = true;
-               win_name = DIRECT64_PROPNAME;
+               direct_mapping = !default_win_removed ||
+                       (len == MAX_PHYSMEM_BITS) ||
+                       (!pmem_present && (len == max_ram_len));
+               win_name = direct_mapping ? DIRECT64_PROPNAME : DMA64_PROPNAME;
        }
 
        ret = create_ddw(dev, ddw_avail, &create, page_shift, len);
@@ -1406,8 +1397,8 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
                        dev_info(&dev->dev, "failed to map DMA window for %pOF: %d\n",
                                 dn, ret);
 
-               /* Make sure to clean DDW if any TCE was set*/
-               clean_dma_window(pdn, win64->value);
+                       /* Make sure to clean DDW if any TCE was set*/
+                       clean_dma_window(pdn, win64->value);
                        goto out_del_list;
                }
        } else {
@@ -1454,7 +1445,6 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
        spin_unlock(&dma_win_list_lock);
 
        dev->dev.archdata.dma_offset = win_addr;
-       ddw_enabled = true;
        goto out_unlock;
 
 out_del_list:
@@ -1490,10 +1480,10 @@ out_unlock:
         * as RAM, then we failed to create a window to cover persistent
         * memory and need to set the DMA limit.
         */
-       if (pmem_present && ddw_enabled && direct_mapping && len == max_ram_len)
+       if (pmem_present && direct_mapping && len == max_ram_len)
                dev->dev.bus_dma_limit = dev->dev.archdata.dma_offset + (1ULL << len);
 
-    return ddw_enabled && direct_mapping;
+       return direct_mapping;
 }
 
 static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
index 97796c6..785c292 100644 (file)
@@ -3,7 +3,6 @@ config PPC_XIVE
        bool
        select PPC_SMP_MUXED_IPI
        select HARDIRQS_SW_RESEND
-       select IRQ_DOMAIN_NOMAP
 
 config PPC_XIVE_NATIVE
        bool
index c5d75c0..7b69299 100644 (file)
@@ -1443,8 +1443,7 @@ static const struct irq_domain_ops xive_irq_domain_ops = {
 
 static void __init xive_init_host(struct device_node *np)
 {
-       xive_irq_domain = irq_domain_add_nomap(np, XIVE_MAX_IRQ,
-                                              &xive_irq_domain_ops, NULL);
+       xive_irq_domain = irq_domain_add_tree(np, &xive_irq_domain_ops, NULL);
        if (WARN_ON(xive_irq_domain == NULL))
                return;
        irq_set_default_host(xive_irq_domain);
index 5927c94..8a107ed 100644 (file)
@@ -107,11 +107,13 @@ PHONY += vdso_install
 vdso_install:
        $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@
 
+ifeq ($(KBUILD_EXTMOD),)
 ifeq ($(CONFIG_MMU),y)
 prepare: vdso_prepare
 vdso_prepare: prepare0
        $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso include/generated/vdso-offsets.h
 endif
+endif
 
 ifneq ($(CONFIG_XIP_KERNEL),y)
 ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_SOC_CANAAN),yy)
index c252fd5..ef473e2 100644 (file)
@@ -19,6 +19,8 @@ CONFIG_SOC_VIRT=y
 CONFIG_SOC_MICROCHIP_POLARFIRE=y
 CONFIG_SMP=y
 CONFIG_HOTPLUG_CPU=y
+CONFIG_VIRTUALIZATION=y
+CONFIG_KVM=m
 CONFIG_JUMP_LABEL=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
index 434ef5b..6e9f12f 100644 (file)
@@ -19,6 +19,8 @@ CONFIG_SOC_VIRT=y
 CONFIG_ARCH_RV32I=y
 CONFIG_SMP=y
 CONFIG_HOTPLUG_CPU=y
+CONFIG_VIRTUALIZATION=y
+CONFIG_KVM=m
 CONFIG_JUMP_LABEL=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
index e3d3aed..fb84619 100644 (file)
@@ -740,7 +740,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
                 * Ensure we set mode to IN_GUEST_MODE after we disable
                 * interrupts and before the final VCPU requests check.
                 * See the comment in kvm_vcpu_exiting_guest_mode() and
-                * Documentation/virtual/kvm/vcpu-requests.rst
+                * Documentation/virt/kvm/vcpu-requests.rst
                 */
                vcpu->mode = IN_GUEST_MODE;
 
index eb3c045..3b0e703 100644 (file)
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
-/**
+/*
  * Copyright (c) 2019 Western Digital Corporation or its affiliates.
  *
  * Authors:
index 26399df..fb18af3 100644 (file)
@@ -74,7 +74,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
                r = 1;
                break;
        case KVM_CAP_NR_VCPUS:
-               r = num_online_cpus();
+               r = min_t(unsigned int, num_online_cpus(), KVM_MAX_VCPUS);
                break;
        case KVM_CAP_MAX_VCPUS:
                r = KVM_MAX_VCPUS;
index 8857ec3..2a5bb4f 100644 (file)
@@ -47,7 +47,7 @@ config ARCH_SUPPORTS_UPROBES
 config KASAN_SHADOW_OFFSET
        hex
        depends on KASAN
-       default 0x18000000000000
+       default 0x1C000000000000
 
 config S390
        def_bool y
@@ -194,6 +194,7 @@ config S390
        select HAVE_RELIABLE_STACKTRACE
        select HAVE_RSEQ
        select HAVE_SAMPLE_FTRACE_DIRECT
+       select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
        select HAVE_SOFTIRQ_ON_OWN_STACK
        select HAVE_SYSCALL_TRACEPOINTS
        select HAVE_VIRT_CPU_ACCOUNTING
index 69c45f6..609e369 100644 (file)
@@ -77,10 +77,12 @@ KBUILD_AFLAGS_DECOMPRESSOR += $(aflags-y)
 KBUILD_CFLAGS_DECOMPRESSOR += $(cflags-y)
 
 ifneq ($(call cc-option,-mstack-size=8192 -mstack-guard=128),)
-cflags-$(CONFIG_CHECK_STACK) += -mstack-size=$(STACK_SIZE)
-ifeq ($(call cc-option,-mstack-size=8192),)
-cflags-$(CONFIG_CHECK_STACK) += -mstack-guard=$(CONFIG_STACK_GUARD)
-endif
+  CC_FLAGS_CHECK_STACK := -mstack-size=$(STACK_SIZE)
+  ifeq ($(call cc-option,-mstack-size=8192),)
+    CC_FLAGS_CHECK_STACK += -mstack-guard=$(CONFIG_STACK_GUARD)
+  endif
+  export CC_FLAGS_CHECK_STACK
+  cflags-$(CONFIG_CHECK_STACK) += $(CC_FLAGS_CHECK_STACK)
 endif
 
 ifdef CONFIG_EXPOLINE
index 7571dee..1aa11a8 100644 (file)
@@ -149,82 +149,56 @@ static void setup_ident_map_size(unsigned long max_physmem_end)
 
 static void setup_kernel_memory_layout(void)
 {
-       bool vmalloc_size_verified = false;
-       unsigned long vmemmap_off;
-       unsigned long vspace_left;
+       unsigned long vmemmap_start;
        unsigned long rte_size;
        unsigned long pages;
-       unsigned long vmax;
 
        pages = ident_map_size / PAGE_SIZE;
        /* vmemmap contains a multiple of PAGES_PER_SECTION struct pages */
        vmemmap_size = SECTION_ALIGN_UP(pages) * sizeof(struct page);
 
        /* choose kernel address space layout: 4 or 3 levels. */
-       vmemmap_off = round_up(ident_map_size, _REGION3_SIZE);
+       vmemmap_start = round_up(ident_map_size, _REGION3_SIZE);
        if (IS_ENABLED(CONFIG_KASAN) ||
            vmalloc_size > _REGION2_SIZE ||
-           vmemmap_off + vmemmap_size + vmalloc_size + MODULES_LEN > _REGION2_SIZE)
-               vmax = _REGION1_SIZE;
-       else
-               vmax = _REGION2_SIZE;
-
-       /* keep vmemmap_off aligned to a top level region table entry */
-       rte_size = vmax == _REGION1_SIZE ? _REGION2_SIZE : _REGION3_SIZE;
-       MODULES_END = vmax;
-       if (is_prot_virt_host()) {
-               /*
-                * forcing modules and vmalloc area under the ultravisor
-                * secure storage limit, so that any vmalloc allocation
-                * we do could be used to back secure guest storage.
-                */
-               adjust_to_uv_max(&MODULES_END);
-       }
-
-#ifdef CONFIG_KASAN
-       if (MODULES_END < vmax) {
-               /* force vmalloc and modules below kasan shadow */
-               MODULES_END = min(MODULES_END, KASAN_SHADOW_START);
+           vmemmap_start + vmemmap_size + vmalloc_size + MODULES_LEN >
+                   _REGION2_SIZE) {
+               MODULES_END = _REGION1_SIZE;
+               rte_size = _REGION2_SIZE;
        } else {
-               /*
-                * leave vmalloc and modules above kasan shadow but make
-                * sure they don't overlap with it
-                */
-               vmalloc_size = min(vmalloc_size, vmax - KASAN_SHADOW_END - MODULES_LEN);
-               vmalloc_size_verified = true;
-               vspace_left = KASAN_SHADOW_START;
+               MODULES_END = _REGION2_SIZE;
+               rte_size = _REGION3_SIZE;
        }
+       /*
+        * forcing modules and vmalloc area under the ultravisor
+        * secure storage limit, so that any vmalloc allocation
+        * we do could be used to back secure guest storage.
+        */
+       adjust_to_uv_max(&MODULES_END);
+#ifdef CONFIG_KASAN
+       /* force vmalloc and modules below kasan shadow */
+       MODULES_END = min(MODULES_END, KASAN_SHADOW_START);
 #endif
        MODULES_VADDR = MODULES_END - MODULES_LEN;
        VMALLOC_END = MODULES_VADDR;
 
-       if (vmalloc_size_verified) {
-               VMALLOC_START = VMALLOC_END - vmalloc_size;
-       } else {
-               vmemmap_off = round_up(ident_map_size, rte_size);
-
-               if (vmemmap_off + vmemmap_size > VMALLOC_END ||
-                   vmalloc_size > VMALLOC_END - vmemmap_off - vmemmap_size) {
-                       /*
-                        * allow vmalloc area to occupy up to 1/2 of
-                        * the rest virtual space left.
-                        */
-                       vmalloc_size = min(vmalloc_size, VMALLOC_END / 2);
-               }
-               VMALLOC_START = VMALLOC_END - vmalloc_size;
-               vspace_left = VMALLOC_START;
-       }
+       /* allow vmalloc area to occupy up to about 1/2 of the rest virtual space left */
+       vmalloc_size = min(vmalloc_size, round_down(VMALLOC_END / 2, _REGION3_SIZE));
+       VMALLOC_START = VMALLOC_END - vmalloc_size;
 
-       pages = vspace_left / (PAGE_SIZE + sizeof(struct page));
+       /* split remaining virtual space between 1:1 mapping & vmemmap array */
+       pages = VMALLOC_START / (PAGE_SIZE + sizeof(struct page));
        pages = SECTION_ALIGN_UP(pages);
-       vmemmap_off = round_up(vspace_left - pages * sizeof(struct page), rte_size);
-       /* keep vmemmap left most starting from a fresh region table entry */
-       vmemmap_off = min(vmemmap_off, round_up(ident_map_size, rte_size));
-       /* take care that identity map is lower then vmemmap */
-       ident_map_size = min(ident_map_size, vmemmap_off);
+       /* keep vmemmap_start aligned to a top level region table entry */
+       vmemmap_start = round_down(VMALLOC_START - pages * sizeof(struct page), rte_size);
+       /* vmemmap_start is the future VMEM_MAX_PHYS, make sure it is within MAX_PHYSMEM */
+       vmemmap_start = min(vmemmap_start, 1UL << MAX_PHYSMEM_BITS);
+       /* make sure identity map doesn't overlay with vmemmap */
+       ident_map_size = min(ident_map_size, vmemmap_start);
        vmemmap_size = SECTION_ALIGN_UP(ident_map_size / PAGE_SIZE) * sizeof(struct page);
-       VMALLOC_START = max(vmemmap_off + vmemmap_size, VMALLOC_START);
-       vmemmap = (struct page *)vmemmap_off;
+       /* make sure vmemmap doesn't overlay with vmalloc area */
+       VMALLOC_START = max(vmemmap_start + vmemmap_size, VMALLOC_START);
+       vmemmap = (struct page *)vmemmap_start;
 }
 
 /*
index ea398a0..7f3c9ac 100644 (file)
@@ -74,6 +74,12 @@ void *kexec_file_add_components(struct kimage *image,
 int arch_kexec_do_relocs(int r_type, void *loc, unsigned long val,
                         unsigned long addr);
 
+#define ARCH_HAS_KIMAGE_ARCH
+
+struct kimage_arch {
+       void *ipl_buf;
+};
+
 extern const struct kexec_file_ops s390_kexec_image_ops;
 extern const struct kexec_file_ops s390_kexec_elf_ops;
 
index d72a6df..785d54c 100644 (file)
@@ -191,8 +191,8 @@ static int copy_oldmem_user(void __user *dst, void *src, size_t count)
                                return rc;
                } else {
                        /* Check for swapped kdump oldmem areas */
-                       if (oldmem_data.start && from - oldmem_data.size < oldmem_data.size) {
-                               from -= oldmem_data.size;
+                       if (oldmem_data.start && from - oldmem_data.start < oldmem_data.size) {
+                               from -= oldmem_data.start;
                                len = min(count, oldmem_data.size - from);
                        } else if (oldmem_data.start && from < oldmem_data.size) {
                                len = min(count, oldmem_data.size - from);
index e2cc357..5ad1dde 100644 (file)
@@ -2156,7 +2156,7 @@ void *ipl_report_finish(struct ipl_report *report)
 
        buf = vzalloc(report->size);
        if (!buf)
-               return ERR_PTR(-ENOMEM);
+               goto out;
        ptr = buf;
 
        memcpy(ptr, report->ipib, report->ipib->hdr.len);
@@ -2195,6 +2195,7 @@ void *ipl_report_finish(struct ipl_report *report)
        }
 
        BUG_ON(ptr > buf + report->size);
+out:
        return buf;
 }
 
index 528edff..9975ad2 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kexec.h>
 #include <linux/module_signature.h>
 #include <linux/verification.h>
+#include <linux/vmalloc.h>
 #include <asm/boot_data.h>
 #include <asm/ipl.h>
 #include <asm/setup.h>
@@ -170,6 +171,7 @@ static int kexec_file_add_ipl_report(struct kimage *image,
        struct kexec_buf buf;
        unsigned long addr;
        void *ptr, *end;
+       int ret;
 
        buf.image = image;
 
@@ -199,9 +201,13 @@ static int kexec_file_add_ipl_report(struct kimage *image,
                ptr += len;
        }
 
+       ret = -ENOMEM;
        buf.buffer = ipl_report_finish(data->report);
+       if (!buf.buffer)
+               goto out;
        buf.bufsz = data->report->size;
        buf.memsz = buf.bufsz;
+       image->arch.ipl_buf = buf.buffer;
 
        data->memsz += buf.memsz;
 
@@ -209,7 +215,9 @@ static int kexec_file_add_ipl_report(struct kimage *image,
                data->kernel_buf + offsetof(struct lowcore, ipl_parmblock_ptr);
        *lc_ipl_parmblock_ptr = (__u32)buf.mem;
 
-       return kexec_add_buffer(&buf);
+       ret = kexec_add_buffer(&buf);
+out:
+       return ret;
 }
 
 void *kexec_file_add_components(struct kimage *image,
@@ -322,3 +330,11 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
        }
        return 0;
 }
+
+int arch_kimage_file_post_load_cleanup(struct kimage *image)
+{
+       vfree(image->arch.ipl_buf);
+       image->arch.ipl_buf = NULL;
+
+       return kexec_image_post_load_cleanup_default(image);
+}
index 40405f2..225ab2d 100644 (file)
@@ -606,7 +606,7 @@ static void __init setup_resources(void)
 
 static void __init setup_memory_end(void)
 {
-       memblock_remove(ident_map_size, ULONG_MAX);
+       memblock_remove(ident_map_size, PHYS_ADDR_MAX - ident_map_size);
        max_pfn = max_low_pfn = PFN_DOWN(ident_map_size);
        pr_notice("The maximum memory size is %luMB\n", ident_map_size >> 20);
 }
@@ -637,14 +637,6 @@ static struct notifier_block kdump_mem_nb = {
 
 #endif
 
-/*
- * Make sure that the area above identity mapping is protected
- */
-static void __init reserve_above_ident_map(void)
-{
-       memblock_reserve(ident_map_size, ULONG_MAX);
-}
-
 /*
  * Reserve memory for kdump kernel to be loaded with kexec
  */
@@ -785,7 +777,6 @@ static void __init memblock_add_mem_detect_info(void)
        }
        memblock_set_bottom_up(false);
        memblock_set_node(0, ULONG_MAX, &memblock.memory, 0);
-       memblock_dump_all();
 }
 
 /*
@@ -826,9 +817,6 @@ static void __init setup_memory(void)
                storage_key_init_range(start, end);
 
        psw_set_key(PAGE_DEFAULT_KEY);
-
-       /* Only cosmetics */
-       memblock_enforce_memory_limit(memblock_end_of_DRAM());
 }
 
 static void __init relocate_amode31_section(void)
@@ -999,24 +987,24 @@ void __init setup_arch(char **cmdline_p)
        setup_control_program_code();
 
        /* Do some memory reservations *before* memory is added to memblock */
-       reserve_above_ident_map();
        reserve_kernel();
        reserve_initrd();
        reserve_certificate_list();
        reserve_mem_detect_info();
+       memblock_set_current_limit(ident_map_size);
        memblock_allow_resize();
 
        /* Get information about *all* installed memory */
        memblock_add_mem_detect_info();
 
        free_mem_detect_info();
+       setup_memory_end();
+       memblock_dump_all();
+       setup_memory();
 
        relocate_amode31_section();
        setup_cr();
-
        setup_uv();
-       setup_memory_end();
-       setup_memory();
        dma_contiguous_reserve(ident_map_size);
        vmcp_cma_reserve();
        if (MACHINE_HAS_EDAT2)
index df5261e..ed9c5c2 100644 (file)
 446  common    landlock_restrict_self  sys_landlock_restrict_self      sys_landlock_restrict_self
 # 447 reserved for memfd_secret
 448  common    process_mrelease        sys_process_mrelease            sys_process_mrelease
+449  common    futex_waitv             sys_futex_waitv                 sys_futex_waitv
index 035705c..2b78078 100644 (file)
@@ -84,7 +84,7 @@ static void default_trap_handler(struct pt_regs *regs)
 {
        if (user_mode(regs)) {
                report_user_fault(regs, SIGSEGV, 0);
-               force_fatal_sig(SIGSEGV);
+               force_exit_sig(SIGSEGV);
        } else
                die(regs, "Unknown program exception");
 }
index e3e6ac5..245bddf 100644 (file)
@@ -22,7 +22,7 @@ KBUILD_AFLAGS_32 += -m31 -s
 KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS))
 KBUILD_CFLAGS_32 += -m31 -fPIC -shared -fno-common -fno-builtin
 
-LDFLAGS_vdso32.so.dbg += -fPIC -shared -nostdlib -soname=linux-vdso32.so.1 \
+LDFLAGS_vdso32.so.dbg += -fPIC -shared -soname=linux-vdso32.so.1 \
        --hash-style=both --build-id=sha1 -melf_s390 -T
 
 $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_32)
index 6568de2..9e2b95a 100644 (file)
@@ -8,8 +8,9 @@ ARCH_REL_TYPE_ABS += R_390_GOT|R_390_PLT
 include $(srctree)/lib/vdso/Makefile
 obj-vdso64 = vdso_user_wrapper.o note.o
 obj-cvdso64 = vdso64_generic.o getcpu.o
-CFLAGS_REMOVE_getcpu.o = -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE)
-CFLAGS_REMOVE_vdso64_generic.o = -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE)
+VDSO_CFLAGS_REMOVE := -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE) $(CC_FLAGS_CHECK_STACK)
+CFLAGS_REMOVE_getcpu.o = $(VDSO_CFLAGS_REMOVE)
+CFLAGS_REMOVE_vdso64_generic.o = $(VDSO_CFLAGS_REMOVE)
 
 # Build rules
 
@@ -25,7 +26,7 @@ KBUILD_AFLAGS_64 += -m64 -s
 
 KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS))
 KBUILD_CFLAGS_64 += -m64 -fPIC -shared -fno-common -fno-builtin
-ldflags-y := -fPIC -shared -nostdlib -soname=linux-vdso64.so.1 \
+ldflags-y := -fPIC -shared -soname=linux-vdso64.so.1 \
             --hash-style=both --build-id=sha1 -T
 
 $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_64)
index c6257f6..14a18ba 100644 (file)
@@ -585,6 +585,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
                        r = KVM_MAX_VCPUS;
                else if (sclp.has_esca && sclp.has_64bscao)
                        r = KVM_S390_ESCA_CPU_SLOTS;
+               if (ext == KVM_CAP_NR_VCPUS)
+                       r = min_t(unsigned int, num_online_cpus(), r);
                break;
        case KVM_CAP_S390_COW:
                r = MACHINE_HAS_ESOP;
index c7a97f3..481a664 100644 (file)
@@ -43,7 +43,6 @@ extern void flush_cache_range(struct vm_area_struct *vma,
                                 unsigned long start, unsigned long end);
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 void flush_dcache_page(struct page *page);
-void flush_dcache_folio(struct folio *folio);
 extern void flush_icache_range(unsigned long start, unsigned long end);
 #define flush_icache_user_range flush_icache_range
 extern void flush_icache_page(struct vm_area_struct *vma,
index 208f131..d9539d2 100644 (file)
 446    common  landlock_restrict_self          sys_landlock_restrict_self
 # 447 reserved for memfd_secret
 448    common  process_mrelease                sys_process_mrelease
+449    common  futex_waitv                     sys_futex_waitv
index cd677bc..ffab163 100644 (file)
@@ -244,7 +244,7 @@ static int setup_frame(struct ksignal *ksig, struct pt_regs *regs,
                get_sigframe(ksig, regs, sigframe_size);
 
        if (invalid_frame_pointer(sf, sigframe_size)) {
-               force_fatal_sig(SIGILL);
+               force_exit_sig(SIGILL);
                return -EINVAL;
        }
 
@@ -336,7 +336,7 @@ static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs,
        sf = (struct rt_signal_frame __user *)
                get_sigframe(ksig, regs, sigframe_size);
        if (invalid_frame_pointer(sf, sigframe_size)) {
-               force_fatal_sig(SIGILL);
+               force_exit_sig(SIGILL);
                return -EINVAL;
        }
 
index c37764d..46adabc 100644 (file)
 446    common  landlock_restrict_self          sys_landlock_restrict_self
 # 447 reserved for memfd_secret
 448    common  process_mrelease                sys_process_mrelease
+449    common  futex_waitv                     sys_futex_waitv
index bbbd40c..8f20862 100644 (file)
@@ -122,7 +122,7 @@ void try_to_clear_window_buffer(struct pt_regs *regs, int who)
                if ((sp & 7) ||
                    copy_to_user((char __user *) sp, &tp->reg_window[window],
                                 sizeof(struct reg_window32))) {
-                       force_fatal_sig(SIGILL);
+                       force_exit_sig(SIGILL);
                        return;
                }
        }
index 95dd1ee..7399327 100644 (file)
@@ -193,7 +193,7 @@ config X86
        select HAVE_DYNAMIC_FTRACE_WITH_ARGS    if X86_64
        select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
        select HAVE_SAMPLE_FTRACE_DIRECT        if X86_64
-       select HAVE_SAMPLE_FTRACE_MULTI_DIRECT  if X86_64
+       select HAVE_SAMPLE_FTRACE_DIRECT_MULTI  if X86_64
        select HAVE_EBPF_JIT
        select HAVE_EFFICIENT_UNALIGNED_ACCESS
        select HAVE_EISA
index 0b6b277..fd2ee94 100644 (file)
@@ -226,7 +226,7 @@ bool emulate_vsyscall(unsigned long error_code,
        if ((!tmp && regs->orig_ax != syscall_nr) || regs->ip != address) {
                warn_bad_vsyscall(KERN_DEBUG, regs,
                                  "seccomp tried to change syscall nr or ip");
-               force_fatal_sig(SIGSYS);
+               force_exit_sig(SIGSYS);
                return true;
        }
        regs->orig_ax = -1;
index 42cf01e..ec6444f 100644 (file)
@@ -2211,7 +2211,6 @@ intel_pmu_snapshot_branch_stack(struct perf_branch_entry *entries, unsigned int
        /* must not have branches... */
        local_irq_save(flags);
        __intel_pmu_disable_all(false); /* we don't care about BTS */
-       __intel_pmu_pebs_disable_all();
        __intel_pmu_lbr_disable();
        /*            ... until here */
        return __intel_pmu_snapshot_branch_stack(entries, cnt, flags);
@@ -2225,7 +2224,6 @@ intel_pmu_snapshot_arch_branch_stack(struct perf_branch_entry *entries, unsigned
        /* must not have branches... */
        local_irq_save(flags);
        __intel_pmu_disable_all(false); /* we don't care about BTS */
-       __intel_pmu_pebs_disable_all();
        __intel_pmu_arch_lbr_disable();
        /*            ... until here */
        return __intel_pmu_snapshot_branch_stack(entries, cnt, flags);
index eb2c6ce..3660f69 100644 (file)
@@ -3608,6 +3608,9 @@ static int skx_cha_hw_config(struct intel_uncore_box *box, struct perf_event *ev
        struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
        struct extra_reg *er;
        int idx = 0;
+       /* Any of the CHA events may be filtered by Thread/Core-ID.*/
+       if (event->hw.config & SNBEP_CBO_PMON_CTL_TID_EN)
+               idx = SKX_CHA_MSR_PMON_BOX_FILTER_TID;
 
        for (er = skx_uncore_cha_extra_regs; er->msr; er++) {
                if (er->event != (event->hw.config & er->config_mask))
@@ -3675,6 +3678,7 @@ static struct event_constraint skx_uncore_iio_constraints[] = {
        UNCORE_EVENT_CONSTRAINT(0xc0, 0xc),
        UNCORE_EVENT_CONSTRAINT(0xc5, 0xc),
        UNCORE_EVENT_CONSTRAINT(0xd4, 0xc),
+       UNCORE_EVENT_CONSTRAINT(0xd5, 0xc),
        EVENT_CONSTRAINT_END
 };
 
@@ -4525,6 +4529,13 @@ static void snr_iio_cleanup_mapping(struct intel_uncore_type *type)
        pmu_iio_cleanup_mapping(type, &snr_iio_mapping_group);
 }
 
+static struct event_constraint snr_uncore_iio_constraints[] = {
+       UNCORE_EVENT_CONSTRAINT(0x83, 0x3),
+       UNCORE_EVENT_CONSTRAINT(0xc0, 0xc),
+       UNCORE_EVENT_CONSTRAINT(0xd5, 0xc),
+       EVENT_CONSTRAINT_END
+};
+
 static struct intel_uncore_type snr_uncore_iio = {
        .name                   = "iio",
        .num_counters           = 4,
@@ -4536,6 +4547,7 @@ static struct intel_uncore_type snr_uncore_iio = {
        .event_mask_ext         = SNR_IIO_PMON_RAW_EVENT_MASK_EXT,
        .box_ctl                = SNR_IIO_MSR_PMON_BOX_CTL,
        .msr_offset             = SNR_IIO_MSR_OFFSET,
+       .constraints            = snr_uncore_iio_constraints,
        .ops                    = &ivbep_uncore_msr_ops,
        .format_group           = &snr_uncore_iio_format_group,
        .attr_update            = snr_iio_attr_update,
index 24f4a06..96eb7db 100644 (file)
@@ -177,6 +177,9 @@ void set_hv_tscchange_cb(void (*cb)(void))
                return;
        }
 
+       if (!hv_vp_index)
+               return;
+
        hv_reenlightenment_cb = cb;
 
        /* Make sure callback is registered before we write to MSRs */
@@ -383,20 +386,13 @@ static void __init hv_get_partition_id(void)
  */
 void __init hyperv_init(void)
 {
-       u64 guest_id, required_msrs;
+       u64 guest_id;
        union hv_x64_msr_hypercall_contents hypercall_msr;
        int cpuhp;
 
        if (x86_hyper_type != X86_HYPER_MS_HYPERV)
                return;
 
-       /* Absolutely required MSRs */
-       required_msrs = HV_MSR_HYPERCALL_AVAILABLE |
-               HV_MSR_VP_INDEX_AVAILABLE;
-
-       if ((ms_hyperv.features & required_msrs) != required_msrs)
-               return;
-
        if (hv_common_init())
                return;
 
index 6053674..c2767a6 100644 (file)
@@ -102,12 +102,6 @@ extern void switch_fpu_return(void);
  */
 extern int cpu_has_xfeatures(u64 xfeatures_mask, const char **feature_name);
 
-/*
- * Tasks that are not using SVA have mm->pasid set to zero to note that they
- * will not have the valid bit set in MSR_IA32_PASID while they are running.
- */
-#define PASID_DISABLED 0
-
 /* Trap handling */
 extern int  fpu__exception_code(struct fpu *fpu, int trap_nr);
 extern void fpu_sync_fpstate(struct fpu *fpu);
index e5d8700..6ac61f8 100644 (file)
@@ -363,6 +363,7 @@ union kvm_mmu_extended_role {
                unsigned int cr4_smap:1;
                unsigned int cr4_smep:1;
                unsigned int cr4_la57:1;
+               unsigned int efer_lma:1;
        };
 };
 
index 0575f58..e5e0fe1 100644 (file)
@@ -281,13 +281,13 @@ HYPERVISOR_callback_op(int cmd, void *arg)
        return _hypercall2(int, callback_op, cmd, arg);
 }
 
-static inline int
+static __always_inline int
 HYPERVISOR_set_debugreg(int reg, unsigned long value)
 {
        return _hypercall2(int, set_debugreg, reg, value);
 }
 
-static inline unsigned long
+static __always_inline unsigned long
 HYPERVISOR_get_debugreg(int reg)
 {
        return _hypercall1(unsigned long, get_debugreg, reg);
index 4957f59..5adab89 100644 (file)
@@ -64,6 +64,7 @@ void xen_arch_unregister_cpu(int num);
 
 #ifdef CONFIG_PVH
 void __init xen_pvh_init(struct boot_params *boot_params);
+void __init mem_map_via_hcall(struct boot_params *boot_params_p);
 #endif
 
 #endif /* _ASM_X86_XEN_HYPERVISOR_H */
index 4794b71..ff55df6 100644 (file)
@@ -163,12 +163,22 @@ static uint32_t  __init ms_hyperv_platform(void)
        cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS,
              &eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]);
 
-       if (eax >= HYPERV_CPUID_MIN &&
-           eax <= HYPERV_CPUID_MAX &&
-           !memcmp("Microsoft Hv", hyp_signature, 12))
-               return HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS;
+       if (eax < HYPERV_CPUID_MIN || eax > HYPERV_CPUID_MAX ||
+           memcmp("Microsoft Hv", hyp_signature, 12))
+               return 0;
 
-       return 0;
+       /* HYPERCALL and VP_INDEX MSRs are mandatory for all features. */
+       eax = cpuid_eax(HYPERV_CPUID_FEATURES);
+       if (!(eax & HV_MSR_HYPERCALL_AVAILABLE)) {
+               pr_warn("x86/hyperv: HYPERCALL MSR not available.\n");
+               return 0;
+       }
+       if (!(eax & HV_MSR_VP_INDEX_AVAILABLE)) {
+               pr_warn("x86/hyperv: VP_INDEX MSR not available.\n");
+               return 0;
+       }
+
+       return HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS;
 }
 
 static unsigned char hv_get_nmi_reason(void)
index 63d3de0..8471a8b 100644 (file)
@@ -28,8 +28,7 @@ static DECLARE_WAIT_QUEUE_HEAD(ksgxd_waitq);
 static LIST_HEAD(sgx_active_page_list);
 static DEFINE_SPINLOCK(sgx_reclaimer_lock);
 
-/* The free page list lock protected variables prepend the lock. */
-static unsigned long sgx_nr_free_pages;
+static atomic_long_t sgx_nr_free_pages = ATOMIC_LONG_INIT(0);
 
 /* Nodes with one or more EPC sections. */
 static nodemask_t sgx_numa_mask;
@@ -403,14 +402,15 @@ skip:
 
                spin_lock(&node->lock);
                list_add_tail(&epc_page->list, &node->free_page_list);
-               sgx_nr_free_pages++;
                spin_unlock(&node->lock);
+               atomic_long_inc(&sgx_nr_free_pages);
        }
 }
 
 static bool sgx_should_reclaim(unsigned long watermark)
 {
-       return sgx_nr_free_pages < watermark && !list_empty(&sgx_active_page_list);
+       return atomic_long_read(&sgx_nr_free_pages) < watermark &&
+              !list_empty(&sgx_active_page_list);
 }
 
 static int ksgxd(void *p)
@@ -471,9 +471,9 @@ static struct sgx_epc_page *__sgx_alloc_epc_page_from_node(int nid)
 
        page = list_first_entry(&node->free_page_list, struct sgx_epc_page, list);
        list_del_init(&page->list);
-       sgx_nr_free_pages--;
 
        spin_unlock(&node->lock);
+       atomic_long_dec(&sgx_nr_free_pages);
 
        return page;
 }
@@ -625,9 +625,9 @@ void sgx_free_epc_page(struct sgx_epc_page *page)
        spin_lock(&node->lock);
 
        list_add_tail(&page->list, &node->free_page_list);
-       sgx_nr_free_pages++;
 
        spin_unlock(&node->lock);
+       atomic_long_inc(&sgx_nr_free_pages);
 }
 
 static bool __init sgx_setup_epc_section(u64 phys_addr, u64 size,
index e9ee8b5..04143a6 100644 (file)
@@ -964,6 +964,9 @@ unsigned long __get_wchan(struct task_struct *p)
        struct unwind_state state;
        unsigned long addr = 0;
 
+       if (!try_get_task_stack(p))
+               return 0;
+
        for (unwind_start(&state, p, NULL, NULL); !unwind_done(&state);
             unwind_next_frame(&state)) {
                addr = unwind_get_return_address(&state);
@@ -974,6 +977,8 @@ unsigned long __get_wchan(struct task_struct *p)
                break;
        }
 
+       put_task_stack(p);
+
        return addr;
 }
 
index 49b596d..6a190c7 100644 (file)
@@ -742,6 +742,28 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p)
        return 0;
 }
 
+static char * __init prepare_command_line(void)
+{
+#ifdef CONFIG_CMDLINE_BOOL
+#ifdef CONFIG_CMDLINE_OVERRIDE
+       strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
+#else
+       if (builtin_cmdline[0]) {
+               /* append boot loader cmdline to builtin */
+               strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE);
+               strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE);
+               strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
+       }
+#endif
+#endif
+
+       strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
+
+       parse_early_param();
+
+       return command_line;
+}
+
 /*
  * Determine if we were loaded by an EFI loader.  If so, then we have also been
  * passed the efi memmap, systab, etc., so we should use these data structures
@@ -830,6 +852,23 @@ void __init setup_arch(char **cmdline_p)
 
        x86_init.oem.arch_setup();
 
+       /*
+        * x86_configure_nx() is called before parse_early_param() (called by
+        * prepare_command_line()) to detect whether hardware doesn't support
+        * NX (so that the early EHCI debug console setup can safely call
+        * set_fixmap()). It may then be called again from within noexec_setup()
+        * during parsing early parameters to honor the respective command line
+        * option.
+        */
+       x86_configure_nx();
+
+       /*
+        * This parses early params and it needs to run before
+        * early_reserve_memory() because latter relies on such settings
+        * supplied as early params.
+        */
+       *cmdline_p = prepare_command_line();
+
        /*
         * Do some memory reservations *before* memory is added to memblock, so
         * memblock allocations won't overwrite it.
@@ -863,33 +902,6 @@ void __init setup_arch(char **cmdline_p)
        bss_resource.start = __pa_symbol(__bss_start);
        bss_resource.end = __pa_symbol(__bss_stop)-1;
 
-#ifdef CONFIG_CMDLINE_BOOL
-#ifdef CONFIG_CMDLINE_OVERRIDE
-       strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
-#else
-       if (builtin_cmdline[0]) {
-               /* append boot loader cmdline to builtin */
-               strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE);
-               strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE);
-               strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
-       }
-#endif
-#endif
-
-       strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
-       *cmdline_p = command_line;
-
-       /*
-        * x86_configure_nx() is called before parse_early_param() to detect
-        * whether hardware doesn't support NX (so that the early EHCI debug
-        * console setup can safely call set_fixmap()). It may then be called
-        * again from within noexec_setup() during parsing early parameters
-        * to honor the respective command line option.
-        */
-       x86_configure_nx();
-
-       parse_early_param();
-
 #ifdef CONFIG_MEMORY_HOTPLUG
        /*
         * Memory used by the kernel cannot be hot-removed because Linux
index cce1c89..c21bcd6 100644 (file)
@@ -160,7 +160,7 @@ Efault_end:
        user_access_end();
 Efault:
        pr_alert("could not access userspace vm86 info\n");
-       force_fatal_sig(SIGSEGV);
+       force_exit_sig(SIGSEGV);
        goto exit_vm86;
 }
 
index e19dabf..07e9215 100644 (file)
@@ -125,7 +125,7 @@ static void kvm_update_kvm_cpuid_base(struct kvm_vcpu *vcpu)
        }
 }
 
-struct kvm_cpuid_entry2 *kvm_find_kvm_cpuid_features(struct kvm_vcpu *vcpu)
+static struct kvm_cpuid_entry2 *kvm_find_kvm_cpuid_features(struct kvm_vcpu *vcpu)
 {
        u32 base = vcpu->arch.kvm_cpuid_base;
 
index 4a555f3..5e19e6e 100644 (file)
@@ -2022,7 +2022,7 @@ static void kvm_hv_hypercall_set_result(struct kvm_vcpu *vcpu, u64 result)
 {
        bool longmode;
 
-       longmode = is_64_bit_mode(vcpu);
+       longmode = is_64_bit_hypercall(vcpu);
        if (longmode)
                kvm_rax_write(vcpu, result);
        else {
@@ -2171,7 +2171,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
        }
 
 #ifdef CONFIG_X86_64
-       if (is_64_bit_mode(vcpu)) {
+       if (is_64_bit_hypercall(vcpu)) {
                hc.param = kvm_rcx_read(vcpu);
                hc.ingpa = kvm_rdx_read(vcpu);
                hc.outgpa = kvm_r8_read(vcpu);
index 3379437..3be9bee 100644 (file)
@@ -4682,6 +4682,7 @@ static union kvm_mmu_extended_role kvm_calc_mmu_role_ext(struct kvm_vcpu *vcpu,
                /* PKEY and LA57 are active iff long mode is active. */
                ext.cr4_pke = ____is_efer_lma(regs) && ____is_cr4_pke(regs);
                ext.cr4_la57 = ____is_efer_lma(regs) && ____is_cr4_la57(regs);
+               ext.efer_lma = ____is_efer_lma(regs);
        }
 
        ext.valid = 1;
index 902c52a..21ac0a5 100644 (file)
@@ -237,7 +237,6 @@ static void sev_unbind_asid(struct kvm *kvm, unsigned int handle)
 static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
 {
        struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
-       bool es_active = argp->id == KVM_SEV_ES_INIT;
        int asid, ret;
 
        if (kvm->created_vcpus)
@@ -247,7 +246,8 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
        if (unlikely(sev->active))
                return ret;
 
-       sev->es_active = es_active;
+       sev->active = true;
+       sev->es_active = argp->id == KVM_SEV_ES_INIT;
        asid = sev_asid_new(sev);
        if (asid < 0)
                goto e_no_asid;
@@ -257,8 +257,6 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
        if (ret)
                goto e_free;
 
-       sev->active = true;
-       sev->asid = asid;
        INIT_LIST_HEAD(&sev->regions_list);
 
        return 0;
@@ -268,6 +266,7 @@ e_free:
        sev->asid = 0;
 e_no_asid:
        sev->es_active = false;
+       sev->active = false;
        return ret;
 }
 
@@ -1530,7 +1529,7 @@ static int sev_receive_finish(struct kvm *kvm, struct kvm_sev_cmd *argp)
        return sev_issue_cmd(kvm, SEV_CMD_RECEIVE_FINISH, &data, &argp->error);
 }
 
-static bool cmd_allowed_from_miror(u32 cmd_id)
+static bool is_cmd_allowed_from_mirror(u32 cmd_id)
 {
        /*
         * Allow mirrors VM to call KVM_SEV_LAUNCH_UPDATE_VMSA to enable SEV-ES
@@ -1757,7 +1756,7 @@ int svm_mem_enc_op(struct kvm *kvm, void __user *argp)
 
        /* Only the enc_context_owner handles some memory enc operations. */
        if (is_mirroring_enc_context(kvm) &&
-           !cmd_allowed_from_miror(sev_cmd.id)) {
+           !is_cmd_allowed_from_mirror(sev_cmd.id)) {
                r = -EINVAL;
                goto out;
        }
@@ -1990,7 +1989,12 @@ int svm_vm_copy_asid_from(struct kvm *kvm, unsigned int source_fd)
        mutex_unlock(&source_kvm->lock);
        mutex_lock(&kvm->lock);
 
-       if (sev_guest(kvm)) {
+       /*
+        * Disallow out-of-band SEV/SEV-ES init if the target is already an
+        * SEV guest, or if vCPUs have been created.  KVM relies on vCPUs being
+        * created after SEV/SEV-ES initialization, e.g. to init intercepts.
+        */
+       if (sev_guest(kvm) || kvm->created_vcpus) {
                ret = -EINVAL;
                goto e_mirror_unlock;
        }
index 437e685..5faad3d 100644 (file)
@@ -247,7 +247,7 @@ static __always_inline bool sev_es_guest(struct kvm *kvm)
 #ifdef CONFIG_KVM_AMD_SEV
        struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
 
-       return sev_guest(kvm) && sev->es_active;
+       return sev->es_active && !WARN_ON_ONCE(!sev->active);
 #else
        return false;
 #endif
index b213ca9..1e2f669 100644 (file)
@@ -670,33 +670,39 @@ static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu,
 static void nested_cache_shadow_vmcs12(struct kvm_vcpu *vcpu,
                                       struct vmcs12 *vmcs12)
 {
-       struct kvm_host_map map;
-       struct vmcs12 *shadow;
+       struct vcpu_vmx *vmx = to_vmx(vcpu);
+       struct gfn_to_hva_cache *ghc = &vmx->nested.shadow_vmcs12_cache;
 
        if (!nested_cpu_has_shadow_vmcs(vmcs12) ||
            vmcs12->vmcs_link_pointer == INVALID_GPA)
                return;
 
-       shadow = get_shadow_vmcs12(vcpu);
-
-       if (kvm_vcpu_map(vcpu, gpa_to_gfn(vmcs12->vmcs_link_pointer), &map))
+       if (ghc->gpa != vmcs12->vmcs_link_pointer &&
+           kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc,
+                                     vmcs12->vmcs_link_pointer, VMCS12_SIZE))
                return;
 
-       memcpy(shadow, map.hva, VMCS12_SIZE);
-       kvm_vcpu_unmap(vcpu, &map, false);
+       kvm_read_guest_cached(vmx->vcpu.kvm, ghc, get_shadow_vmcs12(vcpu),
+                             VMCS12_SIZE);
 }
 
 static void nested_flush_cached_shadow_vmcs12(struct kvm_vcpu *vcpu,
                                              struct vmcs12 *vmcs12)
 {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
+       struct gfn_to_hva_cache *ghc = &vmx->nested.shadow_vmcs12_cache;
 
        if (!nested_cpu_has_shadow_vmcs(vmcs12) ||
            vmcs12->vmcs_link_pointer == INVALID_GPA)
                return;
 
-       kvm_write_guest(vmx->vcpu.kvm, vmcs12->vmcs_link_pointer,
-                       get_shadow_vmcs12(vcpu), VMCS12_SIZE);
+       if (ghc->gpa != vmcs12->vmcs_link_pointer &&
+           kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc,
+                                     vmcs12->vmcs_link_pointer, VMCS12_SIZE))
+               return;
+
+       kvm_write_guest_cached(vmx->vcpu.kvm, ghc, get_shadow_vmcs12(vcpu),
+                              VMCS12_SIZE);
 }
 
 /*
@@ -2830,6 +2836,17 @@ static int nested_vmx_check_controls(struct kvm_vcpu *vcpu,
        return 0;
 }
 
+static int nested_vmx_check_address_space_size(struct kvm_vcpu *vcpu,
+                                      struct vmcs12 *vmcs12)
+{
+#ifdef CONFIG_X86_64
+       if (CC(!!(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE) !=
+               !!(vcpu->arch.efer & EFER_LMA)))
+               return -EINVAL;
+#endif
+       return 0;
+}
+
 static int nested_vmx_check_host_state(struct kvm_vcpu *vcpu,
                                       struct vmcs12 *vmcs12)
 {
@@ -2854,18 +2871,16 @@ static int nested_vmx_check_host_state(struct kvm_vcpu *vcpu,
                return -EINVAL;
 
 #ifdef CONFIG_X86_64
-       ia32e = !!(vcpu->arch.efer & EFER_LMA);
+       ia32e = !!(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE);
 #else
        ia32e = false;
 #endif
 
        if (ia32e) {
-               if (CC(!(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE)) ||
-                   CC(!(vmcs12->host_cr4 & X86_CR4_PAE)))
+               if (CC(!(vmcs12->host_cr4 & X86_CR4_PAE)))
                        return -EINVAL;
        } else {
-               if (CC(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE) ||
-                   CC(vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) ||
+               if (CC(vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) ||
                    CC(vmcs12->host_cr4 & X86_CR4_PCIDE) ||
                    CC((vmcs12->host_rip) >> 32))
                        return -EINVAL;
@@ -2910,9 +2925,9 @@ static int nested_vmx_check_host_state(struct kvm_vcpu *vcpu,
 static int nested_vmx_check_vmcs_link_ptr(struct kvm_vcpu *vcpu,
                                          struct vmcs12 *vmcs12)
 {
-       int r = 0;
-       struct vmcs12 *shadow;
-       struct kvm_host_map map;
+       struct vcpu_vmx *vmx = to_vmx(vcpu);
+       struct gfn_to_hva_cache *ghc = &vmx->nested.shadow_vmcs12_cache;
+       struct vmcs_hdr hdr;
 
        if (vmcs12->vmcs_link_pointer == INVALID_GPA)
                return 0;
@@ -2920,17 +2935,21 @@ static int nested_vmx_check_vmcs_link_ptr(struct kvm_vcpu *vcpu,
        if (CC(!page_address_valid(vcpu, vmcs12->vmcs_link_pointer)))
                return -EINVAL;
 
-       if (CC(kvm_vcpu_map(vcpu, gpa_to_gfn(vmcs12->vmcs_link_pointer), &map)))
-               return -EINVAL;
+       if (ghc->gpa != vmcs12->vmcs_link_pointer &&
+           CC(kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc,
+                                        vmcs12->vmcs_link_pointer, VMCS12_SIZE)))
+                return -EINVAL;
 
-       shadow = map.hva;
+       if (CC(kvm_read_guest_offset_cached(vcpu->kvm, ghc, &hdr,
+                                           offsetof(struct vmcs12, hdr),
+                                           sizeof(hdr))))
+               return -EINVAL;
 
-       if (CC(shadow->hdr.revision_id != VMCS12_REVISION) ||
-           CC(shadow->hdr.shadow_vmcs != nested_cpu_has_shadow_vmcs(vmcs12)))
-               r = -EINVAL;
+       if (CC(hdr.revision_id != VMCS12_REVISION) ||
+           CC(hdr.shadow_vmcs != nested_cpu_has_shadow_vmcs(vmcs12)))
+               return -EINVAL;
 
-       kvm_vcpu_unmap(vcpu, &map, false);
-       return r;
+       return 0;
 }
 
 /*
@@ -3535,6 +3554,9 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
        if (nested_vmx_check_controls(vcpu, vmcs12))
                return nested_vmx_fail(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
 
+       if (nested_vmx_check_address_space_size(vcpu, vmcs12))
+               return nested_vmx_fail(vcpu, VMXERR_ENTRY_INVALID_HOST_STATE_FIELD);
+
        if (nested_vmx_check_host_state(vcpu, vmcs12))
                return nested_vmx_fail(vcpu, VMXERR_ENTRY_INVALID_HOST_STATE_FIELD);
 
@@ -5264,10 +5286,11 @@ static int handle_vmptrld(struct kvm_vcpu *vcpu)
                return 1;
 
        if (vmx->nested.current_vmptr != vmptr) {
-               struct kvm_host_map map;
-               struct vmcs12 *new_vmcs12;
+               struct gfn_to_hva_cache *ghc = &vmx->nested.vmcs12_cache;
+               struct vmcs_hdr hdr;
 
-               if (kvm_vcpu_map(vcpu, gpa_to_gfn(vmptr), &map)) {
+               if (ghc->gpa != vmptr &&
+                   kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, vmptr, VMCS12_SIZE)) {
                        /*
                         * Reads from an unbacked page return all 1s,
                         * which means that the 32 bits located at the
@@ -5278,12 +5301,16 @@ static int handle_vmptrld(struct kvm_vcpu *vcpu)
                                VMXERR_VMPTRLD_INCORRECT_VMCS_REVISION_ID);
                }
 
-               new_vmcs12 = map.hva;
+               if (kvm_read_guest_offset_cached(vcpu->kvm, ghc, &hdr,
+                                                offsetof(struct vmcs12, hdr),
+                                                sizeof(hdr))) {
+                       return nested_vmx_fail(vcpu,
+                               VMXERR_VMPTRLD_INCORRECT_VMCS_REVISION_ID);
+               }
 
-               if (new_vmcs12->hdr.revision_id != VMCS12_REVISION ||
-                   (new_vmcs12->hdr.shadow_vmcs &&
+               if (hdr.revision_id != VMCS12_REVISION ||
+                   (hdr.shadow_vmcs &&
                     !nested_cpu_has_vmx_shadow_vmcs(vcpu))) {
-                       kvm_vcpu_unmap(vcpu, &map, false);
                        return nested_vmx_fail(vcpu,
                                VMXERR_VMPTRLD_INCORRECT_VMCS_REVISION_ID);
                }
@@ -5294,8 +5321,11 @@ static int handle_vmptrld(struct kvm_vcpu *vcpu)
                 * Load VMCS12 from guest memory since it is not already
                 * cached.
                 */
-               memcpy(vmx->nested.cached_vmcs12, new_vmcs12, VMCS12_SIZE);
-               kvm_vcpu_unmap(vcpu, &map, false);
+               if (kvm_read_guest_cached(vcpu->kvm, ghc, vmx->nested.cached_vmcs12,
+                                         VMCS12_SIZE)) {
+                       return nested_vmx_fail(vcpu,
+                               VMXERR_VMPTRLD_INCORRECT_VMCS_REVISION_ID);
+               }
 
                set_current_vmptr(vmx, vmptr);
        }
index a4ead60..4df2ac2 100644 (file)
@@ -141,6 +141,16 @@ struct nested_vmx {
         */
        struct vmcs12 *cached_shadow_vmcs12;
 
+       /*
+        * GPA to HVA cache for accessing vmcs12->vmcs_link_pointer
+        */
+       struct gfn_to_hva_cache shadow_vmcs12_cache;
+
+       /*
+        * GPA to HVA cache for VMCS12
+        */
+       struct gfn_to_hva_cache vmcs12_cache;
+
        /*
         * Indicates if the shadow vmcs or enlightened vmcs must be updated
         * with the data held by struct vmcs12.
index dc7eb5f..5a403d9 100644 (file)
@@ -3307,9 +3307,9 @@ static void record_steal_time(struct kvm_vcpu *vcpu)
                             "xor %1, %1\n"
                             "2:\n"
                             _ASM_EXTABLE_UA(1b, 2b)
-                            : "+r" (st_preempted),
-                              "+&r" (err)
-                            : "m" (st->preempted));
+                            : "+q" (st_preempted),
+                              "+&r" (err),
+                              "+m" (st->preempted));
                if (err)
                        goto out;
 
@@ -4179,7 +4179,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
                r = !static_call(kvm_x86_cpu_has_accelerated_tpr)();
                break;
        case KVM_CAP_NR_VCPUS:
-               r = num_online_cpus();
+               r = min_t(unsigned int, num_online_cpus(), KVM_MAX_VCPUS);
                break;
        case KVM_CAP_MAX_VCPUS:
                r = KVM_MAX_VCPUS;
@@ -8848,7 +8848,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
 
        trace_kvm_hypercall(nr, a0, a1, a2, a3);
 
-       op_64_bit = is_64_bit_mode(vcpu);
+       op_64_bit = is_64_bit_hypercall(vcpu);
        if (!op_64_bit) {
                nr &= 0xFFFFFFFF;
                a0 &= 0xFFFFFFFF;
@@ -9547,12 +9547,16 @@ static void vcpu_load_eoi_exitmap(struct kvm_vcpu *vcpu)
        if (!kvm_apic_hw_enabled(vcpu->arch.apic))
                return;
 
-       if (to_hv_vcpu(vcpu))
+       if (to_hv_vcpu(vcpu)) {
                bitmap_or((ulong *)eoi_exit_bitmap,
                          vcpu->arch.ioapic_handled_vectors,
                          to_hv_synic(vcpu)->vec_bitmap, 256);
+               static_call(kvm_x86_load_eoi_exitmap)(vcpu, eoi_exit_bitmap);
+               return;
+       }
 
-       static_call(kvm_x86_load_eoi_exitmap)(vcpu, eoi_exit_bitmap);
+       static_call(kvm_x86_load_eoi_exitmap)(
+               vcpu, (u64 *)vcpu->arch.ioapic_handled_vectors);
 }
 
 void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
index ea264c4..997669a 100644 (file)
@@ -153,12 +153,24 @@ static inline bool is_64_bit_mode(struct kvm_vcpu *vcpu)
 {
        int cs_db, cs_l;
 
+       WARN_ON_ONCE(vcpu->arch.guest_state_protected);
+
        if (!is_long_mode(vcpu))
                return false;
        static_call(kvm_x86_get_cs_db_l_bits)(vcpu, &cs_db, &cs_l);
        return cs_l;
 }
 
+static inline bool is_64_bit_hypercall(struct kvm_vcpu *vcpu)
+{
+       /*
+        * If running with protected guest state, the CS register is not
+        * accessible. The hypercall register values will have had to been
+        * provided in 64-bit mode, so assume the guest is in 64-bit.
+        */
+       return vcpu->arch.guest_state_protected || is_64_bit_mode(vcpu);
+}
+
 static inline bool x86_exception_has_error_code(unsigned int vector)
 {
        static u32 exception_has_error_code = BIT(DF_VECTOR) | BIT(TS_VECTOR) |
index 8f62bae..dff2bdf 100644 (file)
@@ -127,9 +127,9 @@ void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, int state)
        state_entry_time = vx->runstate_entry_time;
        state_entry_time |= XEN_RUNSTATE_UPDATE;
 
-       BUILD_BUG_ON(sizeof(((struct vcpu_runstate_info *)0)->state_entry_time) !=
+       BUILD_BUG_ON(sizeof_field(struct vcpu_runstate_info, state_entry_time) !=
                     sizeof(state_entry_time));
-       BUILD_BUG_ON(sizeof(((struct compat_vcpu_runstate_info *)0)->state_entry_time) !=
+       BUILD_BUG_ON(sizeof_field(struct compat_vcpu_runstate_info, state_entry_time) !=
                     sizeof(state_entry_time));
 
        if (kvm_write_guest_offset_cached(v->kvm, &v->arch.xen.runstate_cache,
@@ -144,9 +144,9 @@ void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, int state)
         */
        BUILD_BUG_ON(offsetof(struct vcpu_runstate_info, state) !=
                     offsetof(struct compat_vcpu_runstate_info, state));
-       BUILD_BUG_ON(sizeof(((struct vcpu_runstate_info *)0)->state) !=
+       BUILD_BUG_ON(sizeof_field(struct vcpu_runstate_info, state) !=
                     sizeof(vx->current_runstate));
-       BUILD_BUG_ON(sizeof(((struct compat_vcpu_runstate_info *)0)->state) !=
+       BUILD_BUG_ON(sizeof_field(struct compat_vcpu_runstate_info, state) !=
                     sizeof(vx->current_runstate));
 
        if (kvm_write_guest_offset_cached(v->kvm, &v->arch.xen.runstate_cache,
@@ -163,9 +163,9 @@ void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, int state)
                     offsetof(struct vcpu_runstate_info, time) - sizeof(u64));
        BUILD_BUG_ON(offsetof(struct compat_vcpu_runstate_info, state_entry_time) !=
                     offsetof(struct compat_vcpu_runstate_info, time) - sizeof(u64));
-       BUILD_BUG_ON(sizeof(((struct vcpu_runstate_info *)0)->time) !=
-                    sizeof(((struct compat_vcpu_runstate_info *)0)->time));
-       BUILD_BUG_ON(sizeof(((struct vcpu_runstate_info *)0)->time) !=
+       BUILD_BUG_ON(sizeof_field(struct vcpu_runstate_info, time) !=
+                    sizeof_field(struct compat_vcpu_runstate_info, time));
+       BUILD_BUG_ON(sizeof_field(struct vcpu_runstate_info, time) !=
                     sizeof(vx->runstate_times));
 
        if (kvm_write_guest_offset_cached(v->kvm, &v->arch.xen.runstate_cache,
@@ -205,9 +205,9 @@ int __kvm_xen_has_interrupt(struct kvm_vcpu *v)
        BUILD_BUG_ON(offsetof(struct vcpu_info, evtchn_upcall_pending) !=
                     offsetof(struct compat_vcpu_info, evtchn_upcall_pending));
        BUILD_BUG_ON(sizeof(rc) !=
-                    sizeof(((struct vcpu_info *)0)->evtchn_upcall_pending));
+                    sizeof_field(struct vcpu_info, evtchn_upcall_pending));
        BUILD_BUG_ON(sizeof(rc) !=
-                    sizeof(((struct compat_vcpu_info *)0)->evtchn_upcall_pending));
+                    sizeof_field(struct compat_vcpu_info, evtchn_upcall_pending));
 
        /*
         * For efficiency, this mirrors the checks for using the valid
@@ -299,7 +299,7 @@ int kvm_xen_hvm_get_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data)
                break;
 
        case KVM_XEN_ATTR_TYPE_SHARED_INFO:
-               data->u.shared_info.gfn = gpa_to_gfn(kvm->arch.xen.shinfo_gfn);
+               data->u.shared_info.gfn = kvm->arch.xen.shinfo_gfn;
                r = 0;
                break;
 
@@ -698,7 +698,7 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu)
            kvm_hv_hypercall_enabled(vcpu))
                return kvm_hv_hypercall(vcpu);
 
-       longmode = is_64_bit_mode(vcpu);
+       longmode = is_64_bit_hypercall(vcpu);
        if (!longmode) {
                params[0] = (u32)kvm_rbx_read(vcpu);
                params[1] = (u32)kvm_rcx_read(vcpu);
index a8a0416..7b43593 100644 (file)
@@ -121,7 +121,6 @@ void flush_cache_page(struct vm_area_struct*,
 
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 void flush_dcache_page(struct page *);
-void flush_dcache_folio(struct folio *);
 
 void local_flush_cache_range(struct vm_area_struct *vma,
                unsigned long start, unsigned long end);
@@ -138,9 +137,7 @@ void local_flush_cache_page(struct vm_area_struct *vma,
 #define flush_cache_vunmap(start,end)                  do { } while (0)
 
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_FOLIO
 #define flush_dcache_page(page)                                do { } while (0)
-static inline void flush_dcache_folio(struct folio *folio) { }
 
 #define flush_icache_range local_flush_icache_range
 #define flush_cache_page(vma, addr, pfn)               do { } while (0)
index 104b327..3e3e1a5 100644 (file)
 446    common  landlock_restrict_self          sys_landlock_restrict_self
 # 447 reserved for memfd_secret
 448    common  process_mrelease                sys_process_mrelease
+449    common  futex_waitv                     sys_futex_waitv
index b4dab2f..b1d087e 100644 (file)
@@ -753,8 +753,7 @@ struct block_device *blkdev_get_no_open(dev_t dev)
 
        if (!bdev)
                return NULL;
-       if ((bdev->bd_disk->flags & GENHD_FL_HIDDEN) ||
-           !try_module_get(bdev->bd_disk->fops->owner)) {
+       if ((bdev->bd_disk->flags & GENHD_FL_HIDDEN)) {
                put_device(&bdev->bd_device);
                return NULL;
        }
@@ -764,7 +763,6 @@ struct block_device *blkdev_get_no_open(dev_t dev)
 
 void blkdev_put_no_open(struct block_device *bdev)
 {
-       module_put(bdev->bd_disk->fops->owner);
        put_device(&bdev->bd_device);
 }
 
@@ -820,12 +818,14 @@ struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode, void *holder)
        ret = -ENXIO;
        if (!disk_live(disk))
                goto abort_claiming;
+       if (!try_module_get(disk->fops->owner))
+               goto abort_claiming;
        if (bdev_is_partition(bdev))
                ret = blkdev_get_part(bdev, mode);
        else
                ret = blkdev_get_whole(bdev, mode);
        if (ret)
-               goto abort_claiming;
+               goto put_module;
        if (mode & FMODE_EXCL) {
                bd_finish_claiming(bdev, holder);
 
@@ -847,7 +847,8 @@ struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode, void *holder)
        if (unblock_events)
                disk_unblock_events(disk);
        return bdev;
-
+put_module:
+       module_put(disk->fops->owner);
 abort_claiming:
        if (mode & FMODE_EXCL)
                bd_abort_claiming(bdev, holder);
@@ -956,6 +957,7 @@ void blkdev_put(struct block_device *bdev, fmode_t mode)
                blkdev_put_whole(bdev, mode);
        mutex_unlock(&disk->open_mutex);
 
+       module_put(disk->fops->owner);
        blkdev_put_no_open(bdev);
 }
 EXPORT_SYMBOL(blkdev_put);
index 88b1fce..663aabf 100644 (file)
@@ -640,7 +640,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
         */
        ret = blk_queue_enter(q, 0);
        if (ret)
-               return ret;
+               goto fail;
 
        rcu_read_lock();
        spin_lock_irq(&q->queue_lock);
@@ -676,13 +676,13 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
                new_blkg = blkg_alloc(pos, q, GFP_KERNEL);
                if (unlikely(!new_blkg)) {
                        ret = -ENOMEM;
-                       goto fail;
+                       goto fail_exit_queue;
                }
 
                if (radix_tree_preload(GFP_KERNEL)) {
                        blkg_free(new_blkg);
                        ret = -ENOMEM;
-                       goto fail;
+                       goto fail_exit_queue;
                }
 
                rcu_read_lock();
@@ -722,9 +722,10 @@ fail_preloaded:
 fail_unlock:
        spin_unlock_irq(&q->queue_lock);
        rcu_read_unlock();
+fail_exit_queue:
+       blk_queue_exit(q);
 fail:
        blkdev_put_no_open(bdev);
-       blk_queue_exit(q);
        /*
         * If queue was bypassing, we should retry.  Do so after a
         * short msleep().  It isn't strictly necessary but queue
index 9ee32f8..1378d08 100644 (file)
@@ -363,8 +363,10 @@ void blk_cleanup_queue(struct request_queue *q)
        blk_queue_flag_set(QUEUE_FLAG_DEAD, q);
 
        blk_sync_queue(q);
-       if (queue_is_mq(q))
+       if (queue_is_mq(q)) {
+               blk_mq_cancel_work_sync(q);
                blk_mq_exit_queue(q);
+       }
 
        /*
         * In theory, request pool of sched_tags belongs to request queue.
@@ -1015,6 +1017,7 @@ EXPORT_SYMBOL(submit_bio);
 /**
  * bio_poll - poll for BIO completions
  * @bio: bio to poll for
+ * @iob: batches of IO
  * @flags: BLK_POLL_* flags that control the behavior
  *
  * Poll for completions on queue associated with the bio. Returns number of
index 8e364bd..1fce6d1 100644 (file)
@@ -379,7 +379,7 @@ static void mq_flush_data_end_io(struct request *rq, blk_status_t error)
  * @rq is being submitted.  Analyze what needs to be done and put it on the
  * right queue.
  */
-bool blk_insert_flush(struct request *rq)
+void blk_insert_flush(struct request *rq)
 {
        struct request_queue *q = rq->q;
        unsigned long fflags = q->queue_flags;  /* may change, cache */
@@ -409,7 +409,7 @@ bool blk_insert_flush(struct request *rq)
         */
        if (!policy) {
                blk_mq_end_request(rq, 0);
-               return true;
+               return;
        }
 
        BUG_ON(rq->bio != rq->biotail); /*assumes zero or single bio rq */
@@ -420,8 +420,10 @@ bool blk_insert_flush(struct request *rq)
         * for normal execution.
         */
        if ((policy & REQ_FSEQ_DATA) &&
-           !(policy & (REQ_FSEQ_PREFLUSH | REQ_FSEQ_POSTFLUSH)))
-               return false;
+           !(policy & (REQ_FSEQ_PREFLUSH | REQ_FSEQ_POSTFLUSH))) {
+               blk_mq_request_bypass_insert(rq, false, true);
+               return;
+       }
 
        /*
         * @rq should go through flush machinery.  Mark it part of flush
@@ -437,8 +439,6 @@ bool blk_insert_flush(struct request *rq)
        spin_lock_irq(&fq->mq_flush_lock);
        blk_flush_complete_seq(rq, fq, REQ_FSEQ_ACTIONS & ~policy, 0);
        spin_unlock_irq(&fq->mq_flush_lock);
-
-       return true;
 }
 
 /**
index 3ab34c4..8874a63 100644 (file)
@@ -860,13 +860,14 @@ void blk_mq_end_request_batch(struct io_comp_batch *iob)
                if (iob->need_ts)
                        __blk_mq_end_request_acct(rq, now);
 
+               rq_qos_done(rq->q, rq);
+
                WRITE_ONCE(rq->state, MQ_RQ_IDLE);
                if (!refcount_dec_and_test(&rq->ref))
                        continue;
 
                blk_crypto_free_request(rq);
                blk_pm_mark_last_busy(rq);
-               rq_qos_done(rq->q, rq);
 
                if (nr_tags == TAG_COMP_BATCH || cur_hctx != rq->mq_hctx) {
                        if (cur_hctx)
@@ -2543,8 +2544,7 @@ static struct request *blk_mq_get_new_requests(struct request_queue *q,
        return NULL;
 }
 
-static inline bool blk_mq_can_use_cached_rq(struct request *rq,
-               struct bio *bio)
+static inline bool blk_mq_can_use_cached_rq(struct request *rq, struct bio *bio)
 {
        if (blk_mq_get_hctx_type(bio->bi_opf) != rq->mq_hctx->type)
                return false;
@@ -2565,7 +2565,6 @@ static inline struct request *blk_mq_get_request(struct request_queue *q,
        bool checked = false;
 
        if (plug) {
-
                rq = rq_list_peek(&plug->cached_rq);
                if (rq && rq->q == q) {
                        if (unlikely(!submit_bio_checks(bio)))
@@ -2587,12 +2586,14 @@ static inline struct request *blk_mq_get_request(struct request_queue *q,
 fallback:
        if (unlikely(bio_queue_enter(bio)))
                return NULL;
-       if (!checked && !submit_bio_checks(bio))
-               return NULL;
+       if (unlikely(!checked && !submit_bio_checks(bio)))
+               goto out_put;
        rq = blk_mq_get_new_requests(q, plug, bio, nsegs, same_queue_rq);
-       if (!rq)
-               blk_queue_exit(q);
-       return rq;
+       if (rq)
+               return rq;
+out_put:
+       blk_queue_exit(q);
+       return NULL;
 }
 
 /**
@@ -2647,8 +2648,10 @@ void blk_mq_submit_bio(struct bio *bio)
                return;
        }
 
-       if (op_is_flush(bio->bi_opf) && blk_insert_flush(rq))
+       if (op_is_flush(bio->bi_opf)) {
+               blk_insert_flush(rq);
                return;
+       }
 
        if (plug && (q->nr_hw_queues == 1 ||
            blk_mq_is_shared_tags(rq->mq_hctx->flags) ||
@@ -4417,6 +4420,19 @@ unsigned int blk_mq_rq_cpu(struct request *rq)
 }
 EXPORT_SYMBOL(blk_mq_rq_cpu);
 
+void blk_mq_cancel_work_sync(struct request_queue *q)
+{
+       if (queue_is_mq(q)) {
+               struct blk_mq_hw_ctx *hctx;
+               int i;
+
+               cancel_delayed_work_sync(&q->requeue_work);
+
+               queue_for_each_hw_ctx(q, hctx, i)
+                       cancel_delayed_work_sync(&hctx->run_work);
+       }
+}
+
 static int __init blk_mq_init(void)
 {
        int i;
index 8acfa65..afcf993 100644 (file)
@@ -128,6 +128,8 @@ extern void blk_mq_hctx_kobj_init(struct blk_mq_hw_ctx *hctx);
 void blk_mq_free_plug_rqs(struct blk_plug *plug);
 void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule);
 
+void blk_mq_cancel_work_sync(struct request_queue *q);
+
 void blk_mq_release(struct request_queue *q);
 
 static inline struct blk_mq_ctx *__blk_mq_get_ctx(struct request_queue *q,
index cef1f71..cd75b0f 100644 (file)
@@ -791,16 +791,6 @@ static void blk_release_queue(struct kobject *kobj)
 
        blk_free_queue_stats(q->stats);
 
-       if (queue_is_mq(q)) {
-               struct blk_mq_hw_ctx *hctx;
-               int i;
-
-               cancel_delayed_work_sync(&q->requeue_work);
-
-               queue_for_each_hw_ctx(q, hctx, i)
-                       cancel_delayed_work_sync(&hctx->run_work);
-       }
-
        blk_exit_queue(q);
 
        blk_queue_free_zone_bitmaps(q);
index b4fed20..ccde6e6 100644 (file)
@@ -271,7 +271,7 @@ void __blk_account_io_done(struct request *req, u64 now);
  */
 #define ELV_ON_HASH(rq) ((rq)->rq_flags & RQF_HASHED)
 
-bool blk_insert_flush(struct request *rq);
+void blk_insert_flush(struct request *rq);
 
 int elevator_switch_mq(struct request_queue *q,
                              struct elevator_type *new_e);
index 1f39f6e..19a78d5 100644 (file)
@@ -694,12 +694,18 @@ void elevator_init_mq(struct request_queue *q)
        if (!e)
                return;
 
+       /*
+        * We are called before adding disk, when there isn't any FS I/O,
+        * so freezing queue plus canceling dispatch work is enough to
+        * drain any dispatch activities originated from passthrough
+        * requests, then no need to quiesce queue which may add long boot
+        * latency, especially when lots of disks are involved.
+        */
        blk_mq_freeze_queue(q);
-       blk_mq_quiesce_queue(q);
+       blk_mq_cancel_work_sync(q);
 
        err = blk_mq_init_sched(q, e);
 
-       blk_mq_unquiesce_queue(q);
        blk_mq_unfreeze_queue(q);
 
        if (err) {
index c5392cc..30362ae 100644 (file)
@@ -1111,6 +1111,8 @@ static void disk_release(struct device *dev)
        might_sleep();
        WARN_ON_ONCE(disk_live(disk));
 
+       blk_mq_cancel_work_sync(disk->queue);
+
        disk_release_events(disk);
        kfree(disk->random);
        xa_destroy(&disk->part_tbl);
index 0e4ff24..313c14a 100644 (file)
@@ -69,7 +69,14 @@ int ioprio_check_cap(int ioprio)
 
        switch (class) {
                case IOPRIO_CLASS_RT:
-                       if (!capable(CAP_SYS_NICE) && !capable(CAP_SYS_ADMIN))
+                       /*
+                        * Originally this only checked for CAP_SYS_ADMIN,
+                        * which was implicitly allowed for pid 0 by security
+                        * modules such as SELinux. Make sure we check
+                        * CAP_SYS_ADMIN first to avoid a denial/avc for
+                        * possibly missing CAP_SYS_NICE permission.
+                        */
+                       if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_NICE))
                                return -EPERM;
                        fallthrough;
                        /* rt has prio field too */
index a85c351..b62c87b 100644 (file)
@@ -998,7 +998,14 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
 static int cppc_get_perf(int cpunum, enum cppc_regs reg_idx, u64 *perf)
 {
        struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum);
-       struct cpc_register_resource *reg = &cpc_desc->cpc_regs[reg_idx];
+       struct cpc_register_resource *reg;
+
+       if (!cpc_desc) {
+               pr_debug("No CPC descriptor for CPU:%d\n", cpunum);
+               return -ENODEV;
+       }
+
+       reg = &cpc_desc->cpc_regs[reg_idx];
 
        if (CPC_IN_PCC(reg)) {
                int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum);
index 7cd0009..ef10480 100644 (file)
@@ -347,28 +347,3 @@ void acpi_device_notify_remove(struct device *dev)
 
        acpi_unbind_one(dev);
 }
-
-int acpi_dev_turn_off_if_unused(struct device *dev, void *not_used)
-{
-       struct acpi_device *adev = to_acpi_device(dev);
-
-       /*
-        * Skip device objects with device IDs, because they may be in use even
-        * if they are not companions of any physical device objects.
-        */
-       if (adev->pnp.type.hardware_id)
-               return 0;
-
-       mutex_lock(&adev->physical_node_lock);
-
-       /*
-        * Device objects without device IDs are not in use if they have no
-        * corresponding physical device objects.
-        */
-       if (list_empty(&adev->physical_node_list))
-               acpi_device_set_power(adev, ACPI_STATE_D3_COLD);
-
-       mutex_unlock(&adev->physical_node_lock);
-
-       return 0;
-}
index 8fbdc17..d91b560 100644 (file)
@@ -117,7 +117,6 @@ bool acpi_device_is_battery(struct acpi_device *adev);
 bool acpi_device_is_first_physical_node(struct acpi_device *adev,
                                        const struct device *dev);
 int acpi_bus_register_early_device(int type);
-int acpi_dev_turn_off_if_unused(struct device *dev, void *not_used);
 
 /* --------------------------------------------------------------------------
                      Device Matching and Notification
index e312eba..2366f54 100644 (file)
@@ -1084,21 +1084,17 @@ struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode,
  * Returns parent node of an ACPI device or data firmware node or %NULL if
  * not available.
  */
-struct fwnode_handle *acpi_node_get_parent(const struct fwnode_handle *fwnode)
+static struct fwnode_handle *
+acpi_node_get_parent(const struct fwnode_handle *fwnode)
 {
        if (is_acpi_data_node(fwnode)) {
                /* All data nodes have parent pointer so just return that */
                return to_acpi_data_node(fwnode)->parent;
        } else if (is_acpi_device_node(fwnode)) {
-               acpi_handle handle, parent_handle;
-
-               handle = to_acpi_device_node(fwnode)->handle;
-               if (ACPI_SUCCESS(acpi_get_parent(handle, &parent_handle))) {
-                       struct acpi_device *adev;
+               struct device *dev = to_acpi_device_node(fwnode)->dev.parent;
 
-                       if (!acpi_bus_get_device(parent_handle, &adev))
-                               return acpi_fwnode_handle(adev);
-               }
+               if (dev)
+                       return acpi_fwnode_handle(to_acpi_device(dev));
        }
 
        return NULL;
index a50f196..2c80765 100644 (file)
@@ -2564,12 +2564,6 @@ int __init acpi_scan_init(void)
                }
        }
 
-       /*
-        * Make sure that power management resources are not blocked by ACPI
-        * device objects with no users.
-        */
-       bus_for_each_dev(&acpi_bus_type, NULL, NULL, acpi_dev_turn_off_if_unused);
-
        acpi_turn_off_unused_power_resources();
 
        acpi_scan_initialized = true;
index 49fb741..cffbe57 100644 (file)
@@ -2710,7 +2710,7 @@ static void binder_transaction(struct binder_proc *proc,
                t->from = thread;
        else
                t->from = NULL;
-       t->sender_euid = proc->cred->euid;
+       t->sender_euid = task_euid(proc->tsk);
        t->to_proc = target_proc;
        t->to_thread = target_thread;
        t->code = tr->code;
index d60f347..1e1167e 100644 (file)
@@ -438,6 +438,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        /* AMD */
        { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */
        { PCI_VDEVICE(AMD, 0x7900), board_ahci }, /* AMD CZ */
+       { PCI_VDEVICE(AMD, 0x7901), board_ahci_mobile }, /* AMD Green Sardine */
        /* AMD is using RAID class only for ahci controllers */
        { PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
          PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci },
index 8a6835b..f76b841 100644 (file)
@@ -2323,6 +2323,18 @@ int ahci_port_resume(struct ata_port *ap)
 EXPORT_SYMBOL_GPL(ahci_port_resume);
 
 #ifdef CONFIG_PM
+static void ahci_handle_s2idle(struct ata_port *ap)
+{
+       void __iomem *port_mmio = ahci_port_base(ap);
+       u32 devslp;
+
+       if (pm_suspend_via_firmware())
+               return;
+       devslp = readl(port_mmio + PORT_DEVSLP);
+       if ((devslp & PORT_DEVSLP_ADSE))
+               ata_msleep(ap, devslp_idle_timeout);
+}
+
 static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
 {
        const char *emsg = NULL;
@@ -2336,6 +2348,9 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
                ata_port_freeze(ap);
        }
 
+       if (acpi_storage_d3(ap->host->dev))
+               ahci_handle_s2idle(ap);
+
        ahci_rpm_put_port(ap);
        return rc;
 }
index 8a0ccb1..59ad8c9 100644 (file)
@@ -2031,8 +2031,9 @@ retry:
                        dev->horkage |= ATA_HORKAGE_NO_DMA_LOG;
                        goto retry;
                }
-               ata_dev_err(dev, "Read log page 0x%02x failed, Emask 0x%x\n",
-                           (unsigned int)page, err_mask);
+               ata_dev_err(dev,
+                           "Read log 0x%02x page 0x%02x failed, Emask 0x%x\n",
+                           (unsigned int)log, (unsigned int)page, err_mask);
        }
 
        return err_mask;
@@ -2177,6 +2178,9 @@ static void ata_dev_config_ncq_prio(struct ata_device *dev)
        struct ata_port *ap = dev->link->ap;
        unsigned int err_mask;
 
+       if (!ata_identify_page_supported(dev, ATA_LOG_SATA_SETTINGS))
+               return;
+
        err_mask = ata_read_log_page(dev,
                                     ATA_LOG_IDENTIFY_DEVICE,
                                     ATA_LOG_SATA_SETTINGS,
@@ -2453,7 +2457,8 @@ static void ata_dev_config_devslp(struct ata_device *dev)
         * Check device sleep capability. Get DevSlp timing variables
         * from SATA Settings page of Identify Device Data Log.
         */
-       if (!ata_id_has_devslp(dev->id))
+       if (!ata_id_has_devslp(dev->id) ||
+           !ata_identify_page_supported(dev, ATA_LOG_SATA_SETTINGS))
                return;
 
        err_mask = ata_read_log_page(dev,
index 4e88597..5b78e86 100644 (file)
@@ -922,7 +922,7 @@ DEVICE_ATTR(ncq_prio_enable, S_IRUGO | S_IWUSR,
            ata_ncq_prio_enable_show, ata_ncq_prio_enable_store);
 EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_enable);
 
-struct attribute *ata_ncq_sdev_attrs[] = {
+static struct attribute *ata_ncq_sdev_attrs[] = {
        &dev_attr_unload_heads.attr,
        &dev_attr_ncq_prio_enable.attr,
        &dev_attr_ncq_prio_supported.attr,
index 97bf051..6ae3877 100644 (file)
@@ -316,7 +316,7 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
        struct request *req = bd->rq;
        struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
        unsigned long flags;
-       unsigned int num;
+       int num;
        int qid = hctx->queue_num;
        bool notify = false;
        blk_status_t status;
@@ -1049,7 +1049,6 @@ static struct virtio_driver virtio_blk = {
        .feature_table_size             = ARRAY_SIZE(features),
        .feature_table_legacy           = features_legacy,
        .feature_table_size_legacy      = ARRAY_SIZE(features_legacy),
-       .suppress_used_validation       = true,
        .driver.name                    = KBUILD_MODNAME,
        .driver.owner                   = THIS_MODULE,
        .id_table                       = id_table,
index 08d7953..2507112 100644 (file)
@@ -1853,12 +1853,14 @@ static const struct block_device_operations zram_devops = {
        .owner = THIS_MODULE
 };
 
+#ifdef CONFIG_ZRAM_WRITEBACK
 static const struct block_device_operations zram_wb_devops = {
        .open = zram_open,
        .submit_bio = zram_submit_bio,
        .swap_slot_free_notify = zram_slot_free_notify,
        .owner = THIS_MODULE
 };
+#endif
 
 static DEVICE_ATTR_WO(compact);
 static DEVICE_ATTR_RW(disksize);
index 815df3d..dec2a56 100644 (file)
@@ -338,6 +338,8 @@ static void intel_pstste_sched_itmt_work_fn(struct work_struct *work)
 
 static DECLARE_WORK(sched_itmt_work, intel_pstste_sched_itmt_work_fn);
 
+#define CPPC_MAX_PERF  U8_MAX
+
 static void intel_pstate_set_itmt_prio(int cpu)
 {
        struct cppc_perf_caps cppc_perf;
@@ -348,6 +350,14 @@ static void intel_pstate_set_itmt_prio(int cpu)
        if (ret)
                return;
 
+       /*
+        * On some systems with overclocking enabled, CPPC.highest_perf is hardcoded to 0xff.
+        * In this case we can't use CPPC.highest_perf to enable ITMT.
+        * In this case we can look at MSR_HWP_CAPABILITIES bits [8:0] to decide.
+        */
+       if (cppc_perf.highest_perf == CPPC_MAX_PERF)
+               cppc_perf.highest_perf = HWP_HIGHEST_PERF(READ_ONCE(all_cpu_data[cpu]->hwp_cap_cached));
+
        /*
         * The priorities can be set regardless of whether or not
         * sched_set_itmt_support(true) has been called and it is valid to
@@ -1006,6 +1016,12 @@ static void intel_pstate_hwp_offline(struct cpudata *cpu)
                 */
                value &= ~GENMASK_ULL(31, 24);
                value |= HWP_ENERGY_PERF_PREFERENCE(cpu->epp_cached);
+               /*
+                * However, make sure that EPP will be set to "performance" when
+                * the CPU is brought back online again and the "performance"
+                * scaling algorithm is still in effect.
+                */
+               cpu->epp_policy = CPUFREQ_POLICY_UNKNOWN;
        }
 
        /*
@@ -2353,6 +2369,7 @@ static const struct x86_cpu_id intel_pstate_cpu_oob_ids[] __initconst = {
        X86_MATCH(BROADWELL_D,          core_funcs),
        X86_MATCH(BROADWELL_X,          core_funcs),
        X86_MATCH(SKYLAKE_X,            core_funcs),
+       X86_MATCH(ICELAKE_X,            core_funcs),
        {}
 };
 
index de416f9..f521933 100644 (file)
@@ -34,6 +34,12 @@ struct scmi_msg_resp_base_attributes {
        __le16 reserved;
 };
 
+struct scmi_msg_resp_base_discover_agent {
+       __le32 agent_id;
+       u8 name[SCMI_MAX_STR_SIZE];
+};
+
+
 struct scmi_msg_base_error_notify {
        __le32 event_control;
 #define BASE_TP_NOTIFY_ALL     BIT(0)
@@ -225,18 +231,21 @@ static int scmi_base_discover_agent_get(const struct scmi_protocol_handle *ph,
                                        int id, char *name)
 {
        int ret;
+       struct scmi_msg_resp_base_discover_agent *agent_info;
        struct scmi_xfer *t;
 
        ret = ph->xops->xfer_get_init(ph, BASE_DISCOVER_AGENT,
-                                     sizeof(__le32), SCMI_MAX_STR_SIZE, &t);
+                                     sizeof(__le32), sizeof(*agent_info), &t);
        if (ret)
                return ret;
 
        put_unaligned_le32(id, t->tx.buf);
 
        ret = ph->xops->do_xfer(ph, t);
-       if (!ret)
-               strlcpy(name, t->rx.buf, SCMI_MAX_STR_SIZE);
+       if (!ret) {
+               agent_info = t->rx.buf;
+               strlcpy(name, agent_info->name, SCMI_MAX_STR_SIZE);
+       }
 
        ph->xops->xfer_put(ph, t);
 
index 4371fdc..581d34c 100644 (file)
@@ -138,9 +138,7 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev)
        scmi_pd_data->domains = domains;
        scmi_pd_data->num_domains = num_domains;
 
-       of_genpd_add_provider_onecell(np, scmi_pd_data);
-
-       return 0;
+       return of_genpd_add_provider_onecell(np, scmi_pd_data);
 }
 
 static const struct scmi_device_id scmi_id_table[] = {
index 3084715..cdbb287 100644 (file)
@@ -637,7 +637,7 @@ static int scmi_sensor_config_get(const struct scmi_protocol_handle *ph,
        if (ret)
                return ret;
 
-       put_unaligned_le32(cpu_to_le32(sensor_id), t->tx.buf);
+       put_unaligned_le32(sensor_id, t->tx.buf);
        ret = ph->xops->do_xfer(ph, t);
        if (!ret) {
                struct sensors_info *si = ph->get_priv(ph);
index 11e8efb..87039c5 100644 (file)
@@ -82,7 +82,8 @@ static bool scmi_vio_have_vq_rx(struct virtio_device *vdev)
 }
 
 static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch,
-                              struct scmi_vio_msg *msg)
+                              struct scmi_vio_msg *msg,
+                              struct device *dev)
 {
        struct scatterlist sg_in;
        int rc;
@@ -94,8 +95,7 @@ static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch,
 
        rc = virtqueue_add_inbuf(vioch->vqueue, &sg_in, 1, msg, GFP_ATOMIC);
        if (rc)
-               dev_err_once(vioch->cinfo->dev,
-                            "failed to add to virtqueue (%d)\n", rc);
+               dev_err_once(dev, "failed to add to virtqueue (%d)\n", rc);
        else
                virtqueue_kick(vioch->vqueue);
 
@@ -108,7 +108,7 @@ static void scmi_finalize_message(struct scmi_vio_channel *vioch,
                                  struct scmi_vio_msg *msg)
 {
        if (vioch->is_rx) {
-               scmi_vio_feed_vq_rx(vioch, msg);
+               scmi_vio_feed_vq_rx(vioch, msg, vioch->cinfo->dev);
        } else {
                /* Here IRQs are assumed to be already disabled by the caller */
                spin_lock(&vioch->lock);
@@ -269,7 +269,7 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
                        list_add_tail(&msg->list, &vioch->free_list);
                        spin_unlock_irqrestore(&vioch->lock, flags);
                } else {
-                       scmi_vio_feed_vq_rx(vioch, msg);
+                       scmi_vio_feed_vq_rx(vioch, msg, cinfo->dev);
                }
        }
 
index a504895..ac08e81 100644 (file)
@@ -156,7 +156,7 @@ static int scmi_voltage_descriptors_get(const struct scmi_protocol_handle *ph,
                        int cnt;
 
                        cmd->domain_id = cpu_to_le32(v->id);
-                       cmd->level_index = desc_index;
+                       cmd->level_index = cpu_to_le32(desc_index);
                        ret = ph->xops->do_xfer(ph, tl);
                        if (ret)
                                break;
index 581aa5e..dd7c3d5 100644 (file)
@@ -50,7 +50,7 @@ static int __init smccc_soc_init(void)
        arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
                             ARM_SMCCC_ARCH_SOC_ID, &res);
 
-       if (res.a0 == SMCCC_RET_NOT_SUPPORTED) {
+       if ((int)res.a0 == SMCCC_RET_NOT_SUPPORTED) {
                pr_info("ARCH_SOC_ID not implemented, skipping ....\n");
                return 0;
        }
index 072ed61..60d9374 100644 (file)
@@ -523,6 +523,7 @@ config GPIO_REG
 config GPIO_ROCKCHIP
        tristate "Rockchip GPIO support"
        depends on ARCH_ROCKCHIP || COMPILE_TEST
+       select GENERIC_IRQ_CHIP
        select GPIOLIB_IRQCHIP
        default ARCH_ROCKCHIP
        help
index aeec4bf..84f96b7 100644 (file)
@@ -434,7 +434,7 @@ static void virtio_gpio_event_vq(struct virtqueue *vq)
                ret = generic_handle_domain_irq(vgpio->gc.irq.domain, gpio);
                if (ret)
                        dev_err(dev, "failed to handle interrupt: %d\n", ret);
-       };
+       }
 }
 
 static void virtio_gpio_request_vq(struct virtqueue *vq)
index 71acd57..71a6a9e 100644 (file)
@@ -646,12 +646,6 @@ kfd_mem_attach_dmabuf(struct amdgpu_device *adev, struct kgd_mem *mem,
        if (IS_ERR(gobj))
                return PTR_ERR(gobj);
 
-       /* Import takes an extra reference on the dmabuf. Drop it now to
-        * avoid leaking it. We only need the one reference in
-        * kgd_mem->dmabuf.
-        */
-       dma_buf_put(mem->dmabuf);
-
        *bo = gem_to_amdgpu_bo(gobj);
        (*bo)->flags |= AMDGPU_GEM_CREATE_PREEMPTIBLE;
        (*bo)->parent = amdgpu_bo_ref(mem->bo);
index 96b7bb1..12a6b1c 100644 (file)
@@ -1569,6 +1569,18 @@ void amdgpu_atombios_scratch_regs_engine_hung(struct amdgpu_device *adev,
        WREG32(adev->bios_scratch_reg_offset + 3, tmp);
 }
 
+void amdgpu_atombios_scratch_regs_set_backlight_level(struct amdgpu_device *adev,
+                                                     u32 backlight_level)
+{
+       u32 tmp = RREG32(adev->bios_scratch_reg_offset + 2);
+
+       tmp &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK;
+       tmp |= (backlight_level << ATOM_S2_CURRENT_BL_LEVEL_SHIFT) &
+               ATOM_S2_CURRENT_BL_LEVEL_MASK;
+
+       WREG32(adev->bios_scratch_reg_offset + 2, tmp);
+}
+
 bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev)
 {
        u32 tmp = RREG32(adev->bios_scratch_reg_offset + 7);
index 8cc0222..27e74b1 100644 (file)
@@ -185,6 +185,8 @@ bool amdgpu_atombios_has_gpu_virtualization_table(struct amdgpu_device *adev);
 void amdgpu_atombios_scratch_regs_lock(struct amdgpu_device *adev, bool lock);
 void amdgpu_atombios_scratch_regs_engine_hung(struct amdgpu_device *adev,
                                              bool hung);
+void amdgpu_atombios_scratch_regs_set_backlight_level(struct amdgpu_device *adev,
+                                                     u32 backlight_level);
 bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev);
 
 void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le);
index b9c11c2..0de66f5 100644 (file)
@@ -827,6 +827,7 @@ static int amdgpu_connector_vga_get_modes(struct drm_connector *connector)
 
        amdgpu_connector_get_edid(connector);
        ret = amdgpu_connector_ddc_get_modes(connector);
+       amdgpu_get_native_mode(connector);
 
        return ret;
 }
index 5625f77..d94fa74 100644 (file)
@@ -3509,6 +3509,9 @@ int amdgpu_device_init(struct amdgpu_device *adev,
                adev->rmmio_size = pci_resource_len(adev->pdev, 2);
        }
 
+       for (i = 0; i < AMD_IP_BLOCK_TYPE_NUM; i++)
+               atomic_set(&adev->pm.pwr_state[i], POWER_STATE_UNKNOWN);
+
        adev->rmmio = ioremap(adev->rmmio_base, adev->rmmio_size);
        if (adev->rmmio == NULL) {
                return -ENOMEM;
@@ -4313,7 +4316,6 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev,
 
        amdgpu_irq_gpu_reset_resume_helper(adev);
        r = amdgpu_ib_ring_tests(adev);
-       amdgpu_amdkfd_post_reset(adev);
 
 error:
        if (!r && adev->virt.gim_feature & AMDGIM_FEATURE_GIM_FLR_VRAMLOST) {
@@ -5086,7 +5088,7 @@ retry:    /* Rest of adevs pre asic reset from XGMI hive. */
 
        tmp_vram_lost_counter = atomic_read(&((adev)->vram_lost_counter));
        /* Actual ASIC resets if needed.*/
-       /* TODO Implement XGMI hive reset logic for SRIOV */
+       /* Host driver will handle XGMI hive reset for SRIOV */
        if (amdgpu_sriov_vf(adev)) {
                r = amdgpu_device_reset_sriov(adev, job ? false : true);
                if (r)
@@ -5146,8 +5148,8 @@ skip_hw_reset:
 
 skip_sched_resume:
        list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
-               /* unlock kfd: SRIOV would do it separately */
-               if (!need_emergency_restart && !amdgpu_sriov_vf(tmp_adev))
+               /* unlock kfd */
+               if (!need_emergency_restart)
                        amdgpu_amdkfd_post_reset(tmp_adev);
 
                /* kfd_post_reset will do nothing if kfd device is not initialized,
index ff70bc2..503995c 100644 (file)
@@ -248,8 +248,8 @@ get_from_vram:
 
        offset = offsetof(struct binary_header, binary_checksum) +
                sizeof(bhdr->binary_checksum);
-       size = bhdr->binary_size - offset;
-       checksum = bhdr->binary_checksum;
+       size = le16_to_cpu(bhdr->binary_size) - offset;
+       checksum = le16_to_cpu(bhdr->binary_checksum);
 
        if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset,
                                              size, checksum)) {
@@ -270,7 +270,7 @@ get_from_vram:
        }
 
        if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset,
-                                             ihdr->size, checksum)) {
+                                             le16_to_cpu(ihdr->size), checksum)) {
                DRM_ERROR("invalid ip discovery data table checksum\n");
                r = -EINVAL;
                goto out;
@@ -282,7 +282,7 @@ get_from_vram:
        ghdr = (struct gpu_info_header *)(adev->mman.discovery_bin + offset);
 
        if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset,
-                                             ghdr->size, checksum)) {
+                                             le32_to_cpu(ghdr->size), checksum)) {
                DRM_ERROR("invalid gc data table checksum\n");
                r = -EINVAL;
                goto out;
@@ -489,10 +489,10 @@ void amdgpu_discovery_harvest_ip(struct amdgpu_device *adev)
                        le16_to_cpu(bhdr->table_list[HARVEST_INFO].offset));
 
        for (i = 0; i < 32; i++) {
-               if (le32_to_cpu(harvest_info->list[i].hw_id) == 0)
+               if (le16_to_cpu(harvest_info->list[i].hw_id) == 0)
                        break;
 
-               switch (le32_to_cpu(harvest_info->list[i].hw_id)) {
+               switch (le16_to_cpu(harvest_info->list[i].hw_id)) {
                case VCN_HWID:
                        vcn_harvest_count++;
                        if (harvest_info->list[i].number_instance == 0)
@@ -587,6 +587,9 @@ static int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev)
                amdgpu_device_ip_block_add(adev, &nv_common_ip_block);
                break;
        default:
+               dev_err(adev->dev,
+                       "Failed to add common ip block(GC_HWIP:0x%x)\n",
+                       adev->ip_versions[GC_HWIP][0]);
                return -EINVAL;
        }
        return 0;
@@ -619,6 +622,9 @@ static int amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device *adev)
                amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block);
                break;
        default:
+               dev_err(adev->dev,
+                       "Failed to add gmc ip block(GC_HWIP:0x%x)\n",
+                       adev->ip_versions[GC_HWIP][0]);
                return -EINVAL;
        }
        return 0;
@@ -648,6 +654,9 @@ static int amdgpu_discovery_set_ih_ip_blocks(struct amdgpu_device *adev)
                amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
                break;
        default:
+               dev_err(adev->dev,
+                       "Failed to add ih ip block(OSSSYS_HWIP:0x%x)\n",
+                       adev->ip_versions[OSSSYS_HWIP][0]);
                return -EINVAL;
        }
        return 0;
@@ -688,6 +697,9 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
                amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
                break;
        default:
+               dev_err(adev->dev,
+                       "Failed to add psp ip block(MP0_HWIP:0x%x)\n",
+                       adev->ip_versions[MP0_HWIP][0]);
                return -EINVAL;
        }
        return 0;
@@ -726,6 +738,9 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)
                amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
                break;
        default:
+               dev_err(adev->dev,
+                       "Failed to add smu ip block(MP1_HWIP:0x%x)\n",
+                       adev->ip_versions[MP1_HWIP][0]);
                return -EINVAL;
        }
        return 0;
@@ -753,6 +768,9 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
                        amdgpu_device_ip_block_add(adev, &dm_ip_block);
                        break;
                default:
+                       dev_err(adev->dev,
+                               "Failed to add dm ip block(DCE_HWIP:0x%x)\n",
+                               adev->ip_versions[DCE_HWIP][0]);
                        return -EINVAL;
                }
        } else if (adev->ip_versions[DCI_HWIP][0]) {
@@ -763,6 +781,9 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
                        amdgpu_device_ip_block_add(adev, &dm_ip_block);
                        break;
                default:
+                       dev_err(adev->dev,
+                               "Failed to add dm ip block(DCI_HWIP:0x%x)\n",
+                               adev->ip_versions[DCI_HWIP][0]);
                        return -EINVAL;
                }
 #endif
@@ -796,6 +817,9 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
                amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
                break;
        default:
+               dev_err(adev->dev,
+                       "Failed to add gfx ip block(GC_HWIP:0x%x)\n",
+                       adev->ip_versions[GC_HWIP][0]);
                return -EINVAL;
        }
        return 0;
@@ -829,6 +853,9 @@ static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev)
                amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
                break;
        default:
+               dev_err(adev->dev,
+                       "Failed to add sdma ip block(SDMA0_HWIP:0x%x)\n",
+                       adev->ip_versions[SDMA0_HWIP][0]);
                return -EINVAL;
        }
        return 0;
@@ -845,6 +872,9 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
                                amdgpu_device_ip_block_add(adev, &uvd_v7_0_ip_block);
                        break;
                default:
+                       dev_err(adev->dev,
+                               "Failed to add uvd v7 ip block(UVD_HWIP:0x%x)\n",
+                               adev->ip_versions[UVD_HWIP][0]);
                        return -EINVAL;
                }
                switch (adev->ip_versions[VCE_HWIP][0]) {
@@ -855,6 +885,9 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
                                amdgpu_device_ip_block_add(adev, &vce_v4_0_ip_block);
                        break;
                default:
+                       dev_err(adev->dev,
+                               "Failed to add VCE v4 ip block(VCE_HWIP:0x%x)\n",
+                               adev->ip_versions[VCE_HWIP][0]);
                        return -EINVAL;
                }
        } else {
@@ -893,6 +926,9 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
                        amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block);
                        break;
                default:
+                       dev_err(adev->dev,
+                               "Failed to add vcn/jpeg ip block(UVD_HWIP:0x%x)\n",
+                               adev->ip_versions[UVD_HWIP][0]);
                        return -EINVAL;
                }
        }
index f3d62e1..0c7963d 100644 (file)
@@ -223,7 +223,7 @@ int amdgpu_ih_wait_on_checkpoint_process(struct amdgpu_device *adev,
  */
 int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih)
 {
-       unsigned int count = AMDGPU_IH_MAX_NUM_IVS;
+       unsigned int count;
        u32 wptr;
 
        if (!ih->enabled || adev->shutdown)
@@ -232,6 +232,7 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih)
        wptr = amdgpu_ih_get_wptr(adev, ih);
 
 restart_ih:
+       count  = AMDGPU_IH_MAX_NUM_IVS;
        DRM_DEBUG("%s: rptr %d, wptr %d\n", __func__, ih->rptr, wptr);
 
        /* Order reading of wptr vs. reading of IH ring data */
index 0fad2bf..567df2d 100644 (file)
@@ -386,6 +386,7 @@ struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev)
                        "%s", "xgmi_hive_info");
        if (ret) {
                dev_err(adev->dev, "XGMI: failed initializing kobject for xgmi hive\n");
+               kobject_put(&hive->kobj);
                kfree(hive);
                hive = NULL;
                goto pro_end;
index e7dfeb4..dbe7442 100644 (file)
@@ -7707,8 +7707,19 @@ static uint64_t gfx_v10_0_get_gpu_clock_counter(struct amdgpu_device *adev)
        switch (adev->ip_versions[GC_HWIP][0]) {
        case IP_VERSION(10, 3, 1):
        case IP_VERSION(10, 3, 3):
-               clock = (uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Vangogh) |
-                       ((uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Vangogh) << 32ULL);
+               preempt_disable();
+               clock_hi = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Vangogh);
+               clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Vangogh);
+               hi_check = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Vangogh);
+               /* The SMUIO TSC clock frequency is 100MHz, which sets 32-bit carry over
+                * roughly every 42 seconds.
+                */
+               if (hi_check != clock_hi) {
+                       clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Vangogh);
+                       clock_hi = hi_check;
+               }
+               preempt_enable();
+               clock = clock_lo | (clock_hi << 32ULL);
                break;
        default:
                preempt_disable();
index b4b80f2..34478bc 100644 (file)
@@ -140,6 +140,11 @@ MODULE_FIRMWARE("amdgpu/aldebaran_rlc.bin");
 #define mmTCP_CHAN_STEER_5_ARCT                                                                0x0b0c
 #define mmTCP_CHAN_STEER_5_ARCT_BASE_IDX                                                       0
 
+#define mmGOLDEN_TSC_COUNT_UPPER_Renoir                0x0025
+#define mmGOLDEN_TSC_COUNT_UPPER_Renoir_BASE_IDX       1
+#define mmGOLDEN_TSC_COUNT_LOWER_Renoir                0x0026
+#define mmGOLDEN_TSC_COUNT_LOWER_Renoir_BASE_IDX       1
+
 enum ta_ras_gfx_subblock {
        /*CPC*/
        TA_RAS_BLOCK__GFX_CPC_INDEX_START = 0,
@@ -4238,19 +4243,38 @@ failed_kiq_read:
 
 static uint64_t gfx_v9_0_get_gpu_clock_counter(struct amdgpu_device *adev)
 {
-       uint64_t clock;
+       uint64_t clock, clock_lo, clock_hi, hi_check;
 
-       amdgpu_gfx_off_ctrl(adev, false);
-       mutex_lock(&adev->gfx.gpu_clock_mutex);
-       if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 0, 1) && amdgpu_sriov_runtime(adev)) {
-               clock = gfx_v9_0_kiq_read_clock(adev);
-       } else {
-               WREG32_SOC15(GC, 0, mmRLC_CAPTURE_GPU_CLOCK_COUNT, 1);
-               clock = (uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_LSB) |
-                       ((uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_MSB) << 32ULL);
+       switch (adev->ip_versions[GC_HWIP][0]) {
+       case IP_VERSION(9, 3, 0):
+               preempt_disable();
+               clock_hi = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Renoir);
+               clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Renoir);
+               hi_check = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Renoir);
+               /* The SMUIO TSC clock frequency is 100MHz, which sets 32-bit carry over
+                * roughly every 42 seconds.
+                */
+               if (hi_check != clock_hi) {
+                       clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Renoir);
+                       clock_hi = hi_check;
+               }
+               preempt_enable();
+               clock = clock_lo | (clock_hi << 32ULL);
+               break;
+       default:
+               amdgpu_gfx_off_ctrl(adev, false);
+               mutex_lock(&adev->gfx.gpu_clock_mutex);
+               if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 0, 1) && amdgpu_sriov_runtime(adev)) {
+                       clock = gfx_v9_0_kiq_read_clock(adev);
+               } else {
+                       WREG32_SOC15(GC, 0, mmRLC_CAPTURE_GPU_CLOCK_COUNT, 1);
+                       clock = (uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_LSB) |
+                               ((uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_MSB) << 32ULL);
+               }
+               mutex_unlock(&adev->gfx.gpu_clock_mutex);
+               amdgpu_gfx_off_ctrl(adev, true);
+               break;
        }
-       mutex_unlock(&adev->gfx.gpu_clock_mutex);
-       amdgpu_gfx_off_ctrl(adev, true);
        return clock;
 }
 
index 1d8414c..38241cf 100644 (file)
@@ -160,6 +160,7 @@ static int navi10_ih_toggle_ring_interrupts(struct amdgpu_device *adev,
 
        tmp = RREG32(ih_regs->ih_rb_cntl);
        tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_ENABLE, (enable ? 1 : 0));
+       tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_GPU_TS_ENABLE, 1);
        /* enable_intr field is only valid in ring0 */
        if (ih == &adev->irq.ih)
                tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0));
@@ -275,10 +276,8 @@ static int navi10_ih_enable_ring(struct amdgpu_device *adev,
        tmp = navi10_ih_rb_cntl(ih, tmp);
        if (ih == &adev->irq.ih)
                tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RPTR_REARM, !!adev->irq.msi_enabled);
-       if (ih == &adev->irq.ih1) {
-               tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 0);
+       if (ih == &adev->irq.ih1)
                tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_FULL_DRAIN_ENABLE, 1);
-       }
 
        if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
                if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) {
@@ -319,7 +318,6 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev)
 {
        struct amdgpu_ih_ring *ih[] = {&adev->irq.ih, &adev->irq.ih1, &adev->irq.ih2};
        u32 ih_chicken;
-       u32 tmp;
        int ret;
        int i;
 
@@ -363,15 +361,6 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev)
        adev->nbio.funcs->ih_doorbell_range(adev, ih[0]->use_doorbell,
                                            ih[0]->doorbell_index);
 
-       tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL);
-       tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL,
-                           CLIENT18_IS_STORM_CLIENT, 1);
-       WREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL, tmp);
-
-       tmp = RREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL);
-       tmp = REG_SET_FIELD(tmp, IH_INT_FLOOD_CNTL, FLOOD_CNTL_ENABLE, 1);
-       WREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL, tmp);
-
        pci_set_master(adev->pdev);
 
        /* enable interrupts */
@@ -420,12 +409,19 @@ static u32 navi10_ih_get_wptr(struct amdgpu_device *adev,
        u32 wptr, tmp;
        struct amdgpu_ih_regs *ih_regs;
 
-       wptr = le32_to_cpu(*ih->wptr_cpu);
-       ih_regs = &ih->ih_regs;
+       if (ih == &adev->irq.ih) {
+               /* Only ring0 supports writeback. On other rings fall back
+                * to register-based code with overflow checking below.
+                */
+               wptr = le32_to_cpu(*ih->wptr_cpu);
 
-       if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
-               goto out;
+               if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
+                       goto out;
+       }
 
+       ih_regs = &ih->ih_regs;
+
+       /* Double check that the overflow wasn't already cleared. */
        wptr = RREG32_NO_KIQ(ih_regs->ih_rb_wptr);
        if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
                goto out;
@@ -513,15 +509,11 @@ static int navi10_ih_self_irq(struct amdgpu_device *adev,
                              struct amdgpu_irq_src *source,
                              struct amdgpu_iv_entry *entry)
 {
-       uint32_t wptr = cpu_to_le32(entry->src_data[0]);
-
        switch (entry->ring_id) {
        case 1:
-               *adev->irq.ih1.wptr_cpu = wptr;
                schedule_work(&adev->irq.ih1_work);
                break;
        case 2:
-               *adev->irq.ih2.wptr_cpu = wptr;
                schedule_work(&adev->irq.ih2_work);
                break;
        default: break;
index 4ecd2b5..ee7cab3 100644 (file)
@@ -359,6 +359,10 @@ static void nbio_v2_3_init_registers(struct amdgpu_device *adev)
 
        if (def != data)
                WREG32_PCIE(smnPCIE_CONFIG_CNTL, data);
+
+       if (amdgpu_sriov_vf(adev))
+               adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0,
+                       mmBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2;
 }
 
 #define NAVI10_PCIE__LC_L0S_INACTIVITY_DEFAULT         0x00000000 // off by default, no gains over L1
index 0d2d629..4bbacf1 100644 (file)
@@ -276,6 +276,10 @@ static void nbio_v6_1_init_registers(struct amdgpu_device *adev)
 
        if (def != data)
                WREG32_PCIE(smnPCIE_CI_CNTL, data);
+
+       if (amdgpu_sriov_vf(adev))
+               adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0,
+                       mmBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2;
 }
 
 static void nbio_v6_1_program_ltr(struct amdgpu_device *adev)
index 3c00666..37a4039 100644 (file)
@@ -273,7 +273,9 @@ const struct nbio_hdp_flush_reg nbio_v7_0_hdp_flush_reg = {
 
 static void nbio_v7_0_init_registers(struct amdgpu_device *adev)
 {
-
+       if (amdgpu_sriov_vf(adev))
+               adev->rmmio_remap.reg_offset =
+                       SOC15_REG_OFFSET(NBIO, 0, mmHDP_MEM_COHERENCY_FLUSH_CNTL) << 2;
 }
 
 const struct amdgpu_nbio_funcs nbio_v7_0_funcs = {
index 8f2a315..3444332 100644 (file)
@@ -371,6 +371,10 @@ static void nbio_v7_2_init_registers(struct amdgpu_device *adev)
                if (def != data)
                        WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CONFIG_CNTL), data);
        }
+
+       if (amdgpu_sriov_vf(adev))
+               adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0,
+                       regBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2;
 }
 
 const struct amdgpu_nbio_funcs nbio_v7_2_funcs = {
index b8bd03d..dc5e937 100644 (file)
@@ -362,7 +362,9 @@ const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg_ald = {
 
 static void nbio_v7_4_init_registers(struct amdgpu_device *adev)
 {
-
+       if (amdgpu_sriov_vf(adev))
+               adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0,
+                       mmBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2;
 }
 
 static void nbio_v7_4_handle_ras_controller_intr_no_bifring(struct amdgpu_device *adev)
@@ -692,6 +694,9 @@ static void nbio_v7_4_program_aspm(struct amdgpu_device *adev)
 {
        uint32_t def, data;
 
+       if (adev->ip_versions[NBIO_HWIP][0] == IP_VERSION(7, 4, 4))
+               return;
+
        def = data = RREG32_PCIE(smnPCIE_LC_CNTL);
        data &= ~PCIE_LC_CNTL__LC_L1_INACTIVITY_MASK;
        data &= ~PCIE_LC_CNTL__LC_L0S_INACTIVITY_MASK;
index 59eafa3..a6659d9 100644 (file)
@@ -731,8 +731,10 @@ static int nv_common_early_init(void *handle)
 #define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET;
-       adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET;
+       if (!amdgpu_sriov_vf(adev)) {
+               adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET;
+               adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET;
+       }
        adev->smc_rreg = NULL;
        adev->smc_wreg = NULL;
        adev->pcie_rreg = &nv_pcie_rreg;
@@ -1032,7 +1034,7 @@ static int nv_common_hw_init(void *handle)
         * for the purpose of expose those registers
         * to process space
         */
-       if (adev->nbio.funcs->remap_hdp_registers)
+       if (adev->nbio.funcs->remap_hdp_registers && !amdgpu_sriov_vf(adev))
                adev->nbio.funcs->remap_hdp_registers(adev);
        /* enable the doorbell aperture */
        nv_enable_doorbell_aperture(adev, true);
index 0c316a2..de9b553 100644 (file)
@@ -971,8 +971,10 @@ static int soc15_common_early_init(void *handle)
 #define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET;
-       adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET;
+       if (!amdgpu_sriov_vf(adev)) {
+               adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET;
+               adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET;
+       }
        adev->smc_rreg = NULL;
        adev->smc_wreg = NULL;
        adev->pcie_rreg = &soc15_pcie_rreg;
@@ -1285,7 +1287,7 @@ static int soc15_common_hw_init(void *handle)
         * for the purpose of expose those registers
         * to process space
         */
-       if (adev->nbio.funcs->remap_hdp_registers)
+       if (adev->nbio.funcs->remap_hdp_registers && !amdgpu_sriov_vf(adev))
                adev->nbio.funcs->remap_hdp_registers(adev);
 
        /* enable the doorbell aperture */
index 003ba6a..93e33dd 100644 (file)
@@ -1226,6 +1226,11 @@ static int stop_cpsch(struct device_queue_manager *dqm)
        bool hanging;
 
        dqm_lock(dqm);
+       if (!dqm->sched_running) {
+               dqm_unlock(dqm);
+               return 0;
+       }
+
        if (!dqm->is_hws_hang)
                unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0);
        hanging = dqm->is_hws_hang || dqm->is_resetting;
index 94e92c0..8fd48d0 100644 (file)
@@ -766,7 +766,7 @@ struct svm_range_list {
        struct list_head                deferred_range_list;
        spinlock_t                      deferred_list_lock;
        atomic_t                        evicted_ranges;
-       bool                            drain_pagefaults;
+       atomic_t                        drain_pagefaults;
        struct delayed_work             restore_work;
        DECLARE_BITMAP(bitmap_supported, MAX_GPU_INSTANCE);
        struct task_struct              *faulting_task;
index 16137c4..58b89b5 100644 (file)
@@ -1968,10 +1968,16 @@ static void svm_range_drain_retry_fault(struct svm_range_list *svms)
        struct kfd_process_device *pdd;
        struct amdgpu_device *adev;
        struct kfd_process *p;
+       int drain;
        uint32_t i;
 
        p = container_of(svms, struct kfd_process, svms);
 
+restart:
+       drain = atomic_read(&svms->drain_pagefaults);
+       if (!drain)
+               return;
+
        for_each_set_bit(i, svms->bitmap_supported, p->n_pdds) {
                pdd = p->pdds[i];
                if (!pdd)
@@ -1983,6 +1989,8 @@ static void svm_range_drain_retry_fault(struct svm_range_list *svms)
                amdgpu_ih_wait_on_checkpoint_process(adev, &adev->irq.ih1);
                pr_debug("drain retry fault gpu %d svms 0x%p done\n", i, svms);
        }
+       if (atomic_cmpxchg(&svms->drain_pagefaults, drain, 0) != drain)
+               goto restart;
 }
 
 static void svm_range_deferred_list_work(struct work_struct *work)
@@ -1990,43 +1998,41 @@ static void svm_range_deferred_list_work(struct work_struct *work)
        struct svm_range_list *svms;
        struct svm_range *prange;
        struct mm_struct *mm;
+       struct kfd_process *p;
 
        svms = container_of(work, struct svm_range_list, deferred_list_work);
        pr_debug("enter svms 0x%p\n", svms);
 
+       p = container_of(svms, struct kfd_process, svms);
+       /* Avoid mm is gone when inserting mmu notifier */
+       mm = get_task_mm(p->lead_thread);
+       if (!mm) {
+               pr_debug("svms 0x%p process mm gone\n", svms);
+               return;
+       }
+retry:
+       mmap_write_lock(mm);
+
+       /* Checking for the need to drain retry faults must be inside
+        * mmap write lock to serialize with munmap notifiers.
+        */
+       if (unlikely(atomic_read(&svms->drain_pagefaults))) {
+               mmap_write_unlock(mm);
+               svm_range_drain_retry_fault(svms);
+               goto retry;
+       }
+
        spin_lock(&svms->deferred_list_lock);
        while (!list_empty(&svms->deferred_range_list)) {
                prange = list_first_entry(&svms->deferred_range_list,
                                          struct svm_range, deferred_list);
+               list_del_init(&prange->deferred_list);
                spin_unlock(&svms->deferred_list_lock);
+
                pr_debug("prange 0x%p [0x%lx 0x%lx] op %d\n", prange,
                         prange->start, prange->last, prange->work_item.op);
 
-               mm = prange->work_item.mm;
-retry:
-               mmap_write_lock(mm);
                mutex_lock(&svms->lock);
-
-               /* Checking for the need to drain retry faults must be in
-                * mmap write lock to serialize with munmap notifiers.
-                *
-                * Remove from deferred_list must be inside mmap write lock,
-                * otherwise, svm_range_list_lock_and_flush_work may hold mmap
-                * write lock, and continue because deferred_list is empty, then
-                * deferred_list handle is blocked by mmap write lock.
-                */
-               spin_lock(&svms->deferred_list_lock);
-               if (unlikely(svms->drain_pagefaults)) {
-                       svms->drain_pagefaults = false;
-                       spin_unlock(&svms->deferred_list_lock);
-                       mutex_unlock(&svms->lock);
-                       mmap_write_unlock(mm);
-                       svm_range_drain_retry_fault(svms);
-                       goto retry;
-               }
-               list_del_init(&prange->deferred_list);
-               spin_unlock(&svms->deferred_list_lock);
-
                mutex_lock(&prange->migrate_mutex);
                while (!list_empty(&prange->child_list)) {
                        struct svm_range *pchild;
@@ -2042,12 +2048,13 @@ retry:
 
                svm_range_handle_list_op(svms, prange);
                mutex_unlock(&svms->lock);
-               mmap_write_unlock(mm);
 
                spin_lock(&svms->deferred_list_lock);
        }
        spin_unlock(&svms->deferred_list_lock);
 
+       mmap_write_unlock(mm);
+       mmput(mm);
        pr_debug("exit svms 0x%p\n", svms);
 }
 
@@ -2056,12 +2063,6 @@ svm_range_add_list_work(struct svm_range_list *svms, struct svm_range *prange,
                        struct mm_struct *mm, enum svm_work_list_ops op)
 {
        spin_lock(&svms->deferred_list_lock);
-       /* Make sure pending page faults are drained in the deferred worker
-        * before the range is freed to avoid straggler interrupts on
-        * unmapped memory causing "phantom faults".
-        */
-       if (op == SVM_OP_UNMAP_RANGE)
-               svms->drain_pagefaults = true;
        /* if prange is on the deferred list */
        if (!list_empty(&prange->deferred_list)) {
                pr_debug("update exist prange 0x%p work op %d\n", prange, op);
@@ -2140,6 +2141,12 @@ svm_range_unmap_from_cpu(struct mm_struct *mm, struct svm_range *prange,
        pr_debug("svms 0x%p prange 0x%p [0x%lx 0x%lx] [0x%lx 0x%lx]\n", svms,
                 prange, prange->start, prange->last, start, last);
 
+       /* Make sure pending page faults are drained in the deferred worker
+        * before the range is freed to avoid straggler interrupts on
+        * unmapped memory causing "phantom faults".
+        */
+       atomic_inc(&svms->drain_pagefaults);
+
        unmap_parent = start <= prange->start && last >= prange->last;
 
        list_for_each_entry(pchild, &prange->child_list, child_list) {
@@ -2559,20 +2566,13 @@ svm_range_count_fault(struct amdgpu_device *adev, struct kfd_process *p,
 }
 
 static bool
-svm_fault_allowed(struct mm_struct *mm, uint64_t addr, bool write_fault)
+svm_fault_allowed(struct vm_area_struct *vma, bool write_fault)
 {
        unsigned long requested = VM_READ;
-       struct vm_area_struct *vma;
 
        if (write_fault)
                requested |= VM_WRITE;
 
-       vma = find_vma(mm, addr << PAGE_SHIFT);
-       if (!vma || (addr << PAGE_SHIFT) < vma->vm_start) {
-               pr_debug("address 0x%llx VMA is removed\n", addr);
-               return true;
-       }
-
        pr_debug("requested 0x%lx, vma permission flags 0x%lx\n", requested,
                vma->vm_flags);
        return (vma->vm_flags & requested) == requested;
@@ -2590,6 +2590,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
        int32_t best_loc;
        int32_t gpuidx = MAX_GPU_INSTANCE;
        bool write_locked = false;
+       struct vm_area_struct *vma;
        int r = 0;
 
        if (!KFD_IS_SVM_API_SUPPORTED(adev->kfd.dev)) {
@@ -2600,7 +2601,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
        p = kfd_lookup_process_by_pasid(pasid);
        if (!p) {
                pr_debug("kfd process not founded pasid 0x%x\n", pasid);
-               return -ESRCH;
+               return 0;
        }
        if (!p->xnack_enabled) {
                pr_debug("XNACK not enabled for pasid 0x%x\n", pasid);
@@ -2611,10 +2612,17 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
 
        pr_debug("restoring svms 0x%p fault address 0x%llx\n", svms, addr);
 
+       if (atomic_read(&svms->drain_pagefaults)) {
+               pr_debug("draining retry fault, drop fault 0x%llx\n", addr);
+               goto out;
+       }
+
+       /* p->lead_thread is available as kfd_process_wq_release flush the work
+        * before releasing task ref.
+        */
        mm = get_task_mm(p->lead_thread);
        if (!mm) {
                pr_debug("svms 0x%p failed to get mm\n", svms);
-               r = -ESRCH;
                goto out;
        }
 
@@ -2663,7 +2671,17 @@ retry_write_locked:
                goto out_unlock_range;
        }
 
-       if (!svm_fault_allowed(mm, addr, write_fault)) {
+       /* __do_munmap removed VMA, return success as we are handling stale
+        * retry fault.
+        */
+       vma = find_vma(mm, addr << PAGE_SHIFT);
+       if (!vma || (addr << PAGE_SHIFT) < vma->vm_start) {
+               pr_debug("address 0x%llx VMA is removed\n", addr);
+               r = 0;
+               goto out_unlock_range;
+       }
+
+       if (!svm_fault_allowed(vma, write_fault)) {
                pr_debug("fault addr 0x%llx no %s permission\n", addr,
                        write_fault ? "write" : "read");
                r = -EPERM;
@@ -2741,6 +2759,14 @@ void svm_range_list_fini(struct kfd_process *p)
        /* Ensure list work is finished before process is destroyed */
        flush_work(&p->svms.deferred_list_work);
 
+       /*
+        * Ensure no retry fault comes in afterwards, as page fault handler will
+        * not find kfd process and take mm lock to recover fault.
+        */
+       atomic_inc(&p->svms.drain_pagefaults);
+       svm_range_drain_retry_fault(&p->svms);
+
+
        list_for_each_entry_safe(prange, next, &p->svms.list, list) {
                svm_range_unlink(prange);
                svm_range_remove_notifier(prange);
@@ -2761,6 +2787,7 @@ int svm_range_list_init(struct kfd_process *p)
        mutex_init(&svms->lock);
        INIT_LIST_HEAD(&svms->list);
        atomic_set(&svms->evicted_ranges, 0);
+       atomic_set(&svms->drain_pagefaults, 0);
        INIT_DELAYED_WORK(&svms->restore_work, svm_range_restore_work);
        INIT_WORK(&svms->deferred_list_work, svm_range_deferred_list_work);
        INIT_LIST_HEAD(&svms->deferred_range_list);
index c911b30..1cd6b9f 100644 (file)
@@ -51,6 +51,7 @@
 #include <drm/drm_hdcp.h>
 #endif
 #include "amdgpu_pm.h"
+#include "amdgpu_atombios.h"
 
 #include "amd_shared.h"
 #include "amdgpu_dm_irq.h"
@@ -2561,6 +2562,22 @@ static int dm_resume(void *handle)
        if (amdgpu_in_reset(adev)) {
                dc_state = dm->cached_dc_state;
 
+               /*
+                * The dc->current_state is backed up into dm->cached_dc_state
+                * before we commit 0 streams.
+                *
+                * DC will clear link encoder assignments on the real state
+                * but the changes won't propagate over to the copy we made
+                * before the 0 streams commit.
+                *
+                * DC expects that link encoder assignments are *not* valid
+                * when committing a state, so as a workaround it needs to be
+                * cleared here.
+                */
+               link_enc_cfg_init(dm->dc, dc_state);
+
+               amdgpu_dm_outbox_init(adev);
+
                r = dm_dmub_hw_init(adev);
                if (r)
                        DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r);
@@ -2572,8 +2589,8 @@ static int dm_resume(void *handle)
 
                for (i = 0; i < dc_state->stream_count; i++) {
                        dc_state->streams[i]->mode_changed = true;
-                       for (j = 0; j < dc_state->stream_status->plane_count; j++) {
-                               dc_state->stream_status->plane_states[j]->update_flags.raw
+                       for (j = 0; j < dc_state->stream_status[i].plane_count; j++) {
+                               dc_state->stream_status[i].plane_states[j]->update_flags.raw
                                        = 0xffffffff;
                        }
                }
@@ -3909,6 +3926,9 @@ static int amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
        caps = dm->backlight_caps[bl_idx];
 
        dm->brightness[bl_idx] = user_brightness;
+       /* update scratch register */
+       if (bl_idx == 0)
+               amdgpu_atombios_scratch_regs_set_backlight_level(dm->adev, dm->brightness[bl_idx]);
        brightness = convert_brightness_from_user(&caps, dm->brightness[bl_idx]);
        link = (struct dc_link *)dm->backlight_link[bl_idx];
 
@@ -4242,7 +4262,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
                } else if (dc_link_detect(link, DETECT_REASON_BOOT)) {
                        amdgpu_dm_update_connector_after_detect(aconnector);
                        register_backlight_device(dm, link);
-
+                       if (dm->num_of_edps)
+                               update_connector_ext_caps(aconnector);
                        if (psr_feature_enabled)
                                amdgpu_dm_set_psr_caps(link);
                }
index 0b788d7..04d7bdd 100644 (file)
@@ -1637,7 +1637,7 @@ void dcn10_reset_hw_ctx_wrap(
 
                        dcn10_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state);
                        if (hws->funcs.enable_stream_gating)
-                               hws->funcs.enable_stream_gating(dc, pipe_ctx);
+                               hws->funcs.enable_stream_gating(dc, pipe_ctx_old);
                        if (old_clk)
                                old_clk->funcs->cs_power_down(old_clk);
                }
index 4f88376..e6af99a 100644 (file)
@@ -2270,7 +2270,7 @@ void dcn20_reset_hw_ctx_wrap(
 
                        dcn20_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state);
                        if (hws->funcs.enable_stream_gating)
-                               hws->funcs.enable_stream_gating(dc, pipe_ctx);
+                               hws->funcs.enable_stream_gating(dc, pipe_ctx_old);
                        if (old_clk)
                                old_clk->funcs->cs_power_down(old_clk);
                }
index 5dd1ce9..4d4ac4c 100644 (file)
@@ -602,7 +602,7 @@ void dcn31_reset_hw_ctx_wrap(
 
                        dcn31_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state);
                        if (hws->funcs.enable_stream_gating)
-                               hws->funcs.enable_stream_gating(dc, pipe_ctx);
+                               hws->funcs.enable_stream_gating(dc, pipe_ctx_old);
                        if (old_clk)
                                old_clk->funcs->cs_power_down(old_clk);
                }
index f1a46d1..4b9e68a 100644 (file)
@@ -98,7 +98,8 @@ enum amd_ip_block_type {
        AMD_IP_BLOCK_TYPE_ACP,
        AMD_IP_BLOCK_TYPE_VCN,
        AMD_IP_BLOCK_TYPE_MES,
-       AMD_IP_BLOCK_TYPE_JPEG
+       AMD_IP_BLOCK_TYPE_JPEG,
+       AMD_IP_BLOCK_TYPE_NUM,
 };
 
 enum amd_clockgating_state {
index 03581d5..08362d5 100644 (file)
@@ -927,6 +927,13 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block
 {
        int ret = 0;
        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+       enum ip_power_state pwr_state = gate ? POWER_STATE_OFF : POWER_STATE_ON;
+
+       if (atomic_read(&adev->pm.pwr_state[block_type]) == pwr_state) {
+               dev_dbg(adev->dev, "IP block%d already in the target %s state!",
+                               block_type, gate ? "gate" : "ungate");
+               return 0;
+       }
 
        switch (block_type) {
        case AMD_IP_BLOCK_TYPE_UVD:
@@ -979,6 +986,9 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block
                break;
        }
 
+       if (!ret)
+               atomic_set(&adev->pm.pwr_state[block_type], pwr_state);
+
        return ret;
 }
 
index 98f1b3d..16e3f72 100644 (file)
@@ -417,6 +417,12 @@ struct amdgpu_dpm {
        enum amd_dpm_forced_level forced_level;
 };
 
+enum ip_power_state {
+       POWER_STATE_UNKNOWN,
+       POWER_STATE_ON,
+       POWER_STATE_OFF,
+};
+
 struct amdgpu_pm {
        struct mutex            mutex;
        u32                     current_sclk;
@@ -452,6 +458,8 @@ struct amdgpu_pm {
        struct i2c_adapter smu_i2c;
        struct mutex            smu_i2c_mutex;
        struct list_head        pm_attr_list;
+
+       atomic_t                pwr_state[AMD_IP_BLOCK_TYPE_NUM];
 };
 
 #define R600_SSTU_DFLT                               0
index 258c573..1f406f2 100644 (file)
@@ -1024,8 +1024,6 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
        uint32_t min_freq, max_freq = 0;
        uint32_t ret = 0;
 
-       phm_get_sysfs_buf(&buf, &size);
-
        switch (type) {
        case PP_SCLK:
                smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency, &now);
@@ -1038,13 +1036,13 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
                else
                        i = 1;
 
-               size += sysfs_emit_at(buf, size, "0: %uMhz %s\n",
+               size += sprintf(buf + size, "0: %uMhz %s\n",
                                        data->gfx_min_freq_limit/100,
                                        i == 0 ? "*" : "");
-               size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
+               size += sprintf(buf + size, "1: %uMhz %s\n",
                                        i == 1 ? now : SMU10_UMD_PSTATE_GFXCLK,
                                        i == 1 ? "*" : "");
-               size += sysfs_emit_at(buf, size, "2: %uMhz %s\n",
+               size += sprintf(buf + size, "2: %uMhz %s\n",
                                        data->gfx_max_freq_limit/100,
                                        i == 2 ? "*" : "");
                break;
@@ -1052,7 +1050,7 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
                smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency, &now);
 
                for (i = 0; i < mclk_table->count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                        i,
                                        mclk_table->entries[i].clk / 100,
                                        ((mclk_table->entries[i].clk / 100)
@@ -1067,10 +1065,10 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
                        if (ret)
                                return ret;
 
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK");
-                       size += sysfs_emit_at(buf, size, "0: %10uMhz\n",
+                       size += sprintf(buf + size, "%s:\n", "OD_SCLK");
+                       size += sprintf(buf + size, "0: %10uMhz\n",
                        (data->gfx_actual_soft_min_freq > 0) ? data->gfx_actual_soft_min_freq : min_freq);
-                       size += sysfs_emit_at(buf, size, "1: %10uMhz\n",
+                       size += sprintf(buf + size, "1: %10uMhz\n",
                        (data->gfx_actual_soft_max_freq > 0) ? data->gfx_actual_soft_max_freq : max_freq);
                }
                break;
@@ -1083,8 +1081,8 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
                        if (ret)
                                return ret;
 
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
-                       size += sysfs_emit_at(buf, size, "SCLK: %7uMHz %10uMHz\n",
+                       size += sprintf(buf + size, "%s:\n", "OD_RANGE");
+                       size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n",
                                min_freq, max_freq);
                }
                break;
index aceebf5..611969b 100644 (file)
@@ -4914,8 +4914,6 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
        int size = 0;
        uint32_t i, now, clock, pcie_speed;
 
-       phm_get_sysfs_buf(&buf, &size);
-
        switch (type) {
        case PP_SCLK:
                smum_send_msg_to_smc(hwmgr, PPSMC_MSG_API_GetSclkFrequency, &clock);
@@ -4928,7 +4926,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
                now = i;
 
                for (i = 0; i < sclk_table->count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                        i, sclk_table->dpm_levels[i].value / 100,
                                        (i == now) ? "*" : "");
                break;
@@ -4943,7 +4941,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
                now = i;
 
                for (i = 0; i < mclk_table->count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                        i, mclk_table->dpm_levels[i].value / 100,
                                        (i == now) ? "*" : "");
                break;
@@ -4957,7 +4955,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
                now = i;
 
                for (i = 0; i < pcie_table->count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %s %s\n", i,
+                       size += sprintf(buf + size, "%d: %s %s\n", i,
                                        (pcie_table->dpm_levels[i].value == 0) ? "2.5GT/s, x8" :
                                        (pcie_table->dpm_levels[i].value == 1) ? "5.0GT/s, x16" :
                                        (pcie_table->dpm_levels[i].value == 2) ? "8.0GT/s, x16" : "",
@@ -4965,32 +4963,32 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
                break;
        case OD_SCLK:
                if (hwmgr->od_enabled) {
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK");
+                       size += sprintf(buf + size, "%s:\n", "OD_SCLK");
                        for (i = 0; i < odn_sclk_table->num_of_pl; i++)
-                               size += sysfs_emit_at(buf, size, "%d: %10uMHz %10umV\n",
+                               size += sprintf(buf + size, "%d: %10uMHz %10umV\n",
                                        i, odn_sclk_table->entries[i].clock/100,
                                        odn_sclk_table->entries[i].vddc);
                }
                break;
        case OD_MCLK:
                if (hwmgr->od_enabled) {
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK");
+                       size += sprintf(buf + size, "%s:\n", "OD_MCLK");
                        for (i = 0; i < odn_mclk_table->num_of_pl; i++)
-                               size += sysfs_emit_at(buf, size, "%d: %10uMHz %10umV\n",
+                               size += sprintf(buf + size, "%d: %10uMHz %10umV\n",
                                        i, odn_mclk_table->entries[i].clock/100,
                                        odn_mclk_table->entries[i].vddc);
                }
                break;
        case OD_RANGE:
                if (hwmgr->od_enabled) {
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
-                       size += sysfs_emit_at(buf, size, "SCLK: %7uMHz %10uMHz\n",
+                       size += sprintf(buf + size, "%s:\n", "OD_RANGE");
+                       size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n",
                                data->golden_dpm_table.sclk_table.dpm_levels[0].value/100,
                                hwmgr->platform_descriptor.overdriveLimit.engineClock/100);
-                       size += sysfs_emit_at(buf, size, "MCLK: %7uMHz %10uMHz\n",
+                       size += sprintf(buf + size, "MCLK: %7uMHz %10uMHz\n",
                                data->golden_dpm_table.mclk_table.dpm_levels[0].value/100,
                                hwmgr->platform_descriptor.overdriveLimit.memoryClock/100);
-                       size += sysfs_emit_at(buf, size, "VDDC: %7umV %11umV\n",
+                       size += sprintf(buf + size, "VDDC: %7umV %11umV\n",
                                data->odn_dpm_table.min_vddc,
                                data->odn_dpm_table.max_vddc);
                }
index 8e28a8e..03bf8f0 100644 (file)
@@ -1550,8 +1550,6 @@ static int smu8_print_clock_levels(struct pp_hwmgr *hwmgr,
        uint32_t i, now;
        int size = 0;
 
-       phm_get_sysfs_buf(&buf, &size);
-
        switch (type) {
        case PP_SCLK:
                now = PHM_GET_FIELD(cgs_read_ind_register(hwmgr->device,
@@ -1561,7 +1559,7 @@ static int smu8_print_clock_levels(struct pp_hwmgr *hwmgr,
                                CURR_SCLK_INDEX);
 
                for (i = 0; i < sclk_table->count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                        i, sclk_table->entries[i].clk / 100,
                                        (i == now) ? "*" : "");
                break;
@@ -1573,7 +1571,7 @@ static int smu8_print_clock_levels(struct pp_hwmgr *hwmgr,
                                CURR_MCLK_INDEX);
 
                for (i = SMU8_NUM_NBPMEMORYCLOCK; i > 0; i--)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                        SMU8_NUM_NBPMEMORYCLOCK-i, data->sys_info.nbp_memory_clock[i-1] / 100,
                                        (SMU8_NUM_NBPMEMORYCLOCK-i == now) ? "*" : "");
                break;
index c981fc2..e633665 100644 (file)
@@ -4639,8 +4639,6 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
 
        int i, now, size = 0, count = 0;
 
-       phm_get_sysfs_buf(&buf, &size);
-
        switch (type) {
        case PP_SCLK:
                if (data->registry_data.sclk_dpm_key_disabled)
@@ -4654,7 +4652,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
                else
                        count = sclk_table->count;
                for (i = 0; i < count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                        i, sclk_table->dpm_levels[i].value / 100,
                                        (i == now) ? "*" : "");
                break;
@@ -4665,7 +4663,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
                smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex, &now);
 
                for (i = 0; i < mclk_table->count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                        i, mclk_table->dpm_levels[i].value / 100,
                                        (i == now) ? "*" : "");
                break;
@@ -4676,7 +4674,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
                smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentSocclkIndex, &now);
 
                for (i = 0; i < soc_table->count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                        i, soc_table->dpm_levels[i].value / 100,
                                        (i == now) ? "*" : "");
                break;
@@ -4688,7 +4686,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
                                PPSMC_MSG_GetClockFreqMHz, CLK_DCEFCLK, &now);
 
                for (i = 0; i < dcef_table->count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                        i, dcef_table->dpm_levels[i].value / 100,
                                        (dcef_table->dpm_levels[i].value / 100 == now) ?
                                        "*" : "");
@@ -4702,7 +4700,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
                        gen_speed = pptable->PcieGenSpeed[i];
                        lane_width = pptable->PcieLaneCount[i];
 
-                       size += sysfs_emit_at(buf, size, "%d: %s %s %s\n", i,
+                       size += sprintf(buf + size, "%d: %s %s %s\n", i,
                                        (gen_speed == 0) ? "2.5GT/s," :
                                        (gen_speed == 1) ? "5.0GT/s," :
                                        (gen_speed == 2) ? "8.0GT/s," :
@@ -4721,34 +4719,34 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
 
        case OD_SCLK:
                if (hwmgr->od_enabled) {
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK");
+                       size += sprintf(buf + size, "%s:\n", "OD_SCLK");
                        podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_sclk;
                        for (i = 0; i < podn_vdd_dep->count; i++)
-                               size += sysfs_emit_at(buf, size, "%d: %10uMhz %10umV\n",
+                               size += sprintf(buf + size, "%d: %10uMhz %10umV\n",
                                        i, podn_vdd_dep->entries[i].clk / 100,
                                                podn_vdd_dep->entries[i].vddc);
                }
                break;
        case OD_MCLK:
                if (hwmgr->od_enabled) {
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK");
+                       size += sprintf(buf + size, "%s:\n", "OD_MCLK");
                        podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_mclk;
                        for (i = 0; i < podn_vdd_dep->count; i++)
-                               size += sysfs_emit_at(buf, size, "%d: %10uMhz %10umV\n",
+                               size += sprintf(buf + size, "%d: %10uMhz %10umV\n",
                                        i, podn_vdd_dep->entries[i].clk/100,
                                                podn_vdd_dep->entries[i].vddc);
                }
                break;
        case OD_RANGE:
                if (hwmgr->od_enabled) {
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
-                       size += sysfs_emit_at(buf, size, "SCLK: %7uMHz %10uMHz\n",
+                       size += sprintf(buf + size, "%s:\n", "OD_RANGE");
+                       size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n",
                                data->golden_dpm_table.gfx_table.dpm_levels[0].value/100,
                                hwmgr->platform_descriptor.overdriveLimit.engineClock/100);
-                       size += sysfs_emit_at(buf, size, "MCLK: %7uMHz %10uMHz\n",
+                       size += sprintf(buf + size, "MCLK: %7uMHz %10uMHz\n",
                                data->golden_dpm_table.mem_table.dpm_levels[0].value/100,
                                hwmgr->platform_descriptor.overdriveLimit.memoryClock/100);
-                       size += sysfs_emit_at(buf, size, "VDDC: %7umV %11umV\n",
+                       size += sprintf(buf + size, "VDDC: %7umV %11umV\n",
                                data->odn_dpm_table.min_vddc,
                                data->odn_dpm_table.max_vddc);
                }
index f7e783e..a2f4d67 100644 (file)
@@ -2246,8 +2246,6 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr,
        int i, now, size = 0;
        struct pp_clock_levels_with_latency clocks;
 
-       phm_get_sysfs_buf(&buf, &size);
-
        switch (type) {
        case PP_SCLK:
                PP_ASSERT_WITH_CODE(
@@ -2260,7 +2258,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr,
                                "Attempt to get gfx clk levels Failed!",
                                return -1);
                for (i = 0; i < clocks.num_levels; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                i, clocks.data[i].clocks_in_khz / 1000,
                                (clocks.data[i].clocks_in_khz / 1000 == now / 100) ? "*" : "");
                break;
@@ -2276,7 +2274,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr,
                                "Attempt to get memory clk levels Failed!",
                                return -1);
                for (i = 0; i < clocks.num_levels; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                i, clocks.data[i].clocks_in_khz / 1000,
                                (clocks.data[i].clocks_in_khz / 1000 == now / 100) ? "*" : "");
                break;
@@ -2294,7 +2292,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr,
                                "Attempt to get soc clk levels Failed!",
                                return -1);
                for (i = 0; i < clocks.num_levels; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                i, clocks.data[i].clocks_in_khz / 1000,
                                (clocks.data[i].clocks_in_khz / 1000 == now) ? "*" : "");
                break;
@@ -2312,7 +2310,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr,
                                "Attempt to get dcef clk levels Failed!",
                                return -1);
                for (i = 0; i < clocks.num_levels; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                i, clocks.data[i].clocks_in_khz / 1000,
                                (clocks.data[i].clocks_in_khz / 1000 == now) ? "*" : "");
                break;
index 03e63be..85d55ab 100644 (file)
@@ -3366,8 +3366,6 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
        int ret = 0;
        uint32_t gen_speed, lane_width, current_gen_speed, current_lane_width;
 
-       phm_get_sysfs_buf(&buf, &size);
-
        switch (type) {
        case PP_SCLK:
                ret = vega20_get_current_clk_freq(hwmgr, PPCLK_GFXCLK, &now);
@@ -3376,13 +3374,13 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                                return ret);
 
                if (vega20_get_sclks(hwmgr, &clocks)) {
-                       size += sysfs_emit_at(buf, size, "0: %uMhz * (DPM disabled)\n",
+                       size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n",
                                now / 100);
                        break;
                }
 
                for (i = 0; i < clocks.num_levels; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                i, clocks.data[i].clocks_in_khz / 1000,
                                (clocks.data[i].clocks_in_khz == now * 10) ? "*" : "");
                break;
@@ -3394,13 +3392,13 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                                return ret);
 
                if (vega20_get_memclocks(hwmgr, &clocks)) {
-                       size += sysfs_emit_at(buf, size, "0: %uMhz * (DPM disabled)\n",
+                       size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n",
                                now / 100);
                        break;
                }
 
                for (i = 0; i < clocks.num_levels; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                i, clocks.data[i].clocks_in_khz / 1000,
                                (clocks.data[i].clocks_in_khz == now * 10) ? "*" : "");
                break;
@@ -3412,13 +3410,13 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                                return ret);
 
                if (vega20_get_socclocks(hwmgr, &clocks)) {
-                       size += sysfs_emit_at(buf, size, "0: %uMhz * (DPM disabled)\n",
+                       size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n",
                                now / 100);
                        break;
                }
 
                for (i = 0; i < clocks.num_levels; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                i, clocks.data[i].clocks_in_khz / 1000,
                                (clocks.data[i].clocks_in_khz == now * 10) ? "*" : "");
                break;
@@ -3430,7 +3428,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                                return ret);
 
                for (i = 0; i < fclk_dpm_table->count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                i, fclk_dpm_table->dpm_levels[i].value,
                                fclk_dpm_table->dpm_levels[i].value == (now / 100) ? "*" : "");
                break;
@@ -3442,13 +3440,13 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                                return ret);
 
                if (vega20_get_dcefclocks(hwmgr, &clocks)) {
-                       size += sysfs_emit_at(buf, size, "0: %uMhz * (DPM disabled)\n",
+                       size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n",
                                now / 100);
                        break;
                }
 
                for (i = 0; i < clocks.num_levels; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                i, clocks.data[i].clocks_in_khz / 1000,
                                (clocks.data[i].clocks_in_khz == now * 10) ? "*" : "");
                break;
@@ -3462,7 +3460,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                        gen_speed = pptable->PcieGenSpeed[i];
                        lane_width = pptable->PcieLaneCount[i];
 
-                       size += sysfs_emit_at(buf, size, "%d: %s %s %dMhz %s\n", i,
+                       size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i,
                                        (gen_speed == 0) ? "2.5GT/s," :
                                        (gen_speed == 1) ? "5.0GT/s," :
                                        (gen_speed == 2) ? "8.0GT/s," :
@@ -3483,18 +3481,18 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
        case OD_SCLK:
                if (od8_settings[OD8_SETTING_GFXCLK_FMIN].feature_id &&
                    od8_settings[OD8_SETTING_GFXCLK_FMAX].feature_id) {
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK");
-                       size += sysfs_emit_at(buf, size, "0: %10uMhz\n",
+                       size += sprintf(buf + size, "%s:\n", "OD_SCLK");
+                       size += sprintf(buf + size, "0: %10uMhz\n",
                                od_table->GfxclkFmin);
-                       size += sysfs_emit_at(buf, size, "1: %10uMhz\n",
+                       size += sprintf(buf + size, "1: %10uMhz\n",
                                od_table->GfxclkFmax);
                }
                break;
 
        case OD_MCLK:
                if (od8_settings[OD8_SETTING_UCLK_FMAX].feature_id) {
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK");
-                       size += sysfs_emit_at(buf, size, "1: %10uMhz\n",
+                       size += sprintf(buf + size, "%s:\n", "OD_MCLK");
+                       size += sprintf(buf + size, "1: %10uMhz\n",
                                od_table->UclkFmax);
                }
 
@@ -3507,14 +3505,14 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                    od8_settings[OD8_SETTING_GFXCLK_VOLTAGE1].feature_id &&
                    od8_settings[OD8_SETTING_GFXCLK_VOLTAGE2].feature_id &&
                    od8_settings[OD8_SETTING_GFXCLK_VOLTAGE3].feature_id) {
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_VDDC_CURVE");
-                       size += sysfs_emit_at(buf, size, "0: %10uMhz %10dmV\n",
+                       size += sprintf(buf + size, "%s:\n", "OD_VDDC_CURVE");
+                       size += sprintf(buf + size, "0: %10uMhz %10dmV\n",
                                od_table->GfxclkFreq1,
                                od_table->GfxclkVolt1 / VOLTAGE_SCALE);
-                       size += sysfs_emit_at(buf, size, "1: %10uMhz %10dmV\n",
+                       size += sprintf(buf + size, "1: %10uMhz %10dmV\n",
                                od_table->GfxclkFreq2,
                                od_table->GfxclkVolt2 / VOLTAGE_SCALE);
-                       size += sysfs_emit_at(buf, size, "2: %10uMhz %10dmV\n",
+                       size += sprintf(buf + size, "2: %10uMhz %10dmV\n",
                                od_table->GfxclkFreq3,
                                od_table->GfxclkVolt3 / VOLTAGE_SCALE);
                }
@@ -3522,17 +3520,17 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                break;
 
        case OD_RANGE:
-               size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
+               size += sprintf(buf + size, "%s:\n", "OD_RANGE");
 
                if (od8_settings[OD8_SETTING_GFXCLK_FMIN].feature_id &&
                    od8_settings[OD8_SETTING_GFXCLK_FMAX].feature_id) {
-                       size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n",
+                       size += sprintf(buf + size, "SCLK: %7uMhz %10uMhz\n",
                                od8_settings[OD8_SETTING_GFXCLK_FMIN].min_value,
                                od8_settings[OD8_SETTING_GFXCLK_FMAX].max_value);
                }
 
                if (od8_settings[OD8_SETTING_UCLK_FMAX].feature_id) {
-                       size += sysfs_emit_at(buf, size, "MCLK: %7uMhz %10uMhz\n",
+                       size += sprintf(buf + size, "MCLK: %7uMhz %10uMhz\n",
                                od8_settings[OD8_SETTING_UCLK_FMAX].min_value,
                                od8_settings[OD8_SETTING_UCLK_FMAX].max_value);
                }
@@ -3543,22 +3541,22 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                    od8_settings[OD8_SETTING_GFXCLK_VOLTAGE1].feature_id &&
                    od8_settings[OD8_SETTING_GFXCLK_VOLTAGE2].feature_id &&
                    od8_settings[OD8_SETTING_GFXCLK_VOLTAGE3].feature_id) {
-                       size += sysfs_emit_at(buf, size, "VDDC_CURVE_SCLK[0]: %7uMhz %10uMhz\n",
+                       size += sprintf(buf + size, "VDDC_CURVE_SCLK[0]: %7uMhz %10uMhz\n",
                                od8_settings[OD8_SETTING_GFXCLK_FREQ1].min_value,
                                od8_settings[OD8_SETTING_GFXCLK_FREQ1].max_value);
-                       size += sysfs_emit_at(buf, size, "VDDC_CURVE_VOLT[0]: %7dmV %11dmV\n",
+                       size += sprintf(buf + size, "VDDC_CURVE_VOLT[0]: %7dmV %11dmV\n",
                                od8_settings[OD8_SETTING_GFXCLK_VOLTAGE1].min_value,
                                od8_settings[OD8_SETTING_GFXCLK_VOLTAGE1].max_value);
-                       size += sysfs_emit_at(buf, size, "VDDC_CURVE_SCLK[1]: %7uMhz %10uMhz\n",
+                       size += sprintf(buf + size, "VDDC_CURVE_SCLK[1]: %7uMhz %10uMhz\n",
                                od8_settings[OD8_SETTING_GFXCLK_FREQ2].min_value,
                                od8_settings[OD8_SETTING_GFXCLK_FREQ2].max_value);
-                       size += sysfs_emit_at(buf, size, "VDDC_CURVE_VOLT[1]: %7dmV %11dmV\n",
+                       size += sprintf(buf + size, "VDDC_CURVE_VOLT[1]: %7dmV %11dmV\n",
                                od8_settings[OD8_SETTING_GFXCLK_VOLTAGE2].min_value,
                                od8_settings[OD8_SETTING_GFXCLK_VOLTAGE2].max_value);
-                       size += sysfs_emit_at(buf, size, "VDDC_CURVE_SCLK[2]: %7uMhz %10uMhz\n",
+                       size += sprintf(buf + size, "VDDC_CURVE_SCLK[2]: %7uMhz %10uMhz\n",
                                od8_settings[OD8_SETTING_GFXCLK_FREQ3].min_value,
                                od8_settings[OD8_SETTING_GFXCLK_FREQ3].max_value);
-                       size += sysfs_emit_at(buf, size, "VDDC_CURVE_VOLT[2]: %7dmV %11dmV\n",
+                       size += sprintf(buf + size, "VDDC_CURVE_VOLT[2]: %7dmV %11dmV\n",
                                od8_settings[OD8_SETTING_GFXCLK_VOLTAGE3].min_value,
                                od8_settings[OD8_SETTING_GFXCLK_VOLTAGE3].max_value);
                }
index cbc3f99..2238ee1 100644 (file)
@@ -309,6 +309,7 @@ static int cyan_skillfish_print_clk_levels(struct smu_context *smu,
 {
        int ret = 0, size = 0;
        uint32_t cur_value = 0;
+       int i;
 
        smu_cmn_get_sysfs_buf(&buf, &size);
 
@@ -334,8 +335,6 @@ static int cyan_skillfish_print_clk_levels(struct smu_context *smu,
                size += sysfs_emit_at(buf, size, "VDDC: %7umV  %10umV\n",
                                                CYAN_SKILLFISH_VDDC_MIN, CYAN_SKILLFISH_VDDC_MAX);
                break;
-       case SMU_GFXCLK:
-       case SMU_SCLK:
        case SMU_FCLK:
        case SMU_MCLK:
        case SMU_SOCCLK:
@@ -346,6 +345,25 @@ static int cyan_skillfish_print_clk_levels(struct smu_context *smu,
                        return ret;
                size += sysfs_emit_at(buf, size, "0: %uMhz *\n", cur_value);
                break;
+       case SMU_SCLK:
+       case SMU_GFXCLK:
+               ret = cyan_skillfish_get_current_clk_freq(smu, clk_type, &cur_value);
+               if (ret)
+                       return ret;
+               if (cur_value  == CYAN_SKILLFISH_SCLK_MAX)
+                       i = 2;
+               else if (cur_value == CYAN_SKILLFISH_SCLK_MIN)
+                       i = 0;
+               else
+                       i = 1;
+               size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", CYAN_SKILLFISH_SCLK_MIN,
+                               i == 0 ? "*" : "");
+               size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
+                               i == 1 ? cur_value : cyan_skillfish_sclk_default,
+                               i == 1 ? "*" : "");
+               size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", CYAN_SKILLFISH_SCLK_MAX,
+                               i == 2 ? "*" : "");
+               break;
        default:
                dev_warn(smu->adev->dev, "Unsupported clock type\n");
                return ret;
index 71161f6..60a5570 100644 (file)
@@ -1265,7 +1265,7 @@ static int navi10_print_clk_levels(struct smu_context *smu,
                        enum smu_clk_type clk_type, char *buf)
 {
        uint16_t *curve_settings;
-       int i, size = 0, ret = 0;
+       int i, levels, size = 0, ret = 0;
        uint32_t cur_value = 0, value = 0, count = 0;
        uint32_t freq_values[3] = {0};
        uint32_t mark_index = 0;
@@ -1319,14 +1319,17 @@ static int navi10_print_clk_levels(struct smu_context *smu,
                        freq_values[1] = cur_value;
                        mark_index = cur_value == freq_values[0] ? 0 :
                                     cur_value == freq_values[2] ? 2 : 1;
-                       if (mark_index != 1)
-                               freq_values[1] = (freq_values[0] + freq_values[2]) / 2;
 
-                       for (i = 0; i < 3; i++) {
+                       levels = 3;
+                       if (mark_index != 1) {
+                               levels = 2;
+                               freq_values[1] = freq_values[2];
+                       }
+
+                       for (i = 0; i < levels; i++) {
                                size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, freq_values[i],
                                                i == mark_index ? "*" : "");
                        }
-
                }
                break;
        case SMU_PCIE:
index 421f38e..c02ed65 100644 (file)
@@ -683,6 +683,7 @@ static int vangogh_print_clk_levels(struct smu_context *smu,
        int i, size = 0, ret = 0;
        uint32_t cur_value = 0, value = 0, count = 0;
        bool cur_value_match_level = false;
+       uint32_t min, max;
 
        memset(&metrics, 0, sizeof(metrics));
 
@@ -743,6 +744,13 @@ static int vangogh_print_clk_levels(struct smu_context *smu,
                if (ret)
                        return ret;
                break;
+       case SMU_GFXCLK:
+       case SMU_SCLK:
+               ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetGfxclkFrequency, 0, &cur_value);
+               if (ret) {
+                       return ret;
+               }
+               break;
        default:
                break;
        }
@@ -768,6 +776,24 @@ static int vangogh_print_clk_levels(struct smu_context *smu,
                if (!cur_value_match_level)
                        size += sysfs_emit_at(buf, size, "   %uMhz *\n", cur_value);
                break;
+       case SMU_GFXCLK:
+       case SMU_SCLK:
+               min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq;
+               max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq;
+               if (cur_value  == max)
+                       i = 2;
+               else if (cur_value == min)
+                       i = 0;
+               else
+                       i = 1;
+               size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min,
+                               i == 0 ? "*" : "");
+               size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
+                               i == 1 ? cur_value : VANGOGH_UMD_PSTATE_STANDARD_GFXCLK,
+                               i == 1 ? "*" : "");
+               size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max,
+                               i == 2 ? "*" : "");
+               break;
        default:
                break;
        }
index 8215bbf..caf1775 100644 (file)
@@ -697,6 +697,11 @@ static int yellow_carp_get_current_clk_freq(struct smu_context *smu,
        case SMU_FCLK:
                return smu_cmn_send_smc_msg_with_param(smu,
                                SMU_MSG_GetFclkFrequency, 0, value);
+       case SMU_GFXCLK:
+       case SMU_SCLK:
+               return smu_cmn_send_smc_msg_with_param(smu,
+                               SMU_MSG_GetGfxclkFrequency, 0, value);
+               break;
        default:
                return -EINVAL;
        }
@@ -967,6 +972,7 @@ static int yellow_carp_print_clk_levels(struct smu_context *smu,
 {
        int i, size = 0, ret = 0;
        uint32_t cur_value = 0, value = 0, count = 0;
+       uint32_t min, max;
 
        smu_cmn_get_sysfs_buf(&buf, &size);
 
@@ -1005,6 +1011,27 @@ static int yellow_carp_print_clk_levels(struct smu_context *smu,
                                        cur_value == value ? "*" : "");
                }
                break;
+       case SMU_GFXCLK:
+       case SMU_SCLK:
+               ret = yellow_carp_get_current_clk_freq(smu, clk_type, &cur_value);
+               if (ret)
+                       goto print_clk_out;
+               min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq;
+               max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq;
+               if (cur_value  == max)
+                       i = 2;
+               else if (cur_value == min)
+                       i = 0;
+               else
+                       i = 1;
+               size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min,
+                               i == 0 ? "*" : "");
+               size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
+                               i == 1 ? cur_value : YELLOW_CARP_UMD_PSTATE_GFXCLK,
+                               i == 1 ? "*" : "");
+               size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max,
+                               i == 2 ? "*" : "");
+               break;
        default:
                break;
        }
index b3ad835..a9205a8 100644 (file)
@@ -24,5 +24,6 @@
 #define __YELLOW_CARP_PPT_H__
 
 extern void yellow_carp_set_ppt_funcs(struct smu_context *smu);
+#define YELLOW_CARP_UMD_PSTATE_GFXCLK       1100
 
 #endif
index 843d2cb..ea6f50c 100644 (file)
@@ -139,9 +139,13 @@ static void __smu_cmn_reg_print_error(struct smu_context *smu,
        const char *message = smu_get_message_name(smu, msg);
 
        switch (reg_c2pmsg_90) {
-       case SMU_RESP_NONE:
+       case SMU_RESP_NONE: {
+               u32 msg_idx = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_66);
+               u32 prm     = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82);
                dev_err_ratelimited(adev->dev,
-                                   "SMU: I'm not done with your previous command!");
+                                   "SMU: I'm not done with your previous command: SMN_C2PMSG_66:0x%08X SMN_C2PMSG_82:0x%08X",
+                                   msg_idx, prm);
+       }
                break;
        case SMU_RESP_OK:
                /* The SMU executed the command. It completed with a
index b53fee6..65f1728 100644 (file)
@@ -291,7 +291,7 @@ vga_pw_show(struct device *dev, struct device_attribute *attr, char *buf)
        if (rc)
                return rc;
 
-       return sprintf(buf, "%u\n", reg & 1);
+       return sprintf(buf, "%u\n", reg);
 }
 static DEVICE_ATTR_RO(vga_pw);
 
index d533881..9d05674 100644 (file)
@@ -210,8 +210,13 @@ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj)
                        dma_buf_vunmap(gem_obj->import_attach->dmabuf, &map);
                drm_prime_gem_destroy(gem_obj, cma_obj->sgt);
        } else if (cma_obj->vaddr) {
-               dma_free_wc(gem_obj->dev->dev, cma_obj->base.size,
-                           cma_obj->vaddr, cma_obj->paddr);
+               if (cma_obj->map_noncoherent)
+                       dma_free_noncoherent(gem_obj->dev->dev, cma_obj->base.size,
+                                            cma_obj->vaddr, cma_obj->paddr,
+                                            DMA_TO_DEVICE);
+               else
+                       dma_free_wc(gem_obj->dev->dev, cma_obj->base.size,
+                                   cma_obj->vaddr, cma_obj->paddr);
        }
 
        drm_gem_object_release(gem_obj);
index cd818a6..00e53de 100644 (file)
@@ -225,12 +225,29 @@ static int hyperv_vmbus_remove(struct hv_device *hdev)
 {
        struct drm_device *dev = hv_get_drvdata(hdev);
        struct hyperv_drm_device *hv = to_hv(dev);
+       struct pci_dev *pdev;
 
        drm_dev_unplug(dev);
        drm_atomic_helper_shutdown(dev);
        vmbus_close(hdev->channel);
        hv_set_drvdata(hdev, NULL);
-       vmbus_free_mmio(hv->mem->start, hv->fb_size);
+
+       /*
+        * Free allocated MMIO memory only on Gen2 VMs.
+        * On Gen1 VMs, release the PCI device
+        */
+       if (efi_enabled(EFI_BOOT)) {
+               vmbus_free_mmio(hv->mem->start, hv->fb_size);
+       } else {
+               pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT,
+                                     PCI_DEVICE_ID_HYPERV_VIDEO, NULL);
+               if (!pdev) {
+                       drm_err(dev, "Unable to find PCI Hyper-V video\n");
+                       return -ENODEV;
+               }
+               pci_release_region(pdev, 0);
+               pci_dev_put(pdev);
+       }
 
        return 0;
 }
index 168c84a..71fbdcd 100644 (file)
@@ -696,10 +696,7 @@ static void gen11_dsi_map_pll(struct intel_encoder *encoder,
        intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, val);
 
        for_each_dsi_phy(phy, intel_dsi->phys) {
-               if (DISPLAY_VER(dev_priv) >= 12)
-                       val |= ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
-               else
-                       val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
+               val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
        }
        intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, val);
 
@@ -1135,8 +1132,6 @@ static void
 gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder,
                              const struct intel_crtc_state *crtc_state)
 {
-       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-
        /* step 4a: power up all lanes of the DDI used by DSI */
        gen11_dsi_power_up_lanes(encoder);
 
@@ -1162,8 +1157,7 @@ gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder,
        gen11_dsi_configure_transcoder(encoder, crtc_state);
 
        /* Step 4l: Gate DDI clocks */
-       if (DISPLAY_VER(dev_priv) == 11)
-               gen11_dsi_gate_clocks(encoder);
+       gen11_dsi_gate_clocks(encoder);
 }
 
 static void gen11_dsi_powerup_panel(struct intel_encoder *encoder)
@@ -1271,7 +1265,8 @@ static void adlp_set_lp_hs_wakeup_gb(struct intel_encoder *encoder)
        if (DISPLAY_VER(i915) == 13) {
                for_each_dsi_port(port, intel_dsi->ports)
                        intel_de_rmw(i915, TGL_DSI_CHKN_REG(port),
-                                    TGL_DSI_CHKN_LSHS_GB, 0x4);
+                                    TGL_DSI_CHKN_LSHS_GB_MASK,
+                                    TGL_DSI_CHKN_LSHS_GB(4));
        }
 }
 
index 524eaf6..795689e 100644 (file)
@@ -301,7 +301,7 @@ void intel_gt_suspend_prepare(struct intel_gt *gt)
        user_forcewake(gt, true);
        wait_for_suspend(gt);
 
-       intel_pxp_suspend(&gt->pxp, false);
+       intel_pxp_suspend_prepare(&gt->pxp);
 }
 
 static suspend_state_t pm_suspend_target(void)
@@ -326,6 +326,7 @@ void intel_gt_suspend_late(struct intel_gt *gt)
        GEM_BUG_ON(gt->awake);
 
        intel_uc_suspend(&gt->uc);
+       intel_pxp_suspend(&gt->pxp);
 
        /*
         * On disabling the device, we want to turn off HW access to memory
@@ -353,7 +354,7 @@ void intel_gt_suspend_late(struct intel_gt *gt)
 
 void intel_gt_runtime_suspend(struct intel_gt *gt)
 {
-       intel_pxp_suspend(&gt->pxp, true);
+       intel_pxp_runtime_suspend(&gt->pxp);
        intel_uc_runtime_suspend(&gt->uc);
 
        GT_TRACE(gt, "\n");
@@ -371,7 +372,7 @@ int intel_gt_runtime_resume(struct intel_gt *gt)
        if (ret)
                return ret;
 
-       intel_pxp_resume(&gt->pxp);
+       intel_pxp_runtime_resume(&gt->pxp);
 
        return 0;
 }
index 38b47e7..c48557d 100644 (file)
@@ -3080,8 +3080,8 @@ guc_create_parallel(struct intel_engine_cs **engines,
 
                ce = intel_engine_create_virtual(siblings, num_siblings,
                                                 FORCE_VIRTUAL);
-               if (!ce) {
-                       err = ERR_PTR(-ENOMEM);
+               if (IS_ERR(ce)) {
+                       err = ERR_CAST(ce);
                        goto unwind;
                }
 
index da9055c..bcee121 100644 (file)
@@ -11717,7 +11717,9 @@ enum skl_power_gate {
 #define TGL_DSI_CHKN_REG(port)         _MMIO_PORT(port,        \
                                                    _TGL_DSI_CHKN_REG_0, \
                                                    _TGL_DSI_CHKN_REG_1)
-#define TGL_DSI_CHKN_LSHS_GB                   REG_GENMASK(15, 12)
+#define TGL_DSI_CHKN_LSHS_GB_MASK              REG_GENMASK(15, 12)
+#define TGL_DSI_CHKN_LSHS_GB(byte_clocks)      REG_FIELD_PREP(TGL_DSI_CHKN_LSHS_GB_MASK, \
+                                                              (byte_clocks))
 
 /* Display Stream Splitter Control */
 #define DSS_CTL1                               _MMIO(0x67400)
index 23fd86d..6a7d4e2 100644 (file)
@@ -7,26 +7,29 @@
 #include "intel_pxp_irq.h"
 #include "intel_pxp_pm.h"
 #include "intel_pxp_session.h"
+#include "i915_drv.h"
 
-void intel_pxp_suspend(struct intel_pxp *pxp, bool runtime)
+void intel_pxp_suspend_prepare(struct intel_pxp *pxp)
 {
        if (!intel_pxp_is_enabled(pxp))
                return;
 
        pxp->arb_is_valid = false;
 
-       /*
-        * Contexts using protected objects keep a runtime PM reference, so we
-        * can only runtime suspend when all of them have been either closed
-        * or banned. Therefore, there is no need to invalidate in that
-        * scenario.
-        */
-       if (!runtime)
-               intel_pxp_invalidate(pxp);
+       intel_pxp_invalidate(pxp);
+}
 
-       intel_pxp_fini_hw(pxp);
+void intel_pxp_suspend(struct intel_pxp *pxp)
+{
+       intel_wakeref_t wakeref;
 
-       pxp->hw_state_invalidated = false;
+       if (!intel_pxp_is_enabled(pxp))
+               return;
+
+       with_intel_runtime_pm(&pxp_to_gt(pxp)->i915->runtime_pm, wakeref) {
+               intel_pxp_fini_hw(pxp);
+               pxp->hw_state_invalidated = false;
+       }
 }
 
 void intel_pxp_resume(struct intel_pxp *pxp)
@@ -44,3 +47,15 @@ void intel_pxp_resume(struct intel_pxp *pxp)
 
        intel_pxp_init_hw(pxp);
 }
+
+void intel_pxp_runtime_suspend(struct intel_pxp *pxp)
+{
+       if (!intel_pxp_is_enabled(pxp))
+               return;
+
+       pxp->arb_is_valid = false;
+
+       intel_pxp_fini_hw(pxp);
+
+       pxp->hw_state_invalidated = false;
+}
index c89e97a..16990a3 100644 (file)
@@ -9,16 +9,29 @@
 #include "intel_pxp_types.h"
 
 #ifdef CONFIG_DRM_I915_PXP
-void intel_pxp_suspend(struct intel_pxp *pxp, bool runtime);
+void intel_pxp_suspend_prepare(struct intel_pxp *pxp);
+void intel_pxp_suspend(struct intel_pxp *pxp);
 void intel_pxp_resume(struct intel_pxp *pxp);
+void intel_pxp_runtime_suspend(struct intel_pxp *pxp);
 #else
-static inline void intel_pxp_suspend(struct intel_pxp *pxp, bool runtime)
+static inline void intel_pxp_suspend_prepare(struct intel_pxp *pxp)
+{
+}
+
+static inline void intel_pxp_suspend(struct intel_pxp *pxp)
 {
 }
 
 static inline void intel_pxp_resume(struct intel_pxp *pxp)
 {
 }
-#endif
 
+static inline void intel_pxp_runtime_suspend(struct intel_pxp *pxp)
+{
+}
+#endif
+static inline void intel_pxp_runtime_resume(struct intel_pxp *pxp)
+{
+       intel_pxp_resume(pxp);
+}
 #endif /* __INTEL_PXP_PM_H__ */
index b51d690..88d262b 100644 (file)
@@ -2626,6 +2626,27 @@ nv174_chipset = {
        .fifo     = { 0x00000001, ga102_fifo_new },
 };
 
+static const struct nvkm_device_chip
+nv176_chipset = {
+       .name = "GA106",
+       .bar      = { 0x00000001, tu102_bar_new },
+       .bios     = { 0x00000001, nvkm_bios_new },
+       .devinit  = { 0x00000001, ga100_devinit_new },
+       .fb       = { 0x00000001, ga102_fb_new },
+       .gpio     = { 0x00000001, ga102_gpio_new },
+       .i2c      = { 0x00000001, gm200_i2c_new },
+       .imem     = { 0x00000001, nv50_instmem_new },
+       .mc       = { 0x00000001, ga100_mc_new },
+       .mmu      = { 0x00000001, tu102_mmu_new },
+       .pci      = { 0x00000001, gp100_pci_new },
+       .privring = { 0x00000001, gm200_privring_new },
+       .timer    = { 0x00000001, gk20a_timer_new },
+       .top      = { 0x00000001, ga100_top_new },
+       .disp     = { 0x00000001, ga102_disp_new },
+       .dma      = { 0x00000001, gv100_dma_new },
+       .fifo     = { 0x00000001, ga102_fifo_new },
+};
+
 static const struct nvkm_device_chip
 nv177_chipset = {
        .name = "GA107",
@@ -3072,6 +3093,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
                case 0x168: device->chip = &nv168_chipset; break;
                case 0x172: device->chip = &nv172_chipset; break;
                case 0x174: device->chip = &nv174_chipset; break;
+               case 0x176: device->chip = &nv176_chipset; break;
                case 0x177: device->chip = &nv177_chipset; break;
                default:
                        if (nvkm_boolopt(device->cfgopt, "NvEnableUnsupportedChipsets", false)) {
index 6e3c450..3ff4934 100644 (file)
@@ -62,7 +62,6 @@ gv100_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet,
                nvkm_wr32(device, 0x6f0108 + hdmi, vendor_infoframe.header);
                nvkm_wr32(device, 0x6f010c + hdmi, vendor_infoframe.subpack0_low);
                nvkm_wr32(device, 0x6f0110 + hdmi, vendor_infoframe.subpack0_high);
-               nvkm_wr32(device, 0x6f0110 + hdmi, 0x00000000);
                nvkm_wr32(device, 0x6f0114 + hdmi, 0x00000000);
                nvkm_wr32(device, 0x6f0118 + hdmi, 0x00000000);
                nvkm_wr32(device, 0x6f011c + hdmi, 0x00000000);
index cdb1ead..82b4c8e 100644 (file)
@@ -207,11 +207,13 @@ int
 gm200_acr_wpr_parse(struct nvkm_acr *acr)
 {
        const struct wpr_header *hdr = (void *)acr->wpr_fw->data;
+       struct nvkm_acr_lsfw *lsfw;
 
        while (hdr->falcon_id != WPR_HEADER_V0_FALCON_ID_INVALID) {
                wpr_header_dump(&acr->subdev, hdr);
-               if (!nvkm_acr_lsfw_add(NULL, acr, NULL, (hdr++)->falcon_id))
-                       return -ENOMEM;
+               lsfw = nvkm_acr_lsfw_add(NULL, acr, NULL, (hdr++)->falcon_id);
+               if (IS_ERR(lsfw))
+                       return PTR_ERR(lsfw);
        }
 
        return 0;
index fb9132a..fd97a93 100644 (file)
@@ -161,11 +161,13 @@ int
 gp102_acr_wpr_parse(struct nvkm_acr *acr)
 {
        const struct wpr_header_v1 *hdr = (void *)acr->wpr_fw->data;
+       struct nvkm_acr_lsfw *lsfw;
 
        while (hdr->falcon_id != WPR_HEADER_V1_FALCON_ID_INVALID) {
                wpr_header_v1_dump(&acr->subdev, hdr);
-               if (!nvkm_acr_lsfw_add(NULL, acr, NULL, (hdr++)->falcon_id))
-                       return -ENOMEM;
+               lsfw = nvkm_acr_lsfw_add(NULL, acr, NULL, (hdr++)->falcon_id);
+               if (IS_ERR(lsfw))
+                       return PTR_ERR(lsfw);
        }
 
        return 0;
index 5bc5f77..f91fb31 100644 (file)
@@ -704,9 +704,13 @@ int drm_sched_job_add_implicit_dependencies(struct drm_sched_job *job,
        int ret;
 
        dma_resv_for_each_fence(&cursor, obj->resv, write, fence) {
+               /* Make sure to grab an additional ref on the added fence */
+               dma_fence_get(fence);
                ret = drm_sched_job_add_dependency(job, fence);
-               if (ret)
+               if (ret) {
+                       dma_fence_put(fence);
                        return ret;
+               }
        }
        return 0;
 }
index 5755f04..8c796de 100644 (file)
@@ -46,6 +46,7 @@ config DRM_SUN6I_DSI
        default MACH_SUN8I
        select CRC_CCITT
        select DRM_MIPI_DSI
+       select RESET_CONTROLLER
        select PHY_SUN6I_MIPI_DPHY
        help
          Choose this option if you want have an Allwinner SoC with
index fddaeb0..f642bd6 100644 (file)
@@ -391,7 +391,7 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size)
 
        bo = kzalloc(sizeof(*bo), GFP_KERNEL);
        if (!bo)
-               return ERR_PTR(-ENOMEM);
+               return NULL;
 
        bo->madv = VC4_MADV_WILLNEED;
        refcount_set(&bo->usecnt, 0);
index 9f14d99..bc76053 100644 (file)
@@ -773,6 +773,7 @@ static struct xenbus_driver xen_driver = {
        .probe = xen_drv_probe,
        .remove = xen_drv_remove,
        .otherend_changed = displback_changed,
+       .not_essential = true,
 };
 
 static int __init xen_drv_init(void)
index 5d57214..f3ecddc 100644 (file)
@@ -854,7 +854,7 @@ static int asus_input_mapping(struct hid_device *hdev,
                switch (usage->hid & HID_USAGE) {
                case 0x10: asus_map_key_clear(KEY_BRIGHTNESSDOWN);      break;
                case 0x20: asus_map_key_clear(KEY_BRIGHTNESSUP);                break;
-               case 0x35: asus_map_key_clear(KEY_SCREENLOCK);          break;
+               case 0x35: asus_map_key_clear(KEY_DISPLAY_OFF);         break;
                case 0x6c: asus_map_key_clear(KEY_SLEEP);               break;
                case 0x7c: asus_map_key_clear(KEY_MICMUTE);             break;
                case 0x82: asus_map_key_clear(KEY_CAMERA);              break;
index 4ef1c3b..8ee77f4 100644 (file)
@@ -966,24 +966,23 @@ static int ft260_probe(struct hid_device *hdev, const struct hid_device_id *id)
        mutex_init(&dev->lock);
        init_completion(&dev->wait);
 
+       ret = ft260_xfer_status(dev);
+       if (ret)
+               ft260_i2c_reset(hdev);
+
+       i2c_set_adapdata(&dev->adap, dev);
        ret = i2c_add_adapter(&dev->adap);
        if (ret) {
                hid_err(hdev, "failed to add i2c adapter\n");
                goto err_hid_close;
        }
 
-       i2c_set_adapdata(&dev->adap, dev);
-
        ret = sysfs_create_group(&hdev->dev.kobj, &ft260_attr_group);
        if (ret < 0) {
                hid_err(hdev, "failed to create sysfs attrs\n");
                goto err_i2c_free;
        }
 
-       ret = ft260_xfer_status(dev);
-       if (ret)
-               ft260_i2c_reset(hdev);
-
        return 0;
 
 err_i2c_free:
index 95037a3..96a4559 100644 (file)
 #define USB_DEVICE_ID_TOSHIBA_CLICK_L9W        0x0401
 #define USB_DEVICE_ID_HP_X2            0x074d
 #define USB_DEVICE_ID_HP_X2_10_COVER   0x0755
+#define I2C_DEVICE_ID_HP_ENVY_X360_15  0x2d05
 #define I2C_DEVICE_ID_HP_SPECTRE_X360_15       0x2817
 #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN   0x2706
 #define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN   0x261A
index 2c72ce4..217f2d1 100644 (file)
@@ -160,6 +160,7 @@ static int hidinput_setkeycode(struct input_dev *dev,
        if (usage) {
                *old_keycode = usage->type == EV_KEY ?
                                usage->code : KEY_RESERVED;
+               usage->type = EV_KEY;
                usage->code = ke->keycode;
 
                clear_bit(*old_keycode, dev->keybit);
@@ -324,6 +325,8 @@ static const struct hid_device_id hid_battery_quirks[] = {
          HID_BATTERY_QUIRK_IGNORE },
        { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN),
          HID_BATTERY_QUIRK_IGNORE },
+       { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15),
+         HID_BATTERY_QUIRK_IGNORE },
        { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_15),
          HID_BATTERY_QUIRK_IGNORE },
        { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN),
@@ -650,10 +653,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                                                code += KEY_MACRO1;
                                        else
                                                code += BTN_TRIGGER_HAPPY - 0x1e;
-                               } else {
-                                       goto ignore;
+                                       break;
                                }
-                               break;
+                               fallthrough;
                default:
                        switch (field->physical) {
                        case HID_GD_MOUSE:
index 686788e..d7687ce 100644 (file)
@@ -256,8 +256,11 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
                unsigned long now = jiffies;
                int step_x = msc->touches[id].scroll_x - x;
                int step_y = msc->touches[id].scroll_y - y;
-               int step_hr = ((64 - (int)scroll_speed) * msc->scroll_accel) /
-                             SCROLL_HR_STEPS;
+               int step_hr =
+                       max_t(int,
+                             ((64 - (int)scroll_speed) * msc->scroll_accel) /
+                                       SCROLL_HR_STEPS,
+                             1);
                int step_x_hr = msc->touches[id].scroll_x_hr - x;
                int step_y_hr = msc->touches[id].scroll_y_hr - y;
 
index e1afddb..082376a 100644 (file)
@@ -1888,6 +1888,11 @@ static const struct hid_device_id mt_devices[] = {
                MT_USB_DEVICE(USB_VENDOR_ID_CVTOUCH,
                        USB_DEVICE_ID_CVTOUCH_SCREEN) },
 
+       /* eGalax devices (SAW) */
+       { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+               MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
+                       USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER) },
+
        /* eGalax devices (resistive) */
        { .driver_data = MT_CLS_EGALAX,
                MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
index a1e0f68..b6a9a0f 100644 (file)
@@ -189,6 +189,7 @@ struct joycon_rumble_amp_data {
        u16 amp;
 };
 
+#if IS_ENABLED(CONFIG_NINTENDO_FF)
 /*
  * These tables are from
  * https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md
@@ -289,6 +290,10 @@ static const struct joycon_rumble_amp_data joycon_rumble_amplitudes[] = {
        { 0xc2, 0x8070,  940 }, { 0xc4, 0x0071,  960 }, { 0xc6, 0x8071,  981 },
        { 0xc8, 0x0072, joycon_max_rumble_amp }
 };
+static const u16 JC_RUMBLE_DFLT_LOW_FREQ = 160;
+static const u16 JC_RUMBLE_DFLT_HIGH_FREQ = 320;
+#endif /* IS_ENABLED(CONFIG_NINTENDO_FF) */
+static const u16 JC_RUMBLE_PERIOD_MS = 50;
 
 /* States for controller state machine */
 enum joycon_ctlr_state {
@@ -397,9 +402,6 @@ struct joycon_input_report {
 #define JC_RUMBLE_DATA_SIZE    8
 #define JC_RUMBLE_QUEUE_SIZE   8
 
-static const u16 JC_RUMBLE_DFLT_LOW_FREQ = 160;
-static const u16 JC_RUMBLE_DFLT_HIGH_FREQ = 320;
-static const u16 JC_RUMBLE_PERIOD_MS = 50;
 static const unsigned short JC_RUMBLE_ZERO_AMP_PKT_CNT = 5;
 
 static const char * const joycon_player_led_names[] = {
@@ -1850,8 +1852,10 @@ static int joycon_leds_create(struct joycon_ctlr *ctlr)
                                      d_name,
                                      "green",
                                      joycon_player_led_names[i]);
-               if (!name)
+               if (!name) {
+                       mutex_unlock(&joycon_input_num_mutex);
                        return -ENOMEM;
+               }
 
                led = &ctlr->leds[i];
                led->name = name;
@@ -1864,6 +1868,7 @@ static int joycon_leds_create(struct joycon_ctlr *ctlr)
                ret = devm_led_classdev_register(&hdev->dev, led);
                if (ret) {
                        hid_err(hdev, "Failed registering %s LED\n", led->name);
+                       mutex_unlock(&joycon_input_num_mutex);
                        return ret;
                }
        }
index d44550a..3a53334 100644 (file)
@@ -205,7 +205,7 @@ static void thrustmaster_model_handler(struct urb *urb)
        struct tm_wheel *tm_wheel = hid_get_drvdata(hdev);
        uint16_t model = 0;
        int i, ret;
-       const struct tm_wheel_info *twi = 0;
+       const struct tm_wheel_info *twi = NULL;
 
        if (urb->status) {
                hid_err(hdev, "URB to get model id failed with error %d\n", urb->status);
@@ -238,7 +238,7 @@ static void thrustmaster_model_handler(struct urb *urb)
                tm_wheel->usb_dev,
                usb_sndctrlpipe(tm_wheel->usb_dev, 0),
                (char *)tm_wheel->change_request,
-               0, 0, // We do not expect any response from the wheel
+               NULL, 0, // We do not expect any response from the wheel
                thrustmaster_change_handler,
                hdev
        );
@@ -272,7 +272,7 @@ static void thrustmaster_remove(struct hid_device *hdev)
 static int thrustmaster_probe(struct hid_device *hdev, const struct hid_device_id *id)
 {
        int ret = 0;
-       struct tm_wheel *tm_wheel = 0;
+       struct tm_wheel *tm_wheel = NULL;
 
        ret = hid_parse(hdev);
        if (ret) {
index 1b486f2..0e1183e 100644 (file)
@@ -76,9 +76,12 @@ enum ish_loader_commands {
 #define LOADER_XFER_MODE_ISHTP                 BIT(1)
 
 /* ISH Transport Loader client unique GUID */
-static const guid_t loader_ishtp_guid =
-       GUID_INIT(0xc804d06a, 0x55bd, 0x4ea7,
-                 0xad, 0xed, 0x1e, 0x31, 0x22, 0x8c, 0x76, 0xdc);
+static const struct ishtp_device_id loader_ishtp_id_table[] = {
+       { .guid = GUID_INIT(0xc804d06a, 0x55bd, 0x4ea7,
+                 0xad, 0xed, 0x1e, 0x31, 0x22, 0x8c, 0x76, 0xdc) },
+       { }
+};
+MODULE_DEVICE_TABLE(ishtp, loader_ishtp_id_table);
 
 #define FILENAME_SIZE                          256
 
@@ -880,7 +883,7 @@ static int loader_init(struct ishtp_cl *loader_ishtp_cl, int reset)
 
        fw_client =
                ishtp_fw_cl_get_client(ishtp_get_ishtp_device(loader_ishtp_cl),
-                                      &loader_ishtp_guid);
+                                      &loader_ishtp_id_table[0].guid);
        if (!fw_client) {
                dev_err(cl_data_to_dev(client_data),
                        "ISH client uuid not found\n");
@@ -1057,7 +1060,7 @@ static int loader_ishtp_cl_reset(struct ishtp_cl_device *cl_device)
 
 static struct ishtp_cl_driver  loader_ishtp_cl_driver = {
        .name = "ish-loader",
-       .guid = &loader_ishtp_guid,
+       .id = loader_ishtp_id_table,
        .probe = loader_ishtp_cl_probe,
        .remove = loader_ishtp_cl_remove,
        .reset = loader_ishtp_cl_reset,
@@ -1083,4 +1086,3 @@ MODULE_DESCRIPTION("ISH ISH-TP Host firmware Loader Client Driver");
 MODULE_AUTHOR("Rushikesh S Kadam <rushikesh.s.kadam@intel.com>");
 
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("ishtp:*");
index 91bf4d0..4338c9b 100644 (file)
 #include "ishtp-hid.h"
 
 /* ISH Transport protocol (ISHTP in short) GUID */
-static const guid_t hid_ishtp_guid =
-       GUID_INIT(0x33AECD58, 0xB679, 0x4E54,
-                 0x9B, 0xD9, 0xA0, 0x4D, 0x34, 0xF0, 0xC2, 0x26);
+static const struct ishtp_device_id hid_ishtp_id_table[] = {
+       { .guid = GUID_INIT(0x33AECD58, 0xB679, 0x4E54,
+                 0x9B, 0xD9, 0xA0, 0x4D, 0x34, 0xF0, 0xC2, 0x26), },
+       { }
+};
+MODULE_DEVICE_TABLE(ishtp, hid_ishtp_id_table);
 
 /* Rx ring buffer pool size */
 #define HID_CL_RX_RING_SIZE    32
@@ -662,7 +665,7 @@ static int hid_ishtp_cl_init(struct ishtp_cl *hid_ishtp_cl, int reset)
        ishtp_set_tx_ring_size(hid_ishtp_cl, HID_CL_TX_RING_SIZE);
        ishtp_set_rx_ring_size(hid_ishtp_cl, HID_CL_RX_RING_SIZE);
 
-       fw_client = ishtp_fw_cl_get_client(dev, &hid_ishtp_guid);
+       fw_client = ishtp_fw_cl_get_client(dev, &hid_ishtp_id_table[0].guid);
        if (!fw_client) {
                dev_err(cl_data_to_dev(client_data),
                        "ish client uuid not found\n");
@@ -945,7 +948,7 @@ static const struct dev_pm_ops hid_ishtp_pm_ops = {
 
 static struct ishtp_cl_driver  hid_ishtp_cl_driver = {
        .name = "ish-hid",
-       .guid = &hid_ishtp_guid,
+       .id = hid_ishtp_id_table,
        .probe = hid_ishtp_cl_probe,
        .remove = hid_ishtp_cl_remove,
        .reset = hid_ishtp_cl_reset,
@@ -981,4 +984,3 @@ MODULE_AUTHOR("Daniel Drubin <daniel.drubin@intel.com>");
 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
 
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("ishtp:*");
index 334eac6..f68aba8 100644 (file)
@@ -241,7 +241,7 @@ static int ishtp_cl_bus_match(struct device *dev, struct device_driver *drv)
        struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
        struct ishtp_cl_driver *driver = to_ishtp_cl_driver(drv);
 
-       return guid_equal(driver->guid,
+       return guid_equal(&driver->id[0].guid,
                          &device->fw_client->props.protocol_name);
 }
 
@@ -350,7 +350,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
 {
        int len;
 
-       len = snprintf(buf, PAGE_SIZE, "ishtp:%s\n", dev_name(dev));
+       len = snprintf(buf, PAGE_SIZE, ISHTP_MODULE_PREFIX "%s\n", dev_name(dev));
        return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
 }
 static DEVICE_ATTR_RO(modalias);
@@ -363,7 +363,7 @@ ATTRIBUTE_GROUPS(ishtp_cl_dev);
 
 static int ishtp_cl_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
-       if (add_uevent_var(env, "MODALIAS=ishtp:%s", dev_name(dev)))
+       if (add_uevent_var(env, "MODALIAS=" ISHTP_MODULE_PREFIX "%s", dev_name(dev)))
                return -ENOMEM;
        return 0;
 }
index 33a6908..2a4cc39 100644 (file)
@@ -2603,6 +2603,9 @@ static void wacom_wac_finger_event(struct hid_device *hdev,
                return;
 
        switch (equivalent_usage) {
+       case HID_DG_CONFIDENCE:
+               wacom_wac->hid_data.confidence = value;
+               break;
        case HID_GD_X:
                wacom_wac->hid_data.x = value;
                break;
@@ -2635,7 +2638,8 @@ static void wacom_wac_finger_event(struct hid_device *hdev,
        }
 
        if (usage->usage_index + 1 == field->report_count) {
-               if (equivalent_usage == wacom_wac->hid_data.last_slot_field)
+               if (equivalent_usage == wacom_wac->hid_data.last_slot_field &&
+                   wacom_wac->hid_data.confidence)
                        wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input);
        }
 }
@@ -2653,6 +2657,8 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev,
 
        wacom_wac->is_invalid_bt_frame = false;
 
+       hid_data->confidence = true;
+
        for (i = 0; i < report->maxfield; i++) {
                struct hid_field *field = report->field[i];
                int j;
index 8b2d4e5..466b62c 100644 (file)
@@ -301,6 +301,7 @@ struct hid_data {
        bool barrelswitch;
        bool barrelswitch2;
        bool serialhi;
+       bool confidence;
        int x;
        int y;
        int pressure;
index 7f11ea0..ca873a3 100644 (file)
@@ -480,7 +480,7 @@ module_param(pressure_report_delay, uint, (S_IRUGO | S_IWUSR));
 MODULE_PARM_DESC(pressure_report_delay, "Delay in secs in reporting pressure");
 static atomic_t trans_id = ATOMIC_INIT(0);
 
-static int dm_ring_size = 20 * 1024;
+static int dm_ring_size = VMBUS_RING_SIZE(16 * 1024);
 
 /*
  * Driver specific state.
index 0518745..41446f9 100644 (file)
 #define SMBSLVSTS_HST_NTFY_STS BIT(0)
 
 /* Host Notify Command register bits */
+#define SMBSLVCMD_SMBALERT_DISABLE     BIT(2)
 #define SMBSLVCMD_HST_NTFY_INTREN      BIT(0)
 
 #define STATUS_ERROR_FLAGS     (SMBHSTSTS_FAILED | SMBHSTSTS_BUS_ERR | \
@@ -259,6 +260,7 @@ struct i801_priv {
        struct i2c_adapter adapter;
        unsigned long smba;
        unsigned char original_hstcfg;
+       unsigned char original_hstcnt;
        unsigned char original_slvcmd;
        struct pci_dev *pci_dev;
        unsigned int features;
@@ -641,12 +643,20 @@ static irqreturn_t i801_isr(int irq, void *dev_id)
                i801_isr_byte_done(priv);
 
        /*
-        * Clear irq sources and report transaction result.
+        * Clear remaining IRQ sources: Completion of last command, errors
+        * and the SMB_ALERT signal. SMB_ALERT status is set after signal
+        * assertion independently of the interrupt generation being blocked
+        * or not so clear it always when the status is set.
+        */
+       status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS | SMBHSTSTS_SMBALERT_STS;
+       if (status)
+               outb_p(status, SMBHSTSTS(priv));
+       status &= ~SMBHSTSTS_SMBALERT_STS; /* SMB_ALERT not reported */
+       /*
+        * Report transaction result.
         * ->status must be cleared before the next transaction is started.
         */
-       status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS;
        if (status) {
-               outb_p(status, SMBHSTSTS(priv));
                priv->status = status;
                complete(&priv->done);
        }
@@ -974,9 +984,13 @@ static void i801_enable_host_notify(struct i2c_adapter *adapter)
        if (!(priv->features & FEATURE_HOST_NOTIFY))
                return;
 
-       if (!(SMBSLVCMD_HST_NTFY_INTREN & priv->original_slvcmd))
-               outb_p(SMBSLVCMD_HST_NTFY_INTREN | priv->original_slvcmd,
-                      SMBSLVCMD(priv));
+       /*
+        * Enable host notify interrupt and block the generation of interrupt
+        * from the SMB_ALERT signal because the driver does not support
+        * SMBus Alert.
+        */
+       outb_p(SMBSLVCMD_HST_NTFY_INTREN | SMBSLVCMD_SMBALERT_DISABLE |
+              priv->original_slvcmd, SMBSLVCMD(priv));
 
        /* clear Host Notify bit to allow a new notification */
        outb_p(SMBSLVSTS_HST_NTFY_STS, SMBSLVSTS(priv));
@@ -1805,7 +1819,8 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
                outb_p(inb_p(SMBAUXCTL(priv)) &
                       ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv));
 
-       /* Remember original Host Notify setting */
+       /* Remember original Interrupt and Host Notify settings */
+       priv->original_hstcnt = inb_p(SMBHSTCNT(priv)) & ~SMBHSTCNT_KILL;
        if (priv->features & FEATURE_HOST_NOTIFY)
                priv->original_slvcmd = inb_p(SMBSLVCMD(priv));
 
@@ -1869,6 +1884,7 @@ static void i801_remove(struct pci_dev *dev)
 {
        struct i801_priv *priv = pci_get_drvdata(dev);
 
+       outb_p(priv->original_hstcnt, SMBHSTCNT(priv));
        i801_disable_host_notify(priv);
        i801_del_mux(priv);
        i2c_del_adapter(&priv->adapter);
@@ -1892,6 +1908,7 @@ static void i801_shutdown(struct pci_dev *dev)
        struct i801_priv *priv = pci_get_drvdata(dev);
 
        /* Restore config registers to avoid hard hang on some systems */
+       outb_p(priv->original_hstcnt, SMBHSTCNT(priv));
        i801_disable_host_notify(priv);
        pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
 }
@@ -1901,6 +1918,7 @@ static int i801_suspend(struct device *dev)
 {
        struct i801_priv *priv = dev_get_drvdata(dev);
 
+       outb_p(priv->original_hstcnt, SMBHSTCNT(priv));
        pci_write_config_byte(priv->pci_dev, SMBHSTCFG, priv->original_hstcfg);
        return 0;
 }
index 1ed4daa..9537878 100644 (file)
@@ -104,11 +104,10 @@ static int virtio_i2c_prepare_reqs(struct virtqueue *vq,
 
 static int virtio_i2c_complete_reqs(struct virtqueue *vq,
                                    struct virtio_i2c_req *reqs,
-                                   struct i2c_msg *msgs, int num,
-                                   bool timedout)
+                                   struct i2c_msg *msgs, int num)
 {
        struct virtio_i2c_req *req;
-       bool failed = timedout;
+       bool failed = false;
        unsigned int len;
        int i, j = 0;
 
@@ -130,7 +129,7 @@ static int virtio_i2c_complete_reqs(struct virtqueue *vq,
                        j++;
        }
 
-       return timedout ? -ETIMEDOUT : j;
+       return j;
 }
 
 static int virtio_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
@@ -139,7 +138,6 @@ static int virtio_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
        struct virtio_i2c *vi = i2c_get_adapdata(adap);
        struct virtqueue *vq = vi->vq;
        struct virtio_i2c_req *reqs;
-       unsigned long time_left;
        int count;
 
        reqs = kcalloc(num, sizeof(*reqs), GFP_KERNEL);
@@ -162,11 +160,9 @@ static int virtio_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
        reinit_completion(&vi->completion);
        virtqueue_kick(vq);
 
-       time_left = wait_for_completion_timeout(&vi->completion, adap->timeout);
-       if (!time_left)
-               dev_err(&adap->dev, "virtio i2c backend timeout.\n");
+       wait_for_completion(&vi->completion);
 
-       count = virtio_i2c_complete_reqs(vq, reqs, msgs, count, !time_left);
+       count = virtio_i2c_complete_reqs(vq, reqs, msgs, count);
 
 err_free:
        kfree(reqs);
index fedc0fa..f5aacaf 100644 (file)
@@ -1906,7 +1906,8 @@ static int nldev_stat_set_mode_doit(struct sk_buff *msg,
        int ret;
 
        /* Currently only counter for QP is supported */
-       if (nla_get_u32(tb[RDMA_NLDEV_ATTR_STAT_RES]) != RDMA_NLDEV_ATTR_RES_QP)
+       if (!tb[RDMA_NLDEV_ATTR_STAT_RES] ||
+           nla_get_u32(tb[RDMA_NLDEV_ATTR_STAT_RES]) != RDMA_NLDEV_ATTR_RES_QP)
                return -EINVAL;
 
        mode = nla_get_u32(tb[RDMA_NLDEV_ATTR_STAT_MODE]);
index 692d5ff..c18634b 100644 (file)
@@ -1232,6 +1232,9 @@ static struct ib_qp *create_qp(struct ib_device *dev, struct ib_pd *pd,
        INIT_LIST_HEAD(&qp->rdma_mrs);
        INIT_LIST_HEAD(&qp->sig_mrs);
 
+       qp->send_cq = attr->send_cq;
+       qp->recv_cq = attr->recv_cq;
+
        rdma_restrack_new(&qp->res, RDMA_RESTRACK_QP);
        WARN_ONCE(!udata && !caller, "Missing kernel QP owner");
        rdma_restrack_set_name(&qp->res, udata ? NULL : caller);
index ed9fa0d..dc9211f 100644 (file)
@@ -1628,8 +1628,7 @@ static int init_cntr_names(const char *names_in, const size_t names_len,
                        n++;
 
        names_out =
-               kmalloc((n + num_extra_names) * sizeof(struct rdma_stat_desc) +
-                               names_len,
+               kzalloc((n + num_extra_names) * sizeof(*q) + names_len,
                        GFP_KERNEL);
        if (!names_out) {
                *num_cntrs = 0;
@@ -1637,7 +1636,7 @@ static int init_cntr_names(const char *names_in, const size_t names_len,
                return -ENOMEM;
        }
 
-       p = names_out + (n + num_extra_names) * sizeof(struct rdma_stat_desc);
+       p = names_out + (n + num_extra_names) * sizeof(*q);
        memcpy(p, names_in, names_len);
 
        q = (struct rdma_stat_desc *)names_out;
index ceca059..0d2fa33 100644 (file)
@@ -2215,6 +2215,11 @@ static const struct ib_device_ops mlx4_ib_hw_stats_ops = {
        .get_hw_stats = mlx4_ib_get_hw_stats,
 };
 
+static const struct ib_device_ops mlx4_ib_hw_stats_ops1 = {
+       .alloc_hw_device_stats = mlx4_ib_alloc_hw_device_stats,
+       .get_hw_stats = mlx4_ib_get_hw_stats,
+};
+
 static int mlx4_ib_alloc_diag_counters(struct mlx4_ib_dev *ibdev)
 {
        struct mlx4_ib_diag_counters *diag = ibdev->diag_counters;
@@ -2227,9 +2232,16 @@ static int mlx4_ib_alloc_diag_counters(struct mlx4_ib_dev *ibdev)
                return 0;
 
        for (i = 0; i < MLX4_DIAG_COUNTERS_TYPES; i++) {
-               /* i == 1 means we are building port counters */
-               if (i && !per_port)
-                       continue;
+               /*
+                * i == 1 means we are building port counters, set a different
+                * stats ops without port stats callback.
+                */
+               if (i && !per_port) {
+                       ib_set_device_ops(&ibdev->ib_dev,
+                                         &mlx4_ib_hw_stats_ops1);
+
+                       return 0;
+               }
 
                ret = __mlx4_ib_alloc_diag_counters(ibdev, &diag[i].descs,
                                                    &diag[i].offset,
index 4ff5cd2..3d17a0b 100644 (file)
@@ -542,6 +542,7 @@ static struct xenbus_driver xenkbd_driver = {
        .remove = xenkbd_remove,
        .resume = xenkbd_resume,
        .otherend_changed = xenkbd_backend_changed,
+       .not_essential = true,
 };
 
 static int __init xenkbd_init(void)
index 13cbeb9..58da08c 100644 (file)
@@ -929,10 +929,8 @@ static int __init amd_iommu_v2_init(void)
 {
        int ret;
 
-       pr_info("AMD IOMMUv2 driver by Joerg Roedel <jroedel@suse.de>\n");
-
        if (!amd_iommu_v2_supported()) {
-               pr_info("AMD IOMMUv2 functionality not available on this system\n");
+               pr_info("AMD IOMMUv2 functionality not available on this system - This is not a bug.\n");
                /*
                 * Load anyway to provide the symbols to other modules
                 * which may use AMD IOMMUv2 optionally.
@@ -947,6 +945,8 @@ static int __init amd_iommu_v2_init(void)
 
        amd_iommu_register_ppr_notifier(&ppr_nb);
 
+       pr_info("AMD IOMMUv2 loaded and initialized\n");
+
        return 0;
 
 out:
index b39d223..71596fc 100644 (file)
@@ -144,6 +144,7 @@ static int cap_audit_static(struct intel_iommu *iommu, enum cap_audit_type type)
 {
        struct dmar_drhd_unit *d;
        struct intel_iommu *i;
+       int rc = 0;
 
        rcu_read_lock();
        if (list_empty(&dmar_drhd_units))
@@ -169,11 +170,11 @@ static int cap_audit_static(struct intel_iommu *iommu, enum cap_audit_type type)
         */
        if (intel_cap_smts_sanity() &&
            !intel_cap_flts_sanity() && !intel_cap_slts_sanity())
-               return -EOPNOTSUPP;
+               rc = -EOPNOTSUPP;
 
 out:
        rcu_read_unlock();
-       return 0;
+       return rc;
 }
 
 int intel_cap_audit(enum cap_audit_type type, struct intel_iommu *iommu)
index 0bde0c8..b6a8f32 100644 (file)
@@ -1339,13 +1339,11 @@ static struct page *dma_pte_clear_level(struct dmar_domain *domain, int level,
        pte = &pte[pfn_level_offset(pfn, level)];
 
        do {
-               unsigned long level_pfn;
+               unsigned long level_pfn = pfn & level_mask(level);
 
                if (!dma_pte_present(pte))
                        goto next;
 
-               level_pfn = pfn & level_mask(level);
-
                /* If range covers entire pagetable, free it */
                if (start_pfn <= level_pfn &&
                    last_pfn >= level_pfn + level_size(level) - 1) {
@@ -1366,7 +1364,7 @@ static struct page *dma_pte_clear_level(struct dmar_domain *domain, int level,
                                                       freelist);
                }
 next:
-               pfn += level_size(level);
+               pfn = level_pfn + level_size(level);
        } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
 
        if (first_pte)
index 5cb2608..7f23ad6 100644 (file)
@@ -200,8 +200,8 @@ static inline phys_addr_t rk_dte_pt_address(u32 dte)
 #define DTE_HI_MASK2   GENMASK(7, 4)
 #define DTE_HI_SHIFT1  24 /* shift bit 8 to bit 32 */
 #define DTE_HI_SHIFT2  32 /* shift bit 4 to bit 36 */
-#define PAGE_DESC_HI_MASK1     GENMASK_ULL(39, 36)
-#define PAGE_DESC_HI_MASK2     GENMASK_ULL(35, 32)
+#define PAGE_DESC_HI_MASK1     GENMASK_ULL(35, 32)
+#define PAGE_DESC_HI_MASK2     GENMASK_ULL(39, 36)
 
 static inline phys_addr_t rk_dte_pt_address_v2(u32 dte)
 {
index 79fa36d..cd9cb35 100644 (file)
@@ -1199,6 +1199,7 @@ void cec_received_msg_ts(struct cec_adapter *adap,
                        if (abort)
                                dst->rx_status |= CEC_RX_STATUS_FEATURE_ABORT;
                        msg->flags = dst->flags;
+                       msg->sequence = dst->sequence;
                        /* Remove it from the wait_queue */
                        list_del_init(&data->list);
 
index 1094575..90acafd 100644 (file)
@@ -241,6 +241,7 @@ static void *vb2_dma_sg_get_userptr(struct vb2_buffer *vb, struct device *dev,
        buf->offset = vaddr & ~PAGE_MASK;
        buf->size = size;
        buf->dma_sgt = &buf->sg_table;
+       buf->vb = vb;
        vec = vb2_create_framevec(vaddr, size);
        if (IS_ERR(vec))
                goto userptr_fail_pfnvec;
@@ -642,6 +643,7 @@ static void *vb2_dma_sg_attach_dmabuf(struct vb2_buffer *vb, struct device *dev,
        buf->dma_dir = vb->vb2_queue->dma_dir;
        buf->size = size;
        buf->db_attach = dba;
+       buf->vb = vb;
 
        return buf;
 }
index 822ce30..48909fa 100644 (file)
@@ -7,9 +7,9 @@
 #include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
-#include <linux/of_graph.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm.h>
+#include <linux/property.h>
 #include <linux/regulator/consumer.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
@@ -2176,7 +2176,7 @@ static struct i2c_driver hi846_i2c_driver = {
        .driver = {
                .name = "hi846",
                .pm = &hi846_pm_ops,
-               .of_match_table = of_match_ptr(hi846_of_match),
+               .of_match_table = hi846_of_match,
        },
        .probe_new = hi846_probe,
        .remove = hi846_remove,
index 8176769..0f3d6b5 100644 (file)
@@ -751,10 +751,6 @@ static int put_v4l2_ext_controls32(struct v4l2_ext_controls *p64,
 /*
  * x86 is the only compat architecture with different struct alignment
  * between 32-bit and 64-bit tasks.
- *
- * On all other architectures, v4l2_event32 and v4l2_event32_time32 are
- * the same as v4l2_event and v4l2_event_time32, so we can use the native
- * handlers, converting v4l2_event to v4l2_event_time32 if necessary.
  */
 struct v4l2_event32 {
        __u32                           type;
@@ -772,21 +768,6 @@ struct v4l2_event32 {
        __u32                           reserved[8];
 };
 
-#ifdef CONFIG_COMPAT_32BIT_TIME
-struct v4l2_event32_time32 {
-       __u32                           type;
-       union {
-               compat_s64              value64;
-               __u8                    data[64];
-       } u;
-       __u32                           pending;
-       __u32                           sequence;
-       struct old_timespec32           timestamp;
-       __u32                           id;
-       __u32                           reserved[8];
-};
-#endif
-
 static int put_v4l2_event32(struct v4l2_event *p64,
                            struct v4l2_event32 __user *p32)
 {
@@ -802,7 +783,22 @@ static int put_v4l2_event32(struct v4l2_event *p64,
        return 0;
 }
 
+#endif
+
 #ifdef CONFIG_COMPAT_32BIT_TIME
+struct v4l2_event32_time32 {
+       __u32                           type;
+       union {
+               compat_s64              value64;
+               __u8                    data[64];
+       } u;
+       __u32                           pending;
+       __u32                           sequence;
+       struct old_timespec32           timestamp;
+       __u32                           id;
+       __u32                           reserved[8];
+};
+
 static int put_v4l2_event32_time32(struct v4l2_event *p64,
                                   struct v4l2_event32_time32 __user *p32)
 {
@@ -818,7 +814,6 @@ static int put_v4l2_event32_time32(struct v4l2_event *p64,
        return 0;
 }
 #endif
-#endif
 
 struct v4l2_edid32 {
        __u32 pad;
@@ -880,9 +875,7 @@ static int put_v4l2_edid32(struct v4l2_edid *p64,
 #define VIDIOC_QUERYBUF32_TIME32       _IOWR('V',  9, struct v4l2_buffer32_time32)
 #define VIDIOC_QBUF32_TIME32           _IOWR('V', 15, struct v4l2_buffer32_time32)
 #define VIDIOC_DQBUF32_TIME32          _IOWR('V', 17, struct v4l2_buffer32_time32)
-#ifdef CONFIG_X86_64
 #define        VIDIOC_DQEVENT32_TIME32         _IOR ('V', 89, struct v4l2_event32_time32)
-#endif
 #define VIDIOC_PREPARE_BUF32_TIME32    _IOWR('V', 93, struct v4l2_buffer32_time32)
 #endif
 
@@ -936,10 +929,10 @@ unsigned int v4l2_compat_translate_cmd(unsigned int cmd)
 #ifdef CONFIG_X86_64
        case VIDIOC_DQEVENT32:
                return VIDIOC_DQEVENT;
+#endif
 #ifdef CONFIG_COMPAT_32BIT_TIME
        case VIDIOC_DQEVENT32_TIME32:
                return VIDIOC_DQEVENT;
-#endif
 #endif
        }
        return cmd;
@@ -1032,10 +1025,10 @@ int v4l2_compat_put_user(void __user *arg, void *parg, unsigned int cmd)
 #ifdef CONFIG_X86_64
        case VIDIOC_DQEVENT32:
                return put_v4l2_event32(parg, arg);
+#endif
 #ifdef CONFIG_COMPAT_32BIT_TIME
        case VIDIOC_DQEVENT32_TIME32:
                return put_v4l2_event32_time32(parg, arg);
-#endif
 #endif
        }
        return 0;
index b883dcc..e201e59 100644 (file)
@@ -241,7 +241,7 @@ static void mtk_smi_larb_config_port_gen2_general(struct device *dev)
 {
        struct mtk_smi_larb *larb = dev_get_drvdata(dev);
        u32 reg, flags_general = larb->larb_gen->flags_general;
-       const u8 *larbostd = larb->larb_gen->ostd[larb->larbid];
+       const u8 *larbostd = larb->larb_gen->ostd ? larb->larb_gen->ostd[larb->larbid] : NULL;
        int i;
 
        if (BIT(larb->larbid) & larb->larb_gen->larb_direct_to_common_mask)
index f4c8e1a..b431cdd 100644 (file)
@@ -1514,6 +1514,12 @@ static int mmc_spi_remove(struct spi_device *spi)
        return 0;
 }
 
+static const struct spi_device_id mmc_spi_dev_ids[] = {
+       { "mmc-spi-slot"},
+       { },
+};
+MODULE_DEVICE_TABLE(spi, mmc_spi_dev_ids);
+
 static const struct of_device_id mmc_spi_of_match_table[] = {
        { .compatible = "mmc-spi-slot", },
        {},
@@ -1525,6 +1531,7 @@ static struct spi_driver mmc_spi_driver = {
                .name =         "mmc_spi",
                .of_match_table = mmc_spi_of_match_table,
        },
+       .id_table =     mmc_spi_dev_ids,
        .probe =        mmc_spi_probe,
        .remove =       mmc_spi_remove,
 };
index afaf337..764ee1b 100644 (file)
@@ -310,7 +310,6 @@ static struct esdhc_soc_data usdhc_imx8qxp_data = {
        .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
                        | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
                        | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES
-                       | ESDHC_FLAG_CQHCI
                        | ESDHC_FLAG_STATE_LOST_IN_LPMODE
                        | ESDHC_FLAG_CLK_RATE_LOST_IN_PM_RUNTIME,
 };
@@ -319,7 +318,6 @@ static struct esdhc_soc_data usdhc_imx8mm_data = {
        .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
                        | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
                        | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES
-                       | ESDHC_FLAG_CQHCI
                        | ESDHC_FLAG_STATE_LOST_IN_LPMODE,
 };
 
index 269c865..07c6da1 100644 (file)
@@ -771,7 +771,19 @@ static void sdhci_adma_table_pre(struct sdhci_host *host,
                        len -= offset;
                }
 
-               BUG_ON(len > 65536);
+               /*
+                * The block layer forces a minimum segment size of PAGE_SIZE,
+                * so 'len' can be too big here if PAGE_SIZE >= 64KiB. Write
+                * multiple descriptors, noting that the ADMA table is sized
+                * for 4KiB chunks anyway, so it will be big enough.
+                */
+               while (len > host->max_adma) {
+                       int n = 32 * 1024; /* 32KiB*/
+
+                       __sdhci_adma_write_desc(host, &desc, addr, n, ADMA2_TRAN_VALID);
+                       addr += n;
+                       len -= n;
+               }
 
                /* tran, valid */
                if (len)
@@ -3968,6 +3980,7 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev,
         * descriptor for each segment, plus 1 for a nop end descriptor.
         */
        host->adma_table_cnt = SDHCI_MAX_SEGS * 2 + 1;
+       host->max_adma = 65536;
 
        host->max_timeout_count = 0xE;
 
@@ -4633,10 +4646,12 @@ int sdhci_setup_host(struct sdhci_host *host)
         * be larger than 64 KiB though.
         */
        if (host->flags & SDHCI_USE_ADMA) {
-               if (host->quirks & SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC)
+               if (host->quirks & SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC) {
+                       host->max_adma = 65532; /* 32-bit alignment */
                        mmc->max_seg_size = 65535;
-               else
+               } else {
                        mmc->max_seg_size = 65536;
+               }
        } else {
                mmc->max_seg_size = mmc->max_req_size;
        }
index bb88355..d7929d7 100644 (file)
@@ -340,7 +340,8 @@ struct sdhci_adma2_64_desc {
 
 /*
  * Maximum segments assuming a 512KiB maximum requisition size and a minimum
- * 4KiB page size.
+ * 4KiB page size. Note this also allows enough for multiple descriptors in
+ * case of PAGE_SIZE >= 64KiB.
  */
 #define SDHCI_MAX_SEGS         128
 
@@ -543,6 +544,7 @@ struct sdhci_host {
        unsigned int blocks;    /* remaining PIO blocks */
 
        int sg_count;           /* Mapped sg entries */
+       int max_adma;           /* Max. length in ADMA descriptor */
 
        void *adma_table;       /* ADMA descriptor table */
        void *align_buffer;     /* Bounce buffer */
index 10506a4..6cccc3d 100644 (file)
@@ -567,9 +567,7 @@ config XEN_NETDEV_BACKEND
 config VMXNET3
        tristate "VMware VMXNET3 ethernet driver"
        depends on PCI && INET
-       depends on !(PAGE_SIZE_64KB || ARM64_64K_PAGES || \
-                    IA64_PAGE_SIZE_64KB || PARISC_PAGE_SIZE_64KB || \
-                    PPC_64K_PAGES)
+       depends on PAGE_SIZE_LESS_THAN_64KB
        help
          This driver supports VMware's vmxnet3 virtual ethernet NIC.
          To compile this driver as a module, choose M here: the
index 47a04c3..b732ee9 100644 (file)
@@ -3286,7 +3286,7 @@ static void __exit amt_fini(void)
 {
        rtnl_link_unregister(&amt_link_ops);
        unregister_netdevice_notifier(&amt_notifier_block);
-       cancel_delayed_work(&source_gc_wq);
+       cancel_delayed_work_sync(&source_gc_wq);
        __amt_source_gc_work();
        destroy_workqueue(amt_wq);
 }
index 43fc308..013e9c0 100644 (file)
@@ -1002,57 +1002,32 @@ static void ksz8_cfg_port_member(struct ksz_device *dev, int port, u8 member)
        data &= ~PORT_VLAN_MEMBERSHIP;
        data |= (member & dev->port_mask);
        ksz_pwrite8(dev, port, P_MIRROR_CTRL, data);
-       dev->ports[port].member = member;
 }
 
 static void ksz8_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
 {
        struct ksz_device *dev = ds->priv;
-       int forward = dev->member;
        struct ksz_port *p;
-       int member = -1;
        u8 data;
 
-       p = &dev->ports[port];
-
        ksz_pread8(dev, port, P_STP_CTRL, &data);
        data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE);
 
        switch (state) {
        case BR_STATE_DISABLED:
                data |= PORT_LEARN_DISABLE;
-               if (port < dev->phy_port_cnt)
-                       member = 0;
                break;
        case BR_STATE_LISTENING:
                data |= (PORT_RX_ENABLE | PORT_LEARN_DISABLE);
-               if (port < dev->phy_port_cnt &&
-                   p->stp_state == BR_STATE_DISABLED)
-                       member = dev->host_mask | p->vid_member;
                break;
        case BR_STATE_LEARNING:
                data |= PORT_RX_ENABLE;
                break;
        case BR_STATE_FORWARDING:
                data |= (PORT_TX_ENABLE | PORT_RX_ENABLE);
-
-               /* This function is also used internally. */
-               if (port == dev->cpu_port)
-                       break;
-
-               /* Port is a member of a bridge. */
-               if (dev->br_member & BIT(port)) {
-                       dev->member |= BIT(port);
-                       member = dev->member;
-               } else {
-                       member = dev->host_mask | p->vid_member;
-               }
                break;
        case BR_STATE_BLOCKING:
                data |= PORT_LEARN_DISABLE;
-               if (port < dev->phy_port_cnt &&
-                   p->stp_state == BR_STATE_DISABLED)
-                       member = dev->host_mask | p->vid_member;
                break;
        default:
                dev_err(ds->dev, "invalid STP state: %d\n", state);
@@ -1060,22 +1035,11 @@ static void ksz8_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
        }
 
        ksz_pwrite8(dev, port, P_STP_CTRL, data);
+
+       p = &dev->ports[port];
        p->stp_state = state;
-       /* Port membership may share register with STP state. */
-       if (member >= 0 && member != p->member)
-               ksz8_cfg_port_member(dev, port, (u8)member);
-
-       /* Check if forwarding needs to be updated. */
-       if (state != BR_STATE_FORWARDING) {
-               if (dev->br_member & BIT(port))
-                       dev->member &= ~BIT(port);
-       }
 
-       /* When topology has changed the function ksz_update_port_member
-        * should be called to modify port forwarding behavior.
-        */
-       if (forward != dev->member)
-               ksz_update_port_member(dev, port);
+       ksz_update_port_member(dev, port);
 }
 
 static void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port)
@@ -1341,7 +1305,7 @@ static void ksz8795_cpu_interface_select(struct ksz_device *dev, int port)
 
 static void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port)
 {
-       struct ksz_port *p = &dev->ports[port];
+       struct dsa_switch *ds = dev->ds;
        struct ksz8 *ksz8 = dev->priv;
        const u32 *masks;
        u8 member;
@@ -1368,10 +1332,11 @@ static void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port)
                if (!ksz_is_ksz88x3(dev))
                        ksz8795_cpu_interface_select(dev, port);
 
-               member = dev->port_mask;
+               member = dsa_user_ports(ds);
        } else {
-               member = dev->host_mask | p->vid_member;
+               member = BIT(dsa_upstream_port(ds, port));
        }
+
        ksz8_cfg_port_member(dev, port, member);
 }
 
@@ -1392,20 +1357,13 @@ static void ksz8_config_cpu_port(struct dsa_switch *ds)
        ksz_cfg(dev, regs[S_TAIL_TAG_CTRL], masks[SW_TAIL_TAG_ENABLE], true);
 
        p = &dev->ports[dev->cpu_port];
-       p->vid_member = dev->port_mask;
        p->on = 1;
 
        ksz8_port_setup(dev, dev->cpu_port, true);
-       dev->member = dev->host_mask;
 
        for (i = 0; i < dev->phy_port_cnt; i++) {
                p = &dev->ports[i];
 
-               /* Initialize to non-zero so that ksz_cfg_port_member() will
-                * be called.
-                */
-               p->vid_member = BIT(i);
-               p->member = dev->port_mask;
                ksz8_port_stp_state_set(ds, i, BR_STATE_DISABLED);
 
                /* Last port may be disabled. */
index 854e25f..353b5f9 100644 (file)
@@ -391,7 +391,6 @@ static void ksz9477_cfg_port_member(struct ksz_device *dev, int port,
                                    u8 member)
 {
        ksz_pwrite32(dev, port, REG_PORT_VLAN_MEMBERSHIP__4, member);
-       dev->ports[port].member = member;
 }
 
 static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port,
@@ -400,8 +399,6 @@ static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port,
        struct ksz_device *dev = ds->priv;
        struct ksz_port *p = &dev->ports[port];
        u8 data;
-       int member = -1;
-       int forward = dev->member;
 
        ksz_pread8(dev, port, P_STP_CTRL, &data);
        data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE);
@@ -409,40 +406,18 @@ static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port,
        switch (state) {
        case BR_STATE_DISABLED:
                data |= PORT_LEARN_DISABLE;
-               if (port != dev->cpu_port)
-                       member = 0;
                break;
        case BR_STATE_LISTENING:
                data |= (PORT_RX_ENABLE | PORT_LEARN_DISABLE);
-               if (port != dev->cpu_port &&
-                   p->stp_state == BR_STATE_DISABLED)
-                       member = dev->host_mask | p->vid_member;
                break;
        case BR_STATE_LEARNING:
                data |= PORT_RX_ENABLE;
                break;
        case BR_STATE_FORWARDING:
                data |= (PORT_TX_ENABLE | PORT_RX_ENABLE);
-
-               /* This function is also used internally. */
-               if (port == dev->cpu_port)
-                       break;
-
-               member = dev->host_mask | p->vid_member;
-               mutex_lock(&dev->dev_mutex);
-
-               /* Port is a member of a bridge. */
-               if (dev->br_member & (1 << port)) {
-                       dev->member |= (1 << port);
-                       member = dev->member;
-               }
-               mutex_unlock(&dev->dev_mutex);
                break;
        case BR_STATE_BLOCKING:
                data |= PORT_LEARN_DISABLE;
-               if (port != dev->cpu_port &&
-                   p->stp_state == BR_STATE_DISABLED)
-                       member = dev->host_mask | p->vid_member;
                break;
        default:
                dev_err(ds->dev, "invalid STP state: %d\n", state);
@@ -451,23 +426,8 @@ static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port,
 
        ksz_pwrite8(dev, port, P_STP_CTRL, data);
        p->stp_state = state;
-       mutex_lock(&dev->dev_mutex);
-       /* Port membership may share register with STP state. */
-       if (member >= 0 && member != p->member)
-               ksz9477_cfg_port_member(dev, port, (u8)member);
-
-       /* Check if forwarding needs to be updated. */
-       if (state != BR_STATE_FORWARDING) {
-               if (dev->br_member & (1 << port))
-                       dev->member &= ~(1 << port);
-       }
 
-       /* When topology has changed the function ksz_update_port_member
-        * should be called to modify port forwarding behavior.
-        */
-       if (forward != dev->member)
-               ksz_update_port_member(dev, port);
-       mutex_unlock(&dev->dev_mutex);
+       ksz_update_port_member(dev, port);
 }
 
 static void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port)
@@ -1168,10 +1128,10 @@ static void ksz9477_phy_errata_setup(struct ksz_device *dev, int port)
 
 static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
 {
-       u8 data8;
-       u8 member;
-       u16 data16;
        struct ksz_port *p = &dev->ports[port];
+       struct dsa_switch *ds = dev->ds;
+       u8 data8, member;
+       u16 data16;
 
        /* enable tag tail for host port */
        if (cpu_port)
@@ -1250,12 +1210,12 @@ static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
                ksz_pwrite8(dev, port, REG_PORT_XMII_CTRL_1, data8);
                p->phydev.duplex = 1;
        }
-       mutex_lock(&dev->dev_mutex);
+
        if (cpu_port)
-               member = dev->port_mask;
+               member = dsa_user_ports(ds);
        else
-               member = dev->host_mask | p->vid_member;
-       mutex_unlock(&dev->dev_mutex);
+               member = BIT(dsa_upstream_port(ds, port));
+
        ksz9477_cfg_port_member(dev, port, member);
 
        /* clear pending interrupts */
@@ -1276,8 +1236,6 @@ static void ksz9477_config_cpu_port(struct dsa_switch *ds)
                        const char *prev_mode;
 
                        dev->cpu_port = i;
-                       dev->host_mask = (1 << dev->cpu_port);
-                       dev->port_mask |= dev->host_mask;
                        p = &dev->ports[i];
 
                        /* Read from XMII register to determine host port
@@ -1312,23 +1270,15 @@ static void ksz9477_config_cpu_port(struct dsa_switch *ds)
 
                        /* enable cpu port */
                        ksz9477_port_setup(dev, i, true);
-                       p->vid_member = dev->port_mask;
                        p->on = 1;
                }
        }
 
-       dev->member = dev->host_mask;
-
        for (i = 0; i < dev->port_cnt; i++) {
                if (i == dev->cpu_port)
                        continue;
                p = &dev->ports[i];
 
-               /* Initialize to non-zero so that ksz_cfg_port_member() will
-                * be called.
-                */
-               p->vid_member = (1 << i);
-               p->member = dev->port_mask;
                ksz9477_port_stp_state_set(ds, i, BR_STATE_DISABLED);
                p->on = 1;
                if (i < dev->phy_port_cnt)
index 7c2968a..8a04302 100644 (file)
 
 void ksz_update_port_member(struct ksz_device *dev, int port)
 {
-       struct ksz_port *p;
+       struct ksz_port *p = &dev->ports[port];
+       struct dsa_switch *ds = dev->ds;
+       u8 port_member = 0, cpu_port;
+       const struct dsa_port *dp;
        int i;
 
-       for (i = 0; i < dev->port_cnt; i++) {
-               if (i == port || i == dev->cpu_port)
+       if (!dsa_is_user_port(ds, port))
+               return;
+
+       dp = dsa_to_port(ds, port);
+       cpu_port = BIT(dsa_upstream_port(ds, port));
+
+       for (i = 0; i < ds->num_ports; i++) {
+               const struct dsa_port *other_dp = dsa_to_port(ds, i);
+               struct ksz_port *other_p = &dev->ports[i];
+               u8 val = 0;
+
+               if (!dsa_is_user_port(ds, i))
                        continue;
-               p = &dev->ports[i];
-               if (!(dev->member & (1 << i)))
+               if (port == i)
+                       continue;
+               if (!dp->bridge_dev || dp->bridge_dev != other_dp->bridge_dev)
                        continue;
 
-               /* Port is a member of the bridge and is forwarding. */
-               if (p->stp_state == BR_STATE_FORWARDING &&
-                   p->member != dev->member)
-                       dev->dev_ops->cfg_port_member(dev, i, dev->member);
+               if (other_p->stp_state == BR_STATE_FORWARDING &&
+                   p->stp_state == BR_STATE_FORWARDING) {
+                       val |= BIT(port);
+                       port_member |= BIT(i);
+               }
+
+               dev->dev_ops->cfg_port_member(dev, i, val | cpu_port);
        }
+
+       dev->dev_ops->cfg_port_member(dev, port, port_member | cpu_port);
 }
 EXPORT_SYMBOL_GPL(ksz_update_port_member);
 
@@ -175,12 +194,6 @@ EXPORT_SYMBOL_GPL(ksz_get_ethtool_stats);
 int ksz_port_bridge_join(struct dsa_switch *ds, int port,
                         struct net_device *br)
 {
-       struct ksz_device *dev = ds->priv;
-
-       mutex_lock(&dev->dev_mutex);
-       dev->br_member |= (1 << port);
-       mutex_unlock(&dev->dev_mutex);
-
        /* port_stp_state_set() will be called after to put the port in
         * appropriate state so there is no need to do anything.
         */
@@ -192,13 +205,6 @@ EXPORT_SYMBOL_GPL(ksz_port_bridge_join);
 void ksz_port_bridge_leave(struct dsa_switch *ds, int port,
                           struct net_device *br)
 {
-       struct ksz_device *dev = ds->priv;
-
-       mutex_lock(&dev->dev_mutex);
-       dev->br_member &= ~(1 << port);
-       dev->member &= ~(1 << port);
-       mutex_unlock(&dev->dev_mutex);
-
        /* port_stp_state_set() will be called after to put the port in
         * forwarding state so there is no need to do anything.
         */
index 1597c63..54b456b 100644 (file)
@@ -25,8 +25,6 @@ struct ksz_port_mib {
 };
 
 struct ksz_port {
-       u16 member;
-       u16 vid_member;
        bool remove_tag;                /* Remove Tag flag set, for ksz8795 only */
        int stp_state;
        struct phy_device phydev;
@@ -83,8 +81,6 @@ struct ksz_device {
        struct ksz_port *ports;
        struct delayed_work mib_read;
        unsigned long mib_read_interval;
-       u16 br_member;
-       u16 member;
        u16 mirror_rx;
        u16 mirror_tx;
        u32 features;                   /* chip specific features */
index a429c97..147ca39 100644 (file)
@@ -1256,8 +1256,12 @@ qca8k_setup(struct dsa_switch *ds)
                /* Set initial MTU for every port.
                 * We have only have a general MTU setting. So track
                 * every port and set the max across all port.
+                * Set per port MTU to 1500 as the MTU change function
+                * will add the overhead and if its set to 1518 then it
+                * will apply the overhead again and we will end up with
+                * MTU of 1536 instead of 1518
                 */
-               priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
+               priv->port_mtu[i] = ETH_DATA_LEN;
        }
 
        /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */
@@ -1433,6 +1437,12 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 
                qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);
 
+               /* From original code is reported port instability as SGMII also
+                * require delay set. Apply advised values here or take them from DT.
+                */
+               if (state->interface == PHY_INTERFACE_MODE_SGMII)
+                       qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
+
                /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and
                 * falling edge is set writing in the PORT0 PAD reg
                 */
@@ -1455,12 +1465,6 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
                                        QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,
                                        val);
 
-               /* From original code is reported port instability as SGMII also
-                * require delay set. Apply advised values here or take them from DT.
-                */
-               if (state->interface == PHY_INTERFACE_MODE_SGMII)
-                       qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
-
                break;
        default:
                dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
index 24122cc..81b3756 100644 (file)
@@ -298,13 +298,14 @@ bool aq_ring_tx_clean(struct aq_ring_s *self)
                        }
                }
 
-               if (unlikely(buff->is_eop)) {
+               if (unlikely(buff->is_eop && buff->skb)) {
                        u64_stats_update_begin(&self->stats.tx.syncp);
                        ++self->stats.tx.packets;
                        self->stats.tx.bytes += buff->skb->len;
                        u64_stats_update_end(&self->stats.tx.syncp);
 
                        dev_kfree_skb_any(buff->skb);
+                       buff->skb = NULL;
                }
                buff->pa = 0U;
                buff->eop_index = 0xffffU;
index fc0e660..3f1704c 100644 (file)
@@ -559,6 +559,11 @@ int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
                        goto err_exit;
 
                if (fw.len == 0xFFFFU) {
+                       if (sw.len > sizeof(self->rpc)) {
+                               printk(KERN_INFO "Invalid sw len: %x\n", sw.len);
+                               err = -EINVAL;
+                               goto err_exit;
+                       }
                        err = hw_atl_utils_fw_rpc_call(self, sw.len);
                        if (err < 0)
                                goto err_exit;
@@ -567,6 +572,11 @@ int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
 
        if (rpc) {
                if (fw.len) {
+                       if (fw.len > sizeof(self->rpc)) {
+                               printk(KERN_INFO "Invalid fw len: %x\n", fw.len);
+                               err = -EINVAL;
+                               goto err_exit;
+                       }
                        err =
                        hw_atl_utils_fw_downld_dwords(self,
                                                      self->rpc_addr,
index 80263c3..4a83c99 100644 (file)
@@ -127,9 +127,9 @@ struct ax88796c_device {
                #define AX_PRIV_FLAGS_MASK      (AX_CAP_COMP)
 
        unsigned long           flags;
-               #define EVENT_INTR              BIT(0)
-               #define EVENT_TX                BIT(1)
-               #define EVENT_SET_MULTI         BIT(2)
+               #define EVENT_INTR              0
+               #define EVENT_TX                1
+               #define EVENT_SET_MULTI         2
 
 };
 
index 94df4f9..0710e71 100644 (file)
@@ -34,7 +34,7 @@ int axspi_read_status(struct axspi_data *ax_spi, struct spi_status *status)
 
        /* OP */
        ax_spi->cmd_buf[0] = AX_SPICMD_READ_STATUS;
-       ret = spi_write_then_read(ax_spi->spi, ax_spi->cmd_buf, 1, (u8 *)&status, 3);
+       ret = spi_write_then_read(ax_spi->spi, ax_spi->cmd_buf, 1, (u8 *)status, 3);
        if (ret)
                dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret);
        else
index 1835d2e..fc7fce6 100644 (file)
@@ -635,11 +635,13 @@ static int bnx2x_ilt_client_mem_op(struct bnx2x *bp, int cli_num,
 {
        int i, rc;
        struct bnx2x_ilt *ilt = BP_ILT(bp);
-       struct ilt_client_info *ilt_cli = &ilt->clients[cli_num];
+       struct ilt_client_info *ilt_cli;
 
        if (!ilt || !ilt->lines)
                return -1;
 
+       ilt_cli = &ilt->clients[cli_num];
+
        if (ilt_cli->flags & (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM))
                return 0;
 
index d0d5da9..4c9507d 100644 (file)
@@ -2258,6 +2258,16 @@ static inline void bnxt_db_write(struct bnxt *bp, struct bnxt_db_info *db,
        }
 }
 
+/* Must hold rtnl_lock */
+static inline bool bnxt_sriov_cfg(struct bnxt *bp)
+{
+#if defined(CONFIG_BNXT_SRIOV)
+       return BNXT_PF(bp) && (bp->pf.active_vfs || bp->sriov_cfg);
+#else
+       return false;
+#endif
+}
+
 extern const u16 bnxt_lhint_arr[];
 
 int bnxt_alloc_rx_data(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
index 5c464ea..951c4c5 100644 (file)
@@ -360,7 +360,7 @@ bnxt_dl_livepatch_report_err(struct bnxt *bp, struct netlink_ext_ack *extack,
                NL_SET_ERR_MSG_MOD(extack, "Live patch already applied");
                break;
        default:
-               netdev_err(bp->dev, "Unexpected live patch error: %hhd\n", err);
+               netdev_err(bp->dev, "Unexpected live patch error: %d\n", err);
                NL_SET_ERR_MSG_MOD(extack, "Failed to activate live patch");
                break;
        }
@@ -441,12 +441,13 @@ static int bnxt_dl_reload_down(struct devlink *dl, bool netns_change,
 
        switch (action) {
        case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: {
-               if (BNXT_PF(bp) && bp->pf.active_vfs) {
+               rtnl_lock();
+               if (bnxt_sriov_cfg(bp)) {
                        NL_SET_ERR_MSG_MOD(extack,
-                                          "reload is unsupported when VFs are allocated");
+                                          "reload is unsupported while VFs are allocated or being configured");
+                       rtnl_unlock();
                        return -EOPNOTSUPP;
                }
-               rtnl_lock();
                if (bp->dev->reg_state == NETREG_UNREGISTERED) {
                        rtnl_unlock();
                        return -ENODEV;
index e6a4a76..1471b61 100644 (file)
@@ -1868,7 +1868,7 @@ static int bnxt_tc_setup_indr_block_cb(enum tc_setup_type type,
        struct flow_cls_offload *flower = type_data;
        struct bnxt *bp = priv->bp;
 
-       if (flower->common.chain_index)
+       if (!tc_cls_can_offload_and_chain0(bp->dev, type_data))
                return -EOPNOTSUPP;
 
        switch (type) {
index 64479c4..ae9cca7 100644 (file)
@@ -3196,6 +3196,7 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
        }
        if (adapter->registered_device_map == 0) {
                dev_err(&pdev->dev, "could not register any net devices\n");
+               err = -EINVAL;
                goto err_disable_interrupts;
        }
 
index 13121c4..71730ef 100644 (file)
@@ -4709,6 +4709,10 @@ type3_infoblock(struct net_device *dev, u_char count, u_char *p)
         lp->ibn = 3;
         lp->active = *p++;
        if (MOTO_SROM_BUG) lp->active = 0;
+       /* if (MOTO_SROM_BUG) statement indicates lp->active could
+        * be 8 (i.e. the size of array lp->phy) */
+       if (WARN_ON(lp->active >= ARRAY_SIZE(lp->phy)))
+               return -EINVAL;
        lp->phy[lp->active].gep = (*p ? p : NULL); p += (2 * (*p) + 1);
        lp->phy[lp->active].rst = (*p ? p : NULL); p += (2 * (*p) + 1);
        lp->phy[lp->active].mc  = get_unaligned_le16(p); p += 2;
@@ -5000,19 +5004,23 @@ mii_get_phy(struct net_device *dev)
        }
        if ((j == limit) && (i < DE4X5_MAX_MII)) {
            for (k=0; k < DE4X5_MAX_PHY && lp->phy[k].id; k++);
-           lp->phy[k].addr = i;
-           lp->phy[k].id = id;
-           lp->phy[k].spd.reg = GENERIC_REG;      /* ANLPA register         */
-           lp->phy[k].spd.mask = GENERIC_MASK;    /* 100Mb/s technologies   */
-           lp->phy[k].spd.value = GENERIC_VALUE;  /* TX & T4, H/F Duplex    */
-           lp->mii_cnt++;
-           lp->active++;
-           printk("%s: Using generic MII device control. If the board doesn't operate,\nplease mail the following dump to the author:\n", dev->name);
-           j = de4x5_debug;
-           de4x5_debug |= DEBUG_MII;
-           de4x5_dbg_mii(dev, k);
-           de4x5_debug = j;
-           printk("\n");
+           if (k < DE4X5_MAX_PHY) {
+               lp->phy[k].addr = i;
+               lp->phy[k].id = id;
+               lp->phy[k].spd.reg = GENERIC_REG;      /* ANLPA register         */
+               lp->phy[k].spd.mask = GENERIC_MASK;    /* 100Mb/s technologies   */
+               lp->phy[k].spd.value = GENERIC_VALUE;  /* TX & T4, H/F Duplex    */
+               lp->mii_cnt++;
+               lp->active++;
+               printk("%s: Using generic MII device control. If the board doesn't operate,\nplease mail the following dump to the author:\n", dev->name);
+               j = de4x5_debug;
+               de4x5_debug |= DEBUG_MII;
+               de4x5_dbg_mii(dev, k);
+               de4x5_debug = j;
+               printk("\n");
+           } else {
+               goto purgatory;
+           }
        }
     }
   purgatory:
index 714e961..6451c83 100644 (file)
@@ -4550,10 +4550,10 @@ static int dpaa2_eth_remove(struct fsl_mc_device *ls_dev)
 
        fsl_mc_portal_free(priv->mc_io);
 
-       free_netdev(net_dev);
-
        dev_dbg(net_dev->dev.parent, "Removed interface %s\n", net_dev->name);
 
+       free_netdev(net_dev);
+
        return 0;
 }
 
index 23d9cbf..740850b 100644 (file)
@@ -400,6 +400,10 @@ static void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
                return;
 
        if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
+               /* DSAF_MAX_PORT_NUM is 6, but DSAF_GE_NUM is 8.
+                  We need check to prevent array overflow */
+               if (port >= DSAF_MAX_PORT_NUM)
+                       return;
                reg_val_1  = 0x1 << port;
                port_rst_off = dsaf_dev->mac_cb[port]->port_rst_off;
                /* there is difference between V1 and V2 in register.*/
index 67364ab..081295b 100644 (file)
@@ -1081,7 +1081,8 @@ static void hns3_dump_page_pool_info(struct hns3_enet_ring *ring,
        u32 j = 0;
 
        sprintf(result[j++], "%u", index);
-       sprintf(result[j++], "%u", ring->page_pool->pages_state_hold_cnt);
+       sprintf(result[j++], "%u",
+               READ_ONCE(ring->page_pool->pages_state_hold_cnt));
        sprintf(result[j++], "%u",
                atomic_read(&ring->page_pool->pages_state_release_cnt));
        sprintf(result[j++], "%u", ring->page_pool->p.pool_size);
@@ -1106,6 +1107,11 @@ hns3_dbg_page_pool_info(struct hnae3_handle *h, char *buf, int len)
                return -EFAULT;
        }
 
+       if (!priv->ring[h->kinfo.num_tqps].page_pool) {
+               dev_err(&h->pdev->dev, "page pool is not initialized\n");
+               return -EFAULT;
+       }
+
        for (i = 0; i < ARRAY_SIZE(page_pool_info_items); i++)
                result[i] = &data_str[i][0];
 
index c8442b8..c9b4568 100644 (file)
@@ -987,6 +987,7 @@ static int hns3_set_reset(struct net_device *netdev, u32 *flags)
        struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
        const struct hnae3_ae_ops *ops = h->ae_algo->ops;
        const struct hns3_reset_type_map *rst_type_map;
+       enum ethtool_reset_flags rst_flags;
        u32 i, size;
 
        if (ops->ae_dev_resetting && ops->ae_dev_resetting(h))
@@ -1006,6 +1007,7 @@ static int hns3_set_reset(struct net_device *netdev, u32 *flags)
        for (i = 0; i < size; i++) {
                if (rst_type_map[i].rst_flags == *flags) {
                        rst_type = rst_type_map[i].rst_type;
+                       rst_flags = rst_type_map[i].rst_flags;
                        break;
                }
        }
@@ -1021,6 +1023,8 @@ static int hns3_set_reset(struct net_device *netdev, u32 *flags)
 
        ops->reset_event(h->pdev, h);
 
+       *flags &= ~rst_flags;
+
        return 0;
 }
 
index 25c419d..41afaee 100644 (file)
@@ -703,9 +703,9 @@ static int hclgevf_set_rss_tc_mode(struct hclgevf_dev *hdev,  u16 rss_size)
        roundup_size = ilog2(roundup_size);
 
        for (i = 0; i < HCLGEVF_MAX_TC_NUM; i++) {
-               tc_valid[i] = !!(hdev->hw_tc_map & BIT(i));
+               tc_valid[i] = 1;
                tc_size[i] = roundup_size;
-               tc_offset[i] = rss_size * i;
+               tc_offset[i] = (hdev->hw_tc_map & BIT(i)) ? rss_size * i : 0;
        }
 
        hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_RSS_TC_MODE, false);
index 5039a25..0bf3d47 100644 (file)
@@ -3003,9 +3003,10 @@ static void __e100_shutdown(struct pci_dev *pdev, bool *enable_wake)
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct nic *nic = netdev_priv(netdev);
 
+       netif_device_detach(netdev);
+
        if (netif_running(netdev))
                e100_down(nic);
-       netif_device_detach(netdev);
 
        if ((nic->flags & wol_magic) | e100_asf(nic)) {
                /* enable reverse auto-negotiation */
@@ -3022,7 +3023,7 @@ static void __e100_shutdown(struct pci_dev *pdev, bool *enable_wake)
                *enable_wake = false;
        }
 
-       pci_clear_master(pdev);
+       pci_disable_device(pdev);
 }
 
 static int __e100_power_off(struct pci_dev *pdev, bool wake)
@@ -3042,8 +3043,6 @@ static int __maybe_unused e100_suspend(struct device *dev_d)
 
        __e100_shutdown(to_pci_dev(dev_d), &wake);
 
-       device_wakeup_disable(dev_d);
-
        return 0;
 }
 
@@ -3051,6 +3050,14 @@ static int __maybe_unused e100_resume(struct device *dev_d)
 {
        struct net_device *netdev = dev_get_drvdata(dev_d);
        struct nic *nic = netdev_priv(netdev);
+       int err;
+
+       err = pci_enable_device(to_pci_dev(dev_d));
+       if (err) {
+               netdev_err(netdev, "Resume cannot enable PCI device, aborting\n");
+               return err;
+       }
+       pci_set_master(to_pci_dev(dev_d));
 
        /* disable reverse auto-negotiation */
        if (nic->phy == phy_82552_v) {
@@ -3062,10 +3069,11 @@ static int __maybe_unused e100_resume(struct device *dev_d)
                           smartspeed & ~(E100_82552_REV_ANEG));
        }
 
-       netif_device_attach(netdev);
        if (netif_running(netdev))
                e100_up(nic);
 
+       netif_device_attach(netdev);
+
        return 0;
 }
 
index 3d528fb..4d939af 100644 (file)
@@ -161,6 +161,7 @@ enum i40e_vsi_state_t {
        __I40E_VSI_OVERFLOW_PROMISC,
        __I40E_VSI_REINIT_REQUESTED,
        __I40E_VSI_DOWN_REQUESTED,
+       __I40E_VSI_RELEASING,
        /* This must be last as it determines the size of the BITMAP */
        __I40E_VSI_STATE_SIZE__,
 };
@@ -1247,6 +1248,7 @@ void i40e_ptp_restore_hw_time(struct i40e_pf *pf);
 void i40e_ptp_init(struct i40e_pf *pf);
 void i40e_ptp_stop(struct i40e_pf *pf);
 int i40e_ptp_alloc_pins(struct i40e_pf *pf);
+int i40e_update_adq_vsi_queues(struct i40e_vsi *vsi, int vsi_offset);
 int i40e_is_vsi_uplink_mode_veb(struct i40e_vsi *vsi);
 i40e_status i40e_get_partition_bw_setting(struct i40e_pf *pf);
 i40e_status i40e_set_partition_bw_setting(struct i40e_pf *pf);
index ba86213..e118cf9 100644 (file)
@@ -1790,6 +1790,7 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
                                     bool is_add)
 {
        struct i40e_pf *pf = vsi->back;
+       u16 num_tc_qps = 0;
        u16 sections = 0;
        u8 netdev_tc = 0;
        u16 numtc = 1;
@@ -1797,13 +1798,33 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
        u8 offset;
        u16 qmap;
        int i;
-       u16 num_tc_qps = 0;
 
        sections = I40E_AQ_VSI_PROP_QUEUE_MAP_VALID;
        offset = 0;
+       /* zero out queue mapping, it will get updated on the end of the function */
+       memset(ctxt->info.queue_mapping, 0, sizeof(ctxt->info.queue_mapping));
+
+       if (vsi->type == I40E_VSI_MAIN) {
+               /* This code helps add more queue to the VSI if we have
+                * more cores than RSS can support, the higher cores will
+                * be served by ATR or other filters. Furthermore, the
+                * non-zero req_queue_pairs says that user requested a new
+                * queue count via ethtool's set_channels, so use this
+                * value for queues distribution across traffic classes
+                */
+               if (vsi->req_queue_pairs > 0)
+                       vsi->num_queue_pairs = vsi->req_queue_pairs;
+               else if (pf->flags & I40E_FLAG_MSIX_ENABLED)
+                       vsi->num_queue_pairs = pf->num_lan_msix;
+       }
 
        /* Number of queues per enabled TC */
-       num_tc_qps = vsi->alloc_queue_pairs;
+       if (vsi->type == I40E_VSI_MAIN ||
+           (vsi->type == I40E_VSI_SRIOV && vsi->num_queue_pairs != 0))
+               num_tc_qps = vsi->num_queue_pairs;
+       else
+               num_tc_qps = vsi->alloc_queue_pairs;
+
        if (enabled_tc && (vsi->back->flags & I40E_FLAG_DCB_ENABLED)) {
                /* Find numtc from enabled TC bitmap */
                for (i = 0, numtc = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
@@ -1881,15 +1902,11 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
                }
                ctxt->info.tc_mapping[i] = cpu_to_le16(qmap);
        }
-
-       /* Set actual Tx/Rx queue pairs */
-       vsi->num_queue_pairs = offset;
-       if ((vsi->type == I40E_VSI_MAIN) && (numtc == 1)) {
-               if (vsi->req_queue_pairs > 0)
-                       vsi->num_queue_pairs = vsi->req_queue_pairs;
-               else if (pf->flags & I40E_FLAG_MSIX_ENABLED)
-                       vsi->num_queue_pairs = pf->num_lan_msix;
-       }
+       /* Do not change previously set num_queue_pairs for PFs and VFs*/
+       if ((vsi->type == I40E_VSI_MAIN && numtc != 1) ||
+           (vsi->type == I40E_VSI_SRIOV && vsi->num_queue_pairs == 0) ||
+           (vsi->type != I40E_VSI_MAIN && vsi->type != I40E_VSI_SRIOV))
+               vsi->num_queue_pairs = offset;
 
        /* Scheduler section valid can only be set for ADD VSI */
        if (is_add) {
@@ -2623,7 +2640,8 @@ static void i40e_sync_filters_subtask(struct i40e_pf *pf)
 
        for (v = 0; v < pf->num_alloc_vsi; v++) {
                if (pf->vsi[v] &&
-                   (pf->vsi[v]->flags & I40E_VSI_FLAG_FILTER_CHANGED)) {
+                   (pf->vsi[v]->flags & I40E_VSI_FLAG_FILTER_CHANGED) &&
+                   !test_bit(__I40E_VSI_RELEASING, pf->vsi[v]->state)) {
                        int ret = i40e_sync_vsi_filters(pf->vsi[v]);
 
                        if (ret) {
@@ -5426,6 +5444,58 @@ static void i40e_vsi_update_queue_map(struct i40e_vsi *vsi,
               sizeof(vsi->info.tc_mapping));
 }
 
+/**
+ * i40e_update_adq_vsi_queues - update queue mapping for ADq VSI
+ * @vsi: the VSI being reconfigured
+ * @vsi_offset: offset from main VF VSI
+ */
+int i40e_update_adq_vsi_queues(struct i40e_vsi *vsi, int vsi_offset)
+{
+       struct i40e_vsi_context ctxt = {};
+       struct i40e_pf *pf;
+       struct i40e_hw *hw;
+       int ret;
+
+       if (!vsi)
+               return I40E_ERR_PARAM;
+       pf = vsi->back;
+       hw = &pf->hw;
+
+       ctxt.seid = vsi->seid;
+       ctxt.pf_num = hw->pf_id;
+       ctxt.vf_num = vsi->vf_id + hw->func_caps.vf_base_id + vsi_offset;
+       ctxt.uplink_seid = vsi->uplink_seid;
+       ctxt.connection_type = I40E_AQ_VSI_CONN_TYPE_NORMAL;
+       ctxt.flags = I40E_AQ_VSI_TYPE_VF;
+       ctxt.info = vsi->info;
+
+       i40e_vsi_setup_queue_map(vsi, &ctxt, vsi->tc_config.enabled_tc,
+                                false);
+       if (vsi->reconfig_rss) {
+               vsi->rss_size = min_t(int, pf->alloc_rss_size,
+                                     vsi->num_queue_pairs);
+               ret = i40e_vsi_config_rss(vsi);
+               if (ret) {
+                       dev_info(&pf->pdev->dev, "Failed to reconfig rss for num_queues\n");
+                       return ret;
+               }
+               vsi->reconfig_rss = false;
+       }
+
+       ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
+       if (ret) {
+               dev_info(&pf->pdev->dev, "Update vsi config failed, err %s aq_err %s\n",
+                        i40e_stat_str(hw, ret),
+                        i40e_aq_str(hw, hw->aq.asq_last_status));
+               return ret;
+       }
+       /* update the local VSI info with updated queue map */
+       i40e_vsi_update_queue_map(vsi, &ctxt);
+       vsi->info.valid_sections = 0;
+
+       return ret;
+}
+
 /**
  * i40e_vsi_config_tc - Configure VSI Tx Scheduler for given TC map
  * @vsi: VSI to be configured
@@ -5716,24 +5786,6 @@ static void i40e_remove_queue_channels(struct i40e_vsi *vsi)
        INIT_LIST_HEAD(&vsi->ch_list);
 }
 
-/**
- * i40e_is_any_channel - channel exist or not
- * @vsi: ptr to VSI to which channels are associated with
- *
- * Returns true or false if channel(s) exist for associated VSI or not
- **/
-static bool i40e_is_any_channel(struct i40e_vsi *vsi)
-{
-       struct i40e_channel *ch, *ch_tmp;
-
-       list_for_each_entry_safe(ch, ch_tmp, &vsi->ch_list, list) {
-               if (ch->initialized)
-                       return true;
-       }
-
-       return false;
-}
-
 /**
  * i40e_get_max_queues_for_channel
  * @vsi: ptr to VSI to which channels are associated with
@@ -6240,26 +6292,15 @@ int i40e_create_queue_channel(struct i40e_vsi *vsi,
        /* By default we are in VEPA mode, if this is the first VF/VMDq
         * VSI to be added switch to VEB mode.
         */
-       if ((!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) ||
-           (!i40e_is_any_channel(vsi))) {
-               if (!is_power_of_2(vsi->tc_config.tc_info[0].qcount)) {
-                       dev_dbg(&pf->pdev->dev,
-                               "Failed to create channel. Override queues (%u) not power of 2\n",
-                               vsi->tc_config.tc_info[0].qcount);
-                       return -EINVAL;
-               }
 
-               if (!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) {
-                       pf->flags |= I40E_FLAG_VEB_MODE_ENABLED;
+       if (!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) {
+               pf->flags |= I40E_FLAG_VEB_MODE_ENABLED;
 
-                       if (vsi->type == I40E_VSI_MAIN) {
-                               if (pf->flags & I40E_FLAG_TC_MQPRIO)
-                                       i40e_do_reset(pf, I40E_PF_RESET_FLAG,
-                                                     true);
-                               else
-                                       i40e_do_reset_safe(pf,
-                                                          I40E_PF_RESET_FLAG);
-                       }
+               if (vsi->type == I40E_VSI_MAIN) {
+                       if (pf->flags & I40E_FLAG_TC_MQPRIO)
+                               i40e_do_reset(pf, I40E_PF_RESET_FLAG, true);
+                       else
+                               i40e_do_reset_safe(pf, I40E_PF_RESET_FLAG);
                }
                /* now onwards for main VSI, number of queues will be value
                 * of TC0's queue count
@@ -7912,12 +7953,20 @@ config_tc:
                            vsi->seid);
                need_reset = true;
                goto exit;
-       } else {
-               dev_info(&vsi->back->pdev->dev,
-                        "Setup channel (id:%u) utilizing num_queues %d\n",
-                        vsi->seid, vsi->tc_config.tc_info[0].qcount);
+       } else if (enabled_tc &&
+                  (!is_power_of_2(vsi->tc_config.tc_info[0].qcount))) {
+               netdev_info(netdev,
+                           "Failed to create channel. Override queues (%u) not power of 2\n",
+                           vsi->tc_config.tc_info[0].qcount);
+               ret = -EINVAL;
+               need_reset = true;
+               goto exit;
        }
 
+       dev_info(&vsi->back->pdev->dev,
+                "Setup channel (id:%u) utilizing num_queues %d\n",
+                vsi->seid, vsi->tc_config.tc_info[0].qcount);
+
        if (pf->flags & I40E_FLAG_TC_MQPRIO) {
                if (vsi->mqprio_qopt.max_rate[0]) {
                        u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0];
@@ -8482,9 +8531,8 @@ static int i40e_configure_clsflower(struct i40e_vsi *vsi,
                err = i40e_add_del_cloud_filter(vsi, filter, true);
 
        if (err) {
-               dev_err(&pf->pdev->dev,
-                       "Failed to add cloud filter, err %s\n",
-                       i40e_stat_str(&pf->hw, err));
+               dev_err(&pf->pdev->dev, "Failed to add cloud filter, err %d\n",
+                       err);
                goto err;
        }
 
@@ -13771,7 +13819,7 @@ int i40e_vsi_release(struct i40e_vsi *vsi)
                dev_info(&pf->pdev->dev, "Can't remove PF VSI\n");
                return -ENODEV;
        }
-
+       set_bit(__I40E_VSI_RELEASING, vsi->state);
        uplink_seid = vsi->uplink_seid;
        if (vsi->type != I40E_VSI_SRIOV) {
                if (vsi->netdev_registered) {
index 472f56b..80ae264 100644 (file)
@@ -183,17 +183,18 @@ void i40e_vc_notify_vf_reset(struct i40e_vf *vf)
 /***********************misc routines*****************************/
 
 /**
- * i40e_vc_disable_vf
+ * i40e_vc_reset_vf
  * @vf: pointer to the VF info
- *
- * Disable the VF through a SW reset.
+ * @notify_vf: notify vf about reset or not
+ * Reset VF handler.
  **/
-static inline void i40e_vc_disable_vf(struct i40e_vf *vf)
+static void i40e_vc_reset_vf(struct i40e_vf *vf, bool notify_vf)
 {
        struct i40e_pf *pf = vf->pf;
        int i;
 
-       i40e_vc_notify_vf_reset(vf);
+       if (notify_vf)
+               i40e_vc_notify_vf_reset(vf);
 
        /* We want to ensure that an actual reset occurs initiated after this
         * function was called. However, we do not want to wait forever, so
@@ -211,9 +212,14 @@ static inline void i40e_vc_disable_vf(struct i40e_vf *vf)
                usleep_range(10000, 20000);
        }
 
-       dev_warn(&vf->pf->pdev->dev,
-                "Failed to initiate reset for VF %d after 200 milliseconds\n",
-                vf->vf_id);
+       if (notify_vf)
+               dev_warn(&vf->pf->pdev->dev,
+                        "Failed to initiate reset for VF %d after 200 milliseconds\n",
+                        vf->vf_id);
+       else
+               dev_dbg(&vf->pf->pdev->dev,
+                       "Failed to initiate reset for VF %d after 200 milliseconds\n",
+                       vf->vf_id);
 }
 
 /**
@@ -674,14 +680,13 @@ static int i40e_config_vsi_rx_queue(struct i40e_vf *vf, u16 vsi_id,
                                    u16 vsi_queue_id,
                                    struct virtchnl_rxq_info *info)
 {
+       u16 pf_queue_id = i40e_vc_get_pf_queue_id(vf, vsi_id, vsi_queue_id);
        struct i40e_pf *pf = vf->pf;
+       struct i40e_vsi *vsi = pf->vsi[vf->lan_vsi_idx];
        struct i40e_hw *hw = &pf->hw;
        struct i40e_hmc_obj_rxq rx_ctx;
-       u16 pf_queue_id;
        int ret = 0;
 
-       pf_queue_id = i40e_vc_get_pf_queue_id(vf, vsi_id, vsi_queue_id);
-
        /* clear the context structure first */
        memset(&rx_ctx, 0, sizeof(struct i40e_hmc_obj_rxq));
 
@@ -719,6 +724,10 @@ static int i40e_config_vsi_rx_queue(struct i40e_vf *vf, u16 vsi_id,
        }
        rx_ctx.rxmax = info->max_pkt_size;
 
+       /* if port VLAN is configured increase the max packet size */
+       if (vsi->info.pvid)
+               rx_ctx.rxmax += VLAN_HLEN;
+
        /* enable 32bytes desc always */
        rx_ctx.dsize = 1;
 
@@ -2105,20 +2114,6 @@ err:
        return ret;
 }
 
-/**
- * i40e_vc_reset_vf_msg
- * @vf: pointer to the VF info
- *
- * called from the VF to reset itself,
- * unlike other virtchnl messages, PF driver
- * doesn't send the response back to the VF
- **/
-static void i40e_vc_reset_vf_msg(struct i40e_vf *vf)
-{
-       if (test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states))
-               i40e_reset_vf(vf, false);
-}
-
 /**
  * i40e_vc_config_promiscuous_mode_msg
  * @vf: pointer to the VF info
@@ -2217,11 +2212,12 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg)
        struct virtchnl_vsi_queue_config_info *qci =
            (struct virtchnl_vsi_queue_config_info *)msg;
        struct virtchnl_queue_pair_info *qpi;
-       struct i40e_pf *pf = vf->pf;
        u16 vsi_id, vsi_queue_id = 0;
-       u16 num_qps_all = 0;
+       struct i40e_pf *pf = vf->pf;
        i40e_status aq_ret = 0;
        int i, j = 0, idx = 0;
+       struct i40e_vsi *vsi;
+       u16 num_qps_all = 0;
 
        if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
                aq_ret = I40E_ERR_PARAM;
@@ -2310,9 +2306,15 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg)
                pf->vsi[vf->lan_vsi_idx]->num_queue_pairs =
                        qci->num_queue_pairs;
        } else {
-               for (i = 0; i < vf->num_tc; i++)
-                       pf->vsi[vf->ch[i].vsi_idx]->num_queue_pairs =
-                              vf->ch[i].num_qps;
+               for (i = 0; i < vf->num_tc; i++) {
+                       vsi = pf->vsi[vf->ch[i].vsi_idx];
+                       vsi->num_queue_pairs = vf->ch[i].num_qps;
+
+                       if (i40e_update_adq_vsi_queues(vsi, i)) {
+                               aq_ret = I40E_ERR_CONFIG;
+                               goto error_param;
+                       }
+               }
        }
 
 error_param:
@@ -2607,8 +2609,7 @@ static int i40e_vc_request_queues_msg(struct i40e_vf *vf, u8 *msg)
        } else {
                /* successful request */
                vf->num_req_queues = req_pairs;
-               i40e_vc_notify_vf_reset(vf);
-               i40e_reset_vf(vf, false);
+               i40e_vc_reset_vf(vf, true);
                return 0;
        }
 
@@ -3803,8 +3804,7 @@ static int i40e_vc_add_qch_msg(struct i40e_vf *vf, u8 *msg)
        vf->num_req_queues = 0;
 
        /* reset the VF in order to allocate resources */
-       i40e_vc_notify_vf_reset(vf);
-       i40e_reset_vf(vf, false);
+       i40e_vc_reset_vf(vf, true);
 
        return I40E_SUCCESS;
 
@@ -3844,8 +3844,7 @@ static int i40e_vc_del_qch_msg(struct i40e_vf *vf, u8 *msg)
        }
 
        /* reset the VF in order to allocate resources */
-       i40e_vc_notify_vf_reset(vf);
-       i40e_reset_vf(vf, false);
+       i40e_vc_reset_vf(vf, true);
 
        return I40E_SUCCESS;
 
@@ -3907,7 +3906,7 @@ int i40e_vc_process_vf_msg(struct i40e_pf *pf, s16 vf_id, u32 v_opcode,
                i40e_vc_notify_vf_link_state(vf);
                break;
        case VIRTCHNL_OP_RESET_VF:
-               i40e_vc_reset_vf_msg(vf);
+               i40e_vc_reset_vf(vf, false);
                ret = 0;
                break;
        case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE:
@@ -4161,7 +4160,7 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
        /* Force the VF interface down so it has to bring up with new MAC
         * address
         */
-       i40e_vc_disable_vf(vf);
+       i40e_vc_reset_vf(vf, true);
        dev_info(&pf->pdev->dev, "Bring down and up the VF interface to make this change effective.\n");
 
 error_param:
@@ -4169,34 +4168,6 @@ error_param:
        return ret;
 }
 
-/**
- * i40e_vsi_has_vlans - True if VSI has configured VLANs
- * @vsi: pointer to the vsi
- *
- * Check if a VSI has configured any VLANs. False if we have a port VLAN or if
- * we have no configured VLANs. Do not call while holding the
- * mac_filter_hash_lock.
- */
-static bool i40e_vsi_has_vlans(struct i40e_vsi *vsi)
-{
-       bool have_vlans;
-
-       /* If we have a port VLAN, then the VSI cannot have any VLANs
-        * configured, as all MAC/VLAN filters will be assigned to the PVID.
-        */
-       if (vsi->info.pvid)
-               return false;
-
-       /* Since we don't have a PVID, we know that if the device is in VLAN
-        * mode it must be because of a VLAN filter configured on this VSI.
-        */
-       spin_lock_bh(&vsi->mac_filter_hash_lock);
-       have_vlans = i40e_is_vsi_in_vlan(vsi);
-       spin_unlock_bh(&vsi->mac_filter_hash_lock);
-
-       return have_vlans;
-}
-
 /**
  * i40e_ndo_set_vf_port_vlan
  * @netdev: network interface device structure
@@ -4253,19 +4224,9 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id,
                /* duplicate request, so just return success */
                goto error_pvid;
 
-       if (i40e_vsi_has_vlans(vsi)) {
-               dev_err(&pf->pdev->dev,
-                       "VF %d has already configured VLAN filters and the administrator is requesting a port VLAN override.\nPlease unload and reload the VF driver for this change to take effect.\n",
-                       vf_id);
-               /* Administrator Error - knock the VF offline until he does
-                * the right thing by reconfiguring his network correctly
-                * and then reloading the VF driver.
-                */
-               i40e_vc_disable_vf(vf);
-               /* During reset the VF got a new VSI, so refresh the pointer. */
-               vsi = pf->vsi[vf->lan_vsi_idx];
-       }
-
+       i40e_vc_reset_vf(vf, true);
+       /* During reset the VF got a new VSI, so refresh a pointer. */
+       vsi = pf->vsi[vf->lan_vsi_idx];
        /* Locked once because multiple functions below iterate list */
        spin_lock_bh(&vsi->mac_filter_hash_lock);
 
@@ -4641,7 +4602,7 @@ int i40e_ndo_set_vf_trust(struct net_device *netdev, int vf_id, bool setting)
                goto out;
 
        vf->trusted = setting;
-       i40e_vc_disable_vf(vf);
+       i40e_vc_reset_vf(vf, true);
        dev_info(&pf->pdev->dev, "VF %u is now %strusted\n",
                 vf_id, setting ? "" : "un");
 
index e6e7c1d..3789269 100644 (file)
@@ -39,6 +39,7 @@
 #include "iavf_txrx.h"
 #include "iavf_fdir.h"
 #include "iavf_adv_rss.h"
+#include <linux/bitmap.h>
 
 #define DEFAULT_DEBUG_LEVEL_SHIFT 3
 #define PFX "iavf: "
@@ -304,6 +305,7 @@ struct iavf_adapter {
 #define IAVF_FLAG_AQ_DEL_FDIR_FILTER           BIT(26)
 #define IAVF_FLAG_AQ_ADD_ADV_RSS_CFG           BIT(27)
 #define IAVF_FLAG_AQ_DEL_ADV_RSS_CFG           BIT(28)
+#define IAVF_FLAG_AQ_REQUEST_STATS             BIT(29)
 
        /* OS defined structs */
        struct net_device *netdev;
@@ -443,6 +445,7 @@ int iavf_up(struct iavf_adapter *adapter);
 void iavf_down(struct iavf_adapter *adapter);
 int iavf_process_config(struct iavf_adapter *adapter);
 void iavf_schedule_reset(struct iavf_adapter *adapter);
+void iavf_schedule_request_stats(struct iavf_adapter *adapter);
 void iavf_reset(struct iavf_adapter *adapter);
 void iavf_set_ethtool_ops(struct net_device *netdev);
 void iavf_update_stats(struct iavf_adapter *adapter);
@@ -500,4 +503,5 @@ void iavf_add_adv_rss_cfg(struct iavf_adapter *adapter);
 void iavf_del_adv_rss_cfg(struct iavf_adapter *adapter);
 struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter,
                                        const u8 *macaddr);
+int iavf_lock_timeout(struct mutex *lock, unsigned int msecs);
 #endif /* _IAVF_H_ */
index 5a359a0..0cecaff 100644 (file)
@@ -354,6 +354,9 @@ static void iavf_get_ethtool_stats(struct net_device *netdev,
        struct iavf_adapter *adapter = netdev_priv(netdev);
        unsigned int i;
 
+       /* Explicitly request stats refresh */
+       iavf_schedule_request_stats(adapter);
+
        iavf_add_ethtool_stats(&data, adapter, iavf_gstrings_stats);
 
        rcu_read_lock();
@@ -723,12 +726,31 @@ static int iavf_get_per_queue_coalesce(struct net_device *netdev, u32 queue,
  *
  * Change the ITR settings for a specific queue.
  **/
-static void iavf_set_itr_per_queue(struct iavf_adapter *adapter,
-                                  struct ethtool_coalesce *ec, int queue)
+static int iavf_set_itr_per_queue(struct iavf_adapter *adapter,
+                                 struct ethtool_coalesce *ec, int queue)
 {
        struct iavf_ring *rx_ring = &adapter->rx_rings[queue];
        struct iavf_ring *tx_ring = &adapter->tx_rings[queue];
        struct iavf_q_vector *q_vector;
+       u16 itr_setting;
+
+       itr_setting = rx_ring->itr_setting & ~IAVF_ITR_DYNAMIC;
+
+       if (ec->rx_coalesce_usecs != itr_setting &&
+           ec->use_adaptive_rx_coalesce) {
+               netif_info(adapter, drv, adapter->netdev,
+                          "Rx interrupt throttling cannot be changed if adaptive-rx is enabled\n");
+               return -EINVAL;
+       }
+
+       itr_setting = tx_ring->itr_setting & ~IAVF_ITR_DYNAMIC;
+
+       if (ec->tx_coalesce_usecs != itr_setting &&
+           ec->use_adaptive_tx_coalesce) {
+               netif_info(adapter, drv, adapter->netdev,
+                          "Tx interrupt throttling cannot be changed if adaptive-tx is enabled\n");
+               return -EINVAL;
+       }
 
        rx_ring->itr_setting = ITR_REG_ALIGN(ec->rx_coalesce_usecs);
        tx_ring->itr_setting = ITR_REG_ALIGN(ec->tx_coalesce_usecs);
@@ -751,6 +773,7 @@ static void iavf_set_itr_per_queue(struct iavf_adapter *adapter,
         * the Tx and Rx ITR values based on the values we have entered
         * into the q_vector, no need to write the values now.
         */
+       return 0;
 }
 
 /**
@@ -792,9 +815,11 @@ static int __iavf_set_coalesce(struct net_device *netdev,
         */
        if (queue < 0) {
                for (i = 0; i < adapter->num_active_queues; i++)
-                       iavf_set_itr_per_queue(adapter, ec, i);
+                       if (iavf_set_itr_per_queue(adapter, ec, i))
+                               return -EINVAL;
        } else if (queue < adapter->num_active_queues) {
-               iavf_set_itr_per_queue(adapter, ec, queue);
+               if (iavf_set_itr_per_queue(adapter, ec, queue))
+                       return -EINVAL;
        } else {
                netif_info(adapter, drv, netdev, "Invalid queue value, queue range is 0 - %d\n",
                           adapter->num_active_queues - 1);
@@ -1776,6 +1801,7 @@ static int iavf_set_channels(struct net_device *netdev,
 {
        struct iavf_adapter *adapter = netdev_priv(netdev);
        u32 num_req = ch->combined_count;
+       int i;
 
        if ((adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ) &&
            adapter->num_tc) {
@@ -1786,7 +1812,7 @@ static int iavf_set_channels(struct net_device *netdev,
        /* All of these should have already been checked by ethtool before this
         * even gets to us, but just to be sure.
         */
-       if (num_req > adapter->vsi_res->num_queue_pairs)
+       if (num_req == 0 || num_req > adapter->vsi_res->num_queue_pairs)
                return -EINVAL;
 
        if (num_req == adapter->num_active_queues)
@@ -1798,6 +1824,20 @@ static int iavf_set_channels(struct net_device *netdev,
        adapter->num_req_queues = num_req;
        adapter->flags |= IAVF_FLAG_REINIT_ITR_NEEDED;
        iavf_schedule_reset(adapter);
+
+       /* wait for the reset is done */
+       for (i = 0; i < IAVF_RESET_WAIT_COMPLETE_COUNT; i++) {
+               msleep(IAVF_RESET_WAIT_MS);
+               if (adapter->flags & IAVF_FLAG_RESET_PENDING)
+                       continue;
+               break;
+       }
+       if (i == IAVF_RESET_WAIT_COMPLETE_COUNT) {
+               adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED;
+               adapter->num_active_queues = num_req;
+               return -EOPNOTSUPP;
+       }
+
        return 0;
 }
 
@@ -1844,14 +1884,13 @@ static int iavf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
 
        if (hfunc)
                *hfunc = ETH_RSS_HASH_TOP;
-       if (!indir)
-               return 0;
-
-       memcpy(key, adapter->rss_key, adapter->rss_key_size);
+       if (key)
+               memcpy(key, adapter->rss_key, adapter->rss_key_size);
 
-       /* Each 32 bits pointed by 'indir' is stored with a lut entry */
-       for (i = 0; i < adapter->rss_lut_size; i++)
-               indir[i] = (u32)adapter->rss_lut[i];
+       if (indir)
+               /* Each 32 bits pointed by 'indir' is stored with a lut entry */
+               for (i = 0; i < adapter->rss_lut_size; i++)
+                       indir[i] = (u32)adapter->rss_lut[i];
 
        return 0;
 }
index 847d67e..14934a7 100644 (file)
@@ -147,7 +147,7 @@ enum iavf_status iavf_free_virt_mem_d(struct iavf_hw *hw,
  *
  * Returns 0 on success, negative on failure
  **/
-static int iavf_lock_timeout(struct mutex *lock, unsigned int msecs)
+int iavf_lock_timeout(struct mutex *lock, unsigned int msecs)
 {
        unsigned int wait, delay = 10;
 
@@ -174,6 +174,19 @@ void iavf_schedule_reset(struct iavf_adapter *adapter)
        }
 }
 
+/**
+ * iavf_schedule_request_stats - Set the flags and schedule statistics request
+ * @adapter: board private structure
+ *
+ * Sets IAVF_FLAG_AQ_REQUEST_STATS flag so iavf_watchdog_task() will explicitly
+ * request and refresh ethtool stats
+ **/
+void iavf_schedule_request_stats(struct iavf_adapter *adapter)
+{
+       adapter->aq_required |= IAVF_FLAG_AQ_REQUEST_STATS;
+       mod_delayed_work(iavf_wq, &adapter->watchdog_task, 0);
+}
+
 /**
  * iavf_tx_timeout - Respond to a Tx Hang
  * @netdev: network interface device structure
@@ -696,6 +709,21 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, u16 vlan)
        spin_unlock_bh(&adapter->mac_vlan_list_lock);
 }
 
+/**
+ * iavf_restore_filters
+ * @adapter: board private structure
+ *
+ * Restore existing non MAC filters when VF netdev comes back up
+ **/
+static void iavf_restore_filters(struct iavf_adapter *adapter)
+{
+       u16 vid;
+
+       /* re-add all VLAN filters */
+       for_each_set_bit(vid, adapter->vsi.active_vlans, VLAN_N_VID)
+               iavf_add_vlan(adapter, vid);
+}
+
 /**
  * iavf_vlan_rx_add_vid - Add a VLAN filter to a device
  * @netdev: network device struct
@@ -709,8 +737,11 @@ static int iavf_vlan_rx_add_vid(struct net_device *netdev,
 
        if (!VLAN_ALLOWED(adapter))
                return -EIO;
+
        if (iavf_add_vlan(adapter, vid) == NULL)
                return -ENOMEM;
+
+       set_bit(vid, adapter->vsi.active_vlans);
        return 0;
 }
 
@@ -725,11 +756,10 @@ static int iavf_vlan_rx_kill_vid(struct net_device *netdev,
 {
        struct iavf_adapter *adapter = netdev_priv(netdev);
 
-       if (VLAN_ALLOWED(adapter)) {
-               iavf_del_vlan(adapter, vid);
-               return 0;
-       }
-       return -EIO;
+       iavf_del_vlan(adapter, vid);
+       clear_bit(vid, adapter->vsi.active_vlans);
+
+       return 0;
 }
 
 /**
@@ -1639,8 +1669,7 @@ static int iavf_process_aq_command(struct iavf_adapter *adapter)
                iavf_set_promiscuous(adapter, FLAG_VF_MULTICAST_PROMISC);
                return 0;
        }
-
-       if ((adapter->aq_required & IAVF_FLAG_AQ_RELEASE_PROMISC) &&
+       if ((adapter->aq_required & IAVF_FLAG_AQ_RELEASE_PROMISC) ||
            (adapter->aq_required & IAVF_FLAG_AQ_RELEASE_ALLMULTI)) {
                iavf_set_promiscuous(adapter, 0);
                return 0;
@@ -1688,6 +1717,11 @@ static int iavf_process_aq_command(struct iavf_adapter *adapter)
                iavf_del_adv_rss_cfg(adapter);
                return 0;
        }
+       if (adapter->aq_required & IAVF_FLAG_AQ_REQUEST_STATS) {
+               iavf_request_stats(adapter);
+               return 0;
+       }
+
        return -EAGAIN;
 }
 
@@ -2123,8 +2157,8 @@ static void iavf_disable_vf(struct iavf_adapter *adapter)
 
        iavf_free_misc_irq(adapter);
        iavf_reset_interrupt_capability(adapter);
-       iavf_free_queues(adapter);
        iavf_free_q_vectors(adapter);
+       iavf_free_queues(adapter);
        memset(adapter->vf_res, 0, IAVF_VIRTCHNL_VF_RESOURCE_SIZE);
        iavf_shutdown_adminq(&adapter->hw);
        adapter->netdev->flags &= ~IFF_UP;
@@ -2152,7 +2186,6 @@ static void iavf_reset_task(struct work_struct *work)
        struct net_device *netdev = adapter->netdev;
        struct iavf_hw *hw = &adapter->hw;
        struct iavf_mac_filter *f, *ftmp;
-       struct iavf_vlan_filter *vlf;
        struct iavf_cloud_filter *cf;
        u32 reg_val;
        int i = 0, err;
@@ -2233,6 +2266,7 @@ continue_reset:
                   (adapter->state == __IAVF_RESETTING));
 
        if (running) {
+               netdev->flags &= ~IFF_UP;
                netif_carrier_off(netdev);
                netif_tx_stop_all_queues(netdev);
                adapter->link_up = false;
@@ -2292,11 +2326,6 @@ continue_reset:
        list_for_each_entry(f, &adapter->mac_filter_list, list) {
                f->add = true;
        }
-       /* re-add all VLAN filters */
-       list_for_each_entry(vlf, &adapter->vlan_filter_list, list) {
-               vlf->add = true;
-       }
-
        spin_unlock_bh(&adapter->mac_vlan_list_lock);
 
        /* check if TCs are running and re-add all cloud filters */
@@ -2310,7 +2339,6 @@ continue_reset:
        spin_unlock_bh(&adapter->cloud_filter_list_lock);
 
        adapter->aq_required |= IAVF_FLAG_AQ_ADD_MAC_FILTER;
-       adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;
        adapter->aq_required |= IAVF_FLAG_AQ_ADD_CLOUD_FILTER;
        iavf_misc_irq_enable(adapter);
 
@@ -2344,7 +2372,7 @@ continue_reset:
                 * to __IAVF_RUNNING
                 */
                iavf_up_complete(adapter);
-
+               netdev->flags |= IFF_UP;
                iavf_irq_enable(adapter, true);
        } else {
                iavf_change_state(adapter, __IAVF_DOWN);
@@ -2357,8 +2385,10 @@ continue_reset:
 reset_err:
        mutex_unlock(&adapter->client_lock);
        mutex_unlock(&adapter->crit_lock);
-       if (running)
+       if (running) {
                iavf_change_state(adapter, __IAVF_RUNNING);
+               netdev->flags |= IFF_UP;
+       }
        dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n");
        iavf_close(netdev);
 }
@@ -2410,7 +2440,7 @@ static void iavf_adminq_task(struct work_struct *work)
 
        /* check for error indications */
        val = rd32(hw, hw->aq.arq.len);
-       if (val == 0xdeadbeef) /* indicates device in reset */
+       if (val == 0xdeadbeef || val == 0xffffffff) /* device in reset */
                goto freedom;
        oldval = val;
        if (val & IAVF_VF_ARQLEN1_ARQVFE_MASK) {
@@ -3095,8 +3125,10 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter,
                return -ENOMEM;
 
        while (!mutex_trylock(&adapter->crit_lock)) {
-               if (--count == 0)
-                       goto err;
+               if (--count == 0) {
+                       kfree(filter);
+                       return err;
+               }
                udelay(1);
        }
 
@@ -3107,11 +3139,11 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter,
        /* start out with flow type and eth type IPv4 to begin with */
        filter->f.flow_type = VIRTCHNL_TCP_V4_FLOW;
        err = iavf_parse_cls_flower(adapter, cls_flower, filter);
-       if (err < 0)
+       if (err)
                goto err;
 
        err = iavf_handle_tclass(adapter, tc, filter);
-       if (err < 0)
+       if (err)
                goto err;
 
        /* add filter to the list */
@@ -3308,6 +3340,9 @@ static int iavf_open(struct net_device *netdev)
 
        spin_unlock_bh(&adapter->mac_vlan_list_lock);
 
+       /* Restore VLAN filters that were removed with IFF_DOWN */
+       iavf_restore_filters(adapter);
+
        iavf_configure(adapter);
 
        iavf_up_complete(adapter);
@@ -3415,11 +3450,16 @@ static int iavf_set_features(struct net_device *netdev,
 {
        struct iavf_adapter *adapter = netdev_priv(netdev);
 
-       /* Don't allow changing VLAN_RX flag when adapter is not capable
-        * of VLAN offload
+       /* Don't allow enabling VLAN features when adapter is not capable
+        * of VLAN offload/filtering
         */
        if (!VLAN_ALLOWED(adapter)) {
-               if ((netdev->features ^ features) & NETIF_F_HW_VLAN_CTAG_RX)
+               netdev->hw_features &= ~(NETIF_F_HW_VLAN_CTAG_RX |
+                                        NETIF_F_HW_VLAN_CTAG_TX |
+                                        NETIF_F_HW_VLAN_CTAG_FILTER);
+               if (features & (NETIF_F_HW_VLAN_CTAG_RX |
+                               NETIF_F_HW_VLAN_CTAG_TX |
+                               NETIF_F_HW_VLAN_CTAG_FILTER))
                        return -EINVAL;
        } else if ((netdev->features ^ features) & NETIF_F_HW_VLAN_CTAG_RX) {
                if (features & NETIF_F_HW_VLAN_CTAG_RX)
@@ -3503,7 +3543,8 @@ static netdev_features_t iavf_fix_features(struct net_device *netdev,
 {
        struct iavf_adapter *adapter = netdev_priv(netdev);
 
-       if (!(adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
+       if (adapter->vf_res &&
+           !(adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
                features &= ~(NETIF_F_HW_VLAN_CTAG_TX |
                              NETIF_F_HW_VLAN_CTAG_RX |
                              NETIF_F_HW_VLAN_CTAG_FILTER);
index 8c3f0f7..d60bf7c 100644 (file)
@@ -607,7 +607,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
                if (f->add)
                        count++;
        }
-       if (!count) {
+       if (!count || !VLAN_ALLOWED(adapter)) {
                adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_VLAN_FILTER;
                spin_unlock_bh(&adapter->mac_vlan_list_lock);
                return;
@@ -673,9 +673,19 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
 
        spin_lock_bh(&adapter->mac_vlan_list_lock);
 
-       list_for_each_entry(f, &adapter->vlan_filter_list, list) {
-               if (f->remove)
+       list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
+               /* since VLAN capabilities are not allowed, we dont want to send
+                * a VLAN delete request because it will most likely fail and
+                * create unnecessary errors/noise, so just free the VLAN
+                * filters marked for removal to enable bailing out before
+                * sending a virtchnl message
+                */
+               if (f->remove && !VLAN_ALLOWED(adapter)) {
+                       list_del(&f->list);
+                       kfree(f);
+               } else if (f->remove) {
                        count++;
+               }
        }
        if (!count) {
                adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_VLAN_FILTER;
@@ -784,6 +794,8 @@ void iavf_request_stats(struct iavf_adapter *adapter)
                /* no error message, this isn't crucial */
                return;
        }
+
+       adapter->aq_required &= ~IAVF_FLAG_AQ_REQUEST_STATS;
        adapter->current_op = VIRTCHNL_OP_GET_STATS;
        vqs.vsi_id = adapter->vsi_res->vsi_id;
        /* queue maps are ignored for this message - only the vsi is used */
@@ -1722,8 +1734,37 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
                }
                spin_lock_bh(&adapter->mac_vlan_list_lock);
                iavf_add_filter(adapter, adapter->hw.mac.addr);
+
+               if (VLAN_ALLOWED(adapter)) {
+                       if (!list_empty(&adapter->vlan_filter_list)) {
+                               struct iavf_vlan_filter *vlf;
+
+                               /* re-add all VLAN filters over virtchnl */
+                               list_for_each_entry(vlf,
+                                                   &adapter->vlan_filter_list,
+                                                   list)
+                                       vlf->add = true;
+
+                               adapter->aq_required |=
+                                       IAVF_FLAG_AQ_ADD_VLAN_FILTER;
+                       }
+               }
+
                spin_unlock_bh(&adapter->mac_vlan_list_lock);
                iavf_process_config(adapter);
+
+               /* unlock crit_lock before acquiring rtnl_lock as other
+                * processes holding rtnl_lock could be waiting for the same
+                * crit_lock
+                */
+               mutex_unlock(&adapter->crit_lock);
+               rtnl_lock();
+               netdev_update_features(adapter->netdev);
+               rtnl_unlock();
+               if (iavf_lock_timeout(&adapter->crit_lock, 10000))
+                       dev_warn(&adapter->pdev->dev, "failed to acquire crit_lock in %s\n",
+                                __FUNCTION__);
+
                }
                break;
        case VIRTCHNL_OP_ENABLE_QUEUES:
index 4056260..09a3297 100644 (file)
@@ -89,8 +89,13 @@ static int ice_vsi_alloc_arrays(struct ice_vsi *vsi)
        if (!vsi->rx_rings)
                goto err_rings;
 
-       /* XDP will have vsi->alloc_txq Tx queues as well, so double the size */
-       vsi->txq_map = devm_kcalloc(dev, (2 * vsi->alloc_txq),
+       /* txq_map needs to have enough space to track both Tx (stack) rings
+        * and XDP rings; at this point vsi->num_xdp_txq might not be set,
+        * so use num_possible_cpus() as we want to always provide XDP ring
+        * per CPU, regardless of queue count settings from user that might
+        * have come from ethtool's set_channels() callback;
+        */
+       vsi->txq_map = devm_kcalloc(dev, (vsi->alloc_txq + num_possible_cpus()),
                                    sizeof(*vsi->txq_map), GFP_KERNEL);
 
        if (!vsi->txq_map)
index f099797..4d1fc48 100644 (file)
@@ -2609,7 +2609,18 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog)
                        ice_stat_str(status));
                goto clear_xdp_rings;
        }
-       ice_vsi_assign_bpf_prog(vsi, prog);
+
+       /* assign the prog only when it's not already present on VSI;
+        * this flow is a subject of both ethtool -L and ndo_bpf flows;
+        * VSI rebuild that happens under ethtool -L can expose us to
+        * the bpf_prog refcount issues as we would be swapping same
+        * bpf_prog pointers from vsi->xdp_prog and calling bpf_prog_put
+        * on it as it would be treated as an 'old_prog'; for ndo_bpf
+        * this is not harmful as dev_xdp_install bumps the refcount
+        * before calling the op exposed by the driver;
+        */
+       if (!ice_is_xdp_ena_vsi(vsi))
+               ice_vsi_assign_bpf_prog(vsi, prog);
 
        return 0;
 clear_xdp_rings:
@@ -2785,6 +2796,11 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
                if (xdp_ring_err)
                        NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Tx resources failed");
        } else {
+               /* safe to call even when prog == vsi->xdp_prog as
+                * dev_xdp_install in net/core/dev.c incremented prog's
+                * refcount so corresponding bpf_prog_put won't cause
+                * underflow
+                */
                ice_vsi_assign_bpf_prog(vsi, prog);
        }
 
index 836be0d..fd54d3e 100644 (file)
@@ -8026,7 +8026,7 @@ static int igb_poll(struct napi_struct *napi, int budget)
        if (likely(napi_complete_done(napi, work_done)))
                igb_ring_irq_enable(q_vector);
 
-       return min(work_done, budget - 1);
+       return work_done;
 }
 
 /**
index 6433c90..072391c 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/io.h>
 #include <linux/dma-mapping.h>
 #include <linux/module.h>
+#include <linux/property.h>
 
 #include <asm/checksum.h>
 
@@ -239,6 +240,7 @@ ltq_etop_hw_init(struct net_device *dev)
 {
        struct ltq_etop_priv *priv = netdev_priv(dev);
        int i;
+       int err;
 
        ltq_pmu_enable(PMU_PPE);
 
@@ -273,7 +275,13 @@ ltq_etop_hw_init(struct net_device *dev)
 
                if (IS_TX(i)) {
                        ltq_dma_alloc_tx(&ch->dma);
-                       request_irq(irq, ltq_etop_dma_irq, 0, "etop_tx", priv);
+                       err = request_irq(irq, ltq_etop_dma_irq, 0, "etop_tx", priv);
+                       if (err) {
+                               netdev_err(dev,
+                                          "Unable to get Tx DMA IRQ %d\n",
+                                          irq);
+                               return err;
+                       }
                } else if (IS_RX(i)) {
                        ltq_dma_alloc_rx(&ch->dma);
                        for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM;
@@ -281,7 +289,13 @@ ltq_etop_hw_init(struct net_device *dev)
                                if (ltq_etop_alloc_skb(ch))
                                        return -ENOMEM;
                        ch->dma.desc = 0;
-                       request_irq(irq, ltq_etop_dma_irq, 0, "etop_rx", priv);
+                       err = request_irq(irq, ltq_etop_dma_irq, 0, "etop_rx", priv);
+                       if (err) {
+                               netdev_err(dev,
+                                          "Unable to get Rx DMA IRQ %d\n",
+                                          irq);
+                               return err;
+                       }
                }
                ch->dma.irq = irq;
        }
@@ -726,7 +740,7 @@ static struct platform_driver ltq_mii_driver = {
        },
 };
 
-int __init
+static int __init
 init_ltq_etop(void)
 {
        int ret = platform_driver_probe(&ltq_mii_driver, ltq_etop_probe);
index 62a97c4..ef87897 100644 (file)
@@ -429,12 +429,14 @@ static const struct of_device_id orion_mdio_match[] = {
 };
 MODULE_DEVICE_TABLE(of, orion_mdio_match);
 
+#ifdef CONFIG_ACPI
 static const struct acpi_device_id orion_mdio_acpi_match[] = {
        { "MRVL0100", BUS_TYPE_SMI },
        { "MRVL0101", BUS_TYPE_XSMI },
        { },
 };
 MODULE_DEVICE_TABLE(acpi, orion_mdio_acpi_match);
+#endif
 
 static struct platform_driver orion_mdio_driver = {
        .probe = orion_mdio_probe,
index 2b18d89..ce486e1 100644 (file)
@@ -5017,11 +5017,13 @@ static int mvpp2_change_mtu(struct net_device *dev, int mtu)
                mtu = ALIGN(MVPP2_RX_PKT_SIZE(mtu), 8);
        }
 
+       if (port->xdp_prog && mtu > MVPP2_MAX_RX_BUF_SIZE) {
+               netdev_err(dev, "Illegal MTU value %d (> %d) for XDP mode\n",
+                          mtu, (int)MVPP2_MAX_RX_BUF_SIZE);
+               return -EINVAL;
+       }
+
        if (MVPP2_RX_PKT_SIZE(mtu) > MVPP2_BM_LONG_PKT_SIZE) {
-               if (port->xdp_prog) {
-                       netdev_err(dev, "Jumbo frames are not supported with XDP\n");
-                       return -EINVAL;
-               }
                if (priv->percpu_pools) {
                        netdev_warn(dev, "mtu %d too high, switching to shared buffers", mtu);
                        mvpp2_bm_switch_buffers(priv, false);
@@ -5307,8 +5309,8 @@ static int mvpp2_xdp_setup(struct mvpp2_port *port, struct netdev_bpf *bpf)
        bool running = netif_running(port->dev);
        bool reset = !prog != !port->xdp_prog;
 
-       if (port->dev->mtu > ETH_DATA_LEN) {
-               NL_SET_ERR_MSG_MOD(bpf->extack, "XDP is not supported with jumbo frames enabled");
+       if (port->dev->mtu > MVPP2_MAX_RX_BUF_SIZE) {
+               NL_SET_ERR_MSG_MOD(bpf->extack, "MTU too large for XDP");
                return -EOPNOTSUPP;
        }
 
index c7fd466..a09a507 100644 (file)
@@ -236,10 +236,11 @@ static ssize_t rvu_dbg_lmtst_map_table_display(struct file *filp,
        u64 lmt_addr, val, tbl_base;
        int pf, vf, num_vfs, hw_vfs;
        void __iomem *lmt_map_base;
-       int index = 0, off = 0;
-       int bytes_not_copied;
        int buf_size = 10240;
+       size_t off = 0;
+       int index = 0;
        char *buf;
+       int ret;
 
        /* don't allow partial reads */
        if (*ppos != 0)
@@ -303,15 +304,17 @@ static ssize_t rvu_dbg_lmtst_map_table_display(struct file *filp,
        }
        off +=  scnprintf(&buf[off], buf_size - 1 - off, "\n");
 
-       bytes_not_copied = copy_to_user(buffer, buf, off);
+       ret = min(off, count);
+       if (copy_to_user(buffer, buf, ret))
+               ret = -EFAULT;
        kfree(buf);
 
        iounmap(lmt_map_base);
-       if (bytes_not_copied)
-               return -EFAULT;
+       if (ret < 0)
+               return ret;
 
-       *ppos = off;
-       return off;
+       *ppos = ret;
+       return ret;
 }
 
 RVU_DEBUG_FOPS(lmtst_map_table, lmtst_map_table_display, NULL);
index 3ce6ccd..b4599fe 100644 (file)
@@ -497,8 +497,8 @@ int prestera_bridge_port_join(struct net_device *br_dev,
 
        br_port = prestera_bridge_port_add(bridge, port->dev);
        if (IS_ERR(br_port)) {
-               err = PTR_ERR(br_port);
-               goto err_brport_create;
+               prestera_bridge_put(bridge);
+               return PTR_ERR(br_port);
        }
 
        err = switchdev_bridge_port_offload(br_port->dev, port->dev, NULL,
@@ -519,8 +519,6 @@ err_port_join:
        switchdev_bridge_port_unoffload(br_port->dev, NULL, NULL, NULL);
 err_switchdev_offload:
        prestera_bridge_port_put(br_port);
-err_brport_create:
-       prestera_bridge_put(bridge);
        return err;
 }
 
@@ -1124,7 +1122,7 @@ static int prestera_switchdev_blk_event(struct notifier_block *unused,
                                                     prestera_port_obj_attr_set);
                break;
        default:
-               err = -EOPNOTSUPP;
+               return NOTIFY_DONE;
        }
 
        return notifier_from_errno(err);
index f71ec4d..8eaa24d 100644 (file)
@@ -339,6 +339,8 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op,
        case MLX5_CMD_OP_PAGE_FAULT_RESUME:
        case MLX5_CMD_OP_QUERY_ESW_FUNCTIONS:
        case MLX5_CMD_OP_DEALLOC_SF:
+       case MLX5_CMD_OP_DESTROY_UCTX:
+       case MLX5_CMD_OP_DESTROY_UMEM:
                return MLX5_CMD_STAT_OK;
 
        case MLX5_CMD_OP_QUERY_HCA_CAP:
@@ -464,9 +466,7 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op,
        case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT:
        case MLX5_CMD_OP_QUERY_GENERAL_OBJECT:
        case MLX5_CMD_OP_CREATE_UCTX:
-       case MLX5_CMD_OP_DESTROY_UCTX:
        case MLX5_CMD_OP_CREATE_UMEM:
-       case MLX5_CMD_OP_DESTROY_UMEM:
        case MLX5_CMD_OP_ALLOC_MEMIC:
        case MLX5_CMD_OP_MODIFY_XRQ:
        case MLX5_CMD_OP_RELEASE_XRQ_ERROR:
index 02e77ff..5371ad0 100644 (file)
@@ -164,13 +164,14 @@ int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq)
        MLX5_SET(destroy_cq_in, in, cqn, cq->cqn);
        MLX5_SET(destroy_cq_in, in, uid, cq->uid);
        err = mlx5_cmd_exec_in(dev, destroy_cq, in);
+       if (err)
+               return err;
 
        synchronize_irq(cq->irqn);
-
        mlx5_cq_put(cq);
        wait_for_completion(&cq->free);
 
-       return err;
+       return 0;
 }
 EXPORT_SYMBOL(mlx5_core_destroy_cq);
 
index 07c8d98..10d1950 100644 (file)
@@ -507,6 +507,8 @@ void mlx5_debug_cq_remove(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq)
        if (!mlx5_debugfs_root)
                return;
 
-       if (cq->dbg)
+       if (cq->dbg) {
                rem_res_tree(cq->dbg);
+               cq->dbg = NULL;
+       }
 }
index c1c6e74..2445e2a 100644 (file)
@@ -1356,9 +1356,13 @@ mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv *priv,
 int
 mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
                        struct mlx5_flow_attr *attr,
+                       struct mlx5e_tc_mod_hdr_acts *mod_acts,
                        const struct flow_action_entry *act,
                        struct netlink_ext_ack *extack)
 {
+       bool clear_action = act->ct.action & TCA_CT_ACT_CLEAR;
+       int err;
+
        if (!priv) {
                NL_SET_ERR_MSG_MOD(extack,
                                   "offload of ct action isn't available");
@@ -1369,6 +1373,17 @@ mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
        attr->ct_attr.ct_action = act->ct.action;
        attr->ct_attr.nf_ft = act->ct.flow_table;
 
+       if (!clear_action)
+               goto out;
+
+       err = mlx5_tc_ct_entry_set_registers(priv, mod_acts, 0, 0, 0, 0);
+       if (err) {
+               NL_SET_ERR_MSG_MOD(extack, "Failed to set registers for ct clear");
+               return err;
+       }
+       attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
+
+out:
        return 0;
 }
 
@@ -1898,23 +1913,16 @@ __mlx5_tc_ct_flow_offload_clear(struct mlx5_tc_ct_priv *ct_priv,
 
        memcpy(pre_ct_attr, attr, attr_sz);
 
-       err = mlx5_tc_ct_entry_set_registers(ct_priv, mod_acts, 0, 0, 0, 0);
-       if (err) {
-               ct_dbg("Failed to set register for ct clear");
-               goto err_set_registers;
-       }
-
        mod_hdr = mlx5_modify_header_alloc(priv->mdev, ct_priv->ns_type,
                                           mod_acts->num_actions,
                                           mod_acts->actions);
        if (IS_ERR(mod_hdr)) {
                err = PTR_ERR(mod_hdr);
                ct_dbg("Failed to add create ct clear mod hdr");
-               goto err_set_registers;
+               goto err_mod_hdr;
        }
 
        pre_ct_attr->modify_hdr = mod_hdr;
-       pre_ct_attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
 
        rule = mlx5_tc_rule_insert(priv, orig_spec, pre_ct_attr);
        if (IS_ERR(rule)) {
@@ -1930,7 +1938,7 @@ __mlx5_tc_ct_flow_offload_clear(struct mlx5_tc_ct_priv *ct_priv,
 
 err_insert:
        mlx5_modify_header_dealloc(priv->mdev, mod_hdr);
-err_set_registers:
+err_mod_hdr:
        netdev_warn(priv->netdev,
                    "Failed to offload ct clear flow, err %d\n", err);
        kfree(pre_ct_attr);
index 363329f..99662af 100644 (file)
@@ -110,6 +110,7 @@ int mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec);
 int
 mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
                        struct mlx5_flow_attr *attr,
+                       struct mlx5e_tc_mod_hdr_acts *mod_acts,
                        const struct flow_action_entry *act,
                        struct netlink_ext_ack *extack);
 
@@ -172,6 +173,7 @@ mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec)
 static inline int
 mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
                        struct mlx5_flow_attr *attr,
+                       struct mlx5e_tc_mod_hdr_acts *mod_acts,
                        const struct flow_action_entry *act,
                        struct netlink_ext_ack *extack)
 {
index 8f64f2c..b689701 100644 (file)
@@ -102,6 +102,7 @@ struct mlx5e_tc_flow {
        refcount_t refcnt;
        struct rcu_head rcu_head;
        struct completion init_done;
+       struct completion del_hw_done;
        int tunnel_id; /* the mapped tunnel id of this flow */
        struct mlx5_flow_attr *attr;
 };
index 660cca7..042b1ab 100644 (file)
@@ -245,8 +245,14 @@ static void mlx5e_take_tmp_flow(struct mlx5e_tc_flow *flow,
                                struct list_head *flow_list,
                                int index)
 {
-       if (IS_ERR(mlx5e_flow_get(flow)))
+       if (IS_ERR(mlx5e_flow_get(flow))) {
+               /* Flow is being deleted concurrently. Wait for it to be
+                * unoffloaded from hardware, otherwise deleting encap will
+                * fail.
+                */
+               wait_for_completion(&flow->del_hw_done);
                return;
+       }
        wait_for_completion(&flow->init_done);
 
        flow->tmp_entry_index = index;
index 62abce0..a2a9f68 100644 (file)
@@ -55,6 +55,7 @@ struct mlx5e_ktls_offload_context_rx {
        DECLARE_BITMAP(flags, MLX5E_NUM_PRIV_RX_FLAGS);
 
        /* resync */
+       spinlock_t lock; /* protects resync fields */
        struct mlx5e_ktls_rx_resync_ctx resync;
        struct list_head list;
 };
@@ -386,14 +387,18 @@ static void resync_handle_seq_match(struct mlx5e_ktls_offload_context_rx *priv_r
        struct mlx5e_icosq *sq;
        bool trigger_poll;
 
-       memcpy(info->rec_seq, &priv_rx->resync.sw_rcd_sn_be, sizeof(info->rec_seq));
-
        sq = &c->async_icosq;
        ktls_resync = sq->ktls_resync;
+       trigger_poll = false;
 
        spin_lock_bh(&ktls_resync->lock);
-       list_add_tail(&priv_rx->list, &ktls_resync->list);
-       trigger_poll = !test_and_set_bit(MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC, &sq->state);
+       spin_lock_bh(&priv_rx->lock);
+       memcpy(info->rec_seq, &priv_rx->resync.sw_rcd_sn_be, sizeof(info->rec_seq));
+       if (list_empty(&priv_rx->list)) {
+               list_add_tail(&priv_rx->list, &ktls_resync->list);
+               trigger_poll = !test_and_set_bit(MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC, &sq->state);
+       }
+       spin_unlock_bh(&priv_rx->lock);
        spin_unlock_bh(&ktls_resync->lock);
 
        if (!trigger_poll)
@@ -617,6 +622,8 @@ int mlx5e_ktls_add_rx(struct net_device *netdev, struct sock *sk,
        if (err)
                goto err_create_key;
 
+       INIT_LIST_HEAD(&priv_rx->list);
+       spin_lock_init(&priv_rx->lock);
        priv_rx->crypto_info  =
                *(struct tls12_crypto_info_aes_gcm_128 *)crypto_info;
 
@@ -730,10 +737,14 @@ bool mlx5e_ktls_rx_handle_resync_list(struct mlx5e_channel *c, int budget)
                priv_rx = list_first_entry(&local_list,
                                           struct mlx5e_ktls_offload_context_rx,
                                           list);
+               spin_lock(&priv_rx->lock);
                cseg = post_static_params(sq, priv_rx);
-               if (IS_ERR(cseg))
+               if (IS_ERR(cseg)) {
+                       spin_unlock(&priv_rx->lock);
                        break;
-               list_del(&priv_rx->list);
+               }
+               list_del_init(&priv_rx->list);
+               spin_unlock(&priv_rx->lock);
                db_cseg = cseg;
        }
        if (db_cseg)
index 835caa1..3d45f4a 100644 (file)
@@ -1600,6 +1600,7 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv,
                else
                        mlx5e_tc_unoffload_fdb_rules(esw, flow, attr);
        }
+       complete_all(&flow->del_hw_done);
 
        if (mlx5_flow_has_geneve_opt(flow))
                mlx5_geneve_tlv_option_del(priv->mdev->geneve);
@@ -3607,7 +3608,9 @@ parse_tc_nic_actions(struct mlx5e_priv *priv,
                        attr->dest_chain = act->chain_index;
                        break;
                case FLOW_ACTION_CT:
-                       err = mlx5_tc_ct_parse_action(get_ct_priv(priv), attr, act, extack);
+                       err = mlx5_tc_ct_parse_action(get_ct_priv(priv), attr,
+                                                     &parse_attr->mod_hdr_acts,
+                                                     act, extack);
                        if (err)
                                return err;
 
@@ -4276,7 +4279,9 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
                                NL_SET_ERR_MSG_MOD(extack, "Sample action with connection tracking is not supported");
                                return -EOPNOTSUPP;
                        }
-                       err = mlx5_tc_ct_parse_action(get_ct_priv(priv), attr, act, extack);
+                       err = mlx5_tc_ct_parse_action(get_ct_priv(priv), attr,
+                                                     &parse_attr->mod_hdr_acts,
+                                                     act, extack);
                        if (err)
                                return err;
 
@@ -4465,6 +4470,7 @@ mlx5e_alloc_flow(struct mlx5e_priv *priv, int attr_size,
        INIT_LIST_HEAD(&flow->l3_to_l2_reformat);
        refcount_set(&flow->refcnt, 1);
        init_completion(&flow->init_done);
+       init_completion(&flow->del_hw_done);
 
        *__flow = flow;
        *__parse_attr = parse_attr;
index ec136b4..51a8cec 100644 (file)
@@ -1305,12 +1305,17 @@ abort:
  */
 int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs)
 {
+       bool toggle_lag;
        int ret;
 
        if (!mlx5_esw_allowed(esw))
                return 0;
 
-       mlx5_lag_disable_change(esw->dev);
+       toggle_lag = esw->mode == MLX5_ESWITCH_NONE;
+
+       if (toggle_lag)
+               mlx5_lag_disable_change(esw->dev);
+
        down_write(&esw->mode_lock);
        if (esw->mode == MLX5_ESWITCH_NONE) {
                ret = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_LEGACY, num_vfs);
@@ -1324,7 +1329,10 @@ int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs)
                        esw->esw_funcs.num_vfs = num_vfs;
        }
        up_write(&esw->mode_lock);
-       mlx5_lag_enable_change(esw->dev);
+
+       if (toggle_lag)
+               mlx5_lag_enable_change(esw->dev);
+
        return ret;
 }
 
@@ -1572,6 +1580,11 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev)
        esw->enabled_vports = 0;
        esw->mode = MLX5_ESWITCH_NONE;
        esw->offloads.inline_mode = MLX5_INLINE_MODE_NONE;
+       if (MLX5_CAP_ESW_FLOWTABLE_FDB(dev, reformat) &&
+           MLX5_CAP_ESW_FLOWTABLE_FDB(dev, decap))
+               esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_BASIC;
+       else
+               esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_NONE;
 
        dev->priv.eswitch = esw;
        BLOCKING_INIT_NOTIFIER_HEAD(&esw->n_head);
@@ -1934,7 +1947,7 @@ free_out:
        return err;
 }
 
-u8 mlx5_eswitch_mode(struct mlx5_core_dev *dev)
+u8 mlx5_eswitch_mode(const struct mlx5_core_dev *dev)
 {
        struct mlx5_eswitch *esw = dev->priv.eswitch;
 
@@ -1948,7 +1961,7 @@ mlx5_eswitch_get_encap_mode(const struct mlx5_core_dev *dev)
        struct mlx5_eswitch *esw;
 
        esw = dev->priv.eswitch;
-       return mlx5_esw_allowed(esw) ? esw->offloads.encap :
+       return (mlx5_eswitch_mode(dev) == MLX5_ESWITCH_OFFLOADS)  ? esw->offloads.encap :
                DEVLINK_ESWITCH_ENCAP_MODE_NONE;
 }
 EXPORT_SYMBOL(mlx5_eswitch_get_encap_mode);
index f4eaa58..a464556 100644 (file)
@@ -3183,12 +3183,6 @@ int esw_offloads_enable(struct mlx5_eswitch *esw)
        u64 mapping_id;
        int err;
 
-       if (MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, reformat) &&
-           MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, decap))
-               esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_BASIC;
-       else
-               esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_NONE;
-
        mutex_init(&esw->offloads.termtbl_mutex);
        mlx5_rdma_enable_roce(esw->dev);
 
@@ -3286,7 +3280,6 @@ void esw_offloads_disable(struct mlx5_eswitch *esw)
        esw_offloads_metadata_uninit(esw);
        mlx5_rdma_disable_roce(esw->dev);
        mutex_destroy(&esw->offloads.termtbl_mutex);
-       esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_NONE;
 }
 
 static int esw_mode_from_devlink(u16 mode, u16 *mlx5_mode)
@@ -3630,7 +3623,7 @@ int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink,
        *encap = esw->offloads.encap;
 unlock:
        up_write(&esw->mode_lock);
-       return 0;
+       return err;
 }
 
 static bool
index 31c99d5..7e0e04c 100644 (file)
@@ -40,7 +40,7 @@
 #define MLX5_FC_STATS_PERIOD msecs_to_jiffies(1000)
 /* Max number of counters to query in bulk read is 32K */
 #define MLX5_SW_MAX_COUNTERS_BULK BIT(15)
-#define MLX5_SF_NUM_COUNTERS_BULK 6
+#define MLX5_SF_NUM_COUNTERS_BULK 8
 #define MLX5_FC_POOL_MAX_THRESHOLD BIT(18)
 #define MLX5_FC_POOL_USED_BUFF_RATIO 10
 
index 48d2ea6..4ddf6b3 100644 (file)
@@ -615,6 +615,7 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev,
        bool is_bonded, is_in_lag, mode_supported;
        int bond_status = 0;
        int num_slaves = 0;
+       int changed = 0;
        int idx;
 
        if (!netif_is_lag_master(upper))
@@ -653,27 +654,27 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev,
         */
        is_in_lag = num_slaves == MLX5_MAX_PORTS && bond_status == 0x3;
 
-       if (!mlx5_lag_is_ready(ldev) && is_in_lag) {
-               NL_SET_ERR_MSG_MOD(info->info.extack,
-                                  "Can't activate LAG offload, PF is configured with more than 64 VFs");
-               return 0;
-       }
-
        /* Lag mode must be activebackup or hash. */
        mode_supported = tracker->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP ||
                         tracker->tx_type == NETDEV_LAG_TX_TYPE_HASH;
 
-       if (is_in_lag && !mode_supported)
-               NL_SET_ERR_MSG_MOD(info->info.extack,
-                                  "Can't activate LAG offload, TX type isn't supported");
-
        is_bonded = is_in_lag && mode_supported;
        if (tracker->is_bonded != is_bonded) {
                tracker->is_bonded = is_bonded;
-               return 1;
+               changed = 1;
        }
 
-       return 0;
+       if (!is_in_lag)
+               return changed;
+
+       if (!mlx5_lag_is_ready(ldev))
+               NL_SET_ERR_MSG_MOD(info->info.extack,
+                                  "Can't activate LAG offload, PF is configured with more than 64 VFs");
+       else if (!mode_supported)
+               NL_SET_ERR_MSG_MOD(info->info.extack,
+                                  "Can't activate LAG offload, TX type isn't supported");
+
+       return changed;
 }
 
 static int mlx5_handle_changelowerstate_event(struct mlx5_lag *ldev,
@@ -716,9 +717,6 @@ static int mlx5_lag_netdev_event(struct notifier_block *this,
 
        ldev    = container_of(this, struct mlx5_lag, nb);
 
-       if (!mlx5_lag_is_ready(ldev) && event == NETDEV_CHANGELOWERSTATE)
-               return NOTIFY_DONE;
-
        tracker = ldev->tracker;
 
        switch (event) {
index 49089cb..8cbd36c 100644 (file)
@@ -135,25 +135,14 @@ static void dr_domain_fill_uplink_caps(struct mlx5dr_domain *dmn,
 
 static int dr_domain_query_vport(struct mlx5dr_domain *dmn,
                                 u16 vport_number,
+                                bool other_vport,
                                 struct mlx5dr_cmd_vport_cap *vport_caps)
 {
-       u16 cmd_vport = vport_number;
-       bool other_vport = true;
        int ret;
 
-       if (vport_number == MLX5_VPORT_UPLINK) {
-               dr_domain_fill_uplink_caps(dmn, vport_caps);
-               return 0;
-       }
-
-       if (dmn->info.caps.is_ecpf && vport_number == MLX5_VPORT_ECPF) {
-               other_vport = false;
-               cmd_vport = 0;
-       }
-
        ret = mlx5dr_cmd_query_esw_vport_context(dmn->mdev,
                                                 other_vport,
-                                                cmd_vport,
+                                                vport_number,
                                                 &vport_caps->icm_address_rx,
                                                 &vport_caps->icm_address_tx);
        if (ret)
@@ -161,7 +150,7 @@ static int dr_domain_query_vport(struct mlx5dr_domain *dmn,
 
        ret = mlx5dr_cmd_query_gvmi(dmn->mdev,
                                    other_vport,
-                                   cmd_vport,
+                                   vport_number,
                                    &vport_caps->vport_gvmi);
        if (ret)
                return ret;
@@ -176,9 +165,15 @@ static int dr_domain_query_esw_mngr(struct mlx5dr_domain *dmn)
 {
        return dr_domain_query_vport(dmn,
                                     dmn->info.caps.is_ecpf ? MLX5_VPORT_ECPF : 0,
+                                    false,
                                     &dmn->info.caps.vports.esw_manager_caps);
 }
 
+static void dr_domain_query_uplink(struct mlx5dr_domain *dmn)
+{
+       dr_domain_fill_uplink_caps(dmn, &dmn->info.caps.vports.uplink_caps);
+}
+
 static struct mlx5dr_cmd_vport_cap *
 dr_domain_add_vport_cap(struct mlx5dr_domain *dmn, u16 vport)
 {
@@ -190,7 +185,7 @@ dr_domain_add_vport_cap(struct mlx5dr_domain *dmn, u16 vport)
        if (!vport_caps)
                return NULL;
 
-       ret = dr_domain_query_vport(dmn, vport, vport_caps);
+       ret = dr_domain_query_vport(dmn, vport, true, vport_caps);
        if (ret) {
                kvfree(vport_caps);
                return NULL;
@@ -207,16 +202,26 @@ dr_domain_add_vport_cap(struct mlx5dr_domain *dmn, u16 vport)
        return vport_caps;
 }
 
+static bool dr_domain_is_esw_mgr_vport(struct mlx5dr_domain *dmn, u16 vport)
+{
+       struct mlx5dr_cmd_caps *caps = &dmn->info.caps;
+
+       return (caps->is_ecpf && vport == MLX5_VPORT_ECPF) ||
+              (!caps->is_ecpf && vport == 0);
+}
+
 struct mlx5dr_cmd_vport_cap *
 mlx5dr_domain_get_vport_cap(struct mlx5dr_domain *dmn, u16 vport)
 {
        struct mlx5dr_cmd_caps *caps = &dmn->info.caps;
        struct mlx5dr_cmd_vport_cap *vport_caps;
 
-       if ((caps->is_ecpf && vport == MLX5_VPORT_ECPF) ||
-           (!caps->is_ecpf && vport == 0))
+       if (dr_domain_is_esw_mgr_vport(dmn, vport))
                return &caps->vports.esw_manager_caps;
 
+       if (vport == MLX5_VPORT_UPLINK)
+               return &caps->vports.uplink_caps;
+
 vport_load:
        vport_caps = xa_load(&caps->vports.vports_caps_xa, vport);
        if (vport_caps)
@@ -241,17 +246,6 @@ static void dr_domain_clear_vports(struct mlx5dr_domain *dmn)
        }
 }
 
-static int dr_domain_query_uplink(struct mlx5dr_domain *dmn)
-{
-       struct mlx5dr_cmd_vport_cap *vport_caps;
-
-       vport_caps = mlx5dr_domain_get_vport_cap(dmn, MLX5_VPORT_UPLINK);
-       if (!vport_caps)
-               return -EINVAL;
-
-       return 0;
-}
-
 static int dr_domain_query_fdb_caps(struct mlx5_core_dev *mdev,
                                    struct mlx5dr_domain *dmn)
 {
@@ -281,11 +275,7 @@ static int dr_domain_query_fdb_caps(struct mlx5_core_dev *mdev,
                goto free_vports_caps_xa;
        }
 
-       ret = dr_domain_query_uplink(dmn);
-       if (ret) {
-               mlx5dr_err(dmn, "Failed to query uplink vport caps (err: %d)", ret);
-               goto free_vports_caps_xa;
-       }
+       dr_domain_query_uplink(dmn);
 
        return 0;
 
index 75c775b..7933652 100644 (file)
@@ -924,11 +924,12 @@ static int dr_matcher_init(struct mlx5dr_matcher *matcher,
 
        /* Check that all mask data was consumed */
        for (i = 0; i < consumed_mask.match_sz; i++) {
-               if (consumed_mask.match_buf[i]) {
-                       mlx5dr_dbg(dmn, "Match param mask contains unsupported parameters\n");
-                       ret = -EOPNOTSUPP;
-                       goto free_consumed_mask;
-               }
+               if (!((u8 *)consumed_mask.match_buf)[i])
+                       continue;
+
+               mlx5dr_dbg(dmn, "Match param mask contains unsupported parameters\n");
+               ret = -EOPNOTSUPP;
+               goto free_consumed_mask;
        }
 
        ret =  0;
index 3028b77..2333c24 100644 (file)
@@ -764,6 +764,7 @@ struct mlx5dr_roce_cap {
 
 struct mlx5dr_vports {
        struct mlx5dr_cmd_vport_cap esw_manager_caps;
+       struct mlx5dr_cmd_vport_cap uplink_caps;
        struct xarray vports_caps_xa;
 };
 
index 5925db3..03e5bad 100644 (file)
@@ -2153,7 +2153,7 @@ static void mlxsw_sp_pude_event_func(const struct mlxsw_reg_info *reg,
        max_ports = mlxsw_core_max_ports(mlxsw_sp->core);
        local_port = mlxsw_reg_pude_local_port_get(pude_pl);
 
-       if (WARN_ON_ONCE(local_port >= max_ports))
+       if (WARN_ON_ONCE(!local_port || local_port >= max_ports))
                return;
        mlxsw_sp_port = mlxsw_sp->ports[local_port];
        if (!mlxsw_sp_port)
@@ -3290,10 +3290,10 @@ mlxsw_sp_resources_rif_mac_profile_register(struct mlxsw_core *mlxsw_core)
        u8 max_rif_mac_profiles;
 
        if (!MLXSW_CORE_RES_VALID(mlxsw_core, MAX_RIF_MAC_PROFILES))
-               return -EIO;
-
-       max_rif_mac_profiles = MLXSW_CORE_RES_GET(mlxsw_core,
-                                                 MAX_RIF_MAC_PROFILES);
+               max_rif_mac_profiles = 1;
+       else
+               max_rif_mac_profiles = MLXSW_CORE_RES_GET(mlxsw_core,
+                                                         MAX_RIF_MAC_PROFILES);
        devlink_resource_size_params_init(&size_params, max_rif_mac_profiles,
                                          max_rif_mac_profiles, 1,
                                          DEVLINK_RESOURCE_UNIT_ENTRY);
index 4fc9782..7d76474 100644 (file)
@@ -914,8 +914,7 @@ static int lan743x_phy_reset(struct lan743x_adapter *adapter)
 }
 
 static void lan743x_phy_update_flowcontrol(struct lan743x_adapter *adapter,
-                                          u8 duplex, u16 local_adv,
-                                          u16 remote_adv)
+                                          u16 local_adv, u16 remote_adv)
 {
        struct lan743x_phy *phy = &adapter->phy;
        u8 cap;
@@ -943,7 +942,6 @@ static void lan743x_phy_link_status_change(struct net_device *netdev)
 
        phy_print_status(phydev);
        if (phydev->state == PHY_RUNNING) {
-               struct ethtool_link_ksettings ksettings;
                int remote_advertisement = 0;
                int local_advertisement = 0;
 
@@ -980,18 +978,14 @@ static void lan743x_phy_link_status_change(struct net_device *netdev)
                }
                lan743x_csr_write(adapter, MAC_CR, data);
 
-               memset(&ksettings, 0, sizeof(ksettings));
-               phy_ethtool_get_link_ksettings(netdev, &ksettings);
                local_advertisement =
                        linkmode_adv_to_mii_adv_t(phydev->advertising);
                remote_advertisement =
                        linkmode_adv_to_mii_adv_t(phydev->lp_advertising);
 
-               lan743x_phy_update_flowcontrol(adapter,
-                                              ksettings.base.duplex,
-                                              local_advertisement,
+               lan743x_phy_update_flowcontrol(adapter, local_advertisement,
                                               remote_advertisement);
-               lan743x_ptp_update_latency(adapter, ksettings.base.speed);
+               lan743x_ptp_update_latency(adapter, phydev->speed);
        }
 }
 
index e6c18b5..409cde1 100644 (file)
@@ -1278,6 +1278,225 @@ int ocelot_fdb_dump(struct ocelot *ocelot, int port,
 }
 EXPORT_SYMBOL(ocelot_fdb_dump);
 
+static void ocelot_populate_l2_ptp_trap_key(struct ocelot_vcap_filter *trap)
+{
+       trap->key_type = OCELOT_VCAP_KEY_ETYPE;
+       *(__be16 *)trap->key.etype.etype.value = htons(ETH_P_1588);
+       *(__be16 *)trap->key.etype.etype.mask = htons(0xffff);
+}
+
+static void
+ocelot_populate_ipv4_ptp_event_trap_key(struct ocelot_vcap_filter *trap)
+{
+       trap->key_type = OCELOT_VCAP_KEY_IPV4;
+       trap->key.ipv4.dport.value = PTP_EV_PORT;
+       trap->key.ipv4.dport.mask = 0xffff;
+}
+
+static void
+ocelot_populate_ipv6_ptp_event_trap_key(struct ocelot_vcap_filter *trap)
+{
+       trap->key_type = OCELOT_VCAP_KEY_IPV6;
+       trap->key.ipv6.dport.value = PTP_EV_PORT;
+       trap->key.ipv6.dport.mask = 0xffff;
+}
+
+static void
+ocelot_populate_ipv4_ptp_general_trap_key(struct ocelot_vcap_filter *trap)
+{
+       trap->key_type = OCELOT_VCAP_KEY_IPV4;
+       trap->key.ipv4.dport.value = PTP_GEN_PORT;
+       trap->key.ipv4.dport.mask = 0xffff;
+}
+
+static void
+ocelot_populate_ipv6_ptp_general_trap_key(struct ocelot_vcap_filter *trap)
+{
+       trap->key_type = OCELOT_VCAP_KEY_IPV6;
+       trap->key.ipv6.dport.value = PTP_GEN_PORT;
+       trap->key.ipv6.dport.mask = 0xffff;
+}
+
+static int ocelot_trap_add(struct ocelot *ocelot, int port,
+                          unsigned long cookie,
+                          void (*populate)(struct ocelot_vcap_filter *f))
+{
+       struct ocelot_vcap_block *block_vcap_is2;
+       struct ocelot_vcap_filter *trap;
+       bool new = false;
+       int err;
+
+       block_vcap_is2 = &ocelot->block[VCAP_IS2];
+
+       trap = ocelot_vcap_block_find_filter_by_id(block_vcap_is2, cookie,
+                                                  false);
+       if (!trap) {
+               trap = kzalloc(sizeof(*trap), GFP_KERNEL);
+               if (!trap)
+                       return -ENOMEM;
+
+               populate(trap);
+               trap->prio = 1;
+               trap->id.cookie = cookie;
+               trap->id.tc_offload = false;
+               trap->block_id = VCAP_IS2;
+               trap->type = OCELOT_VCAP_FILTER_OFFLOAD;
+               trap->lookup = 0;
+               trap->action.cpu_copy_ena = true;
+               trap->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY;
+               trap->action.port_mask = 0;
+               new = true;
+       }
+
+       trap->ingress_port_mask |= BIT(port);
+
+       if (new)
+               err = ocelot_vcap_filter_add(ocelot, trap, NULL);
+       else
+               err = ocelot_vcap_filter_replace(ocelot, trap);
+       if (err) {
+               trap->ingress_port_mask &= ~BIT(port);
+               if (!trap->ingress_port_mask)
+                       kfree(trap);
+               return err;
+       }
+
+       return 0;
+}
+
+static int ocelot_trap_del(struct ocelot *ocelot, int port,
+                          unsigned long cookie)
+{
+       struct ocelot_vcap_block *block_vcap_is2;
+       struct ocelot_vcap_filter *trap;
+
+       block_vcap_is2 = &ocelot->block[VCAP_IS2];
+
+       trap = ocelot_vcap_block_find_filter_by_id(block_vcap_is2, cookie,
+                                                  false);
+       if (!trap)
+               return 0;
+
+       trap->ingress_port_mask &= ~BIT(port);
+       if (!trap->ingress_port_mask)
+               return ocelot_vcap_filter_del(ocelot, trap);
+
+       return ocelot_vcap_filter_replace(ocelot, trap);
+}
+
+static int ocelot_l2_ptp_trap_add(struct ocelot *ocelot, int port)
+{
+       unsigned long l2_cookie = ocelot->num_phys_ports + 1;
+
+       return ocelot_trap_add(ocelot, port, l2_cookie,
+                              ocelot_populate_l2_ptp_trap_key);
+}
+
+static int ocelot_l2_ptp_trap_del(struct ocelot *ocelot, int port)
+{
+       unsigned long l2_cookie = ocelot->num_phys_ports + 1;
+
+       return ocelot_trap_del(ocelot, port, l2_cookie);
+}
+
+static int ocelot_ipv4_ptp_trap_add(struct ocelot *ocelot, int port)
+{
+       unsigned long ipv4_gen_cookie = ocelot->num_phys_ports + 2;
+       unsigned long ipv4_ev_cookie = ocelot->num_phys_ports + 3;
+       int err;
+
+       err = ocelot_trap_add(ocelot, port, ipv4_ev_cookie,
+                             ocelot_populate_ipv4_ptp_event_trap_key);
+       if (err)
+               return err;
+
+       err = ocelot_trap_add(ocelot, port, ipv4_gen_cookie,
+                             ocelot_populate_ipv4_ptp_general_trap_key);
+       if (err)
+               ocelot_trap_del(ocelot, port, ipv4_ev_cookie);
+
+       return err;
+}
+
+static int ocelot_ipv4_ptp_trap_del(struct ocelot *ocelot, int port)
+{
+       unsigned long ipv4_gen_cookie = ocelot->num_phys_ports + 2;
+       unsigned long ipv4_ev_cookie = ocelot->num_phys_ports + 3;
+       int err;
+
+       err = ocelot_trap_del(ocelot, port, ipv4_ev_cookie);
+       err |= ocelot_trap_del(ocelot, port, ipv4_gen_cookie);
+       return err;
+}
+
+static int ocelot_ipv6_ptp_trap_add(struct ocelot *ocelot, int port)
+{
+       unsigned long ipv6_gen_cookie = ocelot->num_phys_ports + 4;
+       unsigned long ipv6_ev_cookie = ocelot->num_phys_ports + 5;
+       int err;
+
+       err = ocelot_trap_add(ocelot, port, ipv6_ev_cookie,
+                             ocelot_populate_ipv6_ptp_event_trap_key);
+       if (err)
+               return err;
+
+       err = ocelot_trap_add(ocelot, port, ipv6_gen_cookie,
+                             ocelot_populate_ipv6_ptp_general_trap_key);
+       if (err)
+               ocelot_trap_del(ocelot, port, ipv6_ev_cookie);
+
+       return err;
+}
+
+static int ocelot_ipv6_ptp_trap_del(struct ocelot *ocelot, int port)
+{
+       unsigned long ipv6_gen_cookie = ocelot->num_phys_ports + 4;
+       unsigned long ipv6_ev_cookie = ocelot->num_phys_ports + 5;
+       int err;
+
+       err = ocelot_trap_del(ocelot, port, ipv6_ev_cookie);
+       err |= ocelot_trap_del(ocelot, port, ipv6_gen_cookie);
+       return err;
+}
+
+static int ocelot_setup_ptp_traps(struct ocelot *ocelot, int port,
+                                 bool l2, bool l4)
+{
+       int err;
+
+       if (l2)
+               err = ocelot_l2_ptp_trap_add(ocelot, port);
+       else
+               err = ocelot_l2_ptp_trap_del(ocelot, port);
+       if (err)
+               return err;
+
+       if (l4) {
+               err = ocelot_ipv4_ptp_trap_add(ocelot, port);
+               if (err)
+                       goto err_ipv4;
+
+               err = ocelot_ipv6_ptp_trap_add(ocelot, port);
+               if (err)
+                       goto err_ipv6;
+       } else {
+               err = ocelot_ipv4_ptp_trap_del(ocelot, port);
+
+               err |= ocelot_ipv6_ptp_trap_del(ocelot, port);
+       }
+       if (err)
+               return err;
+
+       return 0;
+
+err_ipv6:
+       ocelot_ipv4_ptp_trap_del(ocelot, port);
+err_ipv4:
+       if (l2)
+               ocelot_l2_ptp_trap_del(ocelot, port);
+       return err;
+}
+
 int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr)
 {
        return copy_to_user(ifr->ifr_data, &ocelot->hwtstamp_config,
@@ -1288,7 +1507,9 @@ EXPORT_SYMBOL(ocelot_hwstamp_get);
 int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr)
 {
        struct ocelot_port *ocelot_port = ocelot->ports[port];
+       bool l2 = false, l4 = false;
        struct hwtstamp_config cfg;
+       int err;
 
        if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
                return -EFAULT;
@@ -1320,28 +1541,40 @@ int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr)
        switch (cfg.rx_filter) {
        case HWTSTAMP_FILTER_NONE:
                break;
-       case HWTSTAMP_FILTER_ALL:
-       case HWTSTAMP_FILTER_SOME:
-       case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
-       case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
-       case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
-       case HWTSTAMP_FILTER_NTP_ALL:
        case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
        case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
        case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+               l4 = true;
+               break;
        case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
        case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
        case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+               l2 = true;
+               break;
        case HWTSTAMP_FILTER_PTP_V2_EVENT:
        case HWTSTAMP_FILTER_PTP_V2_SYNC:
        case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
-               cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
+               l2 = true;
+               l4 = true;
                break;
        default:
                mutex_unlock(&ocelot->ptp_lock);
                return -ERANGE;
        }
 
+       err = ocelot_setup_ptp_traps(ocelot, port, l2, l4);
+       if (err)
+               return err;
+
+       if (l2 && l4)
+               cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
+       else if (l2)
+               cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
+       else if (l4)
+               cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
+       else
+               cfg.rx_filter = HWTSTAMP_FILTER_NONE;
+
        /* Commit back the result & save it */
        memcpy(&ocelot->hwtstamp_config, &cfg, sizeof(cfg));
        mutex_unlock(&ocelot->ptp_lock);
@@ -1444,7 +1677,10 @@ int ocelot_get_ts_info(struct ocelot *ocelot, int port,
                                 SOF_TIMESTAMPING_RAW_HARDWARE;
        info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) |
                         BIT(HWTSTAMP_TX_ONESTEP_SYNC);
-       info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL);
+       info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
+                          BIT(HWTSTAMP_FILTER_PTP_V2_EVENT) |
+                          BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
+                          BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT);
 
        return 0;
 }
index 99d7376..337cd08 100644 (file)
@@ -1217,6 +1217,22 @@ int ocelot_vcap_filter_del(struct ocelot *ocelot,
 }
 EXPORT_SYMBOL(ocelot_vcap_filter_del);
 
+int ocelot_vcap_filter_replace(struct ocelot *ocelot,
+                              struct ocelot_vcap_filter *filter)
+{
+       struct ocelot_vcap_block *block = &ocelot->block[filter->block_id];
+       int index;
+
+       index = ocelot_vcap_block_get_filter_index(block, filter);
+       if (index < 0)
+               return index;
+
+       vcap_entry_set(ocelot, index, filter);
+
+       return 0;
+}
+EXPORT_SYMBOL(ocelot_vcap_filter_replace);
+
 int ocelot_vcap_filter_stats_update(struct ocelot *ocelot,
                                    struct ocelot_vcap_filter *filter)
 {
index df20373..0b1865e 100644 (file)
@@ -565,7 +565,6 @@ struct nfp_net_dp {
  * @exn_name:           Name for Exception interrupt
  * @shared_handler:     Handler for shared interrupts
  * @shared_name:        Name for shared interrupt
- * @me_freq_mhz:        ME clock_freq (MHz)
  * @reconfig_lock:     Protects @reconfig_posted, @reconfig_timer_active,
  *                     @reconfig_sync_present and HW reconfiguration request
  *                     regs/machinery from async requests (sync must take
@@ -650,8 +649,6 @@ struct nfp_net {
        irq_handler_t shared_handler;
        char shared_name[IFNAMSIZ + 8];
 
-       u32 me_freq_mhz;
-
        bool link_up;
        spinlock_t link_status_lock;
 
index 1de076f..cf78829 100644 (file)
@@ -1344,7 +1344,7 @@ static int nfp_net_set_coalesce(struct net_device *netdev,
         * ME timestamp ticks.  There are 16 ME clock cycles for each timestamp
         * count.
         */
-       factor = nn->me_freq_mhz / 16;
+       factor = nn->tlv_caps.me_freq_mhz / 16;
 
        /* Each pair of (usecs, max_frames) fields specifies that interrupts
         * should be coalesced until
index cfeb762..07a00dd 100644 (file)
@@ -1209,7 +1209,7 @@ static void *nixge_get_nvmem_address(struct device *dev)
 
        cell = nvmem_cell_get(dev, "address");
        if (IS_ERR(cell))
-               return NULL;
+               return cell;
 
        mac = nvmem_cell_read(cell, &cell_size);
        nvmem_cell_put(cell);
@@ -1282,7 +1282,7 @@ static int nixge_probe(struct platform_device *pdev)
        ndev->max_mtu = NIXGE_JUMBO_MTU;
 
        mac_addr = nixge_get_nvmem_address(&pdev->dev);
-       if (mac_addr && is_valid_ether_addr(mac_addr)) {
+       if (!IS_ERR(mac_addr) && is_valid_ether_addr(mac_addr)) {
                eth_hw_addr_set(ndev, mac_addr);
                kfree(mac_addr);
        } else {
index a97f691..6958ade 100644 (file)
@@ -1045,7 +1045,7 @@ static int qed_int_deassertion(struct qed_hwfn  *p_hwfn,
                if (!parities)
                        continue;
 
-               for (j = 0, bit_idx = 0; bit_idx < 32; j++) {
+               for (j = 0, bit_idx = 0; bit_idx < 32 && j < 32; j++) {
                        struct aeu_invert_reg_bit *p_bit = &p_aeu->bits[j];
 
                        if (qed_int_is_parity_flag(p_hwfn, p_bit) &&
@@ -1083,7 +1083,7 @@ static int qed_int_deassertion(struct qed_hwfn  *p_hwfn,
                         * to current group, making them responsible for the
                         * previous assertion.
                         */
-                       for (j = 0, bit_idx = 0; bit_idx < 32; j++) {
+                       for (j = 0, bit_idx = 0; bit_idx < 32 && j < 32; j++) {
                                long unsigned int bitmask;
                                u8 bit, bit_len;
 
@@ -1382,7 +1382,7 @@ static void qed_int_sb_attn_init(struct qed_hwfn *p_hwfn,
        memset(sb_info->parity_mask, 0, sizeof(u32) * NUM_ATTN_REGS);
        for (i = 0; i < NUM_ATTN_REGS; i++) {
                /* j is array index, k is bit index */
-               for (j = 0, k = 0; k < 32; j++) {
+               for (j = 0, k = 0; k < 32 && j < 32; j++) {
                        struct aeu_invert_reg_bit *p_aeu;
 
                        p_aeu = &aeu_descs[i].bits[j];
index bbe21db..86c44bc 100644 (file)
@@ -5217,8 +5217,8 @@ static int rtl_get_ether_clk(struct rtl8169_private *tp)
 
 static void rtl_init_mac_address(struct rtl8169_private *tp)
 {
+       u8 mac_addr[ETH_ALEN] __aligned(2) = {};
        struct net_device *dev = tp->dev;
-       u8 mac_addr[ETH_ALEN];
        int rc;
 
        rc = eth_platform_get_mac_address(tp_to_dev(tp), mac_addr);
@@ -5233,7 +5233,8 @@ static void rtl_init_mac_address(struct rtl8169_private *tp)
        if (is_valid_ether_addr(mac_addr))
                goto done;
 
-       eth_hw_addr_random(dev);
+       eth_random_addr(mac_addr);
+       dev->addr_assign_type = NET_ADDR_RANDOM;
        dev_warn(tp_to_dev(tp), "can't read MAC address, setting random one\n");
 done:
        eth_hw_addr_set(dev, mac_addr);
index cc2d907..23a336c 100644 (file)
@@ -392,7 +392,7 @@ static int sis96x_get_mac_addr(struct pci_dev *pci_dev,
                        /* get MAC address from EEPROM */
                        for (i = 0; i < 3; i++)
                                addr[i] = read_eeprom(ioaddr, i + EEPROMMACAddr);
-                        eth_hw_addr_set(net_dev, (u8 *)addr);
+                       eth_hw_addr_set(net_dev, (u8 *)addr);
 
                        rc = 1;
                        break;
index 8520812..b7c2579 100644 (file)
@@ -485,8 +485,28 @@ static int socfpga_dwmac_resume(struct device *dev)
 }
 #endif /* CONFIG_PM_SLEEP */
 
-static SIMPLE_DEV_PM_OPS(socfpga_dwmac_pm_ops, stmmac_suspend,
-                                              socfpga_dwmac_resume);
+static int __maybe_unused socfpga_dwmac_runtime_suspend(struct device *dev)
+{
+       struct net_device *ndev = dev_get_drvdata(dev);
+       struct stmmac_priv *priv = netdev_priv(ndev);
+
+       stmmac_bus_clks_config(priv, false);
+
+       return 0;
+}
+
+static int __maybe_unused socfpga_dwmac_runtime_resume(struct device *dev)
+{
+       struct net_device *ndev = dev_get_drvdata(dev);
+       struct stmmac_priv *priv = netdev_priv(ndev);
+
+       return stmmac_bus_clks_config(priv, true);
+}
+
+static const struct dev_pm_ops socfpga_dwmac_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(stmmac_suspend, socfpga_dwmac_resume)
+       SET_RUNTIME_PM_OPS(socfpga_dwmac_runtime_suspend, socfpga_dwmac_runtime_resume, NULL)
+};
 
 static const struct socfpga_dwmac_ops socfpga_gen5_ops = {
        .set_phy_mode = socfpga_gen5_set_phy_mode,
index 43eead7..5f12973 100644 (file)
@@ -314,6 +314,7 @@ int stmmac_mdio_reset(struct mii_bus *mii);
 int stmmac_xpcs_setup(struct mii_bus *mii);
 void stmmac_set_ethtool_ops(struct net_device *netdev);
 
+int stmmac_init_tstamp_counter(struct stmmac_priv *priv, u32 systime_flags);
 void stmmac_ptp_register(struct stmmac_priv *priv);
 void stmmac_ptp_unregister(struct stmmac_priv *priv);
 int stmmac_open(struct net_device *dev);
index d3f350c..7481956 100644 (file)
 #include "dwxgmac2.h"
 #include "hwif.h"
 
+/* As long as the interface is active, we keep the timestamping counter enabled
+ * with fine resolution and binary rollover. This avoid non-monotonic behavior
+ * (clock jumps) when changing timestamping settings at runtime.
+ */
+#define STMMAC_HWTS_ACTIVE     (PTP_TCR_TSENA | PTP_TCR_TSCFUPDT | \
+                                PTP_TCR_TSCTRLSSR)
+
 #define        STMMAC_ALIGN(x)         ALIGN(ALIGN(x, SMP_CACHE_BYTES), 16)
 #define        TSO_MAX_BUFF_SIZE       (SZ_16K - 1)
 
@@ -511,6 +518,14 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
        return true;
 }
 
+static inline u32 stmmac_cdc_adjust(struct stmmac_priv *priv)
+{
+       /* Correct the clk domain crossing(CDC) error */
+       if (priv->plat->has_gmac4 && priv->plat->clk_ptp_rate)
+               return (2 * NSEC_PER_SEC) / priv->plat->clk_ptp_rate;
+       return 0;
+}
+
 /* stmmac_get_tx_hwtstamp - get HW TX timestamps
  * @priv: driver private structure
  * @p : descriptor pointer
@@ -524,7 +539,6 @@ static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv,
 {
        struct skb_shared_hwtstamps shhwtstamp;
        bool found = false;
-       s64 adjust = 0;
        u64 ns = 0;
 
        if (!priv->hwts_tx_en)
@@ -543,12 +557,7 @@ static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv,
        }
 
        if (found) {
-               /* Correct the clk domain crossing(CDC) error */
-               if (priv->plat->has_gmac4 && priv->plat->clk_ptp_rate) {
-                       adjust += -(2 * (NSEC_PER_SEC /
-                                        priv->plat->clk_ptp_rate));
-                       ns += adjust;
-               }
+               ns -= stmmac_cdc_adjust(priv);
 
                memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));
                shhwtstamp.hwtstamp = ns_to_ktime(ns);
@@ -573,7 +582,6 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p,
 {
        struct skb_shared_hwtstamps *shhwtstamp = NULL;
        struct dma_desc *desc = p;
-       u64 adjust = 0;
        u64 ns = 0;
 
        if (!priv->hwts_rx_en)
@@ -586,11 +594,7 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p,
        if (stmmac_get_rx_timestamp_status(priv, p, np, priv->adv_ts)) {
                stmmac_get_timestamp(priv, desc, priv->adv_ts, &ns);
 
-               /* Correct the clk domain crossing(CDC) error */
-               if (priv->plat->has_gmac4 && priv->plat->clk_ptp_rate) {
-                       adjust += 2 * (NSEC_PER_SEC / priv->plat->clk_ptp_rate);
-                       ns -= adjust;
-               }
+               ns -= stmmac_cdc_adjust(priv);
 
                netdev_dbg(priv->dev, "get valid RX hw timestamp %llu\n", ns);
                shhwtstamp = skb_hwtstamps(skb);
@@ -616,8 +620,6 @@ static int stmmac_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
 {
        struct stmmac_priv *priv = netdev_priv(dev);
        struct hwtstamp_config config;
-       struct timespec64 now;
-       u64 temp = 0;
        u32 ptp_v2 = 0;
        u32 tstamp_all = 0;
        u32 ptp_over_ipv4_udp = 0;
@@ -626,11 +628,6 @@ static int stmmac_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
        u32 snap_type_sel = 0;
        u32 ts_master_en = 0;
        u32 ts_event_en = 0;
-       u32 sec_inc = 0;
-       u32 value = 0;
-       bool xmac;
-
-       xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 
        if (!(priv->dma_cap.time_stamp || priv->adv_ts)) {
                netdev_alert(priv->dev, "No support for HW time stamping\n");
@@ -792,42 +789,17 @@ static int stmmac_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
        priv->hwts_rx_en = ((config.rx_filter == HWTSTAMP_FILTER_NONE) ? 0 : 1);
        priv->hwts_tx_en = config.tx_type == HWTSTAMP_TX_ON;
 
-       if (!priv->hwts_tx_en && !priv->hwts_rx_en)
-               stmmac_config_hw_tstamping(priv, priv->ptpaddr, 0);
-       else {
-               value = (PTP_TCR_TSENA | PTP_TCR_TSCFUPDT | PTP_TCR_TSCTRLSSR |
-                        tstamp_all | ptp_v2 | ptp_over_ethernet |
-                        ptp_over_ipv6_udp | ptp_over_ipv4_udp | ts_event_en |
-                        ts_master_en | snap_type_sel);
-               stmmac_config_hw_tstamping(priv, priv->ptpaddr, value);
-
-               /* program Sub Second Increment reg */
-               stmmac_config_sub_second_increment(priv,
-                               priv->ptpaddr, priv->plat->clk_ptp_rate,
-                               xmac, &sec_inc);
-               temp = div_u64(1000000000ULL, sec_inc);
-
-               /* Store sub second increment and flags for later use */
-               priv->sub_second_inc = sec_inc;
-               priv->systime_flags = value;
-
-               /* calculate default added value:
-                * formula is :
-                * addend = (2^32)/freq_div_ratio;
-                * where, freq_div_ratio = 1e9ns/sec_inc
-                */
-               temp = (u64)(temp << 32);
-               priv->default_addend = div_u64(temp, priv->plat->clk_ptp_rate);
-               stmmac_config_addend(priv, priv->ptpaddr, priv->default_addend);
+       priv->systime_flags = STMMAC_HWTS_ACTIVE;
 
-               /* initialize system time */
-               ktime_get_real_ts64(&now);
-
-               /* lower 32 bits of tv_sec are safe until y2106 */
-               stmmac_init_systime(priv, priv->ptpaddr,
-                               (u32)now.tv_sec, now.tv_nsec);
+       if (priv->hwts_tx_en || priv->hwts_rx_en) {
+               priv->systime_flags |= tstamp_all | ptp_v2 |
+                                      ptp_over_ethernet | ptp_over_ipv6_udp |
+                                      ptp_over_ipv4_udp | ts_event_en |
+                                      ts_master_en | snap_type_sel;
        }
 
+       stmmac_config_hw_tstamping(priv, priv->ptpaddr, priv->systime_flags);
+
        memcpy(&priv->tstamp_config, &config, sizeof(config));
 
        return copy_to_user(ifr->ifr_data, &config,
@@ -855,6 +827,66 @@ static int stmmac_hwtstamp_get(struct net_device *dev, struct ifreq *ifr)
                            sizeof(*config)) ? -EFAULT : 0;
 }
 
+/**
+ * stmmac_init_tstamp_counter - init hardware timestamping counter
+ * @priv: driver private structure
+ * @systime_flags: timestamping flags
+ * Description:
+ * Initialize hardware counter for packet timestamping.
+ * This is valid as long as the interface is open and not suspended.
+ * Will be rerun after resuming from suspend, case in which the timestamping
+ * flags updated by stmmac_hwtstamp_set() also need to be restored.
+ */
+int stmmac_init_tstamp_counter(struct stmmac_priv *priv, u32 systime_flags)
+{
+       bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
+       struct timespec64 now;
+       u32 sec_inc = 0;
+       u64 temp = 0;
+       int ret;
+
+       if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp))
+               return -EOPNOTSUPP;
+
+       ret = clk_prepare_enable(priv->plat->clk_ptp_ref);
+       if (ret < 0) {
+               netdev_warn(priv->dev,
+                           "failed to enable PTP reference clock: %pe\n",
+                           ERR_PTR(ret));
+               return ret;
+       }
+
+       stmmac_config_hw_tstamping(priv, priv->ptpaddr, systime_flags);
+       priv->systime_flags = systime_flags;
+
+       /* program Sub Second Increment reg */
+       stmmac_config_sub_second_increment(priv, priv->ptpaddr,
+                                          priv->plat->clk_ptp_rate,
+                                          xmac, &sec_inc);
+       temp = div_u64(1000000000ULL, sec_inc);
+
+       /* Store sub second increment for later use */
+       priv->sub_second_inc = sec_inc;
+
+       /* calculate default added value:
+        * formula is :
+        * addend = (2^32)/freq_div_ratio;
+        * where, freq_div_ratio = 1e9ns/sec_inc
+        */
+       temp = (u64)(temp << 32);
+       priv->default_addend = div_u64(temp, priv->plat->clk_ptp_rate);
+       stmmac_config_addend(priv, priv->ptpaddr, priv->default_addend);
+
+       /* initialize system time */
+       ktime_get_real_ts64(&now);
+
+       /* lower 32 bits of tv_sec are safe until y2106 */
+       stmmac_init_systime(priv, priv->ptpaddr, (u32)now.tv_sec, now.tv_nsec);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(stmmac_init_tstamp_counter);
+
 /**
  * stmmac_init_ptp - init PTP
  * @priv: driver private structure
@@ -865,9 +897,11 @@ static int stmmac_hwtstamp_get(struct net_device *dev, struct ifreq *ifr)
 static int stmmac_init_ptp(struct stmmac_priv *priv)
 {
        bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
+       int ret;
 
-       if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp))
-               return -EOPNOTSUPP;
+       ret = stmmac_init_tstamp_counter(priv, STMMAC_HWTS_ACTIVE);
+       if (ret)
+               return ret;
 
        priv->adv_ts = 0;
        /* Check if adv_ts can be enabled for dwmac 4.x / xgmac core */
@@ -3275,10 +3309,6 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
        stmmac_mmc_setup(priv);
 
        if (init_ptp) {
-               ret = clk_prepare_enable(priv->plat->clk_ptp_ref);
-               if (ret < 0)
-                       netdev_warn(priv->dev, "failed to enable PTP reference clock: %d\n", ret);
-
                ret = stmmac_init_ptp(priv);
                if (ret == -EOPNOTSUPP)
                        netdev_warn(priv->dev, "PTP not supported by HW\n");
@@ -3772,6 +3802,8 @@ int stmmac_release(struct net_device *dev)
        struct stmmac_priv *priv = netdev_priv(dev);
        u32 chan;
 
+       netif_tx_disable(dev);
+
        if (device_may_wakeup(priv->device))
                phylink_speed_down(priv->phylink, false);
        /* Stop and disconnect the PHY */
@@ -5164,12 +5196,13 @@ read_again:
                if (likely(!(status & rx_not_ls)) &&
                    (likely(priv->synopsys_id >= DWMAC_CORE_4_00) ||
                     unlikely(status != llc_snap))) {
-                       if (buf2_len)
+                       if (buf2_len) {
                                buf2_len -= ETH_FCS_LEN;
-                       else
+                               len -= ETH_FCS_LEN;
+                       } else if (buf1_len) {
                                buf1_len -= ETH_FCS_LEN;
-
-                       len -= ETH_FCS_LEN;
+                               len -= ETH_FCS_LEN;
+                       }
                }
 
                if (!skb) {
index 232ac98..5d29f33 100644 (file)
@@ -816,7 +816,7 @@ static int __maybe_unused stmmac_pltfr_noirq_resume(struct device *dev)
                if (ret)
                        return ret;
 
-               clk_prepare_enable(priv->plat->clk_ptp_ref);
+               stmmac_init_tstamp_counter(priv, priv->systime_flags);
        }
 
        return 0;
index bfdf89e..8a19a06 100644 (file)
@@ -306,7 +306,6 @@ static void sp_setup(struct net_device *dev)
 {
        /* Finish setting up the DEVICE info. */
        dev->netdev_ops         = &sp_netdev_ops;
-       dev->needs_free_netdev  = true;
        dev->mtu                = SIXP_MTU;
        dev->hard_header_len    = AX25_MAX_HEADER_LEN;
        dev->header_ops         = &ax25_header_ops;
index e2b332b..7da2bb8 100644 (file)
@@ -31,6 +31,8 @@
 
 #define AX_MTU         236
 
+/* some arch define END as assembly function ending, just undef it */
+#undef END
 /* SLIP/KISS protocol characters. */
 #define END             0300           /* indicates end of frame       */
 #define ESC             0333           /* indicates byte stuffing      */
index cff5173..d57472e 100644 (file)
@@ -661,22 +661,6 @@ void ipa_cmd_pipeline_clear_wait(struct ipa *ipa)
        wait_for_completion(&ipa->completion);
 }
 
-void ipa_cmd_pipeline_clear(struct ipa *ipa)
-{
-       u32 count = ipa_cmd_pipeline_clear_count();
-       struct gsi_trans *trans;
-
-       trans = ipa_cmd_trans_alloc(ipa, count);
-       if (trans) {
-               ipa_cmd_pipeline_clear_add(trans);
-               gsi_trans_commit_wait(trans);
-               ipa_cmd_pipeline_clear_wait(ipa);
-       } else {
-               dev_err(&ipa->pdev->dev,
-                       "error allocating %u entry tag transaction\n", count);
-       }
-}
-
 static struct ipa_cmd_info *
 ipa_cmd_info_alloc(struct ipa_endpoint *endpoint, u32 tre_count)
 {
index 69cd085..05ed7e4 100644 (file)
@@ -163,12 +163,6 @@ u32 ipa_cmd_pipeline_clear_count(void);
  */
 void ipa_cmd_pipeline_clear_wait(struct ipa *ipa);
 
-/**
- * ipa_cmd_pipeline_clear() - Clear the hardware pipeline
- * @ipa:       - IPA pointer
- */
-void ipa_cmd_pipeline_clear(struct ipa *ipa);
-
 /**
  * ipa_cmd_trans_alloc() - Allocate a transaction for the command TX endpoint
  * @ipa:       IPA pointer
index 5528d97..03a1709 100644 (file)
@@ -853,6 +853,7 @@ static void ipa_endpoint_init_hol_block_timer(struct ipa_endpoint *endpoint,
        u32 offset;
        u32 val;
 
+       /* This should only be changed when HOL_BLOCK_EN is disabled */
        offset = IPA_REG_ENDP_INIT_HOL_BLOCK_TIMER_N_OFFSET(endpoint_id);
        val = hol_block_timer_val(ipa, microseconds);
        iowrite32(val, ipa->reg_virt + offset);
@@ -868,6 +869,9 @@ ipa_endpoint_init_hol_block_enable(struct ipa_endpoint *endpoint, bool enable)
        val = enable ? HOL_BLOCK_EN_FMASK : 0;
        offset = IPA_REG_ENDP_INIT_HOL_BLOCK_EN_N_OFFSET(endpoint_id);
        iowrite32(val, endpoint->ipa->reg_virt + offset);
+       /* When enabling, the register must be written twice for IPA v4.5+ */
+       if (enable && endpoint->ipa->version >= IPA_VERSION_4_5)
+               iowrite32(val, endpoint->ipa->reg_virt + offset);
 }
 
 void ipa_endpoint_modem_hol_block_clear_all(struct ipa *ipa)
@@ -880,6 +884,7 @@ void ipa_endpoint_modem_hol_block_clear_all(struct ipa *ipa)
                if (endpoint->toward_ipa || endpoint->ee_id != GSI_EE_MODEM)
                        continue;
 
+               ipa_endpoint_init_hol_block_enable(endpoint, false);
                ipa_endpoint_init_hol_block_timer(endpoint, 0);
                ipa_endpoint_init_hol_block_enable(endpoint, true);
        }
@@ -1631,8 +1636,6 @@ void ipa_endpoint_suspend(struct ipa *ipa)
        if (ipa->modem_netdev)
                ipa_modem_suspend(ipa->modem_netdev);
 
-       ipa_cmd_pipeline_clear(ipa);
-
        ipa_endpoint_suspend_one(ipa->name_map[IPA_ENDPOINT_AP_LAN_RX]);
        ipa_endpoint_suspend_one(ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX]);
 }
index cdfa98a..a448ec1 100644 (file)
@@ -28,6 +28,7 @@
 #include "ipa_reg.h"
 #include "ipa_mem.h"
 #include "ipa_table.h"
+#include "ipa_smp2p.h"
 #include "ipa_modem.h"
 #include "ipa_uc.h"
 #include "ipa_interrupt.h"
@@ -801,6 +802,11 @@ static int ipa_remove(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        int ret;
 
+       /* Prevent the modem from triggering a call to ipa_setup().  This
+        * also ensures a modem-initiated setup that's underway completes.
+        */
+       ipa_smp2p_irq_disable_setup(ipa);
+
        ret = pm_runtime_get_sync(dev);
        if (WARN_ON(ret < 0))
                goto out_power_put;
index ad116bc..d0ab4d7 100644 (file)
@@ -339,9 +339,6 @@ int ipa_modem_stop(struct ipa *ipa)
        if (state != IPA_MODEM_STATE_RUNNING)
                return -EBUSY;
 
-       /* Prevent the modem from triggering a call to ipa_setup() */
-       ipa_smp2p_disable(ipa);
-
        /* Clean up the netdev and endpoints if it was started */
        if (netdev) {
                struct ipa_priv *priv = netdev_priv(netdev);
@@ -369,6 +366,9 @@ static void ipa_modem_crashed(struct ipa *ipa)
        struct device *dev = &ipa->pdev->dev;
        int ret;
 
+       /* Prevent the modem from triggering a call to ipa_setup() */
+       ipa_smp2p_irq_disable_setup(ipa);
+
        ret = pm_runtime_get_sync(dev);
        if (ret < 0) {
                dev_err(dev, "error %d getting power to handle crash\n", ret);
index e3da95d..06cec71 100644 (file)
@@ -52,7 +52,7 @@ static bool ipa_resource_limits_valid(struct ipa *ipa,
                                return false;
        }
 
-       group_count = data->rsrc_group_src_count;
+       group_count = data->rsrc_group_dst_count;
        if (!group_count || group_count > IPA_RESOURCE_GROUP_MAX)
                return false;
 
index df7639c..2112336 100644 (file)
@@ -53,7 +53,7 @@
  * @setup_ready_irq:   IPA interrupt triggered by modem to signal GSI ready
  * @power_on:          Whether IPA power is on
  * @notified:          Whether modem has been notified of power state
- * @disabled:          Whether setup ready interrupt handling is disabled
+ * @setup_disabled:    Whether setup ready interrupt handler is disabled
  * @mutex:             Mutex protecting ready-interrupt/shutdown interlock
  * @panic_notifier:    Panic notifier structure
 */
@@ -67,7 +67,7 @@ struct ipa_smp2p {
        u32 setup_ready_irq;
        bool power_on;
        bool notified;
-       bool disabled;
+       bool setup_disabled;
        struct mutex mutex;
        struct notifier_block panic_notifier;
 };
@@ -155,11 +155,9 @@ static irqreturn_t ipa_smp2p_modem_setup_ready_isr(int irq, void *dev_id)
        struct device *dev;
        int ret;
 
-       mutex_lock(&smp2p->mutex);
-
-       if (smp2p->disabled)
-               goto out_mutex_unlock;
-       smp2p->disabled = true;         /* If any others arrive, ignore them */
+       /* Ignore any (spurious) interrupts received after the first */
+       if (smp2p->ipa->setup_complete)
+               return IRQ_HANDLED;
 
        /* Power needs to be active for setup */
        dev = &smp2p->ipa->pdev->dev;
@@ -176,8 +174,6 @@ static irqreturn_t ipa_smp2p_modem_setup_ready_isr(int irq, void *dev_id)
 out_power_put:
        pm_runtime_mark_last_busy(dev);
        (void)pm_runtime_put_autosuspend(dev);
-out_mutex_unlock:
-       mutex_unlock(&smp2p->mutex);
 
        return IRQ_HANDLED;
 }
@@ -313,7 +309,7 @@ void ipa_smp2p_exit(struct ipa *ipa)
        kfree(smp2p);
 }
 
-void ipa_smp2p_disable(struct ipa *ipa)
+void ipa_smp2p_irq_disable_setup(struct ipa *ipa)
 {
        struct ipa_smp2p *smp2p = ipa->smp2p;
 
@@ -322,7 +318,10 @@ void ipa_smp2p_disable(struct ipa *ipa)
 
        mutex_lock(&smp2p->mutex);
 
-       smp2p->disabled = true;
+       if (!smp2p->setup_disabled) {
+               disable_irq(smp2p->setup_ready_irq);
+               smp2p->setup_disabled = true;
+       }
 
        mutex_unlock(&smp2p->mutex);
 }
index 99a9567..59cee31 100644 (file)
@@ -27,13 +27,12 @@ int ipa_smp2p_init(struct ipa *ipa, bool modem_init);
 void ipa_smp2p_exit(struct ipa *ipa);
 
 /**
- * ipa_smp2p_disable() - Prevent "ipa-setup-ready" interrupt handling
+ * ipa_smp2p_irq_disable_setup() - Disable the "setup ready" interrupt
  * @ipa:       IPA pointer
  *
- * Prevent handling of the "setup ready" interrupt from the modem.
- * This is used before initiating shutdown of the driver.
+ * Disable the "ipa-setup-ready" interrupt from the modem.
  */
-void ipa_smp2p_disable(struct ipa *ipa);
+void ipa_smp2p_irq_disable_setup(struct ipa *ipa);
 
 /**
  * ipa_smp2p_notify_reset() - Reset modem notification state
index cad8205..966c3b4 100644 (file)
@@ -61,6 +61,13 @@ static int aspeed_mdio_read(struct mii_bus *bus, int addr, int regnum)
 
        iowrite32(ctrl, ctx->base + ASPEED_MDIO_CTRL);
 
+       rc = readl_poll_timeout(ctx->base + ASPEED_MDIO_CTRL, ctrl,
+                               !(ctrl & ASPEED_MDIO_CTRL_FIRE),
+                               ASPEED_MDIO_INTERVAL_US,
+                               ASPEED_MDIO_TIMEOUT_US);
+       if (rc < 0)
+               return rc;
+
        rc = readl_poll_timeout(ctx->base + ASPEED_MDIO_DATA, data,
                                data & ASPEED_MDIO_DATA_IDLE,
                                ASPEED_MDIO_INTERVAL_US,
index 3ad7397..5904546 100644 (file)
@@ -710,6 +710,7 @@ static void phylink_resolve(struct work_struct *w)
        struct phylink_link_state link_state;
        struct net_device *ndev = pl->netdev;
        bool mac_config = false;
+       bool retrigger = false;
        bool cur_link_state;
 
        mutex_lock(&pl->state_mutex);
@@ -723,6 +724,7 @@ static void phylink_resolve(struct work_struct *w)
                link_state.link = false;
        } else if (pl->mac_link_dropped) {
                link_state.link = false;
+               retrigger = true;
        } else {
                switch (pl->cur_link_an_mode) {
                case MLO_AN_PHY:
@@ -739,6 +741,19 @@ static void phylink_resolve(struct work_struct *w)
                case MLO_AN_INBAND:
                        phylink_mac_pcs_get_state(pl, &link_state);
 
+                       /* The PCS may have a latching link-fail indicator.
+                        * If the link was up, bring the link down and
+                        * re-trigger the resolve. Otherwise, re-read the
+                        * PCS state to get the current status of the link.
+                        */
+                       if (!link_state.link) {
+                               if (cur_link_state)
+                                       retrigger = true;
+                               else
+                                       phylink_mac_pcs_get_state(pl,
+                                                                 &link_state);
+                       }
+
                        /* If we have a phy, the "up" state is the union of
                         * both the PHY and the MAC
                         */
@@ -747,6 +762,15 @@ static void phylink_resolve(struct work_struct *w)
 
                        /* Only update if the PHY link is up */
                        if (pl->phydev && pl->phy_state.link) {
+                               /* If the interface has changed, force a
+                                * link down event if the link isn't already
+                                * down, and re-resolve.
+                                */
+                               if (link_state.interface !=
+                                   pl->phy_state.interface) {
+                                       retrigger = true;
+                                       link_state.link = false;
+                               }
                                link_state.interface = pl->phy_state.interface;
 
                                /* If we have a PHY, we need to update with
@@ -789,7 +813,7 @@ static void phylink_resolve(struct work_struct *w)
                else
                        phylink_link_up(pl, link_state);
        }
-       if (!link_state.link && pl->mac_link_dropped) {
+       if (!link_state.link && retrigger) {
                pl->mac_link_dropped = false;
                queue_work(system_power_efficient_wq, &pl->resolve);
        }
index c420e59..3d7f88b 100644 (file)
@@ -40,6 +40,8 @@
                                           insmod -oslip_maxdev=nnn     */
 #define SL_MTU         296             /* 296; I am used to 600- FvK   */
 
+/* some arch define END as assembly function ending, just undef it */
+#undef END
 /* SLIP protocol characters. */
 #define END             0300           /* indicates end of frame       */
 #define ESC             0333           /* indicates byte stuffing      */
index fecc9a1..1572878 100644 (file)
@@ -1010,6 +1010,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct tun_struct *tun = netdev_priv(dev);
        int txq = skb->queue_mapping;
+       struct netdev_queue *queue;
        struct tun_file *tfile;
        int len = skb->len;
 
@@ -1054,6 +1055,10 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
        if (ptr_ring_produce(&tfile->tx_ring, skb))
                goto drop;
 
+       /* NETIF_F_LLTX requires to do our own update of trans_start */
+       queue = netdev_get_tx_queue(dev, txq);
+       queue->trans_start = jiffies;
+
        /* Notify and wake up reader process */
        if (tfile->flags & TUN_FASYNC)
                kill_fasync(&tfile->fasync, SIGIO, POLL_IN);
index 4a02f33..f9877a3 100644 (file)
@@ -9603,12 +9603,9 @@ static int rtl8152_probe(struct usb_interface *intf,
                netdev->hw_features &= ~NETIF_F_RXCSUM;
        }
 
-       if (le16_to_cpu(udev->descriptor.idVendor) == VENDOR_ID_LENOVO) {
-               switch (le16_to_cpu(udev->descriptor.idProduct)) {
-               case DEVICE_ID_THINKPAD_THUNDERBOLT3_DOCK_GEN2:
-               case DEVICE_ID_THINKPAD_USB_C_DOCK_GEN2:
-                       tp->lenovo_macpassthru = 1;
-               }
+       if (udev->parent &&
+                       le16_to_cpu(udev->parent->descriptor.idVendor) == VENDOR_ID_LENOVO) {
+               tp->lenovo_macpassthru = 1;
        }
 
        if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x3011 && udev->serial &&
index 20fe4cd..abe0149 100644 (file)
@@ -1050,6 +1050,14 @@ static const struct net_device_ops smsc95xx_netdev_ops = {
        .ndo_set_features       = smsc95xx_set_features,
 };
 
+static void smsc95xx_handle_link_change(struct net_device *net)
+{
+       struct usbnet *dev = netdev_priv(net);
+
+       phy_print_status(net->phydev);
+       usbnet_defer_kevent(dev, EVENT_LINK_CHANGE);
+}
+
 static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
 {
        struct smsc95xx_priv *pdata;
@@ -1154,6 +1162,17 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
        dev->net->min_mtu = ETH_MIN_MTU;
        dev->net->max_mtu = ETH_DATA_LEN;
        dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
+
+       ret = phy_connect_direct(dev->net, pdata->phydev,
+                                &smsc95xx_handle_link_change,
+                                PHY_INTERFACE_MODE_MII);
+       if (ret) {
+               netdev_err(dev->net, "can't attach PHY to %s\n", pdata->mdiobus->id);
+               goto unregister_mdio;
+       }
+
+       phy_attached_info(dev->net->phydev);
+
        return 0;
 
 unregister_mdio:
@@ -1171,47 +1190,25 @@ static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf)
 {
        struct smsc95xx_priv *pdata = dev->driver_priv;
 
+       phy_disconnect(dev->net->phydev);
        mdiobus_unregister(pdata->mdiobus);
        mdiobus_free(pdata->mdiobus);
        netif_dbg(dev, ifdown, dev->net, "free pdata\n");
        kfree(pdata);
 }
 
-static void smsc95xx_handle_link_change(struct net_device *net)
-{
-       struct usbnet *dev = netdev_priv(net);
-
-       phy_print_status(net->phydev);
-       usbnet_defer_kevent(dev, EVENT_LINK_CHANGE);
-}
-
 static int smsc95xx_start_phy(struct usbnet *dev)
 {
-       struct smsc95xx_priv *pdata = dev->driver_priv;
-       struct net_device *net = dev->net;
-       int ret;
+       phy_start(dev->net->phydev);
 
-       ret = smsc95xx_reset(dev);
-       if (ret < 0)
-               return ret;
-
-       ret = phy_connect_direct(net, pdata->phydev,
-                                &smsc95xx_handle_link_change,
-                                PHY_INTERFACE_MODE_MII);
-       if (ret) {
-               netdev_err(net, "can't attach PHY to %s\n", pdata->mdiobus->id);
-               return ret;
-       }
-
-       phy_attached_info(net->phydev);
-       phy_start(net->phydev);
        return 0;
 }
 
-static int smsc95xx_disconnect_phy(struct usbnet *dev)
+static int smsc95xx_stop(struct usbnet *dev)
 {
-       phy_stop(dev->net->phydev);
-       phy_disconnect(dev->net->phydev);
+       if (dev->net->phydev)
+               phy_stop(dev->net->phydev);
+
        return 0;
 }
 
@@ -1966,7 +1963,7 @@ static const struct driver_info smsc95xx_info = {
        .unbind         = smsc95xx_unbind,
        .link_reset     = smsc95xx_link_reset,
        .reset          = smsc95xx_start_phy,
-       .stop           = smsc95xx_disconnect_phy,
+       .stop           = smsc95xx_stop,
        .rx_fixup       = smsc95xx_rx_fixup,
        .tx_fixup       = smsc95xx_tx_fixup,
        .status         = smsc95xx_status,
index 1771d6e..55db6a3 100644 (file)
@@ -3423,7 +3423,6 @@ static struct virtio_driver virtio_net_driver = {
        .feature_table_size = ARRAY_SIZE(features),
        .feature_table_legacy = features_legacy,
        .feature_table_size_legacy = ARRAY_SIZE(features_legacy),
-       .suppress_used_validation = true,
        .driver.name =  KBUILD_MODNAME,
        .driver.owner = THIS_MODULE,
        .id_table =     id_table,
index 221fa3b..f577449 100644 (file)
@@ -202,7 +202,7 @@ static int __init virtual_ncidev_init(void)
        miscdev.minor = MISC_DYNAMIC_MINOR;
        miscdev.name = "virtual_nci";
        miscdev.fops = &virtual_ncidev_fops;
-       miscdev.mode = S_IALLUGO;
+       miscdev.mode = 0600;
 
        return misc_register(&miscdev);
 }
index 4b5de8f..4c63564 100644 (file)
@@ -895,10 +895,19 @@ static inline blk_status_t nvme_setup_write_zeroes(struct nvme_ns *ns,
                cpu_to_le64(nvme_sect_to_lba(ns, blk_rq_pos(req)));
        cmnd->write_zeroes.length =
                cpu_to_le16((blk_rq_bytes(req) >> ns->lba_shift) - 1);
-       if (nvme_ns_has_pi(ns))
+
+       if (nvme_ns_has_pi(ns)) {
                cmnd->write_zeroes.control = cpu_to_le16(NVME_RW_PRINFO_PRACT);
-       else
-               cmnd->write_zeroes.control = 0;
+
+               switch (ns->pi_type) {
+               case NVME_NS_DPS_PI_TYPE1:
+               case NVME_NS_DPS_PI_TYPE2:
+                       cmnd->write_zeroes.reftag =
+                               cpu_to_le32(t10_pi_ref_tag(req));
+                       break;
+               }
+       }
+
        return BLK_STS_OK;
 }
 
@@ -2469,6 +2478,20 @@ static const struct nvme_core_quirk_entry core_quirks[] = {
                .vid = 0x14a4,
                .fr = "22301111",
                .quirks = NVME_QUIRK_SIMPLE_SUSPEND,
+       },
+       {
+               /*
+                * This Kioxia CD6-V Series / HPE PE8030 device times out and
+                * aborts I/O during any load, but more easily reproducible
+                * with discards (fstrim).
+                *
+                * The device is left in a state where it is also not possible
+                * to use "nvme set-feature" to disable APST, but booting with
+                * nvme_core.default_ps_max_latency=0 works.
+                */
+               .vid = 0x1e0f,
+               .mn = "KCD6XVUL6T40",
+               .quirks = NVME_QUIRK_NO_APST,
        }
 };
 
index c5a2b71..282d541 100644 (file)
@@ -698,6 +698,9 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
                        if (token >= 0)
                                pr_warn("I/O fail on reconnect controller after %d sec\n",
                                        token);
+                       else
+                               token = -1;
+
                        opts->fast_io_fail_tmo = token;
                        break;
                case NVMF_OPT_HOSTNQN:
index 33bc83d..4ceb286 100644 (file)
@@ -572,7 +572,7 @@ static int nvme_tcp_handle_comp(struct nvme_tcp_queue *queue,
        return ret;
 }
 
-static int nvme_tcp_setup_h2c_data_pdu(struct nvme_tcp_request *req,
+static void nvme_tcp_setup_h2c_data_pdu(struct nvme_tcp_request *req,
                struct nvme_tcp_r2t_pdu *pdu)
 {
        struct nvme_tcp_data_pdu *data = req->pdu;
@@ -581,32 +581,11 @@ static int nvme_tcp_setup_h2c_data_pdu(struct nvme_tcp_request *req,
        u8 hdgst = nvme_tcp_hdgst_len(queue);
        u8 ddgst = nvme_tcp_ddgst_len(queue);
 
+       req->state = NVME_TCP_SEND_H2C_PDU;
+       req->offset = 0;
        req->pdu_len = le32_to_cpu(pdu->r2t_length);
        req->pdu_sent = 0;
 
-       if (unlikely(!req->pdu_len)) {
-               dev_err(queue->ctrl->ctrl.device,
-                       "req %d r2t len is %u, probably a bug...\n",
-                       rq->tag, req->pdu_len);
-               return -EPROTO;
-       }
-
-       if (unlikely(req->data_sent + req->pdu_len > req->data_len)) {
-               dev_err(queue->ctrl->ctrl.device,
-                       "req %d r2t len %u exceeded data len %u (%zu sent)\n",
-                       rq->tag, req->pdu_len, req->data_len,
-                       req->data_sent);
-               return -EPROTO;
-       }
-
-       if (unlikely(le32_to_cpu(pdu->r2t_offset) < req->data_sent)) {
-               dev_err(queue->ctrl->ctrl.device,
-                       "req %d unexpected r2t offset %u (expected %zu)\n",
-                       rq->tag, le32_to_cpu(pdu->r2t_offset),
-                       req->data_sent);
-               return -EPROTO;
-       }
-
        memset(data, 0, sizeof(*data));
        data->hdr.type = nvme_tcp_h2c_data;
        data->hdr.flags = NVME_TCP_F_DATA_LAST;
@@ -622,7 +601,6 @@ static int nvme_tcp_setup_h2c_data_pdu(struct nvme_tcp_request *req,
        data->command_id = nvme_cid(rq);
        data->data_offset = pdu->r2t_offset;
        data->data_length = cpu_to_le32(req->pdu_len);
-       return 0;
 }
 
 static int nvme_tcp_handle_r2t(struct nvme_tcp_queue *queue,
@@ -630,7 +608,7 @@ static int nvme_tcp_handle_r2t(struct nvme_tcp_queue *queue,
 {
        struct nvme_tcp_request *req;
        struct request *rq;
-       int ret;
+       u32 r2t_length = le32_to_cpu(pdu->r2t_length);
 
        rq = nvme_find_rq(nvme_tcp_tagset(queue), pdu->command_id);
        if (!rq) {
@@ -641,13 +619,28 @@ static int nvme_tcp_handle_r2t(struct nvme_tcp_queue *queue,
        }
        req = blk_mq_rq_to_pdu(rq);
 
-       ret = nvme_tcp_setup_h2c_data_pdu(req, pdu);
-       if (unlikely(ret))
-               return ret;
+       if (unlikely(!r2t_length)) {
+               dev_err(queue->ctrl->ctrl.device,
+                       "req %d r2t len is %u, probably a bug...\n",
+                       rq->tag, r2t_length);
+               return -EPROTO;
+       }
 
-       req->state = NVME_TCP_SEND_H2C_PDU;
-       req->offset = 0;
+       if (unlikely(req->data_sent + r2t_length > req->data_len)) {
+               dev_err(queue->ctrl->ctrl.device,
+                       "req %d r2t len %u exceeded data len %u (%zu sent)\n",
+                       rq->tag, r2t_length, req->data_len, req->data_sent);
+               return -EPROTO;
+       }
 
+       if (unlikely(le32_to_cpu(pdu->r2t_offset) < req->data_sent)) {
+               dev_err(queue->ctrl->ctrl.device,
+                       "req %d unexpected r2t offset %u (expected %zu)\n",
+                       rq->tag, le32_to_cpu(pdu->r2t_offset), req->data_sent);
+               return -EPROTO;
+       }
+
+       nvme_tcp_setup_h2c_data_pdu(req, pdu);
        nvme_tcp_queue_request(req, false, true);
 
        return 0;
@@ -1232,6 +1225,7 @@ static int nvme_tcp_alloc_async_req(struct nvme_tcp_ctrl *ctrl)
 
 static void nvme_tcp_free_queue(struct nvme_ctrl *nctrl, int qid)
 {
+       struct page *page;
        struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl);
        struct nvme_tcp_queue *queue = &ctrl->queues[qid];
 
@@ -1241,6 +1235,11 @@ static void nvme_tcp_free_queue(struct nvme_ctrl *nctrl, int qid)
        if (queue->hdr_digest || queue->data_digest)
                nvme_tcp_free_crypto(queue);
 
+       if (queue->pf_cache.va) {
+               page = virt_to_head_page(queue->pf_cache.va);
+               __page_frag_cache_drain(page, queue->pf_cache.pagecnt_bias);
+               queue->pf_cache.va = NULL;
+       }
        sock_release(queue->sock);
        kfree(queue->pdu);
        mutex_destroy(&queue->send_mutex);
index 6aa30f3..6be6e59 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/uio.h>
 #include <linux/falloc.h>
 #include <linux/file.h>
+#include <linux/fs.h>
 #include "nvmet.h"
 
 #define NVMET_MAX_MPOOL_BVEC           16
@@ -266,7 +267,8 @@ static void nvmet_file_execute_rw(struct nvmet_req *req)
 
        if (req->ns->buffered_io) {
                if (likely(!req->f.mpool_alloc) &&
-                               nvmet_file_execute_io(req, IOCB_NOWAIT))
+                   (req->ns->file->f_mode & FMODE_NOWAIT) &&
+                   nvmet_file_execute_io(req, IOCB_NOWAIT))
                        return;
                nvmet_file_submit_buffered_io(req);
        } else
index 84c387e..cb6a473 100644 (file)
@@ -166,6 +166,8 @@ static struct workqueue_struct *nvmet_tcp_wq;
 static const struct nvmet_fabrics_ops nvmet_tcp_ops;
 static void nvmet_tcp_free_cmd(struct nvmet_tcp_cmd *c);
 static void nvmet_tcp_finish_cmd(struct nvmet_tcp_cmd *cmd);
+static void nvmet_tcp_free_cmd_buffers(struct nvmet_tcp_cmd *cmd);
+static void nvmet_tcp_unmap_pdu_iovec(struct nvmet_tcp_cmd *cmd);
 
 static inline u16 nvmet_tcp_cmd_tag(struct nvmet_tcp_queue *queue,
                struct nvmet_tcp_cmd *cmd)
@@ -297,6 +299,16 @@ static int nvmet_tcp_check_ddgst(struct nvmet_tcp_queue *queue, void *pdu)
        return 0;
 }
 
+static void nvmet_tcp_free_cmd_buffers(struct nvmet_tcp_cmd *cmd)
+{
+       WARN_ON(unlikely(cmd->nr_mapped > 0));
+
+       kfree(cmd->iov);
+       sgl_free(cmd->req.sg);
+       cmd->iov = NULL;
+       cmd->req.sg = NULL;
+}
+
 static void nvmet_tcp_unmap_pdu_iovec(struct nvmet_tcp_cmd *cmd)
 {
        struct scatterlist *sg;
@@ -306,6 +318,8 @@ static void nvmet_tcp_unmap_pdu_iovec(struct nvmet_tcp_cmd *cmd)
 
        for (i = 0; i < cmd->nr_mapped; i++)
                kunmap(sg_page(&sg[i]));
+
+       cmd->nr_mapped = 0;
 }
 
 static void nvmet_tcp_map_pdu_iovec(struct nvmet_tcp_cmd *cmd)
@@ -387,7 +401,7 @@ static int nvmet_tcp_map_data(struct nvmet_tcp_cmd *cmd)
 
        return 0;
 err:
-       sgl_free(cmd->req.sg);
+       nvmet_tcp_free_cmd_buffers(cmd);
        return NVME_SC_INTERNAL;
 }
 
@@ -632,10 +646,8 @@ static int nvmet_try_send_data(struct nvmet_tcp_cmd *cmd, bool last_in_batch)
                }
        }
 
-       if (queue->nvme_sq.sqhd_disabled) {
-               kfree(cmd->iov);
-               sgl_free(cmd->req.sg);
-       }
+       if (queue->nvme_sq.sqhd_disabled)
+               nvmet_tcp_free_cmd_buffers(cmd);
 
        return 1;
 
@@ -664,8 +676,7 @@ static int nvmet_try_send_response(struct nvmet_tcp_cmd *cmd,
        if (left)
                return -EAGAIN;
 
-       kfree(cmd->iov);
-       sgl_free(cmd->req.sg);
+       nvmet_tcp_free_cmd_buffers(cmd);
        cmd->queue->snd_cmd = NULL;
        nvmet_tcp_put_cmd(cmd);
        return 1;
@@ -700,10 +711,11 @@ static int nvmet_try_send_r2t(struct nvmet_tcp_cmd *cmd, bool last_in_batch)
 static int nvmet_try_send_ddgst(struct nvmet_tcp_cmd *cmd, bool last_in_batch)
 {
        struct nvmet_tcp_queue *queue = cmd->queue;
+       int left = NVME_TCP_DIGEST_LENGTH - cmd->offset;
        struct msghdr msg = { .msg_flags = MSG_DONTWAIT };
        struct kvec iov = {
                .iov_base = (u8 *)&cmd->exp_ddgst + cmd->offset,
-               .iov_len = NVME_TCP_DIGEST_LENGTH - cmd->offset
+               .iov_len = left
        };
        int ret;
 
@@ -717,6 +729,10 @@ static int nvmet_try_send_ddgst(struct nvmet_tcp_cmd *cmd, bool last_in_batch)
                return ret;
 
        cmd->offset += ret;
+       left -= ret;
+
+       if (left)
+               return -EAGAIN;
 
        if (queue->nvme_sq.sqhd_disabled) {
                cmd->queue->snd_cmd = NULL;
@@ -1406,8 +1422,7 @@ static void nvmet_tcp_finish_cmd(struct nvmet_tcp_cmd *cmd)
 {
        nvmet_req_uninit(&cmd->req);
        nvmet_tcp_unmap_pdu_iovec(cmd);
-       kfree(cmd->iov);
-       sgl_free(cmd->req.sg);
+       nvmet_tcp_free_cmd_buffers(cmd);
 }
 
 static void nvmet_tcp_uninit_data_in_cmds(struct nvmet_tcp_queue *queue)
@@ -1417,7 +1432,10 @@ static void nvmet_tcp_uninit_data_in_cmds(struct nvmet_tcp_queue *queue)
 
        for (i = 0; i < queue->nr_cmds; i++, cmd++) {
                if (nvmet_tcp_need_data_in(cmd))
-                       nvmet_tcp_finish_cmd(cmd);
+                       nvmet_req_uninit(&cmd->req);
+
+               nvmet_tcp_unmap_pdu_iovec(cmd);
+               nvmet_tcp_free_cmd_buffers(cmd);
        }
 
        if (!queue->nr_cmds && nvmet_tcp_need_data_in(&queue->connect)) {
@@ -1437,7 +1455,9 @@ static void nvmet_tcp_release_queue_work(struct work_struct *w)
        mutex_unlock(&nvmet_tcp_queue_mutex);
 
        nvmet_tcp_restore_socket_callbacks(queue);
-       flush_work(&queue->io_work);
+       cancel_work_sync(&queue->io_work);
+       /* stop accepting incoming data */
+       queue->rcv_state = NVMET_TCP_RECV_ERR;
 
        nvmet_tcp_uninit_data_in_cmds(queue);
        nvmet_sq_destroy(&queue->nvme_sq);
index bae9d42..ecab906 100644 (file)
@@ -598,14 +598,14 @@ static struct irq_chip amd_gpio_irqchip = {
 
 #define PIN_IRQ_PENDING        (BIT(INTERRUPT_STS_OFF) | BIT(WAKE_STS_OFF))
 
-static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
+static bool do_amd_gpio_irq_handler(int irq, void *dev_id)
 {
        struct amd_gpio *gpio_dev = dev_id;
        struct gpio_chip *gc = &gpio_dev->gc;
-       irqreturn_t ret = IRQ_NONE;
        unsigned int i, irqnr;
        unsigned long flags;
        u32 __iomem *regs;
+       bool ret = false;
        u32  regval;
        u64 status, mask;
 
@@ -627,6 +627,14 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
                /* Each status bit covers four pins */
                for (i = 0; i < 4; i++) {
                        regval = readl(regs + i);
+                       /* caused wake on resume context for shared IRQ */
+                       if (irq < 0 && (regval & BIT(WAKE_STS_OFF))) {
+                               dev_dbg(&gpio_dev->pdev->dev,
+                                       "Waking due to GPIO %d: 0x%x",
+                                       irqnr + i, regval);
+                               return true;
+                       }
+
                        if (!(regval & PIN_IRQ_PENDING) ||
                            !(regval & BIT(INTERRUPT_MASK_OFF)))
                                continue;
@@ -650,9 +658,12 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
                        }
                        writel(regval, regs + i);
                        raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
-                       ret = IRQ_HANDLED;
+                       ret = true;
                }
        }
+       /* did not cause wake on resume context for shared IRQ */
+       if (irq < 0)
+               return false;
 
        /* Signal EOI to the GPIO unit */
        raw_spin_lock_irqsave(&gpio_dev->lock, flags);
@@ -664,6 +675,16 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
        return ret;
 }
 
+static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
+{
+       return IRQ_RETVAL(do_amd_gpio_irq_handler(irq, dev_id));
+}
+
+static bool __maybe_unused amd_gpio_check_wake(void *dev_id)
+{
+       return do_amd_gpio_irq_handler(-1, dev_id);
+}
+
 static int amd_get_groups_count(struct pinctrl_dev *pctldev)
 {
        struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev);
@@ -1033,6 +1054,7 @@ static int amd_gpio_probe(struct platform_device *pdev)
                goto out2;
 
        platform_set_drvdata(pdev, gpio_dev);
+       acpi_register_wakeup_handler(gpio_dev->irq, amd_gpio_check_wake, gpio_dev);
 
        dev_dbg(&pdev->dev, "amd gpio driver loaded\n");
        return ret;
@@ -1050,6 +1072,7 @@ static int amd_gpio_remove(struct platform_device *pdev)
        gpio_dev = platform_get_drvdata(pdev);
 
        gpiochip_remove(&gpio_dev->gc);
+       acpi_unregister_wakeup_handler(amd_gpio_check_wake, gpio_dev);
 
        return 0;
 }
index 0cc346b..a786107 100644 (file)
@@ -258,7 +258,7 @@ static void apple_gpio_irq_ack(struct irq_data *data)
               pctl->base + REG_IRQ(irqgrp, data->hwirq));
 }
 
-static int apple_gpio_irq_type(unsigned int type)
+static unsigned int apple_gpio_irq_type(unsigned int type)
 {
        switch (type & IRQ_TYPE_SENSE_MASK) {
        case IRQ_TYPE_EDGE_RISING:
@@ -272,7 +272,7 @@ static int apple_gpio_irq_type(unsigned int type)
        case IRQ_TYPE_LEVEL_LOW:
                return REG_GPIOx_IN_IRQ_LO;
        default:
-               return -EINVAL;
+               return REG_GPIOx_IN_IRQ_OFF;
        }
 }
 
@@ -288,7 +288,7 @@ static void apple_gpio_irq_unmask(struct irq_data *data)
 {
        struct apple_gpio_pinctrl *pctl =
                gpiochip_get_data(irq_data_get_irq_chip_data(data));
-       int irqtype = apple_gpio_irq_type(irqd_get_trigger_type(data));
+       unsigned int irqtype = apple_gpio_irq_type(irqd_get_trigger_type(data));
 
        apple_gpio_set_reg(pctl, data->hwirq, REG_GPIOx_MODE,
                           FIELD_PREP(REG_GPIOx_MODE, irqtype));
@@ -313,10 +313,10 @@ static int apple_gpio_irq_set_type(struct irq_data *data,
 {
        struct apple_gpio_pinctrl *pctl =
                gpiochip_get_data(irq_data_get_irq_chip_data(data));
-       int irqtype = apple_gpio_irq_type(type);
+       unsigned int irqtype = apple_gpio_irq_type(type);
 
-       if (irqtype < 0)
-               return irqtype;
+       if (irqtype == REG_GPIOx_IN_IRQ_OFF)
+               return -EINVAL;
 
        apple_gpio_set_reg(pctl, data->hwirq, REG_GPIOx_MODE,
                           FIELD_PREP(REG_GPIOx_MODE, irqtype));
index b9191f1..3e0c007 100644 (file)
@@ -197,6 +197,7 @@ config PINCTRL_QCOM_SPMI_PMIC
        select PINMUX
        select PINCONF
        select GENERIC_PINCONF
+  select GPIOLIB
        select GPIOLIB_IRQCHIP
        select IRQ_DOMAIN_HIERARCHY
        help
@@ -211,6 +212,7 @@ config PINCTRL_QCOM_SSBI_PMIC
        select PINMUX
        select PINCONF
        select GENERIC_PINCONF
+  select GPIOLIB
        select GPIOLIB_IRQCHIP
        select IRQ_DOMAIN_HIERARCHY
        help
index c51793f..fdfd7b8 100644 (file)
@@ -1310,6 +1310,7 @@ static const struct msm_pinctrl_soc_data sdm845_pinctrl = {
        .ngpios = 151,
        .wakeirq_map = sdm845_pdc_map,
        .nwakeirq_map = ARRAY_SIZE(sdm845_pdc_map),
+       .wakeirq_dual_edge_errata = true,
 };
 
 static const struct msm_pinctrl_soc_data sdm845_acpi_pinctrl = {
index 4d8f863..1c042d3 100644 (file)
@@ -1597,10 +1597,10 @@ static const struct msm_pingroup sm8350_groups[] = {
        [200] = PINGROUP(200, qdss_gpio, _, _, _, _, _, _, _, _),
        [201] = PINGROUP(201, _, _, _, _, _, _, _, _, _),
        [202] = PINGROUP(202, _, _, _, _, _, _, _, _, _),
-       [203] = UFS_RESET(ufs_reset, 0x1d8000),
-       [204] = SDC_PINGROUP(sdc2_clk, 0x1cf000, 14, 6),
-       [205] = SDC_PINGROUP(sdc2_cmd, 0x1cf000, 11, 3),
-       [206] = SDC_PINGROUP(sdc2_data, 0x1cf000, 9, 0),
+       [203] = UFS_RESET(ufs_reset, 0xd8000),
+       [204] = SDC_PINGROUP(sdc2_clk, 0xcf000, 14, 6),
+       [205] = SDC_PINGROUP(sdc2_cmd, 0xcf000, 11, 3),
+       [206] = SDC_PINGROUP(sdc2_data, 0xcf000, 9, 0),
 };
 
 static const struct msm_gpio_wakeirq_map sm8350_pdc_map[] = {
index 425d55a..6853b5b 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 
+#include <asm/mach-ralink/ralink_regs.h>
 #include <asm/mach-ralink/mt7620.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
index 8d734bf..50bd26a 100644 (file)
@@ -275,7 +275,7 @@ static int tegra_pinctrl_set_mux(struct pinctrl_dev *pctldev,
        return 0;
 }
 
-static struct tegra_pingroup *tegra_pinctrl_get_group(struct pinctrl_dev *pctldev,
+static const struct tegra_pingroup *tegra_pinctrl_get_group(struct pinctrl_dev *pctldev,
                                        unsigned int offset)
 {
        struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
@@ -289,7 +289,7 @@ static struct tegra_pingroup *tegra_pinctrl_get_group(struct pinctrl_dev *pctlde
                        continue;
                for (j = 0; j < num_pins; j++) {
                        if (offset == pins[j])
-                               return (struct tegra_pingroup *)&pmx->soc->groups[group];
+                               return &pmx->soc->groups[group];
                }
        }
 
index b4fef91..5c1dfcb 100644 (file)
@@ -1387,7 +1387,6 @@ static struct tegra_function tegra194_functions[] = {
                .schmitt_bit = schmitt_b,                       \
                .drvtype_bit = 13,                              \
                .lpdr_bit = e_lpdr,                             \
-               .drv_reg = -1,                                  \
 
 #define drive_touch_clk_pcc4            DRV_PINGROUP_ENTRY_Y(0x2004,   12,     5,      20,     5,      -1,     -1,     -1,     -1,     1)
 #define drive_uart3_rx_pcc6             DRV_PINGROUP_ENTRY_Y(0x200c,   12,     5,      20,     5,      -1,     -1,     -1,     -1,     1)
index 9d1e7e0..4020b83 100644 (file)
@@ -41,9 +41,12 @@ enum cros_ec_ish_channel {
 #define ISHTP_SEND_TIMEOUT                     (3 * HZ)
 
 /* ISH Transport CrOS EC ISH client unique GUID */
-static const guid_t cros_ish_guid =
-       GUID_INIT(0x7b7154d0, 0x56f4, 0x4bdc,
-                 0xb0, 0xd8, 0x9e, 0x7c, 0xda, 0xe0, 0xd6, 0xa0);
+static const struct ishtp_device_id cros_ec_ishtp_id_table[] = {
+       { .guid = GUID_INIT(0x7b7154d0, 0x56f4, 0x4bdc,
+                 0xb0, 0xd8, 0x9e, 0x7c, 0xda, 0xe0, 0xd6, 0xa0), },
+       { }
+};
+MODULE_DEVICE_TABLE(ishtp, cros_ec_ishtp_id_table);
 
 struct header {
        u8 channel;
@@ -389,7 +392,7 @@ static int cros_ish_init(struct ishtp_cl *cros_ish_cl)
        ishtp_set_tx_ring_size(cros_ish_cl, CROS_ISH_CL_TX_RING_SIZE);
        ishtp_set_rx_ring_size(cros_ish_cl, CROS_ISH_CL_RX_RING_SIZE);
 
-       fw_client = ishtp_fw_cl_get_client(dev, &cros_ish_guid);
+       fw_client = ishtp_fw_cl_get_client(dev, &cros_ec_ishtp_id_table[0].guid);
        if (!fw_client) {
                dev_err(cl_data_to_dev(client_data),
                        "ish client uuid not found\n");
@@ -765,7 +768,7 @@ static SIMPLE_DEV_PM_OPS(cros_ec_ishtp_pm_ops, cros_ec_ishtp_suspend,
 
 static struct ishtp_cl_driver  cros_ec_ishtp_driver = {
        .name = "cros_ec_ishtp",
-       .guid = &cros_ish_guid,
+       .id = cros_ec_ishtp_id_table,
        .probe = cros_ec_ishtp_probe,
        .remove = cros_ec_ishtp_remove,
        .reset = cros_ec_ishtp_reset,
@@ -791,4 +794,3 @@ MODULE_DESCRIPTION("ChromeOS EC ISHTP Client Driver");
 MODULE_AUTHOR("Rushikesh S Kadam <rushikesh.s.kadam@intel.com>");
 
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("ishtp:*");
index 0b7f58f..c897a2f 100644 (file)
@@ -413,7 +413,7 @@ mlxreg_lc_create_static_devices(struct mlxreg_lc *mlxreg_lc, struct mlxreg_hotpl
                                int size)
 {
        struct mlxreg_hotplug_device *dev = devs;
-       int i;
+       int i, ret;
 
        /* Create static I2C device feeding by auxiliary or main power. */
        for (i = 0; i < size; i++, dev++) {
@@ -423,6 +423,7 @@ mlxreg_lc_create_static_devices(struct mlxreg_lc *mlxreg_lc, struct mlxreg_hotpl
                                dev->brdinfo->type, dev->nr, dev->brdinfo->addr);
 
                        dev->adapter = NULL;
+                       ret = PTR_ERR(dev->client);
                        goto fail_create_static_devices;
                }
        }
@@ -435,7 +436,7 @@ fail_create_static_devices:
                i2c_unregister_device(dev->client);
                dev->client = NULL;
        }
-       return IS_ERR(dev->client);
+       return ret;
 }
 
 static void
index d4c079f..7400bc5 100644 (file)
@@ -185,7 +185,7 @@ config ACER_WMI
 
 config AMD_PMC
        tristate "AMD SoC PMC driver"
-       depends on ACPI && PCI
+       depends on ACPI && PCI && RTC_CLASS
        help
          The driver provides support for AMD Power Management Controller
          primarily responsible for S2Idle transactions that are driven from
index 2fffa57..fe224a5 100644 (file)
@@ -187,7 +187,7 @@ config DELL_WMI_AIO
 
 config DELL_WMI_DESCRIPTOR
        tristate
-       default m
+       default n
        depends on ACPI_WMI
 
 config DELL_WMI_LED
index b183967..435a91f 100644 (file)
@@ -331,9 +331,11 @@ static int lis3lv02d_probe(struct platform_device *device)
        INIT_WORK(&hpled_led.work, delayed_set_status_worker);
        ret = led_classdev_register(NULL, &hpled_led.led_classdev);
        if (ret) {
+               i8042_remove_filter(hp_accel_i8042_filter);
                lis3lv02d_joystick_disable(&lis3_dev);
                lis3lv02d_poweroff(&lis3_dev);
                flush_work(&hpled_led.work);
+               lis3lv02d_remove_fs(&lis3_dev);
                return ret;
        }
 
index 12fc98a..93ac8b2 100644 (file)
@@ -93,9 +93,12 @@ struct ishtp_opregion_dev {
 };
 
 /* eclite ishtp client UUID: 6a19cc4b-d760-4de3-b14d-f25ebd0fbcd9 */
-static const guid_t ecl_ishtp_guid =
-       GUID_INIT(0x6a19cc4b, 0xd760, 0x4de3,
-                 0xb1, 0x4d, 0xf2, 0x5e, 0xbd, 0xf, 0xbc, 0xd9);
+static const struct ishtp_device_id ecl_ishtp_id_table[] = {
+       { .guid = GUID_INIT(0x6a19cc4b, 0xd760, 0x4de3,
+                 0xb1, 0x4d, 0xf2, 0x5e, 0xbd, 0xf, 0xbc, 0xd9), },
+       { }
+};
+MODULE_DEVICE_TABLE(ishtp, ecl_ishtp_id_table);
 
 /* ACPI DSM UUID: 91d936a7-1f01-49c6-a6b4-72f00ad8d8a5 */
 static const guid_t ecl_acpi_guid =
@@ -462,7 +465,7 @@ static int ecl_ishtp_cl_init(struct ishtp_cl *ecl_ishtp_cl)
        ishtp_set_tx_ring_size(ecl_ishtp_cl, ECL_CL_TX_RING_SIZE);
        ishtp_set_rx_ring_size(ecl_ishtp_cl, ECL_CL_RX_RING_SIZE);
 
-       fw_client = ishtp_fw_cl_get_client(dev, &ecl_ishtp_guid);
+       fw_client = ishtp_fw_cl_get_client(dev, &ecl_ishtp_id_table[0].guid);
        if (!fw_client) {
                dev_err(cl_data_to_dev(opr_dev), "fw client not found\n");
                return -ENOENT;
@@ -674,7 +677,7 @@ static const struct dev_pm_ops ecl_ishtp_pm_ops = {
 
 static struct ishtp_cl_driver ecl_ishtp_cl_driver = {
        .name = "ishtp-eclite",
-       .guid = &ecl_ishtp_guid,
+       .id = ecl_ishtp_id_table,
        .probe = ecl_ishtp_cl_probe,
        .remove = ecl_ishtp_cl_remove,
        .reset = ecl_ishtp_cl_reset,
@@ -698,4 +701,3 @@ MODULE_DESCRIPTION("ISH ISHTP eclite client opregion driver");
 MODULE_AUTHOR("K Naduvalath, Sumesh <sumesh.k.naduvalath@intel.com>");
 
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("ishtp:*");
index 7ee010a..c1d9ed9 100644 (file)
@@ -152,7 +152,7 @@ struct sabi_config {
 
 static const struct sabi_config sabi_configs[] = {
        {
-               /* I don't know if it is really 2, but it it is
+               /* I don't know if it is really 2, but it is
                 * less than 3 anyway */
                .sabi_version = 2,
 
index 9472aae..c4d9c45 100644 (file)
@@ -888,8 +888,10 @@ static int tlmi_analyze(void)
                        break;
                if (!item)
                        break;
-               if (!*item)
+               if (!*item) {
+                       kfree(item);
                        continue;
+               }
 
                /* It is not allowed to have '/' for file name. Convert it into '\'. */
                strreplace(item, '/', '\\');
@@ -902,6 +904,7 @@ static int tlmi_analyze(void)
                setting = kzalloc(sizeof(*setting), GFP_KERNEL);
                if (!setting) {
                        ret = -ENOMEM;
+                       kfree(item);
                        goto fail_clear_attr;
                }
                setting->index = i;
@@ -916,7 +919,6 @@ static int tlmi_analyze(void)
                }
                kobject_init(&setting->kobj, &tlmi_attr_setting_ktype);
                tlmi_priv.setting[i] = setting;
-               tlmi_priv.settings_count++;
                kfree(item);
        }
 
@@ -983,7 +985,12 @@ static void tlmi_remove(struct wmi_device *wdev)
 
 static int tlmi_probe(struct wmi_device *wdev, const void *context)
 {
-       tlmi_analyze();
+       int ret;
+
+       ret = tlmi_analyze();
+       if (ret)
+               return ret;
+
        return tlmi_sysfs_init();
 }
 
index f8e2682..2ce5086 100644 (file)
@@ -55,7 +55,6 @@ struct tlmi_attr_setting {
 struct think_lmi {
        struct wmi_device *wmi_device;
 
-       int settings_count;
        bool can_set_bios_settings;
        bool can_get_bios_selections;
        bool can_set_bios_password;
index 9c632df..b3ac9c3 100644 (file)
@@ -1105,15 +1105,6 @@ static int tpacpi_rfk_update_swstate(const struct tpacpi_rfk *tp_rfk)
        return status;
 }
 
-/* Query FW and update rfkill sw state for all rfkill switches */
-static void tpacpi_rfk_update_swstate_all(void)
-{
-       unsigned int i;
-
-       for (i = 0; i < TPACPI_RFK_SW_MAX; i++)
-               tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[i]);
-}
-
 /*
  * Sync the HW-blocking state of all rfkill switches,
  * do notice it causes the rfkill core to schedule uevents
@@ -3074,9 +3065,6 @@ static void tpacpi_send_radiosw_update(void)
        if (wlsw == TPACPI_RFK_RADIO_OFF)
                tpacpi_rfk_update_hwblock_state(true);
 
-       /* Sync sw blocking state */
-       tpacpi_rfk_update_swstate_all();
-
        /* Sync hw blocking state last if it is hw-unblocked */
        if (wlsw == TPACPI_RFK_RADIO_ON)
                tpacpi_rfk_update_hwblock_state(false);
@@ -8766,6 +8754,7 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
        TPACPI_Q_LNV3('N', '2', 'E', TPACPI_FAN_2CTL),  /* P1 / X1 Extreme (1st gen) */
        TPACPI_Q_LNV3('N', '2', 'O', TPACPI_FAN_2CTL),  /* P1 / X1 Extreme (2nd gen) */
        TPACPI_Q_LNV3('N', '2', 'V', TPACPI_FAN_2CTL),  /* P1 / X1 Extreme (3nd gen) */
+       TPACPI_Q_LNV3('N', '4', '0', TPACPI_FAN_2CTL),  /* P1 / X1 Extreme (4nd gen) */
        TPACPI_Q_LNV3('N', '3', '0', TPACPI_FAN_2CTL),  /* P15 (1st gen) / P15v (1st gen) */
        TPACPI_Q_LNV3('N', '3', '2', TPACPI_FAN_2CTL),  /* X1 Carbon (9th gen) */
 };
index 44faa3a..b740866 100644 (file)
@@ -166,16 +166,13 @@ static struct dtpm_ops dtpm_ops = {
 
 static int cpuhp_dtpm_cpu_offline(unsigned int cpu)
 {
-       struct em_perf_domain *pd;
        struct dtpm_cpu *dtpm_cpu;
 
-       pd = em_cpu_get(cpu);
-       if (!pd)
-               return -EINVAL;
-
        dtpm_cpu = per_cpu(dtpm_per_cpu, cpu);
+       if (dtpm_cpu)
+               dtpm_update_power(&dtpm_cpu->dtpm);
 
-       return dtpm_update_power(&dtpm_cpu->dtpm);
+       return 0;
 }
 
 static int cpuhp_dtpm_cpu_online(unsigned int cpu)
index 6bc5791..08e429a 100644 (file)
@@ -1699,12 +1699,9 @@ static int initialize_dco_operating_mode(struct idtcm_channel *channel)
 
 /* PTP Hardware Clock interface */
 
-/**
+/*
  * Maximum absolute value for write phase offset in picoseconds
  *
- * @channel:  channel
- * @delta_ns: delta in nanoseconds
- *
  * Destination signed register is 32-bit register in resolution of 50ps
  *
  * 0x7fffffff * 50 =  2147483647 * 50 = 107374182350
index 34f943c..0f1b5a7 100644 (file)
@@ -1304,10 +1304,11 @@ ptp_ocp_register_ext(struct ptp_ocp *bp, struct ocp_resource *r)
        if (!ext)
                return -ENOMEM;
 
-       err = -EINVAL;
        ext->mem = ptp_ocp_get_mem(bp, r);
-       if (!ext->mem)
+       if (IS_ERR(ext->mem)) {
+               err = PTR_ERR(ext->mem);
                goto out;
+       }
 
        ext->bp = bp;
        ext->info = r->extra;
@@ -1371,8 +1372,8 @@ ptp_ocp_register_mem(struct ptp_ocp *bp, struct ocp_resource *r)
        void __iomem *mem;
 
        mem = ptp_ocp_get_mem(bp, r);
-       if (!mem)
-               return -EINVAL;
+       if (IS_ERR(mem))
+               return PTR_ERR(mem);
 
        bp_assign_entry(bp, r, mem);
 
index 2c40fe1..6043c83 100644 (file)
@@ -731,7 +731,7 @@ static ssize_t dasd_ff_show(struct device *dev, struct device_attribute *attr,
                ff_flag = (devmap->features & DASD_FEATURE_FAILFAST) != 0;
        else
                ff_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_FAILFAST) != 0;
-       return snprintf(buf, PAGE_SIZE, ff_flag ? "1\n" : "0\n");
+       return sysfs_emit(buf, ff_flag ? "1\n" : "0\n");
 }
 
 static ssize_t dasd_ff_store(struct device *dev, struct device_attribute *attr,
@@ -773,7 +773,7 @@ dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf)
        spin_unlock(&dasd_devmap_lock);
 
 out:
-       return snprintf(buf, PAGE_SIZE, ro_flag ? "1\n" : "0\n");
+       return sysfs_emit(buf, ro_flag ? "1\n" : "0\n");
 }
 
 static ssize_t
@@ -834,7 +834,7 @@ dasd_erplog_show(struct device *dev, struct device_attribute *attr, char *buf)
                erplog = (devmap->features & DASD_FEATURE_ERPLOG) != 0;
        else
                erplog = (DASD_FEATURE_DEFAULT & DASD_FEATURE_ERPLOG) != 0;
-       return snprintf(buf, PAGE_SIZE, erplog ? "1\n" : "0\n");
+       return sysfs_emit(buf, erplog ? "1\n" : "0\n");
 }
 
 static ssize_t
@@ -1033,13 +1033,13 @@ dasd_discipline_show(struct device *dev, struct device_attribute *attr,
                dasd_put_device(device);
                goto out;
        } else {
-               len = snprintf(buf, PAGE_SIZE, "%s\n",
-                              device->discipline->name);
+               len = sysfs_emit(buf, "%s\n",
+                                device->discipline->name);
                dasd_put_device(device);
                return len;
        }
 out:
-       len = snprintf(buf, PAGE_SIZE, "none\n");
+       len = sysfs_emit(buf, "none\n");
        return len;
 }
 
@@ -1056,30 +1056,30 @@ dasd_device_status_show(struct device *dev, struct device_attribute *attr,
        if (!IS_ERR(device)) {
                switch (device->state) {
                case DASD_STATE_NEW:
-                       len = snprintf(buf, PAGE_SIZE, "new\n");
+                       len = sysfs_emit(buf, "new\n");
                        break;
                case DASD_STATE_KNOWN:
-                       len = snprintf(buf, PAGE_SIZE, "detected\n");
+                       len = sysfs_emit(buf, "detected\n");
                        break;
                case DASD_STATE_BASIC:
-                       len = snprintf(buf, PAGE_SIZE, "basic\n");
+                       len = sysfs_emit(buf, "basic\n");
                        break;
                case DASD_STATE_UNFMT:
-                       len = snprintf(buf, PAGE_SIZE, "unformatted\n");
+                       len = sysfs_emit(buf, "unformatted\n");
                        break;
                case DASD_STATE_READY:
-                       len = snprintf(buf, PAGE_SIZE, "ready\n");
+                       len = sysfs_emit(buf, "ready\n");
                        break;
                case DASD_STATE_ONLINE:
-                       len = snprintf(buf, PAGE_SIZE, "online\n");
+                       len = sysfs_emit(buf, "online\n");
                        break;
                default:
-                       len = snprintf(buf, PAGE_SIZE, "no stat\n");
+                       len = sysfs_emit(buf, "no stat\n");
                        break;
                }
                dasd_put_device(device);
        } else
-               len = snprintf(buf, PAGE_SIZE, "unknown\n");
+               len = sysfs_emit(buf, "unknown\n");
        return len;
 }
 
@@ -1120,7 +1120,7 @@ static ssize_t dasd_vendor_show(struct device *dev,
        device = dasd_device_from_cdev(to_ccwdev(dev));
        vendor = "";
        if (IS_ERR(device))
-               return snprintf(buf, PAGE_SIZE, "%s\n", vendor);
+               return sysfs_emit(buf, "%s\n", vendor);
 
        if (device->discipline && device->discipline->get_uid &&
            !device->discipline->get_uid(device, &uid))
@@ -1128,7 +1128,7 @@ static ssize_t dasd_vendor_show(struct device *dev,
 
        dasd_put_device(device);
 
-       return snprintf(buf, PAGE_SIZE, "%s\n", vendor);
+       return sysfs_emit(buf, "%s\n", vendor);
 }
 
 static DEVICE_ATTR(vendor, 0444, dasd_vendor_show, NULL);
@@ -1148,7 +1148,7 @@ dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf)
        device = dasd_device_from_cdev(to_ccwdev(dev));
        uid_string[0] = 0;
        if (IS_ERR(device))
-               return snprintf(buf, PAGE_SIZE, "%s\n", uid_string);
+               return sysfs_emit(buf, "%s\n", uid_string);
 
        if (device->discipline && device->discipline->get_uid &&
            !device->discipline->get_uid(device, &uid)) {
@@ -1183,7 +1183,7 @@ dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf)
        }
        dasd_put_device(device);
 
-       return snprintf(buf, PAGE_SIZE, "%s\n", uid_string);
+       return sysfs_emit(buf, "%s\n", uid_string);
 }
 static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL);
 
@@ -1201,7 +1201,7 @@ dasd_eer_show(struct device *dev, struct device_attribute *attr, char *buf)
                eer_flag = dasd_eer_enabled(devmap->device);
        else
                eer_flag = 0;
-       return snprintf(buf, PAGE_SIZE, eer_flag ? "1\n" : "0\n");
+       return sysfs_emit(buf, eer_flag ? "1\n" : "0\n");
 }
 
 static ssize_t
@@ -1243,7 +1243,7 @@ dasd_expires_show(struct device *dev, struct device_attribute *attr, char *buf)
        device = dasd_device_from_cdev(to_ccwdev(dev));
        if (IS_ERR(device))
                return -ENODEV;
-       len = snprintf(buf, PAGE_SIZE, "%lu\n", device->default_expires);
+       len = sysfs_emit(buf, "%lu\n", device->default_expires);
        dasd_put_device(device);
        return len;
 }
@@ -1283,7 +1283,7 @@ dasd_retries_show(struct device *dev, struct device_attribute *attr, char *buf)
        device = dasd_device_from_cdev(to_ccwdev(dev));
        if (IS_ERR(device))
                return -ENODEV;
-       len = snprintf(buf, PAGE_SIZE, "%lu\n", device->default_retries);
+       len = sysfs_emit(buf, "%lu\n", device->default_retries);
        dasd_put_device(device);
        return len;
 }
@@ -1324,7 +1324,7 @@ dasd_timeout_show(struct device *dev, struct device_attribute *attr,
        device = dasd_device_from_cdev(to_ccwdev(dev));
        if (IS_ERR(device))
                return -ENODEV;
-       len = snprintf(buf, PAGE_SIZE, "%lu\n", device->blk_timeout);
+       len = sysfs_emit(buf, "%lu\n", device->blk_timeout);
        dasd_put_device(device);
        return len;
 }
@@ -1398,11 +1398,11 @@ static ssize_t dasd_hpf_show(struct device *dev, struct device_attribute *attr,
                return -ENODEV;
        if (!device->discipline || !device->discipline->hpf_enabled) {
                dasd_put_device(device);
-               return snprintf(buf, PAGE_SIZE, "%d\n", dasd_nofcx);
+               return sysfs_emit(buf, "%d\n", dasd_nofcx);
        }
        hpf = device->discipline->hpf_enabled(device);
        dasd_put_device(device);
-       return snprintf(buf, PAGE_SIZE, "%d\n", hpf);
+       return sysfs_emit(buf, "%d\n", hpf);
 }
 
 static DEVICE_ATTR(hpf, 0444, dasd_hpf_show, NULL);
@@ -1416,13 +1416,13 @@ static ssize_t dasd_reservation_policy_show(struct device *dev,
 
        devmap = dasd_find_busid(dev_name(dev));
        if (IS_ERR(devmap)) {
-               rc = snprintf(buf, PAGE_SIZE, "ignore\n");
+               rc = sysfs_emit(buf, "ignore\n");
        } else {
                spin_lock(&dasd_devmap_lock);
                if (devmap->features & DASD_FEATURE_FAILONSLCK)
-                       rc = snprintf(buf, PAGE_SIZE, "fail\n");
+                       rc = sysfs_emit(buf, "fail\n");
                else
-                       rc = snprintf(buf, PAGE_SIZE, "ignore\n");
+                       rc = sysfs_emit(buf, "ignore\n");
                spin_unlock(&dasd_devmap_lock);
        }
        return rc;
@@ -1457,14 +1457,14 @@ static ssize_t dasd_reservation_state_show(struct device *dev,
 
        device = dasd_device_from_cdev(to_ccwdev(dev));
        if (IS_ERR(device))
-               return snprintf(buf, PAGE_SIZE, "none\n");
+               return sysfs_emit(buf, "none\n");
 
        if (test_bit(DASD_FLAG_IS_RESERVED, &device->flags))
-               rc = snprintf(buf, PAGE_SIZE, "reserved\n");
+               rc = sysfs_emit(buf, "reserved\n");
        else if (test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags))
-               rc = snprintf(buf, PAGE_SIZE, "lost\n");
+               rc = sysfs_emit(buf, "lost\n");
        else
-               rc = snprintf(buf, PAGE_SIZE, "none\n");
+               rc = sysfs_emit(buf, "none\n");
        dasd_put_device(device);
        return rc;
 }
@@ -1531,7 +1531,7 @@ dasd_path_threshold_show(struct device *dev,
        device = dasd_device_from_cdev(to_ccwdev(dev));
        if (IS_ERR(device))
                return -ENODEV;
-       len = snprintf(buf, PAGE_SIZE, "%lu\n", device->path_thrhld);
+       len = sysfs_emit(buf, "%lu\n", device->path_thrhld);
        dasd_put_device(device);
        return len;
 }
@@ -1578,7 +1578,7 @@ dasd_path_autodisable_show(struct device *dev,
        else
                flag = (DASD_FEATURE_DEFAULT &
                        DASD_FEATURE_PATH_AUTODISABLE) != 0;
-       return snprintf(buf, PAGE_SIZE, flag ? "1\n" : "0\n");
+       return sysfs_emit(buf, flag ? "1\n" : "0\n");
 }
 
 static ssize_t
@@ -1616,7 +1616,7 @@ dasd_path_interval_show(struct device *dev,
        device = dasd_device_from_cdev(to_ccwdev(dev));
        if (IS_ERR(device))
                return -ENODEV;
-       len = snprintf(buf, PAGE_SIZE, "%lu\n", device->path_interval);
+       len = sysfs_emit(buf, "%lu\n", device->path_interval);
        dasd_put_device(device);
        return len;
 }
@@ -1662,9 +1662,9 @@ dasd_device_fcs_show(struct device *dev, struct device_attribute *attr,
                return -ENODEV;
        fc_sec = dasd_path_get_fcs_device(device);
        if (fc_sec == -EINVAL)
-               rc = snprintf(buf, PAGE_SIZE, "Inconsistent\n");
+               rc = sysfs_emit(buf, "Inconsistent\n");
        else
-               rc = snprintf(buf, PAGE_SIZE, "%s\n", dasd_path_get_fcs_str(fc_sec));
+               rc = sysfs_emit(buf, "%s\n", dasd_path_get_fcs_str(fc_sec));
        dasd_put_device(device);
 
        return rc;
@@ -1677,7 +1677,7 @@ dasd_path_fcs_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
        struct dasd_path *path = to_dasd_path(kobj);
        unsigned int fc_sec = path->fc_security;
 
-       return snprintf(buf, PAGE_SIZE, "%s\n", dasd_path_get_fcs_str(fc_sec));
+       return sysfs_emit(buf, "%s\n", dasd_path_get_fcs_str(fc_sec));
 }
 
 static struct kobj_attribute path_fcs_attribute =
@@ -1698,7 +1698,7 @@ static ssize_t dasd_##_name##_show(struct device *dev,                    \
                val = _func(device);                                    \
        dasd_put_device(device);                                        \
                                                                        \
-       return snprintf(buf, PAGE_SIZE, "%d\n", val);                   \
+       return sysfs_emit(buf, "%d\n", val);                    \
 }                                                                      \
 static DEVICE_ATTR(_name, 0444, dasd_##_name##_show, NULL);            \
 
index 646ec79..dfde0d9 100644 (file)
@@ -1047,24 +1047,24 @@ raw3270_probe (struct ccw_device *cdev)
 static ssize_t
 raw3270_model_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%i\n",
-                       ((struct raw3270 *) dev_get_drvdata(dev))->model);
+       return sysfs_emit(buf, "%i\n",
+                         ((struct raw3270 *)dev_get_drvdata(dev))->model);
 }
 static DEVICE_ATTR(model, 0444, raw3270_model_show, NULL);
 
 static ssize_t
 raw3270_rows_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%i\n",
-                       ((struct raw3270 *) dev_get_drvdata(dev))->rows);
+       return sysfs_emit(buf, "%i\n",
+                         ((struct raw3270 *)dev_get_drvdata(dev))->rows);
 }
 static DEVICE_ATTR(rows, 0444, raw3270_rows_show, NULL);
 
 static ssize_t
 raw3270_columns_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%i\n",
-                       ((struct raw3270 *) dev_get_drvdata(dev))->cols);
+       return sysfs_emit(buf, "%i\n",
+                         ((struct raw3270 *)dev_get_drvdata(dev))->cols);
 }
 static DEVICE_ATTR(columns, 0444, raw3270_columns_show, NULL);
 
index 1097e76..5440f28 100644 (file)
@@ -285,7 +285,7 @@ static ssize_t chp_configure_show(struct device *dev,
        if (status < 0)
                return status;
 
-       return snprintf(buf, PAGE_SIZE, "%d\n", status);
+       return sysfs_emit(buf, "%d\n", status);
 }
 
 static int cfg_wait_idle(void);
index 27eb652..81dab9b 100644 (file)
@@ -639,8 +639,8 @@ static void _base_sync_drv_fw_timestamp(struct MPT3SAS_ADAPTER *ioc)
        mpi_request->IOCParameter = MPI26_SET_IOC_PARAMETER_SYNC_TIMESTAMP;
        current_time = ktime_get_real();
        TimeStamp = ktime_to_ms(current_time);
-       mpi_request->Reserved7 = cpu_to_le32(TimeStamp & 0xFFFFFFFF);
-       mpi_request->IOCParameterValue = cpu_to_le32(TimeStamp >> 32);
+       mpi_request->Reserved7 = cpu_to_le32(TimeStamp >> 32);
+       mpi_request->IOCParameterValue = cpu_to_le32(TimeStamp & 0xFFFFFFFF);
        init_completion(&ioc->scsih_cmds.done);
        ioc->put_smid_default(ioc, smid);
        dinitprintk(ioc, ioc_info(ioc,
index db6a759..a0af986 100644 (file)
 
 #define MPT_MAX_CALLBACKS              32
 
+#define MPT_MAX_HBA_NUM_PHYS           32
+
 #define INTERNAL_CMDS_COUNT            10      /* reserved cmds */
 /* reserved for issuing internally framed scsi io cmds */
 #define INTERNAL_SCSIIO_CMDS_COUNT     3
@@ -798,6 +800,7 @@ struct _sas_phy {
  * @enclosure_handle: handle for this a member of an enclosure
  * @device_info: bitwise defining capabilities of this sas_host/expander
  * @responding: used in _scsih_expander_device_mark_responding
+ * @nr_phys_allocated: Allocated memory for this many count phys
  * @phy: a list of phys that make up this sas_host/expander
  * @sas_port_list: list of ports attached to this sas_host/expander
  * @port: hba port entry containing node's port number info
@@ -813,6 +816,7 @@ struct _sas_node {
        u16     enclosure_handle;
        u64     enclosure_logical_id;
        u8      responding;
+       u8      nr_phys_allocated;
        struct hba_port *port;
        struct  _sas_phy *phy;
        struct list_head sas_port_list;
index cee7170..0079276 100644 (file)
@@ -3869,7 +3869,7 @@ _scsih_ublock_io_device(struct MPT3SAS_ADAPTER *ioc,
 
        shost_for_each_device(sdev, ioc->shost) {
                sas_device_priv_data = sdev->hostdata;
-               if (!sas_device_priv_data)
+               if (!sas_device_priv_data || !sas_device_priv_data->sas_target)
                        continue;
                if (sas_device_priv_data->sas_target->sas_address
                    != sas_address)
@@ -6406,11 +6406,26 @@ _scsih_sas_port_refresh(struct MPT3SAS_ADAPTER *ioc)
        int i, j, count = 0, lcount = 0;
        int ret;
        u64 sas_addr;
+       u8 num_phys;
 
        drsprintk(ioc, ioc_info(ioc,
            "updating ports for sas_host(0x%016llx)\n",
            (unsigned long long)ioc->sas_hba.sas_address));
 
+       mpt3sas_config_get_number_hba_phys(ioc, &num_phys);
+       if (!num_phys) {
+               ioc_err(ioc, "failure at %s:%d/%s()!\n",
+                   __FILE__, __LINE__, __func__);
+               return;
+       }
+
+       if (num_phys > ioc->sas_hba.nr_phys_allocated) {
+               ioc_err(ioc, "failure at %s:%d/%s()!\n",
+                  __FILE__, __LINE__, __func__);
+               return;
+       }
+       ioc->sas_hba.num_phys = num_phys;
+
        port_table = kcalloc(ioc->sas_hba.num_phys,
            sizeof(struct hba_port), GFP_KERNEL);
        if (!port_table)
@@ -6611,6 +6626,30 @@ _scsih_sas_host_refresh(struct MPT3SAS_ADAPTER *ioc)
                        ioc->sas_hba.phy[i].hba_vphy = 1;
                }
 
+               /*
+                * Add new HBA phys to STL if these new phys got added as part
+                * of HBA Firmware upgrade/downgrade operation.
+                */
+               if (!ioc->sas_hba.phy[i].phy) {
+                       if ((mpt3sas_config_get_phy_pg0(ioc, &mpi_reply,
+                                                       &phy_pg0, i))) {
+                               ioc_err(ioc, "failure at %s:%d/%s()!\n",
+                                       __FILE__, __LINE__, __func__);
+                               continue;
+                       }
+                       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+                               MPI2_IOCSTATUS_MASK;
+                       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+                               ioc_err(ioc, "failure at %s:%d/%s()!\n",
+                                       __FILE__, __LINE__, __func__);
+                               continue;
+                       }
+                       ioc->sas_hba.phy[i].phy_id = i;
+                       mpt3sas_transport_add_host_phy(ioc,
+                               &ioc->sas_hba.phy[i], phy_pg0,
+                               ioc->sas_hba.parent_dev);
+                       continue;
+               }
                ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
                attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i].
                    AttachedDevHandle);
@@ -6622,6 +6661,19 @@ _scsih_sas_host_refresh(struct MPT3SAS_ADAPTER *ioc)
                    attached_handle, i, link_rate,
                    ioc->sas_hba.phy[i].port);
        }
+       /*
+        * Clear the phy details if this phy got disabled as part of
+        * HBA Firmware upgrade/downgrade operation.
+        */
+       for (i = ioc->sas_hba.num_phys;
+            i < ioc->sas_hba.nr_phys_allocated; i++) {
+               if (ioc->sas_hba.phy[i].phy &&
+                   ioc->sas_hba.phy[i].phy->negotiated_linkrate >=
+                   SAS_LINK_RATE_1_5_GBPS)
+                       mpt3sas_transport_update_links(ioc,
+                               ioc->sas_hba.sas_address, 0, i,
+                               MPI2_SAS_NEG_LINK_RATE_PHY_DISABLED, NULL);
+       }
  out:
        kfree(sas_iounit_pg0);
 }
@@ -6654,7 +6706,10 @@ _scsih_sas_host_add(struct MPT3SAS_ADAPTER *ioc)
                        __FILE__, __LINE__, __func__);
                return;
        }
-       ioc->sas_hba.phy = kcalloc(num_phys,
+
+       ioc->sas_hba.nr_phys_allocated = max_t(u8,
+           MPT_MAX_HBA_NUM_PHYS, num_phys);
+       ioc->sas_hba.phy = kcalloc(ioc->sas_hba.nr_phys_allocated,
            sizeof(struct _sas_phy), GFP_KERNEL);
        if (!ioc->sas_hba.phy) {
                ioc_err(ioc, "failure at %s:%d/%s()!\n",
index 2e37b18..53d2b85 100644 (file)
@@ -865,7 +865,7 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
                            "APP request entry - portid=%06x.\n", tdid.b24);
 
                        /* Ran out of space */
-                       if (pcnt > app_req.num_ports)
+                       if (pcnt >= app_req.num_ports)
                                break;
 
                        if (tdid.b24 != 0 && tdid.b24 != fcport->d_id.b24)
index 73a3531..10d2655 100644 (file)
@@ -1695,10 +1695,8 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
                mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
        if (IS_FWI2_CAPABLE(vha->hw))
                mcp->in_mb |= MBX_19|MBX_18|MBX_17|MBX_16;
-       if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw)) {
-               mcp->in_mb |= MBX_15;
-               mcp->out_mb |= MBX_7|MBX_21|MBX_22|MBX_23;
-       }
+       if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw))
+               mcp->in_mb |= MBX_15|MBX_21|MBX_22|MBX_23;
 
        mcp->tov = MBX_TOV_SECONDS;
        mcp->flags = 0;
index 1d0278d..3c0da37 100644 (file)
@@ -1189,7 +1189,7 @@ static int p_fill_from_dev_buffer(struct scsi_cmnd *scp, const void *arr,
                 __func__, off_dst, scsi_bufflen(scp), act_len,
                 scsi_get_resid(scp));
        n = scsi_bufflen(scp) - (off_dst + act_len);
-       scsi_set_resid(scp, min_t(int, scsi_get_resid(scp), n));
+       scsi_set_resid(scp, min_t(u32, scsi_get_resid(scp), n));
        return 0;
 }
 
@@ -1562,7 +1562,8 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
        unsigned char pq_pdt;
        unsigned char *arr;
        unsigned char *cmd = scp->cmnd;
-       int alloc_len, n, ret;
+       u32 alloc_len, n;
+       int ret;
        bool have_wlun, is_disk, is_zbc, is_disk_zbc;
 
        alloc_len = get_unaligned_be16(cmd + 3);
@@ -1585,7 +1586,8 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
                kfree(arr);
                return check_condition_result;
        } else if (0x1 & cmd[1]) {  /* EVPD bit set */
-               int lu_id_num, port_group_id, target_dev_id, len;
+               int lu_id_num, port_group_id, target_dev_id;
+               u32 len;
                char lu_id_str[6];
                int host_no = devip->sdbg_host->shost->host_no;
                
@@ -1676,9 +1678,9 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
                        kfree(arr);
                        return check_condition_result;
                }
-               len = min(get_unaligned_be16(arr + 2) + 4, alloc_len);
+               len = min_t(u32, get_unaligned_be16(arr + 2) + 4, alloc_len);
                ret = fill_from_dev_buffer(scp, arr,
-                           min(len, SDEBUG_MAX_INQ_ARR_SZ));
+                           min_t(u32, len, SDEBUG_MAX_INQ_ARR_SZ));
                kfree(arr);
                return ret;
        }
@@ -1714,7 +1716,7 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
        }
        put_unaligned_be16(0x2100, arr + n);    /* SPL-4 no version claimed */
        ret = fill_from_dev_buffer(scp, arr,
-                           min_t(int, alloc_len, SDEBUG_LONG_INQ_SZ));
+                           min_t(u32, alloc_len, SDEBUG_LONG_INQ_SZ));
        kfree(arr);
        return ret;
 }
@@ -1729,8 +1731,8 @@ static int resp_requests(struct scsi_cmnd *scp,
        unsigned char *cmd = scp->cmnd;
        unsigned char arr[SCSI_SENSE_BUFFERSIZE];       /* assume >= 18 bytes */
        bool dsense = !!(cmd[1] & 1);
-       int alloc_len = cmd[4];
-       int len = 18;
+       u32 alloc_len = cmd[4];
+       u32 len = 18;
        int stopped_state = atomic_read(&devip->stopped);
 
        memset(arr, 0, sizeof(arr));
@@ -1774,7 +1776,7 @@ static int resp_requests(struct scsi_cmnd *scp,
                        arr[7] = 0xa;
                }
        }
-       return fill_from_dev_buffer(scp, arr, min_t(int, len, alloc_len));
+       return fill_from_dev_buffer(scp, arr, min_t(u32, len, alloc_len));
 }
 
 static int resp_start_stop(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
@@ -2312,7 +2314,8 @@ static int resp_mode_sense(struct scsi_cmnd *scp,
 {
        int pcontrol, pcode, subpcode, bd_len;
        unsigned char dev_spec;
-       int alloc_len, offset, len, target_dev_id;
+       u32 alloc_len, offset, len;
+       int target_dev_id;
        int target = scp->device->id;
        unsigned char *ap;
        unsigned char arr[SDEBUG_MAX_MSENSE_SZ];
@@ -2468,7 +2471,7 @@ static int resp_mode_sense(struct scsi_cmnd *scp,
                arr[0] = offset - 1;
        else
                put_unaligned_be16((offset - 2), arr + 0);
-       return fill_from_dev_buffer(scp, arr, min_t(int, alloc_len, offset));
+       return fill_from_dev_buffer(scp, arr, min_t(u32, alloc_len, offset));
 }
 
 #define SDEBUG_MAX_MSELECT_SZ 512
@@ -2499,11 +2502,11 @@ static int resp_mode_select(struct scsi_cmnd *scp,
                            __func__, param_len, res);
        md_len = mselect6 ? (arr[0] + 1) : (get_unaligned_be16(arr + 0) + 2);
        bd_len = mselect6 ? arr[3] : get_unaligned_be16(arr + 6);
-       if (md_len > 2) {
+       off = bd_len + (mselect6 ? 4 : 8);
+       if (md_len > 2 || off >= res) {
                mk_sense_invalid_fld(scp, SDEB_IN_DATA, 0, -1);
                return check_condition_result;
        }
-       off = bd_len + (mselect6 ? 4 : 8);
        mpage = arr[off] & 0x3f;
        ps = !!(arr[off] & 0x80);
        if (ps) {
@@ -2583,7 +2586,8 @@ static int resp_ie_l_pg(unsigned char *arr)
 static int resp_log_sense(struct scsi_cmnd *scp,
                          struct sdebug_dev_info *devip)
 {
-       int ppc, sp, pcode, subpcode, alloc_len, len, n;
+       int ppc, sp, pcode, subpcode;
+       u32 alloc_len, len, n;
        unsigned char arr[SDEBUG_MAX_LSENSE_SZ];
        unsigned char *cmd = scp->cmnd;
 
@@ -2653,9 +2657,9 @@ static int resp_log_sense(struct scsi_cmnd *scp,
                mk_sense_invalid_fld(scp, SDEB_IN_CDB, 3, -1);
                return check_condition_result;
        }
-       len = min_t(int, get_unaligned_be16(arr + 2) + 4, alloc_len);
+       len = min_t(u32, get_unaligned_be16(arr + 2) + 4, alloc_len);
        return fill_from_dev_buffer(scp, arr,
-                   min_t(int, len, SDEBUG_MAX_INQ_ARR_SZ));
+                   min_t(u32, len, SDEBUG_MAX_INQ_ARR_SZ));
 }
 
 static inline bool sdebug_dev_is_zoned(struct sdebug_dev_info *devip)
@@ -4430,7 +4434,7 @@ static int resp_report_zones(struct scsi_cmnd *scp,
        put_unaligned_be64(sdebug_capacity - 1, arr + 8);
 
        rep_len = (unsigned long)desc - (unsigned long)arr;
-       ret = fill_from_dev_buffer(scp, arr, min_t(int, alloc_len, rep_len));
+       ret = fill_from_dev_buffer(scp, arr, min_t(u32, alloc_len, rep_len));
 
 fini:
        read_unlock(macc_lckp);
@@ -4653,6 +4657,7 @@ static void zbc_rwp_zone(struct sdebug_dev_info *devip,
                         struct sdeb_zone_state *zsp)
 {
        enum sdebug_z_cond zc;
+       struct sdeb_store_info *sip = devip2sip(devip, false);
 
        if (zbc_zone_is_conv(zsp))
                return;
@@ -4664,6 +4669,10 @@ static void zbc_rwp_zone(struct sdebug_dev_info *devip,
        if (zsp->z_cond == ZC4_CLOSED)
                devip->nr_closed--;
 
+       if (zsp->z_wp > zsp->z_start)
+               memset(sip->storep + zsp->z_start * sdebug_sector_size, 0,
+                      (zsp->z_wp - zsp->z_start) * sdebug_sector_size);
+
        zsp->z_non_seq_resource = false;
        zsp->z_wp = zsp->z_start;
        zsp->z_cond = ZC1_EMPTY;
index 55addd7..d4edce9 100644 (file)
@@ -792,6 +792,7 @@ store_state_field(struct device *dev, struct device_attribute *attr,
        int i, ret;
        struct scsi_device *sdev = to_scsi_device(dev);
        enum scsi_device_state state = 0;
+       bool rescan_dev = false;
 
        for (i = 0; i < ARRAY_SIZE(sdev_states); i++) {
                const int len = strlen(sdev_states[i].name);
@@ -810,20 +811,27 @@ store_state_field(struct device *dev, struct device_attribute *attr,
        }
 
        mutex_lock(&sdev->state_mutex);
-       ret = scsi_device_set_state(sdev, state);
-       /*
-        * If the device state changes to SDEV_RUNNING, we need to
-        * run the queue to avoid I/O hang, and rescan the device
-        * to revalidate it. Running the queue first is necessary
-        * because another thread may be waiting inside
-        * blk_mq_freeze_queue_wait() and because that call may be
-        * waiting for pending I/O to finish.
-        */
-       if (ret == 0 && state == SDEV_RUNNING) {
+       if (sdev->sdev_state == SDEV_RUNNING && state == SDEV_RUNNING) {
+               ret = 0;
+       } else {
+               ret = scsi_device_set_state(sdev, state);
+               if (ret == 0 && state == SDEV_RUNNING)
+                       rescan_dev = true;
+       }
+       mutex_unlock(&sdev->state_mutex);
+
+       if (rescan_dev) {
+               /*
+                * If the device state changes to SDEV_RUNNING, we need to
+                * run the queue to avoid I/O hang, and rescan the device
+                * to revalidate it. Running the queue first is necessary
+                * because another thread may be waiting inside
+                * blk_mq_freeze_queue_wait() and because that call may be
+                * waiting for pending I/O to finish.
+                */
                blk_mq_run_hw_queues(sdev->request_queue, true);
                scsi_rescan_device(dev);
        }
-       mutex_unlock(&sdev->state_mutex);
 
        return ret == 0 ? count : -EINVAL;
 }
index 78343d3..554b6f7 100644 (file)
@@ -1899,12 +1899,12 @@ static void session_recovery_timedout(struct work_struct *work)
        }
        spin_unlock_irqrestore(&session->lock, flags);
 
-       if (session->transport->session_recovery_timedout)
-               session->transport->session_recovery_timedout(session);
-
        ISCSI_DBG_TRANS_SESSION(session, "Unblocking SCSI target\n");
        scsi_target_unblock(&session->dev, SDEV_TRANSPORT_OFFLINE);
        ISCSI_DBG_TRANS_SESSION(session, "Completed unblocking SCSI target\n");
+
+       if (session->transport->session_recovery_timedout)
+               session->transport->session_recovery_timedout(session);
 }
 
 static void __iscsi_unblock_session(struct work_struct *work)
index fc5b214..5393b5c 100644 (file)
@@ -1189,6 +1189,7 @@ static int ufs_mtk_probe(struct platform_device *pdev)
        }
        link = device_link_add(dev, &reset_pdev->dev,
                DL_FLAG_AUTOPROBE_CONSUMER);
+       put_device(&reset_pdev->dev);
        if (!link) {
                dev_notice(dev, "add reset device_link fail\n");
                goto skip_reset;
index afd3814..13c09db 100644 (file)
@@ -6453,9 +6453,8 @@ static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba)
        irqreturn_t ret = IRQ_NONE;
        int tag;
 
-       pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);
-
        spin_lock_irqsave(hba->host->host_lock, flags);
+       pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);
        issued = hba->outstanding_tasks & ~pending;
        for_each_set_bit(tag, &issued, hba->nutmrs) {
                struct request *req = hba->tmf_rqs[tag];
@@ -6616,11 +6615,6 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
        err = wait_for_completion_io_timeout(&wait,
                        msecs_to_jiffies(TM_CMD_TIMEOUT));
        if (!err) {
-               /*
-                * Make sure that ufshcd_compl_tm() does not trigger a
-                * use-after-free.
-                */
-               req->end_io_data = NULL;
                ufshcd_add_tm_upiu_trace(hba, task_tag, UFS_TM_ERR);
                dev_err(hba->dev, "%s: task management cmd 0x%.2x timed-out\n",
                                __func__, tm_function);
@@ -7116,6 +7110,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
                goto release;
        }
 
+       lrbp->cmd = NULL;
        err = SUCCESS;
 
 release:
index 2e31e14..ded5ba9 100644 (file)
@@ -331,7 +331,7 @@ ufshpb_set_hpb_read_to_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp,
        cdb[0] = UFSHPB_READ;
 
        if (hba->dev_quirks & UFS_DEVICE_QUIRK_SWAP_L2P_ENTRY_FOR_HPB_READ)
-               ppn_tmp = swab64(ppn);
+               ppn_tmp = (__force __be64)swab64((__force u64)ppn);
 
        /* ppn value is stored as big-endian in the host memory */
        memcpy(&cdb[6], &ppn_tmp, sizeof(__be64));
index 19f7d7b..28e1d98 100644 (file)
@@ -977,7 +977,6 @@ static unsigned int features[] = {
 static struct virtio_driver virtio_scsi_driver = {
        .feature_table = features,
        .feature_table_size = ARRAY_SIZE(features),
-       .suppress_used_validation = true,
        .driver.name = KBUILD_MODNAME,
        .driver.owner = THIS_MODULE,
        .id_table = id_table,
index 8b3d268..b808c94 100644 (file)
@@ -37,6 +37,7 @@
 #define CQSPI_NEEDS_WR_DELAY           BIT(0)
 #define CQSPI_DISABLE_DAC_MODE         BIT(1)
 #define CQSPI_SUPPORT_EXTERNAL_DMA     BIT(2)
+#define CQSPI_NO_SUPPORT_WR_COMPLETION BIT(3)
 
 /* Capabilities */
 #define CQSPI_SUPPORTS_OCTAL           BIT(0)
@@ -86,6 +87,7 @@ struct cqspi_st {
        struct cqspi_flash_pdata f_pdata[CQSPI_MAX_CHIPSELECT];
        bool                    use_dma_read;
        u32                     pd_dev_id;
+       bool                    wr_completion;
 };
 
 struct cqspi_driver_platdata {
@@ -996,9 +998,11 @@ static int cqspi_write_setup(struct cqspi_flash_pdata *f_pdata,
         * polling on the controller's side. spinand and spi-nor will take
         * care of polling the status register.
         */
-       reg = readl(reg_base + CQSPI_REG_WR_COMPLETION_CTRL);
-       reg |= CQSPI_REG_WR_DISABLE_AUTO_POLL;
-       writel(reg, reg_base + CQSPI_REG_WR_COMPLETION_CTRL);
+       if (cqspi->wr_completion) {
+               reg = readl(reg_base + CQSPI_REG_WR_COMPLETION_CTRL);
+               reg |= CQSPI_REG_WR_DISABLE_AUTO_POLL;
+               writel(reg, reg_base + CQSPI_REG_WR_COMPLETION_CTRL);
+       }
 
        reg = readl(reg_base + CQSPI_REG_SIZE);
        reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
@@ -1736,6 +1740,10 @@ static int cqspi_probe(struct platform_device *pdev)
 
        cqspi->master_ref_clk_hz = clk_get_rate(cqspi->clk);
        master->max_speed_hz = cqspi->master_ref_clk_hz;
+
+       /* write completion is supported by default */
+       cqspi->wr_completion = true;
+
        ddata  = of_device_get_match_data(dev);
        if (ddata) {
                if (ddata->quirks & CQSPI_NEEDS_WR_DELAY)
@@ -1747,6 +1755,8 @@ static int cqspi_probe(struct platform_device *pdev)
                        cqspi->use_direct_mode = true;
                if (ddata->quirks & CQSPI_SUPPORT_EXTERNAL_DMA)
                        cqspi->use_dma_read = true;
+               if (ddata->quirks & CQSPI_NO_SUPPORT_WR_COMPLETION)
+                       cqspi->wr_completion = false;
 
                if (of_device_is_compatible(pdev->dev.of_node,
                                            "xlnx,versal-ospi-1.0"))
@@ -1859,6 +1869,10 @@ static const struct cqspi_driver_platdata intel_lgm_qspi = {
        .quirks = CQSPI_DISABLE_DAC_MODE,
 };
 
+static const struct cqspi_driver_platdata socfpga_qspi = {
+       .quirks = CQSPI_NO_SUPPORT_WR_COMPLETION,
+};
+
 static const struct cqspi_driver_platdata versal_ospi = {
        .hwcaps_mask = CQSPI_SUPPORTS_OCTAL,
        .quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_SUPPORT_EXTERNAL_DMA,
@@ -1887,6 +1901,10 @@ static const struct of_device_id cqspi_dt_ids[] = {
                .compatible = "xlnx,versal-ospi-1.0",
                .data = (void *)&versal_ospi,
        },
+       {
+               .compatible = "intel,socfpga-qspi",
+               .data = (void *)&socfpga_qspi,
+       },
        { /* end of table */ }
 };
 
index 5d98611..c72e501 100644 (file)
@@ -912,7 +912,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
 
        ret = devm_spi_register_controller(&pdev->dev, controller);
        if (ret < 0) {
-               dev_err(&pdev->dev, "spi_register_controller error.\n");
+               dev_err_probe(&pdev->dev, ret, "spi_register_controller error: %i\n", ret);
                goto out_pm_get;
        }
 
index 27a446f..e2affae 100644 (file)
@@ -491,22 +491,26 @@ static int spi_geni_grab_gpi_chan(struct spi_geni_master *mas)
        int ret;
 
        mas->tx = dma_request_chan(mas->dev, "tx");
-       ret = dev_err_probe(mas->dev, IS_ERR(mas->tx), "Failed to get tx DMA ch\n");
-       if (ret < 0)
+       if (IS_ERR(mas->tx)) {
+               ret = dev_err_probe(mas->dev, PTR_ERR(mas->tx),
+                                   "Failed to get tx DMA ch\n");
                goto err_tx;
+       }
 
        mas->rx = dma_request_chan(mas->dev, "rx");
-       ret = dev_err_probe(mas->dev, IS_ERR(mas->rx), "Failed to get rx DMA ch\n");
-       if (ret < 0)
+       if (IS_ERR(mas->rx)) {
+               ret = dev_err_probe(mas->dev, PTR_ERR(mas->rx),
+                                   "Failed to get rx DMA ch\n");
                goto err_rx;
+       }
 
        return 0;
 
 err_rx:
+       mas->rx = NULL;
        dma_release_channel(mas->tx);
-       mas->tx = NULL;
 err_tx:
-       mas->rx = NULL;
+       mas->tx = NULL;
        return ret;
 }
 
index b23e675..fdd530b 100644 (file)
@@ -3099,12 +3099,6 @@ void spi_unregister_controller(struct spi_controller *ctlr)
 
        device_del(&ctlr->dev);
 
-       /* Release the last reference on the controller if its driver
-        * has not yet been converted to devm_spi_alloc_master/slave().
-        */
-       if (!ctlr->devm_allocated)
-               put_device(&ctlr->dev);
-
        /* free bus id */
        mutex_lock(&board_lock);
        if (found == ctlr)
@@ -3113,6 +3107,12 @@ void spi_unregister_controller(struct spi_controller *ctlr)
 
        if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
                mutex_unlock(&ctlr->add_lock);
+
+       /* Release the last reference on the controller if its driver
+        * has not yet been converted to devm_spi_alloc_master/slave().
+        */
+       if (!ctlr->devm_allocated)
+               put_device(&ctlr->dev);
 }
 EXPORT_SYMBOL_GPL(spi_unregister_controller);
 
index 59af251..7fec869 100644 (file)
@@ -66,8 +66,6 @@ source "drivers/staging/gdm724x/Kconfig"
 
 source "drivers/staging/fwserial/Kconfig"
 
-source "drivers/staging/netlogic/Kconfig"
-
 source "drivers/staging/gs_fpgaboot/Kconfig"
 
 source "drivers/staging/unisys/Kconfig"
index 76f4134..e66e19c 100644 (file)
@@ -10,7 +10,6 @@ obj-$(CONFIG_RTL8723BS)               += rtl8723bs/
 obj-$(CONFIG_R8712U)           += rtl8712/
 obj-$(CONFIG_R8188EU)          += r8188eu/
 obj-$(CONFIG_RTS5208)          += rts5208/
-obj-$(CONFIG_NETLOGIC_XLR_NET) += netlogic/
 obj-$(CONFIG_OCTEON_ETHERNET)  += octeon/
 obj-$(CONFIG_OCTEON_USB)       += octeon-usb/
 obj-$(CONFIG_VT6655)           += vt6655/
index cf263a5..6fd549a 100644 (file)
@@ -187,7 +187,6 @@ static struct fbtft_display display = {
        },
 };
 
-#ifdef CONFIG_FB_BACKLIGHT
 static int update_onboard_backlight(struct backlight_device *bd)
 {
        struct fbtft_par *par = bl_get_data(bd);
@@ -231,9 +230,6 @@ static void register_onboard_backlight(struct fbtft_par *par)
        if (!par->fbtftops.unregister_backlight)
                par->fbtftops.unregister_backlight = fbtft_unregister_backlight;
 }
-#else
-static void register_onboard_backlight(struct fbtft_par *par) { };
-#endif
 
 FBTFT_REGISTER_DRIVER(DRVNAME, "solomon,ssd1351", &display);
 
index ecb5f75..f2684d2 100644 (file)
@@ -128,7 +128,6 @@ static int fbtft_request_gpios(struct fbtft_par *par)
        return 0;
 }
 
-#ifdef CONFIG_FB_BACKLIGHT
 static int fbtft_backlight_update_status(struct backlight_device *bd)
 {
        struct fbtft_par *par = bl_get_data(bd);
@@ -161,6 +160,7 @@ void fbtft_unregister_backlight(struct fbtft_par *par)
                par->info->bl_dev = NULL;
        }
 }
+EXPORT_SYMBOL(fbtft_unregister_backlight);
 
 static const struct backlight_ops fbtft_bl_ops = {
        .get_brightness = fbtft_backlight_get_brightness,
@@ -198,12 +198,7 @@ void fbtft_register_backlight(struct fbtft_par *par)
        if (!par->fbtftops.unregister_backlight)
                par->fbtftops.unregister_backlight = fbtft_unregister_backlight;
 }
-#else
-void fbtft_register_backlight(struct fbtft_par *par) { };
-void fbtft_unregister_backlight(struct fbtft_par *par) { };
-#endif
 EXPORT_SYMBOL(fbtft_register_backlight);
-EXPORT_SYMBOL(fbtft_unregister_backlight);
 
 static void fbtft_set_addr_win(struct fbtft_par *par, int xs, int ys, int xe,
                               int ye)
@@ -853,13 +848,11 @@ int fbtft_register_framebuffer(struct fb_info *fb_info)
                 fb_info->fix.smem_len >> 10, text1,
                 HZ / fb_info->fbdefio->delay, text2);
 
-#ifdef CONFIG_FB_BACKLIGHT
        /* Turn on backlight if available */
        if (fb_info->bl_dev) {
                fb_info->bl_dev->props.power = FB_BLANK_UNBLANK;
                fb_info->bl_dev->ops->update_status(fb_info->bl_dev);
        }
-#endif
 
        return 0;
 
index 1ed4772..8437606 100644 (file)
@@ -192,7 +192,11 @@ int gbaudio_remove_component_controls(struct snd_soc_component *component,
                                      unsigned int num_controls)
 {
        struct snd_card *card = component->card->snd_card;
+       int err;
 
-       return gbaudio_remove_controls(card, component->dev, controls,
-                                      num_controls, component->name_prefix);
+       down_write(&card->controls_rwsem);
+       err = gbaudio_remove_controls(card, component->dev, controls,
+                                     num_controls, component->name_prefix);
+       up_write(&card->controls_rwsem);
+       return err;
 }
diff --git a/drivers/staging/netlogic/Kconfig b/drivers/staging/netlogic/Kconfig
deleted file mode 100644 (file)
index e171260..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-config NETLOGIC_XLR_NET
-       tristate "Netlogic XLR/XLS network device"
-       depends on CPU_XLR
-       depends on NETDEVICES
-       select PHYLIB
-       help
-       This driver support Netlogic XLR/XLS on chip gigabit
-       Ethernet.
diff --git a/drivers/staging/netlogic/Makefile b/drivers/staging/netlogic/Makefile
deleted file mode 100644 (file)
index 7e2902a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_NETLOGIC_XLR_NET) += xlr_net.o platform_net.o
diff --git a/drivers/staging/netlogic/TODO b/drivers/staging/netlogic/TODO
deleted file mode 100644 (file)
index 20e22ec..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-* Implementing 64bit stat counter in software
-* All memory allocation should be changed to DMA allocations
-* Changing comments into linux standard format
-
-Please send patches
-To:
-Ganesan Ramalingam <ganesanr@broadcom.com>
-Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Cc:
-Jayachandran Chandrashekaran Nair <jchandra@broadcom.com>
-
diff --git a/drivers/staging/netlogic/platform_net.c b/drivers/staging/netlogic/platform_net.c
deleted file mode 100644 (file)
index 8be9d0b..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-/*
- * Copyright (c) 2003-2012 Broadcom Corporation
- * All Rights Reserved
- */
-
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/resource.h>
-#include <linux/phy.h>
-
-#include <asm/netlogic/haldefs.h>
-#include <asm/netlogic/common.h>
-#include <asm/netlogic/xlr/fmn.h>
-#include <asm/netlogic/xlr/xlr.h>
-#include <asm/netlogic/psb-bootinfo.h>
-#include <asm/netlogic/xlr/pic.h>
-#include <asm/netlogic/xlr/iomap.h>
-
-#include "platform_net.h"
-
-/* Linux Net */
-#define MAX_NUM_GMAC           8
-#define MAX_NUM_XLS_GMAC       8
-#define MAX_NUM_XLR_GMAC       4
-
-static u32 xlr_gmac_offsets[] = {
-       NETLOGIC_IO_GMAC_0_OFFSET, NETLOGIC_IO_GMAC_1_OFFSET,
-       NETLOGIC_IO_GMAC_2_OFFSET, NETLOGIC_IO_GMAC_3_OFFSET,
-       NETLOGIC_IO_GMAC_4_OFFSET, NETLOGIC_IO_GMAC_5_OFFSET,
-       NETLOGIC_IO_GMAC_6_OFFSET, NETLOGIC_IO_GMAC_7_OFFSET
-};
-
-static u32 xlr_gmac_irqs[] = { PIC_GMAC_0_IRQ, PIC_GMAC_1_IRQ,
-       PIC_GMAC_2_IRQ, PIC_GMAC_3_IRQ,
-       PIC_GMAC_4_IRQ, PIC_GMAC_5_IRQ,
-       PIC_GMAC_6_IRQ, PIC_GMAC_7_IRQ
-};
-
-static struct resource xlr_net0_res[8];
-static struct resource xlr_net1_res[8];
-static u32 __iomem *gmac4_addr;
-static u32 __iomem *gpio_addr;
-
-static void xlr_resource_init(struct resource *res, int offset, int irq)
-{
-       res->name = "gmac";
-
-       res->start = CPHYSADDR(nlm_mmio_base(offset));
-       res->end = res->start + 0xfff;
-       res->flags = IORESOURCE_MEM;
-
-       res++;
-       res->name = "gmac";
-       res->start = irq;
-       res->end = irq;
-       res->flags = IORESOURCE_IRQ;
-}
-
-static struct platform_device *gmac_controller2_init(void *gmac0_addr)
-{
-       int mac;
-       static struct xlr_net_data ndata1 = {
-               .phy_interface  = PHY_INTERFACE_MODE_SGMII,
-               .rfr_station    = FMN_STNID_GMAC1_FR_0,
-               .bucket_size    = xlr_board_fmn_config.bucket_size,
-               .gmac_fmn_info  = &xlr_board_fmn_config.gmac[1],
-       };
-
-       static struct platform_device xlr_net_dev1 = {
-               .name           = "xlr-net",
-               .id             = 1,
-               .dev.platform_data = &ndata1,
-       };
-
-       gmac4_addr =
-               ioremap(CPHYSADDR(nlm_mmio_base(NETLOGIC_IO_GMAC_4_OFFSET)),
-                       0xfff);
-       ndata1.serdes_addr = gmac4_addr;
-       ndata1.pcs_addr = gmac4_addr;
-       ndata1.mii_addr = gmac0_addr;
-       ndata1.gpio_addr = gpio_addr;
-       ndata1.cpu_mask = nlm_current_node()->coremask;
-
-       xlr_net_dev1.resource = xlr_net1_res;
-
-       for (mac = 0; mac < 4; mac++) {
-               ndata1.tx_stnid[mac] = FMN_STNID_GMAC1_TX0 + mac;
-               ndata1.phy_addr[mac] = mac + 4 + 0x10;
-
-               xlr_resource_init(&xlr_net1_res[mac * 2],
-                                 xlr_gmac_offsets[mac + 4],
-                                 xlr_gmac_irqs[mac + 4]);
-       }
-       xlr_net_dev1.num_resources = 8;
-
-       return &xlr_net_dev1;
-}
-
-static void xls_gmac_init(void)
-{
-       int mac;
-       struct platform_device *xlr_net_dev1;
-       void __iomem *gmac0_addr =
-               ioremap(CPHYSADDR(nlm_mmio_base(NETLOGIC_IO_GMAC_0_OFFSET)),
-                       0xfff);
-
-       static struct xlr_net_data ndata0 = {
-               .rfr_station    = FMN_STNID_GMACRFR_0,
-               .bucket_size    = xlr_board_fmn_config.bucket_size,
-               .gmac_fmn_info  = &xlr_board_fmn_config.gmac[0],
-       };
-
-       static struct platform_device xlr_net_dev0 = {
-               .name           = "xlr-net",
-               .id             = 0,
-       };
-       xlr_net_dev0.dev.platform_data = &ndata0;
-       ndata0.serdes_addr = gmac0_addr;
-       ndata0.pcs_addr = gmac0_addr;
-       ndata0.mii_addr = gmac0_addr;
-
-       /* Passing GPIO base for serdes init. Only needed on sgmii ports */
-       gpio_addr =
-               ioremap(CPHYSADDR(nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET)),
-                       0xfff);
-       ndata0.gpio_addr = gpio_addr;
-       ndata0.cpu_mask = nlm_current_node()->coremask;
-
-       xlr_net_dev0.resource = xlr_net0_res;
-
-       switch (nlm_prom_info.board_major_version) {
-       case 12:
-               /* first block RGMII or XAUI, use RGMII */
-               ndata0.phy_interface = PHY_INTERFACE_MODE_RGMII;
-               ndata0.tx_stnid[0] = FMN_STNID_GMAC0_TX0;
-               ndata0.phy_addr[0] = 0;
-
-               xlr_net_dev0.num_resources = 2;
-
-               xlr_resource_init(&xlr_net0_res[0], xlr_gmac_offsets[0],
-                                 xlr_gmac_irqs[0]);
-               platform_device_register(&xlr_net_dev0);
-
-               /* second block is XAUI, not supported yet */
-               break;
-       default:
-               /* default XLS config, all ports SGMII */
-               ndata0.phy_interface = PHY_INTERFACE_MODE_SGMII;
-               for (mac = 0; mac < 4; mac++) {
-                       ndata0.tx_stnid[mac] = FMN_STNID_GMAC0_TX0 + mac;
-                       ndata0.phy_addr[mac] = mac + 0x10;
-
-                       xlr_resource_init(&xlr_net0_res[mac * 2],
-                                         xlr_gmac_offsets[mac],
-                                       xlr_gmac_irqs[mac]);
-               }
-               xlr_net_dev0.num_resources = 8;
-               platform_device_register(&xlr_net_dev0);
-
-               xlr_net_dev1 = gmac_controller2_init(gmac0_addr);
-               platform_device_register(xlr_net_dev1);
-       }
-}
-
-static void xlr_gmac_init(void)
-{
-       int mac;
-
-       /* assume all GMACs for now */
-       static struct xlr_net_data ndata0 = {
-               .phy_interface  = PHY_INTERFACE_MODE_RGMII,
-               .serdes_addr    = NULL,
-               .pcs_addr       = NULL,
-               .rfr_station    = FMN_STNID_GMACRFR_0,
-               .bucket_size    = xlr_board_fmn_config.bucket_size,
-               .gmac_fmn_info  = &xlr_board_fmn_config.gmac[0],
-               .gpio_addr      = NULL,
-       };
-
-       static struct platform_device xlr_net_dev0 = {
-               .name           = "xlr-net",
-               .id             = 0,
-               .dev.platform_data = &ndata0,
-       };
-       ndata0.mii_addr =
-               ioremap(CPHYSADDR(nlm_mmio_base(NETLOGIC_IO_GMAC_0_OFFSET)),
-                       0xfff);
-
-       ndata0.cpu_mask = nlm_current_node()->coremask;
-
-       for (mac = 0; mac < MAX_NUM_XLR_GMAC; mac++) {
-               ndata0.tx_stnid[mac] = FMN_STNID_GMAC0_TX0 + mac;
-               ndata0.phy_addr[mac] = mac;
-               xlr_resource_init(&xlr_net0_res[mac * 2], xlr_gmac_offsets[mac],
-                                 xlr_gmac_irqs[mac]);
-       }
-       xlr_net_dev0.num_resources = 8;
-       xlr_net_dev0.resource = xlr_net0_res;
-
-       platform_device_register(&xlr_net_dev0);
-}
-
-static int __init xlr_net_init(void)
-{
-       if (nlm_chip_is_xls())
-               xls_gmac_init();
-       else
-               xlr_gmac_init();
-
-       return 0;
-}
-
-arch_initcall(xlr_net_init);
diff --git a/drivers/staging/netlogic/platform_net.h b/drivers/staging/netlogic/platform_net.h
deleted file mode 100644 (file)
index c8d4c13..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) */
-/*
- * Copyright (c) 2003-2012 Broadcom Corporation
- * All Rights Reserved
- */
-
-#define PORTS_PER_CONTROLLER           4
-
-struct xlr_net_data {
-       int cpu_mask;
-       u32 __iomem *mii_addr;
-       u32 __iomem *serdes_addr;
-       u32 __iomem *pcs_addr;
-       u32 __iomem *gpio_addr;
-       int phy_interface;
-       int rfr_station;
-       int tx_stnid[PORTS_PER_CONTROLLER];
-       int *bucket_size;
-       int phy_addr[PORTS_PER_CONTROLLER];
-       struct xlr_fmn_info *gmac_fmn_info;
-};
diff --git a/drivers/staging/netlogic/xlr_net.c b/drivers/staging/netlogic/xlr_net.c
deleted file mode 100644 (file)
index 69ea61f..0000000
+++ /dev/null
@@ -1,1080 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-/*
- * Copyright (c) 2003-2012 Broadcom Corporation
- * All Rights Reserved
- */
-
-#include <linux/phy.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/smp.h>
-#include <linux/ethtool.h>
-#include <linux/module.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/jiffies.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-
-#include <asm/mipsregs.h>
-/*
- * fmn.h - For FMN credit configuration and registering fmn_handler.
- * FMN is communication mechanism that allows processing agents within
- * XLR/XLS to communicate each other.
- */
-#include <asm/netlogic/xlr/fmn.h>
-
-#include "platform_net.h"
-#include "xlr_net.h"
-
-/*
- * The readl/writel implementation byteswaps on XLR/XLS, so
- * we need to use __raw_ IO to read the NAE registers
- * because they are in the big-endian MMIO area on the SoC.
- */
-static inline void xlr_nae_wreg(u32 __iomem *base, unsigned int reg, u32 val)
-{
-       __raw_writel(val, base + reg);
-}
-
-static inline u32 xlr_nae_rdreg(u32 __iomem *base, unsigned int reg)
-{
-       return __raw_readl(base + reg);
-}
-
-static inline void xlr_reg_update(u32 *base_addr, u32 off, u32 val, u32 mask)
-{
-       u32 tmp;
-
-       tmp = xlr_nae_rdreg(base_addr, off);
-       xlr_nae_wreg(base_addr, off, (tmp & ~mask) | (val & mask));
-}
-
-#define MAC_SKB_BACK_PTR_SIZE SMP_CACHE_BYTES
-
-static int send_to_rfr_fifo(struct xlr_net_priv *priv, void *addr)
-{
-       struct nlm_fmn_msg msg;
-       int ret = 0, num_try = 0, stnid;
-       unsigned long paddr, mflags;
-
-       paddr = virt_to_bus(addr);
-       msg.msg0 = (u64)paddr & 0xffffffffe0ULL;
-       msg.msg1 = 0;
-       msg.msg2 = 0;
-       msg.msg3 = 0;
-       stnid = priv->nd->rfr_station;
-       do {
-               mflags = nlm_cop2_enable_irqsave();
-               ret = nlm_fmn_send(1, 0, stnid, &msg);
-               nlm_cop2_disable_irqrestore(mflags);
-               if (ret == 0)
-                       return 0;
-       } while (++num_try < 10000);
-
-       netdev_err(priv->ndev, "Send to RFR failed in RX path\n");
-       return ret;
-}
-
-static inline unsigned char *xlr_alloc_skb(void)
-{
-       struct sk_buff *skb;
-       int buf_len = sizeof(struct sk_buff *);
-       unsigned char *skb_data;
-
-       /* skb->data is cache aligned */
-       skb = alloc_skb(XLR_RX_BUF_SIZE, GFP_ATOMIC);
-       if (!skb)
-               return NULL;
-       skb_data = skb->data;
-       skb_reserve(skb, MAC_SKB_BACK_PTR_SIZE);
-       memcpy(skb_data, &skb, buf_len);
-
-       return skb->data;
-}
-
-static void xlr_net_fmn_handler(int bkt, int src_stnid, int size, int code,
-                               struct nlm_fmn_msg *msg, void *arg)
-{
-       struct sk_buff *skb;
-       void *skb_data = NULL;
-       struct net_device *ndev;
-       struct xlr_net_priv *priv;
-       u32 port, length;
-       unsigned char *addr;
-       struct xlr_adapter *adapter = arg;
-
-       length = (msg->msg0 >> 40) & 0x3fff;
-       if (length == 0) {
-               addr = bus_to_virt(msg->msg0 & 0xffffffffffULL);
-               addr = addr - MAC_SKB_BACK_PTR_SIZE;
-               skb = (struct sk_buff *)(*(unsigned long *)addr);
-               dev_kfree_skb_any((struct sk_buff *)addr);
-       } else {
-               addr = (unsigned char *)
-                       bus_to_virt(msg->msg0 & 0xffffffffe0ULL);
-               length = length - BYTE_OFFSET - MAC_CRC_LEN;
-               port = ((int)msg->msg0) & 0x0f;
-               addr = addr - MAC_SKB_BACK_PTR_SIZE;
-               skb = (struct sk_buff *)(*(unsigned long *)addr);
-               skb->dev = adapter->netdev[port];
-               if (!skb->dev)
-                       return;
-               ndev = skb->dev;
-               priv = netdev_priv(ndev);
-
-               /* 16 byte IP header align */
-               skb_reserve(skb, BYTE_OFFSET);
-               skb_put(skb, length);
-               skb->protocol = eth_type_trans(skb, skb->dev);
-               netif_rx(skb);
-               /* Fill rx ring */
-               skb_data = xlr_alloc_skb();
-               if (skb_data)
-                       send_to_rfr_fifo(priv, skb_data);
-       }
-}
-
-static struct phy_device *xlr_get_phydev(struct xlr_net_priv *priv)
-{
-       return mdiobus_get_phy(priv->mii_bus, priv->phy_addr);
-}
-
-/*
- * Ethtool operation
- */
-static int xlr_get_link_ksettings(struct net_device *ndev,
-                                 struct ethtool_link_ksettings *ecmd)
-{
-       struct xlr_net_priv *priv = netdev_priv(ndev);
-       struct phy_device *phydev = xlr_get_phydev(priv);
-
-       if (!phydev)
-               return -ENODEV;
-
-       phy_ethtool_ksettings_get(phydev, ecmd);
-
-       return 0;
-}
-
-static int xlr_set_link_ksettings(struct net_device *ndev,
-                                 const struct ethtool_link_ksettings *ecmd)
-{
-       struct xlr_net_priv *priv = netdev_priv(ndev);
-       struct phy_device *phydev = xlr_get_phydev(priv);
-
-       if (!phydev)
-               return -ENODEV;
-       return phy_ethtool_ksettings_set(phydev, ecmd);
-}
-
-static const struct ethtool_ops xlr_ethtool_ops = {
-       .get_link_ksettings = xlr_get_link_ksettings,
-       .set_link_ksettings = xlr_set_link_ksettings,
-};
-
-/*
- * Net operations
- */
-static int xlr_net_fill_rx_ring(struct net_device *ndev)
-{
-       void *skb_data;
-       struct xlr_net_priv *priv = netdev_priv(ndev);
-       int i;
-
-       for (i = 0; i < MAX_FRIN_SPILL / 4; i++) {
-               skb_data = xlr_alloc_skb();
-               if (!skb_data)
-                       return -ENOMEM;
-               send_to_rfr_fifo(priv, skb_data);
-       }
-       netdev_info(ndev, "Rx ring setup done\n");
-       return 0;
-}
-
-static int xlr_net_open(struct net_device *ndev)
-{
-       u32 err;
-       struct xlr_net_priv *priv = netdev_priv(ndev);
-       struct phy_device *phydev = xlr_get_phydev(priv);
-
-       /* schedule a link state check */
-       phy_start(phydev);
-
-       err = phy_start_aneg(phydev);
-       if (err) {
-               pr_err("Autoneg failed\n");
-               return err;
-       }
-       /* Setup the speed from PHY to internal reg*/
-       xlr_set_gmac_speed(priv);
-
-       netif_tx_start_all_queues(ndev);
-
-       return 0;
-}
-
-static int xlr_net_stop(struct net_device *ndev)
-{
-       struct xlr_net_priv *priv = netdev_priv(ndev);
-       struct phy_device *phydev = xlr_get_phydev(priv);
-
-       phy_stop(phydev);
-       netif_tx_stop_all_queues(ndev);
-       return 0;
-}
-
-static void xlr_make_tx_desc(struct nlm_fmn_msg *msg, unsigned long addr,
-                            struct sk_buff *skb)
-{
-       unsigned long physkb = virt_to_phys(skb);
-       int cpu_core = nlm_core_id();
-       int fr_stn_id = cpu_core * 8 + XLR_FB_STN;      /* FB to 6th bucket */
-
-       msg->msg0 = (((u64)1 << 63)     |       /* End of packet descriptor */
-               ((u64)127 << 54)        |       /* No Free back */
-               (u64)skb->len << 40     |       /* Length of data */
-               ((u64)addr));
-       msg->msg1 = (((u64)1 << 63)     |
-               ((u64)fr_stn_id << 54)  |       /* Free back id */
-               (u64)0 << 40            |       /* Set len to 0 */
-               ((u64)physkb  & 0xffffffff));   /* 32bit address */
-       msg->msg2 = 0;
-       msg->msg3 = 0;
-}
-
-static netdev_tx_t xlr_net_start_xmit(struct sk_buff *skb,
-                                     struct net_device *ndev)
-{
-       struct nlm_fmn_msg msg;
-       struct xlr_net_priv *priv = netdev_priv(ndev);
-       int ret;
-       u32 flags;
-
-       xlr_make_tx_desc(&msg, virt_to_phys(skb->data), skb);
-       flags = nlm_cop2_enable_irqsave();
-       ret = nlm_fmn_send(2, 0, priv->tx_stnid, &msg);
-       nlm_cop2_disable_irqrestore(flags);
-       if (ret)
-               dev_kfree_skb_any(skb);
-       return NETDEV_TX_OK;
-}
-
-static void xlr_hw_set_mac_addr(struct net_device *ndev)
-{
-       struct xlr_net_priv *priv = netdev_priv(ndev);
-
-       /* set mac station address */
-       xlr_nae_wreg(priv->base_addr, R_MAC_ADDR0,
-                    ((ndev->dev_addr[5] << 24) | (ndev->dev_addr[4] << 16) |
-                    (ndev->dev_addr[3] << 8) | (ndev->dev_addr[2])));
-       xlr_nae_wreg(priv->base_addr, R_MAC_ADDR0 + 1,
-                    ((ndev->dev_addr[1] << 24) | (ndev->dev_addr[0] << 16)));
-
-       xlr_nae_wreg(priv->base_addr, R_MAC_ADDR_MASK2, 0xffffffff);
-       xlr_nae_wreg(priv->base_addr, R_MAC_ADDR_MASK2 + 1, 0xffffffff);
-       xlr_nae_wreg(priv->base_addr, R_MAC_ADDR_MASK3, 0xffffffff);
-       xlr_nae_wreg(priv->base_addr, R_MAC_ADDR_MASK3 + 1, 0xffffffff);
-
-       xlr_nae_wreg(priv->base_addr, R_MAC_FILTER_CONFIG,
-                    (1 << O_MAC_FILTER_CONFIG__BROADCAST_EN) |
-                    (1 << O_MAC_FILTER_CONFIG__ALL_MCAST_EN) |
-                    (1 << O_MAC_FILTER_CONFIG__MAC_ADDR0_VALID));
-
-       if (priv->nd->phy_interface == PHY_INTERFACE_MODE_RGMII ||
-           priv->nd->phy_interface == PHY_INTERFACE_MODE_SGMII)
-               xlr_reg_update(priv->base_addr, R_IPG_IFG, MAC_B2B_IPG, 0x7f);
-}
-
-static int xlr_net_set_mac_addr(struct net_device *ndev, void *data)
-{
-       int err;
-
-       err = eth_mac_addr(ndev, data);
-       if (err)
-               return err;
-       xlr_hw_set_mac_addr(ndev);
-       return 0;
-}
-
-static void xlr_set_rx_mode(struct net_device *ndev)
-{
-       struct xlr_net_priv *priv = netdev_priv(ndev);
-       u32 regval;
-
-       regval = xlr_nae_rdreg(priv->base_addr, R_MAC_FILTER_CONFIG);
-
-       if (ndev->flags & IFF_PROMISC) {
-               regval |= (1 << O_MAC_FILTER_CONFIG__BROADCAST_EN) |
-               (1 << O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN) |
-               (1 << O_MAC_FILTER_CONFIG__ALL_MCAST_EN) |
-               (1 << O_MAC_FILTER_CONFIG__ALL_UCAST_EN);
-       } else {
-               regval &= ~((1 << O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN) |
-               (1 << O_MAC_FILTER_CONFIG__ALL_UCAST_EN));
-       }
-
-       xlr_nae_wreg(priv->base_addr, R_MAC_FILTER_CONFIG, regval);
-}
-
-static void xlr_stats(struct net_device *ndev, struct rtnl_link_stats64 *stats)
-{
-       struct xlr_net_priv *priv = netdev_priv(ndev);
-
-       stats->rx_packets = xlr_nae_rdreg(priv->base_addr, RX_PACKET_COUNTER);
-       stats->tx_packets = xlr_nae_rdreg(priv->base_addr, TX_PACKET_COUNTER);
-       stats->rx_bytes = xlr_nae_rdreg(priv->base_addr, RX_BYTE_COUNTER);
-       stats->tx_bytes = xlr_nae_rdreg(priv->base_addr, TX_BYTE_COUNTER);
-       stats->tx_errors = xlr_nae_rdreg(priv->base_addr, TX_FCS_ERROR_COUNTER);
-       stats->rx_dropped = xlr_nae_rdreg(priv->base_addr,
-                                         RX_DROP_PACKET_COUNTER);
-       stats->tx_dropped = xlr_nae_rdreg(priv->base_addr,
-                                         TX_DROP_FRAME_COUNTER);
-
-       stats->multicast = xlr_nae_rdreg(priv->base_addr,
-                                        RX_MULTICAST_PACKET_COUNTER);
-       stats->collisions = xlr_nae_rdreg(priv->base_addr,
-                                         TX_TOTAL_COLLISION_COUNTER);
-
-       stats->rx_length_errors = xlr_nae_rdreg(priv->base_addr,
-                                               RX_FRAME_LENGTH_ERROR_COUNTER);
-       stats->rx_over_errors = xlr_nae_rdreg(priv->base_addr,
-                                             RX_DROP_PACKET_COUNTER);
-       stats->rx_crc_errors = xlr_nae_rdreg(priv->base_addr,
-                                            RX_FCS_ERROR_COUNTER);
-       stats->rx_frame_errors = xlr_nae_rdreg(priv->base_addr,
-                                              RX_ALIGNMENT_ERROR_COUNTER);
-
-       stats->rx_fifo_errors = xlr_nae_rdreg(priv->base_addr,
-                                             RX_DROP_PACKET_COUNTER);
-       stats->rx_missed_errors = xlr_nae_rdreg(priv->base_addr,
-                                               RX_CARRIER_SENSE_ERROR_COUNTER);
-
-       stats->rx_errors = (stats->rx_over_errors + stats->rx_crc_errors +
-                           stats->rx_frame_errors + stats->rx_fifo_errors +
-                           stats->rx_missed_errors);
-
-       stats->tx_aborted_errors = xlr_nae_rdreg(priv->base_addr,
-                                                TX_EXCESSIVE_COLLISION_PACKET_COUNTER);
-       stats->tx_carrier_errors = xlr_nae_rdreg(priv->base_addr,
-                                                TX_DROP_FRAME_COUNTER);
-       stats->tx_fifo_errors = xlr_nae_rdreg(priv->base_addr,
-                                             TX_DROP_FRAME_COUNTER);
-}
-
-static const struct net_device_ops xlr_netdev_ops = {
-       .ndo_open = xlr_net_open,
-       .ndo_stop = xlr_net_stop,
-       .ndo_start_xmit = xlr_net_start_xmit,
-       .ndo_select_queue = dev_pick_tx_cpu_id,
-       .ndo_set_mac_address = xlr_net_set_mac_addr,
-       .ndo_set_rx_mode = xlr_set_rx_mode,
-       .ndo_get_stats64 = xlr_stats,
-};
-
-/*
- * Gmac init
- */
-static void *xlr_config_spill(struct xlr_net_priv *priv, int reg_start_0,
-                             int reg_start_1, int reg_size, int size)
-{
-       void *spill;
-       u32 *base;
-       unsigned long phys_addr;
-       u32 spill_size;
-
-       base = priv->base_addr;
-       spill_size = size;
-       spill = kmalloc(spill_size + SMP_CACHE_BYTES, GFP_KERNEL);
-       if (!spill)
-               return ZERO_SIZE_PTR;
-
-       spill = PTR_ALIGN(spill, SMP_CACHE_BYTES);
-       phys_addr = virt_to_phys(spill);
-       dev_dbg(&priv->ndev->dev, "Allocated spill %d bytes at %lx\n",
-               size, phys_addr);
-       xlr_nae_wreg(base, reg_start_0, (phys_addr >> 5) & 0xffffffff);
-       xlr_nae_wreg(base, reg_start_1, ((u64)phys_addr >> 37) & 0x07);
-       xlr_nae_wreg(base, reg_size, spill_size);
-
-       return spill;
-}
-
-/*
- * Configure the 6 FIFO's that are used by the network accelarator to
- * communicate with the rest of the XLx device. 4 of the FIFO's are for
- * packets from NA --> cpu (called Class FIFO's) and 2 are for feeding
- * the NA with free descriptors.
- */
-static void xlr_config_fifo_spill_area(struct xlr_net_priv *priv)
-{
-       priv->frin_spill = xlr_config_spill(priv,
-                                           R_REG_FRIN_SPILL_MEM_START_0,
-                                           R_REG_FRIN_SPILL_MEM_START_1,
-                                           R_REG_FRIN_SPILL_MEM_SIZE,
-                                           MAX_FRIN_SPILL * sizeof(u64));
-       priv->frout_spill = xlr_config_spill(priv,
-                                            R_FROUT_SPILL_MEM_START_0,
-                                            R_FROUT_SPILL_MEM_START_1,
-                                            R_FROUT_SPILL_MEM_SIZE,
-                                            MAX_FROUT_SPILL * sizeof(u64));
-       priv->class_0_spill = xlr_config_spill(priv,
-                                              R_CLASS0_SPILL_MEM_START_0,
-                                              R_CLASS0_SPILL_MEM_START_1,
-                                              R_CLASS0_SPILL_MEM_SIZE,
-                                              MAX_CLASS_0_SPILL * sizeof(u64));
-       priv->class_1_spill = xlr_config_spill(priv,
-                                              R_CLASS1_SPILL_MEM_START_0,
-                                              R_CLASS1_SPILL_MEM_START_1,
-                                              R_CLASS1_SPILL_MEM_SIZE,
-                                              MAX_CLASS_1_SPILL * sizeof(u64));
-       priv->class_2_spill = xlr_config_spill(priv,
-                                              R_CLASS2_SPILL_MEM_START_0,
-                                              R_CLASS2_SPILL_MEM_START_1,
-                                              R_CLASS2_SPILL_MEM_SIZE,
-                                              MAX_CLASS_2_SPILL * sizeof(u64));
-       priv->class_3_spill = xlr_config_spill(priv,
-                                              R_CLASS3_SPILL_MEM_START_0,
-                                              R_CLASS3_SPILL_MEM_START_1,
-                                              R_CLASS3_SPILL_MEM_SIZE,
-                                              MAX_CLASS_3_SPILL * sizeof(u64));
-}
-
-/*
- * Configure PDE to Round-Robin distribution of packets to the
- * available cpu
- */
-static void xlr_config_pde(struct xlr_net_priv *priv)
-{
-       int i = 0;
-       u64 bkt_map = 0;
-
-       /* Each core has 8 buckets(station) */
-       for (i = 0; i < hweight32(priv->nd->cpu_mask); i++)
-               bkt_map |= (0xff << (i * 8));
-
-       xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_0, (bkt_map & 0xffffffff));
-       xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_0 + 1,
-                    ((bkt_map >> 32) & 0xffffffff));
-
-       xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_1, (bkt_map & 0xffffffff));
-       xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_1 + 1,
-                    ((bkt_map >> 32) & 0xffffffff));
-
-       xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_2, (bkt_map & 0xffffffff));
-       xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_2 + 1,
-                    ((bkt_map >> 32) & 0xffffffff));
-
-       xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_3, (bkt_map & 0xffffffff));
-       xlr_nae_wreg(priv->base_addr, R_PDE_CLASS_3 + 1,
-                    ((bkt_map >> 32) & 0xffffffff));
-}
-
-/*
- * Setup the Message ring credits, bucket size and other
- * common configuration
- */
-static int xlr_config_common(struct xlr_net_priv *priv)
-{
-       struct xlr_fmn_info *gmac = priv->nd->gmac_fmn_info;
-       int start_stn_id = gmac->start_stn_id;
-       int end_stn_id = gmac->end_stn_id;
-       int *bucket_size = priv->nd->bucket_size;
-       int i, j, err;
-
-       /* Setting non-core MsgBktSize(0x321 - 0x325) */
-       for (i = start_stn_id; i <= end_stn_id; i++) {
-               xlr_nae_wreg(priv->base_addr,
-                            R_GMAC_RFR0_BUCKET_SIZE + i - start_stn_id,
-                            bucket_size[i]);
-       }
-
-       /*
-        * Setting non-core Credit counter register
-        * Distributing Gmac's credit to CPU's
-        */
-       for (i = 0; i < 8; i++) {
-               for (j = 0; j < 8; j++)
-                       xlr_nae_wreg(priv->base_addr,
-                                    (R_CC_CPU0_0 + (i * 8)) + j,
-                                    gmac->credit_config[(i * 8) + j]);
-       }
-
-       xlr_nae_wreg(priv->base_addr, R_MSG_TX_THRESHOLD, 3);
-       xlr_nae_wreg(priv->base_addr, R_DMACR0, 0xffffffff);
-       xlr_nae_wreg(priv->base_addr, R_DMACR1, 0xffffffff);
-       xlr_nae_wreg(priv->base_addr, R_DMACR2, 0xffffffff);
-       xlr_nae_wreg(priv->base_addr, R_DMACR3, 0xffffffff);
-       xlr_nae_wreg(priv->base_addr, R_FREEQCARVE, 0);
-
-       err = xlr_net_fill_rx_ring(priv->ndev);
-       if (err)
-               return err;
-       nlm_register_fmn_handler(start_stn_id, end_stn_id, xlr_net_fmn_handler,
-                                priv->adapter);
-       return 0;
-}
-
-static void xlr_config_translate_table(struct xlr_net_priv *priv)
-{
-       u32 cpu_mask;
-       u32 val;
-       int bkts[32]; /* one bucket is assumed for each cpu */
-       int b1, b2, c1, c2, i, j, k;
-       int use_bkt;
-
-       use_bkt = 0;
-       cpu_mask = priv->nd->cpu_mask;
-
-       pr_info("Using %s-based distribution\n",
-               (use_bkt) ? "bucket" : "class");
-       j = 0;
-       for (i = 0; i < 32; i++) {
-               if ((1 << i) & cpu_mask) {
-                       /* for each cpu, mark the 4+threadid bucket */
-                       bkts[j] = ((i / 4) * 8) + (i % 4);
-                       j++;
-               }
-       }
-
-       /*configure the 128 * 9 Translation table to send to available buckets*/
-       k = 0;
-       c1 = 3;
-       c2 = 0;
-       for (i = 0; i < 64; i++) {
-               /*
-                * On use_bkt set the b0, b1 are used, else
-                * the 4 classes are used, here implemented
-                * a logic to distribute the packets to the
-                * buckets equally or based on the class
-                */
-               c1 = (c1 + 1) & 3;
-               c2 = (c1 + 1) & 3;
-               b1 = bkts[k];
-               k = (k + 1) % j;
-               b2 = bkts[k];
-               k = (k + 1) % j;
-
-               val = ((c1 << 23) | (b1 << 17) | (use_bkt << 16) |
-                               (c2 << 7) | (b2 << 1) | (use_bkt << 0));
-               dev_dbg(&priv->ndev->dev, "Table[%d] b1=%d b2=%d c1=%d c2=%d\n",
-                       i, b1, b2, c1, c2);
-               xlr_nae_wreg(priv->base_addr, R_TRANSLATETABLE + i, val);
-               c1 = c2;
-       }
-}
-
-static void xlr_config_parser(struct xlr_net_priv *priv)
-{
-       u32 val;
-
-       /* Mark it as ETHERNET type */
-       xlr_nae_wreg(priv->base_addr, R_L2TYPE_0, 0x01);
-
-       /* Use 7bit CRChash for flow classification with 127 as CRC polynomial*/
-       xlr_nae_wreg(priv->base_addr, R_PARSERCONFIGREG,
-                    ((0x7f << 8) | (1 << 1)));
-
-       /* configure the parser : L2 Type is configured in the bootloader */
-       /* extract IP: src, dest protocol */
-       xlr_nae_wreg(priv->base_addr, R_L3CTABLE,
-                    (9 << 20) | (1 << 19) | (1 << 18) | (0x01 << 16) |
-                    (0x0800 << 0));
-       xlr_nae_wreg(priv->base_addr, R_L3CTABLE + 1,
-                    (9 << 25) | (1 << 21) | (12 << 14) | (4 << 10) |
-                    (16 << 4) | 4);
-
-       /* Configure to extract SRC port and Dest port for TCP and UDP pkts */
-       xlr_nae_wreg(priv->base_addr, R_L4CTABLE, 6);
-       xlr_nae_wreg(priv->base_addr, R_L4CTABLE + 2, 17);
-       val = ((0 << 21) | (2 << 17) | (2 << 11) | (2 << 7));
-       xlr_nae_wreg(priv->base_addr, R_L4CTABLE + 1, val);
-       xlr_nae_wreg(priv->base_addr, R_L4CTABLE + 3, val);
-
-       xlr_config_translate_table(priv);
-}
-
-static int xlr_phy_write(u32 *base_addr, int phy_addr, int regnum, u16 val)
-{
-       unsigned long timeout, stoptime, checktime;
-       int timedout;
-
-       /* 100ms timeout*/
-       timeout = msecs_to_jiffies(100);
-       stoptime = jiffies + timeout;
-       timedout = 0;
-
-       xlr_nae_wreg(base_addr, R_MII_MGMT_ADDRESS, (phy_addr << 8) | regnum);
-
-       /* Write the data which starts the write cycle */
-       xlr_nae_wreg(base_addr, R_MII_MGMT_WRITE_DATA, (u32)val);
-
-       /* poll for the read cycle to complete */
-       while (!timedout) {
-               checktime = jiffies;
-               if (xlr_nae_rdreg(base_addr, R_MII_MGMT_INDICATORS) == 0)
-                       break;
-               timedout = time_after(checktime, stoptime);
-       }
-       if (timedout) {
-               pr_info("Phy device write err: device busy");
-               return -EBUSY;
-       }
-
-       return 0;
-}
-
-static int xlr_phy_read(u32 *base_addr, int phy_addr, int regnum)
-{
-       unsigned long timeout, stoptime, checktime;
-       int timedout;
-
-       /* 100ms timeout*/
-       timeout = msecs_to_jiffies(100);
-       stoptime = jiffies + timeout;
-       timedout = 0;
-
-       /* setup the phy reg to be used */
-       xlr_nae_wreg(base_addr, R_MII_MGMT_ADDRESS,
-                    (phy_addr << 8) | (regnum << 0));
-
-       /* Issue the read command */
-       xlr_nae_wreg(base_addr, R_MII_MGMT_COMMAND,
-                    (1 << O_MII_MGMT_COMMAND__rstat));
-
-       /* poll for the read cycle to complete */
-       while (!timedout) {
-               checktime = jiffies;
-               if (xlr_nae_rdreg(base_addr, R_MII_MGMT_INDICATORS) == 0)
-                       break;
-               timedout = time_after(checktime, stoptime);
-       }
-       if (timedout) {
-               pr_info("Phy device read err: device busy");
-               return -EBUSY;
-       }
-
-       /* clear the read cycle */
-       xlr_nae_wreg(base_addr, R_MII_MGMT_COMMAND, 0);
-
-       /* Read the data */
-       return xlr_nae_rdreg(base_addr, R_MII_MGMT_STATUS);
-}
-
-static int xlr_mii_write(struct mii_bus *bus, int phy_addr, int regnum, u16 val)
-{
-       struct xlr_net_priv *priv = bus->priv;
-       int ret;
-
-       ret = xlr_phy_write(priv->mii_addr, phy_addr, regnum, val);
-       dev_dbg(&priv->ndev->dev, "mii_write phy %d : %d <- %x [%x]\n",
-               phy_addr, regnum, val, ret);
-       return ret;
-}
-
-static int xlr_mii_read(struct mii_bus *bus, int phy_addr, int regnum)
-{
-       struct xlr_net_priv *priv = bus->priv;
-       int ret;
-
-       ret =  xlr_phy_read(priv->mii_addr, phy_addr, regnum);
-       dev_dbg(&priv->ndev->dev, "mii_read phy %d : %d [%x]\n",
-               phy_addr, regnum, ret);
-       return ret;
-}
-
-/*
- * XLR ports are RGMII. XLS ports are SGMII mostly except the port0,
- * which can be configured either SGMII or RGMII, considered SGMII
- * by default, if board setup to RGMII the port_type need to set
- * accordingly.Serdes and PCS layer need to configured for SGMII
- */
-static void xlr_sgmii_init(struct xlr_net_priv *priv)
-{
-       int phy;
-
-       xlr_phy_write(priv->serdes_addr, 26, 0, 0x6DB0);
-       xlr_phy_write(priv->serdes_addr, 26, 1, 0xFFFF);
-       xlr_phy_write(priv->serdes_addr, 26, 2, 0xB6D0);
-       xlr_phy_write(priv->serdes_addr, 26, 3, 0x00FF);
-       xlr_phy_write(priv->serdes_addr, 26, 4, 0x0000);
-       xlr_phy_write(priv->serdes_addr, 26, 5, 0x0000);
-       xlr_phy_write(priv->serdes_addr, 26, 6, 0x0005);
-       xlr_phy_write(priv->serdes_addr, 26, 7, 0x0001);
-       xlr_phy_write(priv->serdes_addr, 26, 8, 0x0000);
-       xlr_phy_write(priv->serdes_addr, 26, 9, 0x0000);
-       xlr_phy_write(priv->serdes_addr, 26, 10, 0x0000);
-
-       /* program  GPIO values for serdes init parameters */
-       xlr_nae_wreg(priv->gpio_addr, 0x20, 0x7e6802);
-       xlr_nae_wreg(priv->gpio_addr, 0x10, 0x7104);
-
-       xlr_nae_wreg(priv->gpio_addr, 0x22, 0x7e6802);
-       xlr_nae_wreg(priv->gpio_addr, 0x21, 0x7104);
-
-       /* enable autoneg - more magic */
-       phy = priv->phy_addr % 4 + 27;
-       xlr_phy_write(priv->pcs_addr, phy, 0, 0x1000);
-       xlr_phy_write(priv->pcs_addr, phy, 0, 0x0200);
-}
-
-void xlr_set_gmac_speed(struct xlr_net_priv *priv)
-{
-       struct phy_device *phydev = xlr_get_phydev(priv);
-       int speed;
-
-       if (phydev->interface == PHY_INTERFACE_MODE_SGMII)
-               xlr_sgmii_init(priv);
-
-       if (phydev->speed != priv->phy_speed) {
-               speed = phydev->speed;
-               if (speed == SPEED_1000) {
-                       /* Set interface to Byte mode */
-                       xlr_nae_wreg(priv->base_addr, R_MAC_CONFIG_2, 0x7217);
-                       priv->phy_speed = speed;
-               } else if (speed == SPEED_100 || speed == SPEED_10) {
-                       /* Set interface to Nibble mode */
-                       xlr_nae_wreg(priv->base_addr, R_MAC_CONFIG_2, 0x7117);
-                       priv->phy_speed = speed;
-               }
-               /* Set SGMII speed in Interface control reg */
-               if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
-                       if (speed == SPEED_10)
-                               xlr_nae_wreg(priv->base_addr,
-                                            R_INTERFACE_CONTROL,
-                                            SGMII_SPEED_10);
-                       if (speed == SPEED_100)
-                               xlr_nae_wreg(priv->base_addr,
-                                            R_INTERFACE_CONTROL,
-                                            SGMII_SPEED_100);
-                       if (speed == SPEED_1000)
-                               xlr_nae_wreg(priv->base_addr,
-                                            R_INTERFACE_CONTROL,
-                                            SGMII_SPEED_1000);
-               }
-               if (speed == SPEED_10)
-                       xlr_nae_wreg(priv->base_addr, R_CORECONTROL, 0x2);
-               if (speed == SPEED_100)
-                       xlr_nae_wreg(priv->base_addr, R_CORECONTROL, 0x1);
-               if (speed == SPEED_1000)
-                       xlr_nae_wreg(priv->base_addr, R_CORECONTROL, 0x0);
-       }
-       pr_info("gmac%d : %dMbps\n", priv->port_id, priv->phy_speed);
-}
-
-static void xlr_gmac_link_adjust(struct net_device *ndev)
-{
-       struct xlr_net_priv *priv = netdev_priv(ndev);
-       struct phy_device *phydev = xlr_get_phydev(priv);
-       u32 intreg;
-
-       intreg = xlr_nae_rdreg(priv->base_addr, R_INTREG);
-       if (phydev->link) {
-               if (phydev->speed != priv->phy_speed) {
-                       xlr_set_gmac_speed(priv);
-                       pr_info("gmac%d : Link up\n", priv->port_id);
-               }
-       } else {
-               xlr_set_gmac_speed(priv);
-               pr_info("gmac%d : Link down\n", priv->port_id);
-       }
-}
-
-static int xlr_mii_probe(struct xlr_net_priv *priv)
-{
-       struct phy_device *phydev = xlr_get_phydev(priv);
-
-       if (!phydev) {
-               pr_err("no PHY found on phy_addr %d\n", priv->phy_addr);
-               return -ENODEV;
-       }
-
-       /* Attach MAC to PHY */
-       phydev = phy_connect(priv->ndev, phydev_name(phydev),
-                            xlr_gmac_link_adjust, priv->nd->phy_interface);
-
-       if (IS_ERR(phydev)) {
-               pr_err("could not attach PHY\n");
-               return PTR_ERR(phydev);
-       }
-       phydev->supported &= (ADVERTISED_10baseT_Full
-                               | ADVERTISED_10baseT_Half
-                               | ADVERTISED_100baseT_Full
-                               | ADVERTISED_100baseT_Half
-                               | ADVERTISED_1000baseT_Full
-                               | ADVERTISED_Autoneg
-                               | ADVERTISED_MII);
-
-       phydev->advertising = phydev->supported;
-       phy_attached_info(phydev);
-       return 0;
-}
-
-static int xlr_setup_mdio(struct xlr_net_priv *priv,
-                         struct platform_device *pdev)
-{
-       int err;
-
-       priv->mii_bus = mdiobus_alloc();
-       if (!priv->mii_bus) {
-               pr_err("mdiobus alloc failed\n");
-               return -ENOMEM;
-       }
-
-       priv->mii_bus->priv = priv;
-       priv->mii_bus->name = "xlr-mdio";
-       snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%d",
-                priv->mii_bus->name, priv->port_id);
-       priv->mii_bus->read = xlr_mii_read;
-       priv->mii_bus->write = xlr_mii_write;
-       priv->mii_bus->parent = &pdev->dev;
-
-       /* Scan only the enabled address */
-       priv->mii_bus->phy_mask = ~(1 << priv->phy_addr);
-
-       /* setting clock divisor to 54 */
-       xlr_nae_wreg(priv->base_addr, R_MII_MGMT_CONFIG, 0x7);
-
-       err = mdiobus_register(priv->mii_bus);
-       if (err) {
-               mdiobus_free(priv->mii_bus);
-               pr_err("mdio bus registration failed\n");
-               return err;
-       }
-
-       pr_info("Registered mdio bus id : %s\n", priv->mii_bus->id);
-       err = xlr_mii_probe(priv);
-       if (err) {
-               mdiobus_free(priv->mii_bus);
-               return err;
-       }
-       return 0;
-}
-
-static void xlr_port_enable(struct xlr_net_priv *priv)
-{
-       u32 prid = (read_c0_prid() & 0xf000);
-
-       /* Setup MAC_CONFIG reg if (xls & rgmii) */
-       if ((prid == 0x8000 || prid == 0x4000 || prid == 0xc000) &&
-           priv->nd->phy_interface == PHY_INTERFACE_MODE_RGMII)
-               xlr_reg_update(priv->base_addr, R_RX_CONTROL,
-                              (1 << O_RX_CONTROL__RGMII),
-                              (1 << O_RX_CONTROL__RGMII));
-
-       /* Rx Tx enable */
-       xlr_reg_update(priv->base_addr, R_MAC_CONFIG_1,
-                      ((1 << O_MAC_CONFIG_1__rxen) |
-                       (1 << O_MAC_CONFIG_1__txen) |
-                       (1 << O_MAC_CONFIG_1__rxfc) |
-                       (1 << O_MAC_CONFIG_1__txfc)),
-                      ((1 << O_MAC_CONFIG_1__rxen) |
-                       (1 << O_MAC_CONFIG_1__txen) |
-                       (1 << O_MAC_CONFIG_1__rxfc) |
-                       (1 << O_MAC_CONFIG_1__txfc)));
-
-       /* Setup tx control reg */
-       xlr_reg_update(priv->base_addr, R_TX_CONTROL,
-                      ((1 << O_TX_CONTROL__TXENABLE) |
-                      (512 << O_TX_CONTROL__TXTHRESHOLD)), 0x3fff);
-
-       /* Setup rx control reg */
-       xlr_reg_update(priv->base_addr, R_RX_CONTROL,
-                      1 << O_RX_CONTROL__RXENABLE,
-                      1 << O_RX_CONTROL__RXENABLE);
-}
-
-static void xlr_port_disable(struct xlr_net_priv *priv)
-{
-       /* Setup MAC_CONFIG reg */
-       /* Rx Tx disable*/
-       xlr_reg_update(priv->base_addr, R_MAC_CONFIG_1,
-                      ((1 << O_MAC_CONFIG_1__rxen) |
-                       (1 << O_MAC_CONFIG_1__txen) |
-                       (1 << O_MAC_CONFIG_1__rxfc) |
-                       (1 << O_MAC_CONFIG_1__txfc)), 0x0);
-
-       /* Setup tx control reg */
-       xlr_reg_update(priv->base_addr, R_TX_CONTROL,
-                      ((1 << O_TX_CONTROL__TXENABLE) |
-                      (512 << O_TX_CONTROL__TXTHRESHOLD)), 0);
-
-       /* Setup rx control reg */
-       xlr_reg_update(priv->base_addr, R_RX_CONTROL,
-                      1 << O_RX_CONTROL__RXENABLE, 0);
-}
-
-/*
- * Initialization of gmac
- */
-static int xlr_gmac_init(struct xlr_net_priv *priv,
-                        struct platform_device *pdev)
-{
-       int ret;
-
-       pr_info("Initializing the gmac%d\n", priv->port_id);
-
-       xlr_port_disable(priv);
-
-       xlr_nae_wreg(priv->base_addr, R_DESC_PACK_CTRL,
-                    (1 << O_DESC_PACK_CTRL__MAXENTRY) |
-                    (BYTE_OFFSET << O_DESC_PACK_CTRL__BYTEOFFSET) |
-                    (1600 << O_DESC_PACK_CTRL__REGULARSIZE));
-
-       ret = xlr_setup_mdio(priv, pdev);
-       if (ret)
-               return ret;
-       xlr_port_enable(priv);
-
-       /* Enable Full-duplex/1000Mbps/CRC */
-       xlr_nae_wreg(priv->base_addr, R_MAC_CONFIG_2, 0x7217);
-       /* speed 2.5Mhz */
-       xlr_nae_wreg(priv->base_addr, R_CORECONTROL, 0x02);
-       /* Setup Interrupt mask reg */
-       xlr_nae_wreg(priv->base_addr, R_INTMASK, (1 << O_INTMASK__TXILLEGAL) |
-                    (1 << O_INTMASK__MDINT) | (1 << O_INTMASK__TXFETCHERROR) |
-                    (1 << O_INTMASK__P2PSPILLECC) | (1 << O_INTMASK__TAGFULL) |
-                    (1 << O_INTMASK__UNDERRUN) | (1 << O_INTMASK__ABORT));
-
-       /* Clear all stats */
-       xlr_reg_update(priv->base_addr, R_STATCTRL, 0, 1 << O_STATCTRL__CLRCNT);
-       xlr_reg_update(priv->base_addr, R_STATCTRL, 1 << 2, 1 << 2);
-       return 0;
-}
-
-static int xlr_net_probe(struct platform_device *pdev)
-{
-       struct xlr_net_priv *priv = NULL;
-       struct net_device *ndev;
-       struct resource *res;
-       struct xlr_adapter *adapter;
-       int err, port;
-
-       pr_info("XLR/XLS Ethernet Driver controller %d\n", pdev->id);
-       /*
-        * Allocate our adapter data structure and attach it to the device.
-        */
-       adapter = devm_kzalloc(&pdev->dev, sizeof(*adapter), GFP_KERNEL);
-       if (!adapter)
-               return -ENOMEM;
-
-       /*
-        * XLR and XLS have 1 and 2 NAE controller respectively
-        * Each controller has 4 gmac ports, mapping each controller
-        * under one parent device, 4 gmac ports under one device.
-        */
-       for (port = 0; port < pdev->num_resources / 2; port++) {
-               ndev = alloc_etherdev_mq(sizeof(struct xlr_net_priv), 32);
-               if (!ndev) {
-                       dev_err(&pdev->dev,
-                               "Allocation of Ethernet device failed\n");
-                       return -ENOMEM;
-               }
-
-               priv = netdev_priv(ndev);
-               priv->pdev = pdev;
-               priv->ndev = ndev;
-               priv->port_id = (pdev->id * 4) + port;
-               priv->nd = (struct xlr_net_data *)pdev->dev.platform_data;
-               priv->base_addr = devm_platform_ioremap_resource(pdev, port);
-               if (IS_ERR(priv->base_addr)) {
-                       err = PTR_ERR(priv->base_addr);
-                       goto err_gmac;
-               }
-               priv->adapter = adapter;
-               adapter->netdev[port] = ndev;
-
-               res = platform_get_resource(pdev, IORESOURCE_IRQ, port);
-               if (!res) {
-                       dev_err(&pdev->dev, "No irq resource for MAC %d\n",
-                               priv->port_id);
-                       err = -ENODEV;
-                       goto err_gmac;
-               }
-
-               ndev->irq = res->start;
-
-               priv->phy_addr = priv->nd->phy_addr[port];
-               priv->tx_stnid = priv->nd->tx_stnid[port];
-               priv->mii_addr = priv->nd->mii_addr;
-               priv->serdes_addr = priv->nd->serdes_addr;
-               priv->pcs_addr = priv->nd->pcs_addr;
-               priv->gpio_addr = priv->nd->gpio_addr;
-
-               ndev->netdev_ops = &xlr_netdev_ops;
-               ndev->watchdog_timeo = HZ;
-
-               /* Setup Mac address and Rx mode */
-               eth_hw_addr_random(ndev);
-               xlr_hw_set_mac_addr(ndev);
-               xlr_set_rx_mode(ndev);
-
-               priv->num_rx_desc += MAX_NUM_DESC_SPILL;
-               ndev->ethtool_ops = &xlr_ethtool_ops;
-               SET_NETDEV_DEV(ndev, &pdev->dev);
-
-               xlr_config_fifo_spill_area(priv);
-               /* Configure PDE to Round-Robin pkt distribution */
-               xlr_config_pde(priv);
-               xlr_config_parser(priv);
-
-               /* Call init with respect to port */
-               if (strcmp(res->name, "gmac") == 0) {
-                       err = xlr_gmac_init(priv, pdev);
-                       if (err) {
-                               dev_err(&pdev->dev, "gmac%d init failed\n",
-                                       priv->port_id);
-                               goto err_gmac;
-                       }
-               }
-
-               if (priv->port_id == 0 || priv->port_id == 4) {
-                       err = xlr_config_common(priv);
-                       if (err)
-                               goto err_netdev;
-               }
-
-               err = register_netdev(ndev);
-               if (err) {
-                       dev_err(&pdev->dev,
-                               "Registering netdev failed for gmac%d\n",
-                               priv->port_id);
-                       goto err_netdev;
-               }
-               platform_set_drvdata(pdev, priv);
-       }
-
-       return 0;
-
-err_netdev:
-       mdiobus_free(priv->mii_bus);
-err_gmac:
-       free_netdev(ndev);
-       return err;
-}
-
-static int xlr_net_remove(struct platform_device *pdev)
-{
-       struct xlr_net_priv *priv = platform_get_drvdata(pdev);
-
-       unregister_netdev(priv->ndev);
-       mdiobus_unregister(priv->mii_bus);
-       mdiobus_free(priv->mii_bus);
-       free_netdev(priv->ndev);
-       return 0;
-}
-
-static struct platform_driver xlr_net_driver = {
-       .probe          = xlr_net_probe,
-       .remove         = xlr_net_remove,
-       .driver         = {
-               .name   = "xlr-net",
-       },
-};
-
-module_platform_driver(xlr_net_driver);
-
-MODULE_AUTHOR("Ganesan Ramalingam <ganesanr@broadcom.com>");
-MODULE_DESCRIPTION("Ethernet driver for Netlogic XLR/XLS");
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_ALIAS("platform:xlr-net");
diff --git a/drivers/staging/netlogic/xlr_net.h b/drivers/staging/netlogic/xlr_net.h
deleted file mode 100644 (file)
index 8365b74..0000000
+++ /dev/null
@@ -1,1079 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) */
-/*
- * Copyright (c) 2003-2012 Broadcom Corporation
- * All Rights Reserved
- */
-
-/* #define MAC_SPLIT_MODE */
-
-#define MAC_SPACING                 0x400
-#define XGMAC_SPACING               0x400
-
-/* PE-MCXMAC register and bit field definitions */
-#define R_MAC_CONFIG_1                                              0x00
-#define   O_MAC_CONFIG_1__srst                                      31
-#define   O_MAC_CONFIG_1__simr                                      30
-#define   O_MAC_CONFIG_1__hrrmc                                     18
-#define   W_MAC_CONFIG_1__hrtmc                                      2
-#define   O_MAC_CONFIG_1__hrrfn                                     16
-#define   W_MAC_CONFIG_1__hrtfn                                      2
-#define   O_MAC_CONFIG_1__intlb                                      8
-#define   O_MAC_CONFIG_1__rxfc                                       5
-#define   O_MAC_CONFIG_1__txfc                                       4
-#define   O_MAC_CONFIG_1__srxen                                      3
-#define   O_MAC_CONFIG_1__rxen                                       2
-#define   O_MAC_CONFIG_1__stxen                                      1
-#define   O_MAC_CONFIG_1__txen                                       0
-#define R_MAC_CONFIG_2                                              0x01
-#define   O_MAC_CONFIG_2__prlen                                     12
-#define   W_MAC_CONFIG_2__prlen                                      4
-#define   O_MAC_CONFIG_2__speed                                      8
-#define   W_MAC_CONFIG_2__speed                                      2
-#define   O_MAC_CONFIG_2__hugen                                      5
-#define   O_MAC_CONFIG_2__flchk                                      4
-#define   O_MAC_CONFIG_2__crce                                       1
-#define   O_MAC_CONFIG_2__fulld                                      0
-#define R_IPG_IFG                                                   0x02
-#define   O_IPG_IFG__ipgr1                                          24
-#define   W_IPG_IFG__ipgr1                                           7
-#define   O_IPG_IFG__ipgr2                                          16
-#define   W_IPG_IFG__ipgr2                                           7
-#define   O_IPG_IFG__mifg                                            8
-#define   W_IPG_IFG__mifg                                            8
-#define   O_IPG_IFG__ipgt                                            0
-#define   W_IPG_IFG__ipgt                                            7
-#define R_HALF_DUPLEX                                               0x03
-#define   O_HALF_DUPLEX__abebt                                      24
-#define   W_HALF_DUPLEX__abebt                                       4
-#define   O_HALF_DUPLEX__abebe                                      19
-#define   O_HALF_DUPLEX__bpnb                                       18
-#define   O_HALF_DUPLEX__nobo                                       17
-#define   O_HALF_DUPLEX__edxsdfr                                    16
-#define   O_HALF_DUPLEX__retry                                      12
-#define   W_HALF_DUPLEX__retry                                       4
-#define   O_HALF_DUPLEX__lcol                                        0
-#define   W_HALF_DUPLEX__lcol                                       10
-#define R_MAXIMUM_FRAME_LENGTH                                      0x04
-#define   O_MAXIMUM_FRAME_LENGTH__maxf                               0
-#define   W_MAXIMUM_FRAME_LENGTH__maxf                              16
-#define R_TEST                                                      0x07
-#define   O_TEST__mbof                                               3
-#define   O_TEST__rthdf                                              2
-#define   O_TEST__tpause                                             1
-#define   O_TEST__sstct                                              0
-#define R_MII_MGMT_CONFIG                                           0x08
-#define   O_MII_MGMT_CONFIG__scinc                                   5
-#define   O_MII_MGMT_CONFIG__spre                                    4
-#define   O_MII_MGMT_CONFIG__clks                                    3
-#define   W_MII_MGMT_CONFIG__clks                                    3
-#define R_MII_MGMT_COMMAND                                          0x09
-#define   O_MII_MGMT_COMMAND__scan                                   1
-#define   O_MII_MGMT_COMMAND__rstat                                  0
-#define R_MII_MGMT_ADDRESS                                          0x0A
-#define   O_MII_MGMT_ADDRESS__fiad                                   8
-#define   W_MII_MGMT_ADDRESS__fiad                                   5
-#define   O_MII_MGMT_ADDRESS__fgad                                   5
-#define   W_MII_MGMT_ADDRESS__fgad                                   0
-#define R_MII_MGMT_WRITE_DATA                                       0x0B
-#define   O_MII_MGMT_WRITE_DATA__ctld                                0
-#define   W_MII_MGMT_WRITE_DATA__ctld                               16
-#define R_MII_MGMT_STATUS                                           0x0C
-#define R_MII_MGMT_INDICATORS                                       0x0D
-#define   O_MII_MGMT_INDICATORS__nvalid                              2
-#define   O_MII_MGMT_INDICATORS__scan                                1
-#define   O_MII_MGMT_INDICATORS__busy                                0
-#define R_INTERFACE_CONTROL                                         0x0E
-#define   O_INTERFACE_CONTROL__hrstint                              31
-#define   O_INTERFACE_CONTROL__tbimode                              27
-#define   O_INTERFACE_CONTROL__ghdmode                              26
-#define   O_INTERFACE_CONTROL__lhdmode                              25
-#define   O_INTERFACE_CONTROL__phymod                               24
-#define   O_INTERFACE_CONTROL__hrrmi                                23
-#define   O_INTERFACE_CONTROL__rspd                                 16
-#define   O_INTERFACE_CONTROL__hr100                                15
-#define   O_INTERFACE_CONTROL__frcq                                 10
-#define   O_INTERFACE_CONTROL__nocfr                                 9
-#define   O_INTERFACE_CONTROL__dlfct                                 8
-#define   O_INTERFACE_CONTROL__enjab                                 0
-#define R_INTERFACE_STATUS                                         0x0F
-#define   O_INTERFACE_STATUS__xsdfr                                  9
-#define   O_INTERFACE_STATUS__ssrr                                   8
-#define   W_INTERFACE_STATUS__ssrr                                   5
-#define   O_INTERFACE_STATUS__miilf                                  3
-#define   O_INTERFACE_STATUS__locar                                  2
-#define   O_INTERFACE_STATUS__sqerr                                  1
-#define   O_INTERFACE_STATUS__jabber                                 0
-#define R_STATION_ADDRESS_LS                                       0x10
-#define R_STATION_ADDRESS_MS                                       0x11
-
-/* A-XGMAC register and bit field definitions */
-#define R_XGMAC_CONFIG_0    0x00
-#define   O_XGMAC_CONFIG_0__hstmacrst               31
-#define   O_XGMAC_CONFIG_0__hstrstrctl              23
-#define   O_XGMAC_CONFIG_0__hstrstrfn               22
-#define   O_XGMAC_CONFIG_0__hstrsttctl              18
-#define   O_XGMAC_CONFIG_0__hstrsttfn               17
-#define   O_XGMAC_CONFIG_0__hstrstmiim              16
-#define   O_XGMAC_CONFIG_0__hstloopback             8
-#define R_XGMAC_CONFIG_1    0x01
-#define   O_XGMAC_CONFIG_1__hsttctlen               31
-#define   O_XGMAC_CONFIG_1__hsttfen                 30
-#define   O_XGMAC_CONFIG_1__hstrctlen               29
-#define   O_XGMAC_CONFIG_1__hstrfen                 28
-#define   O_XGMAC_CONFIG_1__tfen                    26
-#define   O_XGMAC_CONFIG_1__rfen                    24
-#define   O_XGMAC_CONFIG_1__hstrctlshrtp            12
-#define   O_XGMAC_CONFIG_1__hstdlyfcstx             10
-#define   W_XGMAC_CONFIG_1__hstdlyfcstx              2
-#define   O_XGMAC_CONFIG_1__hstdlyfcsrx              8
-#define   W_XGMAC_CONFIG_1__hstdlyfcsrx              2
-#define   O_XGMAC_CONFIG_1__hstppen                  7
-#define   O_XGMAC_CONFIG_1__hstbytswp                6
-#define   O_XGMAC_CONFIG_1__hstdrplt64               5
-#define   O_XGMAC_CONFIG_1__hstprmscrx               4
-#define   O_XGMAC_CONFIG_1__hstlenchk                3
-#define   O_XGMAC_CONFIG_1__hstgenfcs                2
-#define   O_XGMAC_CONFIG_1__hstpadmode               0
-#define   W_XGMAC_CONFIG_1__hstpadmode               2
-#define R_XGMAC_CONFIG_2    0x02
-#define   O_XGMAC_CONFIG_2__hsttctlfrcp             31
-#define   O_XGMAC_CONFIG_2__hstmlnkflth             27
-#define   O_XGMAC_CONFIG_2__hstalnkflth             26
-#define   O_XGMAC_CONFIG_2__rflnkflt                24
-#define   W_XGMAC_CONFIG_2__rflnkflt                 2
-#define   O_XGMAC_CONFIG_2__hstipgextmod            16
-#define   W_XGMAC_CONFIG_2__hstipgextmod             5
-#define   O_XGMAC_CONFIG_2__hstrctlfrcp             15
-#define   O_XGMAC_CONFIG_2__hstipgexten              5
-#define   O_XGMAC_CONFIG_2__hstmipgext               0
-#define   W_XGMAC_CONFIG_2__hstmipgext               5
-#define R_XGMAC_CONFIG_3    0x03
-#define   O_XGMAC_CONFIG_3__hstfltrfrm              31
-#define   W_XGMAC_CONFIG_3__hstfltrfrm              16
-#define   O_XGMAC_CONFIG_3__hstfltrfrmdc            15
-#define   W_XGMAC_CONFIG_3__hstfltrfrmdc            16
-#define R_XGMAC_STATION_ADDRESS_LS      0x04
-#define   O_XGMAC_STATION_ADDRESS_LS__hstmacadr0    0
-#define   W_XGMAC_STATION_ADDRESS_LS__hstmacadr0    32
-#define R_XGMAC_STATION_ADDRESS_MS      0x05
-#define R_XGMAC_MAX_FRAME_LEN           0x08
-#define   O_XGMAC_MAX_FRAME_LEN__hstmxfrmwctx       16
-#define   W_XGMAC_MAX_FRAME_LEN__hstmxfrmwctx       14
-#define   O_XGMAC_MAX_FRAME_LEN__hstmxfrmbcrx        0
-#define   W_XGMAC_MAX_FRAME_LEN__hstmxfrmbcrx       16
-#define R_XGMAC_REV_LEVEL               0x0B
-#define   O_XGMAC_REV_LEVEL__revlvl                  0
-#define   W_XGMAC_REV_LEVEL__revlvl                 15
-#define R_XGMAC_MIIM_COMMAND            0x10
-#define   O_XGMAC_MIIM_COMMAND__hstldcmd             3
-#define   O_XGMAC_MIIM_COMMAND__hstmiimcmd           0
-#define   W_XGMAC_MIIM_COMMAND__hstmiimcmd           3
-#define R_XGMAC_MIIM_FILED              0x11
-#define   O_XGMAC_MIIM_FILED__hststfield            30
-#define   W_XGMAC_MIIM_FILED__hststfield             2
-#define   O_XGMAC_MIIM_FILED__hstopfield            28
-#define   W_XGMAC_MIIM_FILED__hstopfield             2
-#define   O_XGMAC_MIIM_FILED__hstphyadx             23
-#define   W_XGMAC_MIIM_FILED__hstphyadx              5
-#define   O_XGMAC_MIIM_FILED__hstregadx             18
-#define   W_XGMAC_MIIM_FILED__hstregadx              5
-#define   O_XGMAC_MIIM_FILED__hsttafield            16
-#define   W_XGMAC_MIIM_FILED__hsttafield             2
-#define   O_XGMAC_MIIM_FILED__miimrddat              0
-#define   W_XGMAC_MIIM_FILED__miimrddat             16
-#define R_XGMAC_MIIM_CONFIG             0x12
-#define   O_XGMAC_MIIM_CONFIG__hstnopram             7
-#define   O_XGMAC_MIIM_CONFIG__hstclkdiv             0
-#define   W_XGMAC_MIIM_CONFIG__hstclkdiv             7
-#define R_XGMAC_MIIM_LINK_FAIL_VECTOR   0x13
-#define   O_XGMAC_MIIM_LINK_FAIL_VECTOR__miimlfvec   0
-#define   W_XGMAC_MIIM_LINK_FAIL_VECTOR__miimlfvec  32
-#define R_XGMAC_MIIM_INDICATOR          0x14
-#define   O_XGMAC_MIIM_INDICATOR__miimphylf          4
-#define   O_XGMAC_MIIM_INDICATOR__miimmoncplt        3
-#define   O_XGMAC_MIIM_INDICATOR__miimmonvld         2
-#define   O_XGMAC_MIIM_INDICATOR__miimmon            1
-#define   O_XGMAC_MIIM_INDICATOR__miimbusy           0
-
-/* GMAC stats registers */
-#define R_RBYT                                                     0x27
-#define R_RPKT                                                     0x28
-#define R_RFCS                                                     0x29
-#define R_RMCA                                                     0x2A
-#define R_RBCA                                                     0x2B
-#define R_RXCF                                                     0x2C
-#define R_RXPF                                                     0x2D
-#define R_RXUO                                                     0x2E
-#define R_RALN                                                     0x2F
-#define R_RFLR                                                     0x30
-#define R_RCDE                                                     0x31
-#define R_RCSE                                                     0x32
-#define R_RUND                                                     0x33
-#define R_ROVR                                                     0x34
-#define R_TBYT                                                     0x38
-#define R_TPKT                                                     0x39
-#define R_TMCA                                                     0x3A
-#define R_TBCA                                                     0x3B
-#define R_TXPF                                                     0x3C
-#define R_TDFR                                                     0x3D
-#define R_TEDF                                                     0x3E
-#define R_TSCL                                                     0x3F
-#define R_TMCL                                                     0x40
-#define R_TLCL                                                     0x41
-#define R_TXCL                                                     0x42
-#define R_TNCL                                                     0x43
-#define R_TJBR                                                     0x46
-#define R_TFCS                                                     0x47
-#define R_TXCF                                                     0x48
-#define R_TOVR                                                     0x49
-#define R_TUND                                                     0x4A
-#define R_TFRG                                                     0x4B
-
-/* Glue logic register and bit field definitions */
-#define R_MAC_ADDR0                                                 0x50
-#define R_MAC_ADDR1                                                 0x52
-#define R_MAC_ADDR2                                                 0x54
-#define R_MAC_ADDR3                                                 0x56
-#define R_MAC_ADDR_MASK2                                            0x58
-#define R_MAC_ADDR_MASK3                                            0x5A
-#define R_MAC_FILTER_CONFIG                                         0x5C
-#define   O_MAC_FILTER_CONFIG__BROADCAST_EN                         10
-#define   O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN                       9
-#define   O_MAC_FILTER_CONFIG__ALL_MCAST_EN                         8
-#define   O_MAC_FILTER_CONFIG__ALL_UCAST_EN                         7
-#define   O_MAC_FILTER_CONFIG__HASH_MCAST_EN                        6
-#define   O_MAC_FILTER_CONFIG__HASH_UCAST_EN                        5
-#define   O_MAC_FILTER_CONFIG__ADDR_MATCH_DISC                      4
-#define   O_MAC_FILTER_CONFIG__MAC_ADDR3_VALID                      3
-#define   O_MAC_FILTER_CONFIG__MAC_ADDR2_VALID                      2
-#define   O_MAC_FILTER_CONFIG__MAC_ADDR1_VALID                      1
-#define   O_MAC_FILTER_CONFIG__MAC_ADDR0_VALID                      0
-#define R_HASH_TABLE_VECTOR                                         0x30
-#define R_TX_CONTROL                                                 0x0A0
-#define   O_TX_CONTROL__TX15HALT                                     31
-#define   O_TX_CONTROL__TX14HALT                                     30
-#define   O_TX_CONTROL__TX13HALT                                     29
-#define   O_TX_CONTROL__TX12HALT                                     28
-#define   O_TX_CONTROL__TX11HALT                                     27
-#define   O_TX_CONTROL__TX10HALT                                     26
-#define   O_TX_CONTROL__TX9HALT                                      25
-#define   O_TX_CONTROL__TX8HALT                                      24
-#define   O_TX_CONTROL__TX7HALT                                      23
-#define   O_TX_CONTROL__TX6HALT                                      22
-#define   O_TX_CONTROL__TX5HALT                                      21
-#define   O_TX_CONTROL__TX4HALT                                      20
-#define   O_TX_CONTROL__TX3HALT                                      19
-#define   O_TX_CONTROL__TX2HALT                                      18
-#define   O_TX_CONTROL__TX1HALT                                      17
-#define   O_TX_CONTROL__TX0HALT                                      16
-#define   O_TX_CONTROL__TXIDLE                                       15
-#define   O_TX_CONTROL__TXENABLE                                     14
-#define   O_TX_CONTROL__TXTHRESHOLD                                  0
-#define   W_TX_CONTROL__TXTHRESHOLD                                  14
-#define R_RX_CONTROL                                                 0x0A1
-#define   O_RX_CONTROL__RGMII                                        10
-#define   O_RX_CONTROL__SOFTRESET                                   2
-#define   O_RX_CONTROL__RXHALT                                       1
-#define   O_RX_CONTROL__RXENABLE                                     0
-#define R_DESC_PACK_CTRL                                            0x0A2
-#define   O_DESC_PACK_CTRL__BYTEOFFSET                              17
-#define   W_DESC_PACK_CTRL__BYTEOFFSET                              3
-#define   O_DESC_PACK_CTRL__PREPADENABLE                            16
-#define   O_DESC_PACK_CTRL__MAXENTRY                                14
-#define   W_DESC_PACK_CTRL__MAXENTRY                                2
-#define   O_DESC_PACK_CTRL__REGULARSIZE                             0
-#define   W_DESC_PACK_CTRL__REGULARSIZE                             14
-#define R_STATCTRL                                                  0x0A3
-#define   O_STATCTRL__OVERFLOWEN                                    4
-#define   O_STATCTRL__GIG                                           3
-#define   O_STATCTRL__STEN                                          2
-#define   O_STATCTRL__CLRCNT                                        1
-#define   O_STATCTRL__AUTOZ                                         0
-#define R_L2ALLOCCTRL                                               0x0A4
-#define   O_L2ALLOCCTRL__TXL2ALLOCATE                               9
-#define   W_L2ALLOCCTRL__TXL2ALLOCATE                               9
-#define   O_L2ALLOCCTRL__RXL2ALLOCATE                               0
-#define   W_L2ALLOCCTRL__RXL2ALLOCATE                               9
-#define R_INTMASK                                                   0x0A5
-#define   O_INTMASK__SPI4TXERROR                                     28
-#define   O_INTMASK__SPI4RXERROR                                     27
-#define   O_INTMASK__RGMIIHALFDUPCOLLISION                           27
-#define   O_INTMASK__ABORT                                           26
-#define   O_INTMASK__UNDERRUN                                        25
-#define   O_INTMASK__DISCARDPACKET                                   24
-#define   O_INTMASK__ASYNCFIFOFULL                                   23
-#define   O_INTMASK__TAGFULL                                         22
-#define   O_INTMASK__CLASS3FULL                                      21
-#define   O_INTMASK__C3EARLYFULL                                     20
-#define   O_INTMASK__CLASS2FULL                                      19
-#define   O_INTMASK__C2EARLYFULL                                     18
-#define   O_INTMASK__CLASS1FULL                                      17
-#define   O_INTMASK__C1EARLYFULL                                     16
-#define   O_INTMASK__CLASS0FULL                                      15
-#define   O_INTMASK__C0EARLYFULL                                     14
-#define   O_INTMASK__RXDATAFULL                                      13
-#define   O_INTMASK__RXEARLYFULL                                     12
-#define   O_INTMASK__RFREEEMPTY                                      9
-#define   O_INTMASK__RFEARLYEMPTY                                    8
-#define   O_INTMASK__P2PSPILLECC                                     7
-#define   O_INTMASK__FREEDESCFULL                                    5
-#define   O_INTMASK__FREEEARLYFULL                                   4
-#define   O_INTMASK__TXFETCHERROR                                    3
-#define   O_INTMASK__STATCARRY                                       2
-#define   O_INTMASK__MDINT                                           1
-#define   O_INTMASK__TXILLEGAL                                       0
-#define R_INTREG                                                    0x0A6
-#define   O_INTREG__SPI4TXERROR                                     28
-#define   O_INTREG__SPI4RXERROR                                     27
-#define   O_INTREG__RGMIIHALFDUPCOLLISION                           27
-#define   O_INTREG__ABORT                                           26
-#define   O_INTREG__UNDERRUN                                        25
-#define   O_INTREG__DISCARDPACKET                                   24
-#define   O_INTREG__ASYNCFIFOFULL                                   23
-#define   O_INTREG__TAGFULL                                         22
-#define   O_INTREG__CLASS3FULL                                      21
-#define   O_INTREG__C3EARLYFULL                                     20
-#define   O_INTREG__CLASS2FULL                                      19
-#define   O_INTREG__C2EARLYFULL                                     18
-#define   O_INTREG__CLASS1FULL                                      17
-#define   O_INTREG__C1EARLYFULL                                     16
-#define   O_INTREG__CLASS0FULL                                      15
-#define   O_INTREG__C0EARLYFULL                                     14
-#define   O_INTREG__RXDATAFULL                                      13
-#define   O_INTREG__RXEARLYFULL                                     12
-#define   O_INTREG__RFREEEMPTY                                      9
-#define   O_INTREG__RFEARLYEMPTY                                    8
-#define   O_INTREG__P2PSPILLECC                                     7
-#define   O_INTREG__FREEDESCFULL                                    5
-#define   O_INTREG__FREEEARLYFULL                                   4
-#define   O_INTREG__TXFETCHERROR                                    3
-#define   O_INTREG__STATCARRY                                       2
-#define   O_INTREG__MDINT                                           1
-#define   O_INTREG__TXILLEGAL                                       0
-#define R_TXRETRY                                                   0x0A7
-#define   O_TXRETRY__COLLISIONRETRY                                 6
-#define   O_TXRETRY__BUSERRORRETRY                                  5
-#define   O_TXRETRY__UNDERRUNRETRY                                  4
-#define   O_TXRETRY__RETRIES                                        0
-#define   W_TXRETRY__RETRIES                                        4
-#define R_CORECONTROL                                               0x0A8
-#define   O_CORECONTROL__ERRORTHREAD                                4
-#define   W_CORECONTROL__ERRORTHREAD                                7
-#define   O_CORECONTROL__SHUTDOWN                                   2
-#define   O_CORECONTROL__SPEED                                      0
-#define   W_CORECONTROL__SPEED                                      2
-#define R_BYTEOFFSET0                                               0x0A9
-#define R_BYTEOFFSET1                                               0x0AA
-#define R_L2TYPE_0                                                  0x0F0
-#define   O_L2TYPE__EXTRAHDRPROTOSIZE                               26
-#define   W_L2TYPE__EXTRAHDRPROTOSIZE                               5
-#define   O_L2TYPE__EXTRAHDRPROTOOFFSET                             20
-#define   W_L2TYPE__EXTRAHDRPROTOOFFSET                             6
-#define   O_L2TYPE__EXTRAHEADERSIZE                                 14
-#define   W_L2TYPE__EXTRAHEADERSIZE                                 6
-#define   O_L2TYPE__PROTOOFFSET                                     8
-#define   W_L2TYPE__PROTOOFFSET                                     6
-#define   O_L2TYPE__L2HDROFFSET                                     2
-#define   W_L2TYPE__L2HDROFFSET                                     6
-#define   O_L2TYPE__L2PROTO                                         0
-#define   W_L2TYPE__L2PROTO                                         2
-#define R_L2TYPE_1                                                  0xF0
-#define R_L2TYPE_2                                                  0xF0
-#define R_L2TYPE_3                                                  0xF0
-#define R_PARSERCONFIGREG                                           0x100
-#define   O_PARSERCONFIGREG__CRCHASHPOLY                            8
-#define   W_PARSERCONFIGREG__CRCHASHPOLY                            7
-#define   O_PARSERCONFIGREG__PREPADOFFSET                           4
-#define   W_PARSERCONFIGREG__PREPADOFFSET                           4
-#define   O_PARSERCONFIGREG__USECAM                                 2
-#define   O_PARSERCONFIGREG__USEHASH                                1
-#define   O_PARSERCONFIGREG__USEPROTO                               0
-#define R_L3CTABLE                                                  0x140
-#define   O_L3CTABLE__OFFSET0                                       25
-#define   W_L3CTABLE__OFFSET0                                       7
-#define   O_L3CTABLE__LEN0                                          21
-#define   W_L3CTABLE__LEN0                                          4
-#define   O_L3CTABLE__OFFSET1                                       14
-#define   W_L3CTABLE__OFFSET1                                       7
-#define   O_L3CTABLE__LEN1                                          10
-#define   W_L3CTABLE__LEN1                                          4
-#define   O_L3CTABLE__OFFSET2                                       4
-#define   W_L3CTABLE__OFFSET2                                       6
-#define   O_L3CTABLE__LEN2                                          0
-#define   W_L3CTABLE__LEN2                                          4
-#define   O_L3CTABLE__L3HDROFFSET                                   26
-#define   W_L3CTABLE__L3HDROFFSET                                   6
-#define   O_L3CTABLE__L4PROTOOFFSET                                 20
-#define   W_L3CTABLE__L4PROTOOFFSET                                 6
-#define   O_L3CTABLE__IPCHKSUMCOMPUTE                               19
-#define   O_L3CTABLE__L4CLASSIFY                                    18
-#define   O_L3CTABLE__L2PROTO                                       16
-#define   W_L3CTABLE__L2PROTO                                       2
-#define   O_L3CTABLE__L3PROTOKEY                                    0
-#define   W_L3CTABLE__L3PROTOKEY                                    16
-#define R_L4CTABLE                                                  0x160
-#define   O_L4CTABLE__OFFSET0                                       21
-#define   W_L4CTABLE__OFFSET0                                       6
-#define   O_L4CTABLE__LEN0                                          17
-#define   W_L4CTABLE__LEN0                                          4
-#define   O_L4CTABLE__OFFSET1                                       11
-#define   W_L4CTABLE__OFFSET1                                       6
-#define   O_L4CTABLE__LEN1                                          7
-#define   W_L4CTABLE__LEN1                                          4
-#define   O_L4CTABLE__TCPCHKSUMENABLE                               0
-#define R_CAM4X128TABLE                                             0x172
-#define   O_CAM4X128TABLE__CLASSID                                  7
-#define   W_CAM4X128TABLE__CLASSID                                  2
-#define   O_CAM4X128TABLE__BUCKETID                                 1
-#define   W_CAM4X128TABLE__BUCKETID                                 6
-#define   O_CAM4X128TABLE__USEBUCKET                                0
-#define R_CAM4X128KEY                                               0x180
-#define R_TRANSLATETABLE                                            0x1A0
-#define R_DMACR0                                                    0x200
-#define   O_DMACR0__DATA0WRMAXCR                                    27
-#define   W_DMACR0__DATA0WRMAXCR                                    3
-#define   O_DMACR0__DATA0RDMAXCR                                    24
-#define   W_DMACR0__DATA0RDMAXCR                                    3
-#define   O_DMACR0__DATA1WRMAXCR                                    21
-#define   W_DMACR0__DATA1WRMAXCR                                    3
-#define   O_DMACR0__DATA1RDMAXCR                                    18
-#define   W_DMACR0__DATA1RDMAXCR                                    3
-#define   O_DMACR0__DATA2WRMAXCR                                    15
-#define   W_DMACR0__DATA2WRMAXCR                                    3
-#define   O_DMACR0__DATA2RDMAXCR                                    12
-#define   W_DMACR0__DATA2RDMAXCR                                    3
-#define   O_DMACR0__DATA3WRMAXCR                                    9
-#define   W_DMACR0__DATA3WRMAXCR                                    3
-#define   O_DMACR0__DATA3RDMAXCR                                    6
-#define   W_DMACR0__DATA3RDMAXCR                                    3
-#define   O_DMACR0__DATA4WRMAXCR                                    3
-#define   W_DMACR0__DATA4WRMAXCR                                    3
-#define   O_DMACR0__DATA4RDMAXCR                                    0
-#define   W_DMACR0__DATA4RDMAXCR                                    3
-#define R_DMACR1                                                    0x201
-#define   O_DMACR1__DATA5WRMAXCR                                    27
-#define   W_DMACR1__DATA5WRMAXCR                                    3
-#define   O_DMACR1__DATA5RDMAXCR                                    24
-#define   W_DMACR1__DATA5RDMAXCR                                    3
-#define   O_DMACR1__DATA6WRMAXCR                                    21
-#define   W_DMACR1__DATA6WRMAXCR                                    3
-#define   O_DMACR1__DATA6RDMAXCR                                    18
-#define   W_DMACR1__DATA6RDMAXCR                                    3
-#define   O_DMACR1__DATA7WRMAXCR                                    15
-#define   W_DMACR1__DATA7WRMAXCR                                    3
-#define   O_DMACR1__DATA7RDMAXCR                                    12
-#define   W_DMACR1__DATA7RDMAXCR                                    3
-#define   O_DMACR1__DATA8WRMAXCR                                    9
-#define   W_DMACR1__DATA8WRMAXCR                                    3
-#define   O_DMACR1__DATA8RDMAXCR                                    6
-#define   W_DMACR1__DATA8RDMAXCR                                    3
-#define   O_DMACR1__DATA9WRMAXCR                                    3
-#define   W_DMACR1__DATA9WRMAXCR                                    3
-#define   O_DMACR1__DATA9RDMAXCR                                    0
-#define   W_DMACR1__DATA9RDMAXCR                                    3
-#define R_DMACR2                                                    0x202
-#define   O_DMACR2__DATA10WRMAXCR                                   27
-#define   W_DMACR2__DATA10WRMAXCR                                   3
-#define   O_DMACR2__DATA10RDMAXCR                                   24
-#define   W_DMACR2__DATA10RDMAXCR                                   3
-#define   O_DMACR2__DATA11WRMAXCR                                   21
-#define   W_DMACR2__DATA11WRMAXCR                                   3
-#define   O_DMACR2__DATA11RDMAXCR                                   18
-#define   W_DMACR2__DATA11RDMAXCR                                   3
-#define   O_DMACR2__DATA12WRMAXCR                                   15
-#define   W_DMACR2__DATA12WRMAXCR                                   3
-#define   O_DMACR2__DATA12RDMAXCR                                   12
-#define   W_DMACR2__DATA12RDMAXCR                                   3
-#define   O_DMACR2__DATA13WRMAXCR                                   9
-#define   W_DMACR2__DATA13WRMAXCR                                   3
-#define   O_DMACR2__DATA13RDMAXCR                                   6
-#define   W_DMACR2__DATA13RDMAXCR                                   3
-#define   O_DMACR2__DATA14WRMAXCR                                   3
-#define   W_DMACR2__DATA14WRMAXCR                                   3
-#define   O_DMACR2__DATA14RDMAXCR                                   0
-#define   W_DMACR2__DATA14RDMAXCR                                   3
-#define R_DMACR3                                                    0x203
-#define   O_DMACR3__DATA15WRMAXCR                                   27
-#define   W_DMACR3__DATA15WRMAXCR                                   3
-#define   O_DMACR3__DATA15RDMAXCR                                   24
-#define   W_DMACR3__DATA15RDMAXCR                                   3
-#define   O_DMACR3__SPCLASSWRMAXCR                                  21
-#define   W_DMACR3__SPCLASSWRMAXCR                                  3
-#define   O_DMACR3__SPCLASSRDMAXCR                                  18
-#define   W_DMACR3__SPCLASSRDMAXCR                                  3
-#define   O_DMACR3__JUMFRINWRMAXCR                                  15
-#define   W_DMACR3__JUMFRINWRMAXCR                                  3
-#define   O_DMACR3__JUMFRINRDMAXCR                                  12
-#define   W_DMACR3__JUMFRINRDMAXCR                                  3
-#define   O_DMACR3__REGFRINWRMAXCR                                  9
-#define   W_DMACR3__REGFRINWRMAXCR                                  3
-#define   O_DMACR3__REGFRINRDMAXCR                                  6
-#define   W_DMACR3__REGFRINRDMAXCR                                  3
-#define   O_DMACR3__FROUTWRMAXCR                                    3
-#define   W_DMACR3__FROUTWRMAXCR                                    3
-#define   O_DMACR3__FROUTRDMAXCR                                    0
-#define   W_DMACR3__FROUTRDMAXCR                                    3
-#define R_REG_FRIN_SPILL_MEM_START_0                                0x204
-#define   O_REG_FRIN_SPILL_MEM_START_0__REGFRINSPILLMEMSTART0        0
-#define   W_REG_FRIN_SPILL_MEM_START_0__REGFRINSPILLMEMSTART0       32
-#define R_REG_FRIN_SPILL_MEM_START_1                                0x205
-#define   O_REG_FRIN_SPILL_MEM_START_1__REGFRINSPILLMEMSTART1        0
-#define   W_REG_FRIN_SPILL_MEM_START_1__REGFRINSPILLMEMSTART1        3
-#define R_REG_FRIN_SPILL_MEM_SIZE                                   0x206
-#define   O_REG_FRIN_SPILL_MEM_SIZE__REGFRINSPILLMEMSIZE             0
-#define   W_REG_FRIN_SPILL_MEM_SIZE__REGFRINSPILLMEMSIZE            32
-#define R_FROUT_SPILL_MEM_START_0                                   0x207
-#define   O_FROUT_SPILL_MEM_START_0__FROUTSPILLMEMSTART0             0
-#define   W_FROUT_SPILL_MEM_START_0__FROUTSPILLMEMSTART0            32
-#define R_FROUT_SPILL_MEM_START_1                                   0x208
-#define   O_FROUT_SPILL_MEM_START_1__FROUTSPILLMEMSTART1             0
-#define   W_FROUT_SPILL_MEM_START_1__FROUTSPILLMEMSTART1             3
-#define R_FROUT_SPILL_MEM_SIZE                                      0x209
-#define   O_FROUT_SPILL_MEM_SIZE__FROUTSPILLMEMSIZE                  0
-#define   W_FROUT_SPILL_MEM_SIZE__FROUTSPILLMEMSIZE                 32
-#define R_CLASS0_SPILL_MEM_START_0                                  0x20A
-#define   O_CLASS0_SPILL_MEM_START_0__CLASS0SPILLMEMSTART0           0
-#define   W_CLASS0_SPILL_MEM_START_0__CLASS0SPILLMEMSTART0          32
-#define R_CLASS0_SPILL_MEM_START_1                                  0x20B
-#define   O_CLASS0_SPILL_MEM_START_1__CLASS0SPILLMEMSTART1           0
-#define   W_CLASS0_SPILL_MEM_START_1__CLASS0SPILLMEMSTART1           3
-#define R_CLASS0_SPILL_MEM_SIZE                                     0x20C
-#define   O_CLASS0_SPILL_MEM_SIZE__CLASS0SPILLMEMSIZE                0
-#define   W_CLASS0_SPILL_MEM_SIZE__CLASS0SPILLMEMSIZE               32
-#define R_JUMFRIN_SPILL_MEM_START_0                                 0x20D
-#define   O_JUMFRIN_SPILL_MEM_START_0__JUMFRINSPILLMEMSTART0          0
-#define   W_JUMFRIN_SPILL_MEM_START_0__JUMFRINSPILLMEMSTART0         32
-#define R_JUMFRIN_SPILL_MEM_START_1                                 0x20E
-#define   O_JUMFRIN_SPILL_MEM_START_1__JUMFRINSPILLMEMSTART1         0
-#define   W_JUMFRIN_SPILL_MEM_START_1__JUMFRINSPILLMEMSTART1         3
-#define R_JUMFRIN_SPILL_MEM_SIZE                                    0x20F
-#define   O_JUMFRIN_SPILL_MEM_SIZE__JUMFRINSPILLMEMSIZE              0
-#define   W_JUMFRIN_SPILL_MEM_SIZE__JUMFRINSPILLMEMSIZE             32
-#define R_CLASS1_SPILL_MEM_START_0                                  0x210
-#define   O_CLASS1_SPILL_MEM_START_0__CLASS1SPILLMEMSTART0           0
-#define   W_CLASS1_SPILL_MEM_START_0__CLASS1SPILLMEMSTART0          32
-#define R_CLASS1_SPILL_MEM_START_1                                  0x211
-#define   O_CLASS1_SPILL_MEM_START_1__CLASS1SPILLMEMSTART1           0
-#define   W_CLASS1_SPILL_MEM_START_1__CLASS1SPILLMEMSTART1           3
-#define R_CLASS1_SPILL_MEM_SIZE                                     0x212
-#define   O_CLASS1_SPILL_MEM_SIZE__CLASS1SPILLMEMSIZE                0
-#define   W_CLASS1_SPILL_MEM_SIZE__CLASS1SPILLMEMSIZE               32
-#define R_CLASS2_SPILL_MEM_START_0                                  0x213
-#define   O_CLASS2_SPILL_MEM_START_0__CLASS2SPILLMEMSTART0           0
-#define   W_CLASS2_SPILL_MEM_START_0__CLASS2SPILLMEMSTART0          32
-#define R_CLASS2_SPILL_MEM_START_1                                  0x214
-#define   O_CLASS2_SPILL_MEM_START_1__CLASS2SPILLMEMSTART1           0
-#define   W_CLASS2_SPILL_MEM_START_1__CLASS2SPILLMEMSTART1           3
-#define R_CLASS2_SPILL_MEM_SIZE                                     0x215
-#define   O_CLASS2_SPILL_MEM_SIZE__CLASS2SPILLMEMSIZE                0
-#define   W_CLASS2_SPILL_MEM_SIZE__CLASS2SPILLMEMSIZE               32
-#define R_CLASS3_SPILL_MEM_START_0                                  0x216
-#define   O_CLASS3_SPILL_MEM_START_0__CLASS3SPILLMEMSTART0           0
-#define   W_CLASS3_SPILL_MEM_START_0__CLASS3SPILLMEMSTART0          32
-#define R_CLASS3_SPILL_MEM_START_1                                  0x217
-#define   O_CLASS3_SPILL_MEM_START_1__CLASS3SPILLMEMSTART1           0
-#define   W_CLASS3_SPILL_MEM_START_1__CLASS3SPILLMEMSTART1           3
-#define R_CLASS3_SPILL_MEM_SIZE                                     0x218
-#define   O_CLASS3_SPILL_MEM_SIZE__CLASS3SPILLMEMSIZE                0
-#define   W_CLASS3_SPILL_MEM_SIZE__CLASS3SPILLMEMSIZE               32
-#define R_REG_FRIN1_SPILL_MEM_START_0                               0x219
-#define R_REG_FRIN1_SPILL_MEM_START_1                               0x21a
-#define R_REG_FRIN1_SPILL_MEM_SIZE                                  0x21b
-#define R_SPIHNGY0                                                  0x219
-#define   O_SPIHNGY0__EG_HNGY_THRESH_0                              24
-#define   W_SPIHNGY0__EG_HNGY_THRESH_0                              7
-#define   O_SPIHNGY0__EG_HNGY_THRESH_1                              16
-#define   W_SPIHNGY0__EG_HNGY_THRESH_1                              7
-#define   O_SPIHNGY0__EG_HNGY_THRESH_2                              8
-#define   W_SPIHNGY0__EG_HNGY_THRESH_2                              7
-#define   O_SPIHNGY0__EG_HNGY_THRESH_3                              0
-#define   W_SPIHNGY0__EG_HNGY_THRESH_3                              7
-#define R_SPIHNGY1                                                  0x21A
-#define   O_SPIHNGY1__EG_HNGY_THRESH_4                              24
-#define   W_SPIHNGY1__EG_HNGY_THRESH_4                              7
-#define   O_SPIHNGY1__EG_HNGY_THRESH_5                              16
-#define   W_SPIHNGY1__EG_HNGY_THRESH_5                              7
-#define   O_SPIHNGY1__EG_HNGY_THRESH_6                              8
-#define   W_SPIHNGY1__EG_HNGY_THRESH_6                              7
-#define   O_SPIHNGY1__EG_HNGY_THRESH_7                              0
-#define   W_SPIHNGY1__EG_HNGY_THRESH_7                              7
-#define R_SPIHNGY2                                                  0x21B
-#define   O_SPIHNGY2__EG_HNGY_THRESH_8                              24
-#define   W_SPIHNGY2__EG_HNGY_THRESH_8                              7
-#define   O_SPIHNGY2__EG_HNGY_THRESH_9                              16
-#define   W_SPIHNGY2__EG_HNGY_THRESH_9                              7
-#define   O_SPIHNGY2__EG_HNGY_THRESH_10                             8
-#define   W_SPIHNGY2__EG_HNGY_THRESH_10                             7
-#define   O_SPIHNGY2__EG_HNGY_THRESH_11                             0
-#define   W_SPIHNGY2__EG_HNGY_THRESH_11                             7
-#define R_SPIHNGY3                                                  0x21C
-#define   O_SPIHNGY3__EG_HNGY_THRESH_12                             24
-#define   W_SPIHNGY3__EG_HNGY_THRESH_12                             7
-#define   O_SPIHNGY3__EG_HNGY_THRESH_13                             16
-#define   W_SPIHNGY3__EG_HNGY_THRESH_13                             7
-#define   O_SPIHNGY3__EG_HNGY_THRESH_14                             8
-#define   W_SPIHNGY3__EG_HNGY_THRESH_14                             7
-#define   O_SPIHNGY3__EG_HNGY_THRESH_15                             0
-#define   W_SPIHNGY3__EG_HNGY_THRESH_15                             7
-#define R_SPISTRV0                                                  0x21D
-#define   O_SPISTRV0__EG_STRV_THRESH_0                              24
-#define   W_SPISTRV0__EG_STRV_THRESH_0                              7
-#define   O_SPISTRV0__EG_STRV_THRESH_1                              16
-#define   W_SPISTRV0__EG_STRV_THRESH_1                              7
-#define   O_SPISTRV0__EG_STRV_THRESH_2                              8
-#define   W_SPISTRV0__EG_STRV_THRESH_2                              7
-#define   O_SPISTRV0__EG_STRV_THRESH_3                              0
-#define   W_SPISTRV0__EG_STRV_THRESH_3                              7
-#define R_SPISTRV1                                                  0x21E
-#define   O_SPISTRV1__EG_STRV_THRESH_4                              24
-#define   W_SPISTRV1__EG_STRV_THRESH_4                              7
-#define   O_SPISTRV1__EG_STRV_THRESH_5                              16
-#define   W_SPISTRV1__EG_STRV_THRESH_5                              7
-#define   O_SPISTRV1__EG_STRV_THRESH_6                              8
-#define   W_SPISTRV1__EG_STRV_THRESH_6                              7
-#define   O_SPISTRV1__EG_STRV_THRESH_7                              0
-#define   W_SPISTRV1__EG_STRV_THRESH_7                              7
-#define R_SPISTRV2                                                  0x21F
-#define   O_SPISTRV2__EG_STRV_THRESH_8                              24
-#define   W_SPISTRV2__EG_STRV_THRESH_8                              7
-#define   O_SPISTRV2__EG_STRV_THRESH_9                              16
-#define   W_SPISTRV2__EG_STRV_THRESH_9                              7
-#define   O_SPISTRV2__EG_STRV_THRESH_10                             8
-#define   W_SPISTRV2__EG_STRV_THRESH_10                             7
-#define   O_SPISTRV2__EG_STRV_THRESH_11                             0
-#define   W_SPISTRV2__EG_STRV_THRESH_11                             7
-#define R_SPISTRV3                                                  0x220
-#define   O_SPISTRV3__EG_STRV_THRESH_12                             24
-#define   W_SPISTRV3__EG_STRV_THRESH_12                             7
-#define   O_SPISTRV3__EG_STRV_THRESH_13                             16
-#define   W_SPISTRV3__EG_STRV_THRESH_13                             7
-#define   O_SPISTRV3__EG_STRV_THRESH_14                             8
-#define   W_SPISTRV3__EG_STRV_THRESH_14                             7
-#define   O_SPISTRV3__EG_STRV_THRESH_15                             0
-#define   W_SPISTRV3__EG_STRV_THRESH_15                             7
-#define R_TXDATAFIFO0                                               0x221
-#define   O_TXDATAFIFO0__TX0DATAFIFOSTART                           24
-#define   W_TXDATAFIFO0__TX0DATAFIFOSTART                           7
-#define   O_TXDATAFIFO0__TX0DATAFIFOSIZE                            16
-#define   W_TXDATAFIFO0__TX0DATAFIFOSIZE                            7
-#define   O_TXDATAFIFO0__TX1DATAFIFOSTART                           8
-#define   W_TXDATAFIFO0__TX1DATAFIFOSTART                           7
-#define   O_TXDATAFIFO0__TX1DATAFIFOSIZE                            0
-#define   W_TXDATAFIFO0__TX1DATAFIFOSIZE                            7
-#define R_TXDATAFIFO1                                               0x222
-#define   O_TXDATAFIFO1__TX2DATAFIFOSTART                           24
-#define   W_TXDATAFIFO1__TX2DATAFIFOSTART                           7
-#define   O_TXDATAFIFO1__TX2DATAFIFOSIZE                            16
-#define   W_TXDATAFIFO1__TX2DATAFIFOSIZE                            7
-#define   O_TXDATAFIFO1__TX3DATAFIFOSTART                           8
-#define   W_TXDATAFIFO1__TX3DATAFIFOSTART                           7
-#define   O_TXDATAFIFO1__TX3DATAFIFOSIZE                            0
-#define   W_TXDATAFIFO1__TX3DATAFIFOSIZE                            7
-#define R_TXDATAFIFO2                                               0x223
-#define   O_TXDATAFIFO2__TX4DATAFIFOSTART                           24
-#define   W_TXDATAFIFO2__TX4DATAFIFOSTART                           7
-#define   O_TXDATAFIFO2__TX4DATAFIFOSIZE                            16
-#define   W_TXDATAFIFO2__TX4DATAFIFOSIZE                            7
-#define   O_TXDATAFIFO2__TX5DATAFIFOSTART                           8
-#define   W_TXDATAFIFO2__TX5DATAFIFOSTART                           7
-#define   O_TXDATAFIFO2__TX5DATAFIFOSIZE                            0
-#define   W_TXDATAFIFO2__TX5DATAFIFOSIZE                            7
-#define R_TXDATAFIFO3                                               0x224
-#define   O_TXDATAFIFO3__TX6DATAFIFOSTART                           24
-#define   W_TXDATAFIFO3__TX6DATAFIFOSTART                           7
-#define   O_TXDATAFIFO3__TX6DATAFIFOSIZE                            16
-#define   W_TXDATAFIFO3__TX6DATAFIFOSIZE                            7
-#define   O_TXDATAFIFO3__TX7DATAFIFOSTART                           8
-#define   W_TXDATAFIFO3__TX7DATAFIFOSTART                           7
-#define   O_TXDATAFIFO3__TX7DATAFIFOSIZE                            0
-#define   W_TXDATAFIFO3__TX7DATAFIFOSIZE                            7
-#define R_TXDATAFIFO4                                               0x225
-#define   O_TXDATAFIFO4__TX8DATAFIFOSTART                           24
-#define   W_TXDATAFIFO4__TX8DATAFIFOSTART                           7
-#define   O_TXDATAFIFO4__TX8DATAFIFOSIZE                            16
-#define   W_TXDATAFIFO4__TX8DATAFIFOSIZE                            7
-#define   O_TXDATAFIFO4__TX9DATAFIFOSTART                           8
-#define   W_TXDATAFIFO4__TX9DATAFIFOSTART                           7
-#define   O_TXDATAFIFO4__TX9DATAFIFOSIZE                            0
-#define   W_TXDATAFIFO4__TX9DATAFIFOSIZE                            7
-#define R_TXDATAFIFO5                                               0x226
-#define   O_TXDATAFIFO5__TX10DATAFIFOSTART                          24
-#define   W_TXDATAFIFO5__TX10DATAFIFOSTART                          7
-#define   O_TXDATAFIFO5__TX10DATAFIFOSIZE                           16
-#define   W_TXDATAFIFO5__TX10DATAFIFOSIZE                           7
-#define   O_TXDATAFIFO5__TX11DATAFIFOSTART                          8
-#define   W_TXDATAFIFO5__TX11DATAFIFOSTART                          7
-#define   O_TXDATAFIFO5__TX11DATAFIFOSIZE                           0
-#define   W_TXDATAFIFO5__TX11DATAFIFOSIZE                           7
-#define R_TXDATAFIFO6                                               0x227
-#define   O_TXDATAFIFO6__TX12DATAFIFOSTART                          24
-#define   W_TXDATAFIFO6__TX12DATAFIFOSTART                          7
-#define   O_TXDATAFIFO6__TX12DATAFIFOSIZE                           16
-#define   W_TXDATAFIFO6__TX12DATAFIFOSIZE                           7
-#define   O_TXDATAFIFO6__TX13DATAFIFOSTART                          8
-#define   W_TXDATAFIFO6__TX13DATAFIFOSTART                          7
-#define   O_TXDATAFIFO6__TX13DATAFIFOSIZE                           0
-#define   W_TXDATAFIFO6__TX13DATAFIFOSIZE                           7
-#define R_TXDATAFIFO7                                               0x228
-#define   O_TXDATAFIFO7__TX14DATAFIFOSTART                          24
-#define   W_TXDATAFIFO7__TX14DATAFIFOSTART                          7
-#define   O_TXDATAFIFO7__TX14DATAFIFOSIZE                           16
-#define   W_TXDATAFIFO7__TX14DATAFIFOSIZE                           7
-#define   O_TXDATAFIFO7__TX15DATAFIFOSTART                          8
-#define   W_TXDATAFIFO7__TX15DATAFIFOSTART                          7
-#define   O_TXDATAFIFO7__TX15DATAFIFOSIZE                           0
-#define   W_TXDATAFIFO7__TX15DATAFIFOSIZE                           7
-#define R_RXDATAFIFO0                                               0x229
-#define   O_RXDATAFIFO0__RX0DATAFIFOSTART                           24
-#define   W_RXDATAFIFO0__RX0DATAFIFOSTART                           7
-#define   O_RXDATAFIFO0__RX0DATAFIFOSIZE                            16
-#define   W_RXDATAFIFO0__RX0DATAFIFOSIZE                            7
-#define   O_RXDATAFIFO0__RX1DATAFIFOSTART                           8
-#define   W_RXDATAFIFO0__RX1DATAFIFOSTART                           7
-#define   O_RXDATAFIFO0__RX1DATAFIFOSIZE                            0
-#define   W_RXDATAFIFO0__RX1DATAFIFOSIZE                            7
-#define R_RXDATAFIFO1                                               0x22A
-#define   O_RXDATAFIFO1__RX2DATAFIFOSTART                           24
-#define   W_RXDATAFIFO1__RX2DATAFIFOSTART                           7
-#define   O_RXDATAFIFO1__RX2DATAFIFOSIZE                            16
-#define   W_RXDATAFIFO1__RX2DATAFIFOSIZE                            7
-#define   O_RXDATAFIFO1__RX3DATAFIFOSTART                           8
-#define   W_RXDATAFIFO1__RX3DATAFIFOSTART                           7
-#define   O_RXDATAFIFO1__RX3DATAFIFOSIZE                            0
-#define   W_RXDATAFIFO1__RX3DATAFIFOSIZE                            7
-#define R_RXDATAFIFO2                                               0x22B
-#define   O_RXDATAFIFO2__RX4DATAFIFOSTART                           24
-#define   W_RXDATAFIFO2__RX4DATAFIFOSTART                           7
-#define   O_RXDATAFIFO2__RX4DATAFIFOSIZE                            16
-#define   W_RXDATAFIFO2__RX4DATAFIFOSIZE                            7
-#define   O_RXDATAFIFO2__RX5DATAFIFOSTART                           8
-#define   W_RXDATAFIFO2__RX5DATAFIFOSTART                           7
-#define   O_RXDATAFIFO2__RX5DATAFIFOSIZE                            0
-#define   W_RXDATAFIFO2__RX5DATAFIFOSIZE                            7
-#define R_RXDATAFIFO3                                               0x22C
-#define   O_RXDATAFIFO3__RX6DATAFIFOSTART                           24
-#define   W_RXDATAFIFO3__RX6DATAFIFOSTART                           7
-#define   O_RXDATAFIFO3__RX6DATAFIFOSIZE                            16
-#define   W_RXDATAFIFO3__RX6DATAFIFOSIZE                            7
-#define   O_RXDATAFIFO3__RX7DATAFIFOSTART                           8
-#define   W_RXDATAFIFO3__RX7DATAFIFOSTART                           7
-#define   O_RXDATAFIFO3__RX7DATAFIFOSIZE                            0
-#define   W_RXDATAFIFO3__RX7DATAFIFOSIZE                            7
-#define R_RXDATAFIFO4                                               0x22D
-#define   O_RXDATAFIFO4__RX8DATAFIFOSTART                           24
-#define   W_RXDATAFIFO4__RX8DATAFIFOSTART                           7
-#define   O_RXDATAFIFO4__RX8DATAFIFOSIZE                            16
-#define   W_RXDATAFIFO4__RX8DATAFIFOSIZE                            7
-#define   O_RXDATAFIFO4__RX9DATAFIFOSTART                           8
-#define   W_RXDATAFIFO4__RX9DATAFIFOSTART                           7
-#define   O_RXDATAFIFO4__RX9DATAFIFOSIZE                            0
-#define   W_RXDATAFIFO4__RX9DATAFIFOSIZE                            7
-#define R_RXDATAFIFO5                                               0x22E
-#define   O_RXDATAFIFO5__RX10DATAFIFOSTART                          24
-#define   W_RXDATAFIFO5__RX10DATAFIFOSTART                          7
-#define   O_RXDATAFIFO5__RX10DATAFIFOSIZE                           16
-#define   W_RXDATAFIFO5__RX10DATAFIFOSIZE                           7
-#define   O_RXDATAFIFO5__RX11DATAFIFOSTART                          8
-#define   W_RXDATAFIFO5__RX11DATAFIFOSTART                          7
-#define   O_RXDATAFIFO5__RX11DATAFIFOSIZE                           0
-#define   W_RXDATAFIFO5__RX11DATAFIFOSIZE                           7
-#define R_RXDATAFIFO6                                               0x22F
-#define   O_RXDATAFIFO6__RX12DATAFIFOSTART                          24
-#define   W_RXDATAFIFO6__RX12DATAFIFOSTART                          7
-#define   O_RXDATAFIFO6__RX12DATAFIFOSIZE                           16
-#define   W_RXDATAFIFO6__RX12DATAFIFOSIZE                           7
-#define   O_RXDATAFIFO6__RX13DATAFIFOSTART                          8
-#define   W_RXDATAFIFO6__RX13DATAFIFOSTART                          7
-#define   O_RXDATAFIFO6__RX13DATAFIFOSIZE                           0
-#define   W_RXDATAFIFO6__RX13DATAFIFOSIZE                           7
-#define R_RXDATAFIFO7                                               0x230
-#define   O_RXDATAFIFO7__RX14DATAFIFOSTART                          24
-#define   W_RXDATAFIFO7__RX14DATAFIFOSTART                          7
-#define   O_RXDATAFIFO7__RX14DATAFIFOSIZE                           16
-#define   W_RXDATAFIFO7__RX14DATAFIFOSIZE                           7
-#define   O_RXDATAFIFO7__RX15DATAFIFOSTART                          8
-#define   W_RXDATAFIFO7__RX15DATAFIFOSTART                          7
-#define   O_RXDATAFIFO7__RX15DATAFIFOSIZE                           0
-#define   W_RXDATAFIFO7__RX15DATAFIFOSIZE                           7
-#define R_XGMACPADCALIBRATION                                       0x231
-#define R_FREEQCARVE                                                0x233
-#define R_SPI4STATICDELAY0                                          0x240
-#define   O_SPI4STATICDELAY0__DATALINE7                             28
-#define   W_SPI4STATICDELAY0__DATALINE7                             4
-#define   O_SPI4STATICDELAY0__DATALINE6                             24
-#define   W_SPI4STATICDELAY0__DATALINE6                             4
-#define   O_SPI4STATICDELAY0__DATALINE5                             20
-#define   W_SPI4STATICDELAY0__DATALINE5                             4
-#define   O_SPI4STATICDELAY0__DATALINE4                             16
-#define   W_SPI4STATICDELAY0__DATALINE4                             4
-#define   O_SPI4STATICDELAY0__DATALINE3                             12
-#define   W_SPI4STATICDELAY0__DATALINE3                             4
-#define   O_SPI4STATICDELAY0__DATALINE2                             8
-#define   W_SPI4STATICDELAY0__DATALINE2                             4
-#define   O_SPI4STATICDELAY0__DATALINE1                             4
-#define   W_SPI4STATICDELAY0__DATALINE1                             4
-#define   O_SPI4STATICDELAY0__DATALINE0                             0
-#define   W_SPI4STATICDELAY0__DATALINE0                             4
-#define R_SPI4STATICDELAY1                                          0x241
-#define   O_SPI4STATICDELAY1__DATALINE15                            28
-#define   W_SPI4STATICDELAY1__DATALINE15                            4
-#define   O_SPI4STATICDELAY1__DATALINE14                            24
-#define   W_SPI4STATICDELAY1__DATALINE14                            4
-#define   O_SPI4STATICDELAY1__DATALINE13                            20
-#define   W_SPI4STATICDELAY1__DATALINE13                            4
-#define   O_SPI4STATICDELAY1__DATALINE12                            16
-#define   W_SPI4STATICDELAY1__DATALINE12                            4
-#define   O_SPI4STATICDELAY1__DATALINE11                            12
-#define   W_SPI4STATICDELAY1__DATALINE11                            4
-#define   O_SPI4STATICDELAY1__DATALINE10                            8
-#define   W_SPI4STATICDELAY1__DATALINE10                            4
-#define   O_SPI4STATICDELAY1__DATALINE9                             4
-#define   W_SPI4STATICDELAY1__DATALINE9                             4
-#define   O_SPI4STATICDELAY1__DATALINE8                             0
-#define   W_SPI4STATICDELAY1__DATALINE8                             4
-#define R_SPI4STATICDELAY2                                          0x242
-#define   O_SPI4STATICDELAY0__TXSTAT1                               8
-#define   W_SPI4STATICDELAY0__TXSTAT1                               4
-#define   O_SPI4STATICDELAY0__TXSTAT0                               4
-#define   W_SPI4STATICDELAY0__TXSTAT0                               4
-#define   O_SPI4STATICDELAY0__RXCONTROL                             0
-#define   W_SPI4STATICDELAY0__RXCONTROL                             4
-#define R_SPI4CONTROL                                               0x243
-#define   O_SPI4CONTROL__STATICDELAY                                2
-#define   O_SPI4CONTROL__LVDS_LVTTL                                 1
-#define   O_SPI4CONTROL__SPI4ENABLE                                 0
-#define R_CLASSWATERMARKS                                           0x244
-#define   O_CLASSWATERMARKS__CLASS0WATERMARK                        24
-#define   W_CLASSWATERMARKS__CLASS0WATERMARK                        5
-#define   O_CLASSWATERMARKS__CLASS1WATERMARK                        16
-#define   W_CLASSWATERMARKS__CLASS1WATERMARK                        5
-#define   O_CLASSWATERMARKS__CLASS3WATERMARK                        0
-#define   W_CLASSWATERMARKS__CLASS3WATERMARK                        5
-#define R_RXWATERMARKS1                                              0x245
-#define   O_RXWATERMARKS__RX0DATAWATERMARK                          24
-#define   W_RXWATERMARKS__RX0DATAWATERMARK                          7
-#define   O_RXWATERMARKS__RX1DATAWATERMARK                          16
-#define   W_RXWATERMARKS__RX1DATAWATERMARK                          7
-#define   O_RXWATERMARKS__RX3DATAWATERMARK                          0
-#define   W_RXWATERMARKS__RX3DATAWATERMARK                          7
-#define R_RXWATERMARKS2                                              0x246
-#define   O_RXWATERMARKS__RX4DATAWATERMARK                          24
-#define   W_RXWATERMARKS__RX4DATAWATERMARK                          7
-#define   O_RXWATERMARKS__RX5DATAWATERMARK                          16
-#define   W_RXWATERMARKS__RX5DATAWATERMARK                          7
-#define   O_RXWATERMARKS__RX6DATAWATERMARK                          8
-#define   W_RXWATERMARKS__RX6DATAWATERMARK                          7
-#define   O_RXWATERMARKS__RX7DATAWATERMARK                          0
-#define   W_RXWATERMARKS__RX7DATAWATERMARK                          7
-#define R_RXWATERMARKS3                                              0x247
-#define   O_RXWATERMARKS__RX8DATAWATERMARK                          24
-#define   W_RXWATERMARKS__RX8DATAWATERMARK                          7
-#define   O_RXWATERMARKS__RX9DATAWATERMARK                          16
-#define   W_RXWATERMARKS__RX9DATAWATERMARK                          7
-#define   O_RXWATERMARKS__RX10DATAWATERMARK                         8
-#define   W_RXWATERMARKS__RX10DATAWATERMARK                         7
-#define   O_RXWATERMARKS__RX11DATAWATERMARK                         0
-#define   W_RXWATERMARKS__RX11DATAWATERMARK                         7
-#define R_RXWATERMARKS4                                              0x248
-#define   O_RXWATERMARKS__RX12DATAWATERMARK                         24
-#define   W_RXWATERMARKS__RX12DATAWATERMARK                         7
-#define   O_RXWATERMARKS__RX13DATAWATERMARK                         16
-#define   W_RXWATERMARKS__RX13DATAWATERMARK                         7
-#define   O_RXWATERMARKS__RX14DATAWATERMARK                         8
-#define   W_RXWATERMARKS__RX14DATAWATERMARK                         7
-#define   O_RXWATERMARKS__RX15DATAWATERMARK                         0
-#define   W_RXWATERMARKS__RX15DATAWATERMARK                         7
-#define R_FREEWATERMARKS                                            0x249
-#define   O_FREEWATERMARKS__FREEOUTWATERMARK                        16
-#define   W_FREEWATERMARKS__FREEOUTWATERMARK                        16
-#define   O_FREEWATERMARKS__JUMFRWATERMARK                          8
-#define   W_FREEWATERMARKS__JUMFRWATERMARK                          7
-#define   O_FREEWATERMARKS__REGFRWATERMARK                          0
-#define   W_FREEWATERMARKS__REGFRWATERMARK                          7
-#define R_EGRESSFIFOCARVINGSLOTS                                    0x24a
-
-#define CTRL_RES0           0
-#define CTRL_RES1           1
-#define CTRL_REG_FREE       2
-#define CTRL_JUMBO_FREE     3
-#define CTRL_CONT           4
-#define CTRL_EOP            5
-#define CTRL_START          6
-#define CTRL_SNGL           7
-
-#define CTRL_B0_NOT_EOP     0
-#define CTRL_B0_EOP         1
-
-#define R_ROUND_ROBIN_TABLE                 0
-#define R_PDE_CLASS_0                       0x300
-#define R_PDE_CLASS_1                       0x302
-#define R_PDE_CLASS_2                       0x304
-#define R_PDE_CLASS_3                       0x306
-
-#define R_MSG_TX_THRESHOLD                  0x308
-
-#define R_GMAC_JFR0_BUCKET_SIZE              0x320
-#define R_GMAC_RFR0_BUCKET_SIZE              0x321
-#define R_GMAC_TX0_BUCKET_SIZE              0x322
-#define R_GMAC_TX1_BUCKET_SIZE              0x323
-#define R_GMAC_TX2_BUCKET_SIZE              0x324
-#define R_GMAC_TX3_BUCKET_SIZE              0x325
-#define R_GMAC_JFR1_BUCKET_SIZE              0x326
-#define R_GMAC_RFR1_BUCKET_SIZE              0x327
-
-#define R_XGS_TX0_BUCKET_SIZE               0x320
-#define R_XGS_TX1_BUCKET_SIZE               0x321
-#define R_XGS_TX2_BUCKET_SIZE               0x322
-#define R_XGS_TX3_BUCKET_SIZE               0x323
-#define R_XGS_TX4_BUCKET_SIZE               0x324
-#define R_XGS_TX5_BUCKET_SIZE               0x325
-#define R_XGS_TX6_BUCKET_SIZE               0x326
-#define R_XGS_TX7_BUCKET_SIZE               0x327
-#define R_XGS_TX8_BUCKET_SIZE               0x328
-#define R_XGS_TX9_BUCKET_SIZE               0x329
-#define R_XGS_TX10_BUCKET_SIZE              0x32A
-#define R_XGS_TX11_BUCKET_SIZE              0x32B
-#define R_XGS_TX12_BUCKET_SIZE              0x32C
-#define R_XGS_TX13_BUCKET_SIZE              0x32D
-#define R_XGS_TX14_BUCKET_SIZE              0x32E
-#define R_XGS_TX15_BUCKET_SIZE              0x32F
-#define R_XGS_JFR_BUCKET_SIZE               0x330
-#define R_XGS_RFR_BUCKET_SIZE               0x331
-
-#define R_CC_CPU0_0                         0x380
-#define R_CC_CPU1_0                         0x388
-#define R_CC_CPU2_0                         0x390
-#define R_CC_CPU3_0                         0x398
-#define R_CC_CPU4_0                         0x3a0
-#define R_CC_CPU5_0                         0x3a8
-#define R_CC_CPU6_0                         0x3b0
-#define R_CC_CPU7_0                         0x3b8
-
-#define XLR_GMAC_BLK_SZ                            (XLR_IO_GMAC_1_OFFSET - \
-               XLR_IO_GMAC_0_OFFSET)
-
-/* Constants used for configuring the devices */
-
-#define XLR_FB_STN                     6 /* Bucket used for Tx freeback */
-
-#define MAC_B2B_IPG                     88
-
-#define        XLR_NET_PREPAD_LEN              32
-
-/* frame sizes need to be cacheline aligned */
-#define MAX_FRAME_SIZE                  (1536 + XLR_NET_PREPAD_LEN)
-#define MAX_FRAME_SIZE_JUMBO            9216
-
-#define MAC_SKB_BACK_PTR_SIZE           SMP_CACHE_BYTES
-#define MAC_PREPAD                      0
-#define BYTE_OFFSET                     2
-#define XLR_RX_BUF_SIZE                 (MAX_FRAME_SIZE + BYTE_OFFSET + \
-               MAC_PREPAD + MAC_SKB_BACK_PTR_SIZE + SMP_CACHE_BYTES)
-#define MAC_CRC_LEN                     4
-#define MAX_NUM_MSGRNG_STN_CC           128
-#define MAX_MSG_SND_ATTEMPTS           100     /* 13 stns x 4 entry msg/stn +
-                                                * headroom
-                                                */
-
-#define MAC_FRIN_TO_BE_SENT_THRESHOLD   16
-
-#define MAX_NUM_DESC_SPILL             1024
-#define MAX_FRIN_SPILL                  (MAX_NUM_DESC_SPILL << 2)
-#define MAX_FROUT_SPILL                 (MAX_NUM_DESC_SPILL << 2)
-#define MAX_CLASS_0_SPILL               (MAX_NUM_DESC_SPILL << 2)
-#define MAX_CLASS_1_SPILL               (MAX_NUM_DESC_SPILL << 2)
-#define MAX_CLASS_2_SPILL               (MAX_NUM_DESC_SPILL << 2)
-#define MAX_CLASS_3_SPILL               (MAX_NUM_DESC_SPILL << 2)
-
-enum {
-       SGMII_SPEED_10 = 0x00000000,
-       SGMII_SPEED_100 = 0x02000000,
-       SGMII_SPEED_1000 = 0x04000000,
-};
-
-enum tsv_rsv_reg {
-       TX_RX_64_BYTE_FRAME = 0x20,
-       TX_RX_64_127_BYTE_FRAME,
-       TX_RX_128_255_BYTE_FRAME,
-       TX_RX_256_511_BYTE_FRAME,
-       TX_RX_512_1023_BYTE_FRAME,
-       TX_RX_1024_1518_BYTE_FRAME,
-       TX_RX_1519_1522_VLAN_BYTE_FRAME,
-
-       RX_BYTE_COUNTER = 0x27,
-       RX_PACKET_COUNTER,
-       RX_FCS_ERROR_COUNTER,
-       RX_MULTICAST_PACKET_COUNTER,
-       RX_BROADCAST_PACKET_COUNTER,
-       RX_CONTROL_FRAME_PACKET_COUNTER,
-       RX_PAUSE_FRAME_PACKET_COUNTER,
-       RX_UNKNOWN_OP_CODE_COUNTER,
-       RX_ALIGNMENT_ERROR_COUNTER,
-       RX_FRAME_LENGTH_ERROR_COUNTER,
-       RX_CODE_ERROR_COUNTER,
-       RX_CARRIER_SENSE_ERROR_COUNTER,
-       RX_UNDERSIZE_PACKET_COUNTER,
-       RX_OVERSIZE_PACKET_COUNTER,
-       RX_FRAGMENTS_COUNTER,
-       RX_JABBER_COUNTER,
-       RX_DROP_PACKET_COUNTER,
-
-       TX_BYTE_COUNTER   = 0x38,
-       TX_PACKET_COUNTER,
-       TX_MULTICAST_PACKET_COUNTER,
-       TX_BROADCAST_PACKET_COUNTER,
-       TX_PAUSE_CONTROL_FRAME_COUNTER,
-       TX_DEFERRAL_PACKET_COUNTER,
-       TX_EXCESSIVE_DEFERRAL_PACKET_COUNTER,
-       TX_SINGLE_COLLISION_PACKET_COUNTER,
-       TX_MULTI_COLLISION_PACKET_COUNTER,
-       TX_LATE_COLLISION_PACKET_COUNTER,
-       TX_EXCESSIVE_COLLISION_PACKET_COUNTER,
-       TX_TOTAL_COLLISION_COUNTER,
-       TX_PAUSE_FRAME_HONERED_COUNTER,
-       TX_DROP_FRAME_COUNTER,
-       TX_JABBER_FRAME_COUNTER,
-       TX_FCS_ERROR_COUNTER,
-       TX_CONTROL_FRAME_COUNTER,
-       TX_OVERSIZE_FRAME_COUNTER,
-       TX_UNDERSIZE_FRAME_COUNTER,
-       TX_FRAGMENT_FRAME_COUNTER,
-
-       CARRY_REG_1 = 0x4c,
-       CARRY_REG_2 = 0x4d,
-};
-
-struct xlr_adapter {
-       struct net_device *netdev[4];
-};
-
-struct xlr_net_priv {
-       u32 __iomem *base_addr;
-       struct net_device *ndev;
-       struct xlr_adapter *adapter;
-       struct mii_bus *mii_bus;
-       int num_rx_desc;
-       int phy_addr;   /* PHY addr on MDIO bus */
-       int pcs_id;     /* PCS id on MDIO bus */
-       int port_id;    /* Port(gmac/xgmac) number, i.e 0-7 */
-       int tx_stnid;
-       u32 __iomem *mii_addr;
-       u32 __iomem *serdes_addr;
-       u32 __iomem *pcs_addr;
-       u32 __iomem *gpio_addr;
-       int phy_speed;
-       int port_type;
-       struct timer_list queue_timer;
-       int wakeup_q;
-       struct platform_device *pdev;
-       struct xlr_net_data *nd;
-
-       u64 *frin_spill;
-       u64 *frout_spill;
-       u64 *class_0_spill;
-       u64 *class_1_spill;
-       u64 *class_2_spill;
-       u64 *class_3_spill;
-};
-
-void xlr_set_gmac_speed(struct xlr_net_priv *priv);
index 55c3d4a..b4820ad 100644 (file)
@@ -107,6 +107,7 @@ static struct rt_channel_plan_map   RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
        {0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
        {0x02}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
        {0x01}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
+       {0x00}, /* 0x13 */
        {0x02}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
        {0x00}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
        {0x00}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
@@ -118,6 +119,7 @@ static struct rt_channel_plan_map   RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
        {0x00}, /* 0x1C, */
        {0x00}, /* 0x1D, */
        {0x00}, /* 0x1E, */
+       {0x00}, /* 0x1F, */
        /*  0x20 ~ 0x7F , New Define ===== */
        {0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
        {0x01}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
@@ -6845,12 +6847,12 @@ void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr, unsi
        struct mlme_ext_priv            *pmlmeext = &padapter->mlmeextpriv;
        struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
 
-       pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
+       pcmd_obj = kzalloc(sizeof(*pcmd_obj), GFP_ATOMIC);
        if (!pcmd_obj)
                return;
 
        cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
-       pevtcmd = kzalloc(cmdsz, GFP_KERNEL);
+       pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
        if (!pevtcmd) {
                kfree(pcmd_obj);
                return;
index 52d42e5..9404355 100644 (file)
@@ -1980,6 +1980,7 @@ static int rtw_wx_read32(struct net_device *dev,
        u32 data32;
        u32 bytes;
        u8 *ptmp;
+       int ret;
 
        padapter = (struct adapter *)rtw_netdev_priv(dev);
        p = &wrqu->data;
@@ -2007,12 +2008,17 @@ static int rtw_wx_read32(struct net_device *dev,
                break;
        default:
                DBG_88E(KERN_INFO "%s: usage> read [bytes],[address(hex)]\n", __func__);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err_free_ptmp;
        }
        DBG_88E(KERN_INFO "%s: addr = 0x%08X data =%s\n", __func__, addr, extra);
 
        kfree(ptmp);
        return 0;
+
+err_free_ptmp:
+       kfree(ptmp);
+       return ret;
 }
 
 static int rtw_wx_write32(struct net_device *dev,
index a9b6ffd..f7ce724 100644 (file)
@@ -112,7 +112,7 @@ void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie)
 
        buff = NULL;
        if (authmode == _WPA_IE_ID_) {
-               buff = kzalloc(IW_CUSTOM_MAX, GFP_KERNEL);
+               buff = kzalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
                if (!buff)
                        return;
                p = buff;
index d2e9df6..b9ce718 100644 (file)
@@ -2549,13 +2549,14 @@ static void _rtl92e_pci_disconnect(struct pci_dev *pdev)
                        free_irq(dev->irq, dev);
                        priv->irq = 0;
                }
-               free_rtllib(dev);
 
                if (dev->mem_start != 0) {
                        iounmap((void __iomem *)dev->mem_start);
                        release_mem_region(pci_resource_start(pdev, 1),
                                        pci_resource_len(pdev, 1));
                }
+
+               free_rtllib(dev);
        }
 
        pci_disable_device(pdev);
index 0b65de9..95a88f6 100644 (file)
@@ -520,7 +520,7 @@ static ssize_t target_fabric_port_alua_tg_pt_gp_show(struct config_item *item,
 {
        struct se_lun *lun = item_to_lun(item);
 
-       if (!lun || !lun->lun_se_dev)
+       if (!lun->lun_se_dev)
                return -ENODEV;
 
        return core_alua_show_tg_pt_gp_info(lun, page);
@@ -531,7 +531,7 @@ static ssize_t target_fabric_port_alua_tg_pt_gp_store(struct config_item *item,
 {
        struct se_lun *lun = item_to_lun(item);
 
-       if (!lun || !lun->lun_se_dev)
+       if (!lun->lun_se_dev)
                return -ENODEV;
 
        return core_alua_store_tg_pt_gp_info(lun, page, count);
@@ -542,7 +542,7 @@ static ssize_t target_fabric_port_alua_tg_pt_offline_show(
 {
        struct se_lun *lun = item_to_lun(item);
 
-       if (!lun || !lun->lun_se_dev)
+       if (!lun->lun_se_dev)
                return -ENODEV;
 
        return core_alua_show_offline_bit(lun, page);
@@ -553,7 +553,7 @@ static ssize_t target_fabric_port_alua_tg_pt_offline_store(
 {
        struct se_lun *lun = item_to_lun(item);
 
-       if (!lun || !lun->lun_se_dev)
+       if (!lun->lun_se_dev)
                return -ENODEV;
 
        return core_alua_store_offline_bit(lun, page, count);
@@ -564,7 +564,7 @@ static ssize_t target_fabric_port_alua_tg_pt_status_show(
 {
        struct se_lun *lun = item_to_lun(item);
 
-       if (!lun || !lun->lun_se_dev)
+       if (!lun->lun_se_dev)
                return -ENODEV;
 
        return core_alua_show_secondary_status(lun, page);
@@ -575,7 +575,7 @@ static ssize_t target_fabric_port_alua_tg_pt_status_store(
 {
        struct se_lun *lun = item_to_lun(item);
 
-       if (!lun || !lun->lun_se_dev)
+       if (!lun->lun_se_dev)
                return -ENODEV;
 
        return core_alua_store_secondary_status(lun, page, count);
@@ -586,7 +586,7 @@ static ssize_t target_fabric_port_alua_tg_pt_write_md_show(
 {
        struct se_lun *lun = item_to_lun(item);
 
-       if (!lun || !lun->lun_se_dev)
+       if (!lun->lun_se_dev)
                return -ENODEV;
 
        return core_alua_show_secondary_write_metadata(lun, page);
@@ -597,7 +597,7 @@ static ssize_t target_fabric_port_alua_tg_pt_write_md_store(
 {
        struct se_lun *lun = item_to_lun(item);
 
-       if (!lun || !lun->lun_se_dev)
+       if (!lun->lun_se_dev)
                return -ENODEV;
 
        return core_alua_store_secondary_write_metadata(lun, page, count);
index 22703a0..4c76498 100644 (file)
@@ -40,11 +40,11 @@ static void spc_fill_alua_data(struct se_lun *lun, unsigned char *buf)
         *
         * See spc4r17 section 6.4.2 Table 135
         */
-       spin_lock(&lun->lun_tg_pt_gp_lock);
-       tg_pt_gp = lun->lun_tg_pt_gp;
+       rcu_read_lock();
+       tg_pt_gp = rcu_dereference(lun->lun_tg_pt_gp);
        if (tg_pt_gp)
                buf[5] |= tg_pt_gp->tg_pt_gp_alua_access_type;
-       spin_unlock(&lun->lun_tg_pt_gp_lock);
+       rcu_read_unlock();
 }
 
 static u16
@@ -325,14 +325,14 @@ check_t10_vend_desc:
                 * Get the PROTOCOL IDENTIFIER as defined by spc4r17
                 * section 7.5.1 Table 362
                 */
-               spin_lock(&lun->lun_tg_pt_gp_lock);
-               tg_pt_gp = lun->lun_tg_pt_gp;
+               rcu_read_lock();
+               tg_pt_gp = rcu_dereference(lun->lun_tg_pt_gp);
                if (!tg_pt_gp) {
-                       spin_unlock(&lun->lun_tg_pt_gp_lock);
+                       rcu_read_unlock();
                        goto check_lu_gp;
                }
                tg_pt_gp_id = tg_pt_gp->tg_pt_gp_id;
-               spin_unlock(&lun->lun_tg_pt_gp_lock);
+               rcu_read_unlock();
 
                buf[off] = tpg->proto_id << 4;
                buf[off++] |= 0x1; /* CODE SET == Binary */
index 4542482..d8c8683 100644 (file)
@@ -810,10 +810,9 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
                return -EINVAL;
 
        optee = kzalloc(sizeof(*optee), GFP_KERNEL);
-       if (!optee) {
-               rc = -ENOMEM;
-               goto err;
-       }
+       if (!optee)
+               return -ENOMEM;
+
        optee->pool = optee_ffa_config_dyn_shm();
        if (IS_ERR(optee->pool)) {
                rc = PTR_ERR(optee->pool);
index 45c31f3..5d046de 100644 (file)
@@ -5,12 +5,12 @@
 
 config INT340X_THERMAL
        tristate "ACPI INT340X thermal drivers"
-       depends on X86 && ACPI && PCI
+       depends on X86_64 && ACPI && PCI
        select THERMAL_GOV_USER_SPACE
        select ACPI_THERMAL_REL
        select ACPI_FAN
        select INTEL_SOC_DTS_IOSF_CORE
-       select PROC_THERMAL_MMIO_RAPL if X86_64 && POWERCAP
+       select PROC_THERMAL_MMIO_RAPL if POWERCAP
        help
          Newer laptops and tablets that use ACPI may have thermal sensors and
          other devices with thermal control capabilities outside the core
index 648829a..82654dc 100644 (file)
@@ -421,6 +421,8 @@ static void thermal_zone_device_init(struct thermal_zone_device *tz)
 {
        struct thermal_instance *pos;
        tz->temperature = THERMAL_TEMP_INVALID;
+       tz->prev_low_trip = -INT_MAX;
+       tz->prev_high_trip = INT_MAX;
        list_for_each_entry(pos, &tz->thermal_instances, tz_node)
                pos->initialized = false;
 }
index f0bf01e..71e0dd2 100644 (file)
@@ -522,6 +522,7 @@ static struct xenbus_driver xencons_driver = {
        .remove = xencons_remove,
        .resume = xencons_resume,
        .otherend_changed = xencons_backend_changed,
+       .not_essential = true,
 };
 #endif /* CONFIG_HVC_XEN_FRONTEND */
 
index f1d1006..097142f 100644 (file)
@@ -420,15 +420,15 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
        data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0);
        if (IS_ERR(data->phy)) {
                ret = PTR_ERR(data->phy);
-               if (ret == -ENODEV) {
-                       data->phy = devm_usb_get_phy_by_phandle(dev, "phys", 0);
-                       if (IS_ERR(data->phy)) {
-                               ret = PTR_ERR(data->phy);
-                               if (ret == -ENODEV)
-                                       data->phy = NULL;
-                               else
-                                       goto err_clk;
-                       }
+               if (ret != -ENODEV)
+                       goto err_clk;
+               data->phy = devm_usb_get_phy_by_phandle(dev, "phys", 0);
+               if (IS_ERR(data->phy)) {
+                       ret = PTR_ERR(data->phy);
+                       if (ret == -ENODEV)
+                               data->phy = NULL;
+                       else
+                               goto err_clk;
                }
        }
 
index 86658a8..00070a8 100644 (file)
@@ -4700,8 +4700,6 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
        if (oldspeed == USB_SPEED_LOW)
                delay = HUB_LONG_RESET_TIME;
 
-       mutex_lock(hcd->address0_mutex);
-
        /* Reset the device; full speed may morph to high speed */
        /* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */
        retval = hub_port_reset(hub, port1, udev, delay, false);
@@ -5016,7 +5014,6 @@ fail:
                hub_port_disable(hub, port1, 0);
                update_devnum(udev, devnum);    /* for disconnect processing */
        }
-       mutex_unlock(hcd->address0_mutex);
        return retval;
 }
 
@@ -5191,6 +5188,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
        struct usb_port *port_dev = hub->ports[port1 - 1];
        struct usb_device *udev = port_dev->child;
        static int unreliable_port = -1;
+       bool retry_locked;
 
        /* Disconnect any existing devices under this port */
        if (udev) {
@@ -5246,8 +5244,11 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
                unit_load = 100;
 
        status = 0;
-       for (i = 0; i < PORT_INIT_TRIES; i++) {
 
+       for (i = 0; i < PORT_INIT_TRIES; i++) {
+               usb_lock_port(port_dev);
+               mutex_lock(hcd->address0_mutex);
+               retry_locked = true;
                /* reallocate for each attempt, since references
                 * to the previous one can escape in various ways
                 */
@@ -5255,6 +5256,8 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
                if (!udev) {
                        dev_err(&port_dev->dev,
                                        "couldn't allocate usb_device\n");
+                       mutex_unlock(hcd->address0_mutex);
+                       usb_unlock_port(port_dev);
                        goto done;
                }
 
@@ -5276,12 +5279,14 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
                }
 
                /* reset (non-USB 3.0 devices) and get descriptor */
-               usb_lock_port(port_dev);
                status = hub_port_init(hub, udev, port1, i);
-               usb_unlock_port(port_dev);
                if (status < 0)
                        goto loop;
 
+               mutex_unlock(hcd->address0_mutex);
+               usb_unlock_port(port_dev);
+               retry_locked = false;
+
                if (udev->quirks & USB_QUIRK_DELAY_INIT)
                        msleep(2000);
 
@@ -5374,6 +5379,10 @@ loop:
                usb_ep0_reinit(udev);
                release_devnum(udev);
                hub_free_dev(udev);
+               if (retry_locked) {
+                       mutex_unlock(hcd->address0_mutex);
+                       usb_unlock_port(port_dev);
+               }
                usb_put_dev(udev);
                if ((status == -ENOTCONN) || (status == -ENOTSUPP))
                        break;
@@ -5915,6 +5924,8 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
        bos = udev->bos;
        udev->bos = NULL;
 
+       mutex_lock(hcd->address0_mutex);
+
        for (i = 0; i < PORT_INIT_TRIES; ++i) {
 
                /* ep0 maxpacket size may change; let the HCD know about it.
@@ -5924,6 +5935,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
                if (ret >= 0 || ret == -ENOTCONN || ret == -ENODEV)
                        break;
        }
+       mutex_unlock(hcd->address0_mutex);
 
        if (ret < 0)
                goto re_enumerate;
index 4ab4a1d..ab8d7da 100644 (file)
@@ -1198,6 +1198,8 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg,
                        }
                        ctrl |= DXEPCTL_CNAK;
                } else {
+                       hs_req->req.frame_number = hs_ep->target_frame;
+                       hs_req->req.actual = 0;
                        dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, -ENODATA);
                        return;
                }
@@ -2857,9 +2859,12 @@ static void dwc2_gadget_handle_ep_disabled(struct dwc2_hsotg_ep *hs_ep)
 
        do {
                hs_req = get_ep_head(hs_ep);
-               if (hs_req)
+               if (hs_req) {
+                       hs_req->req.frame_number = hs_ep->target_frame;
+                       hs_req->req.actual = 0;
                        dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req,
                                                    -ENODATA);
+               }
                dwc2_gadget_incr_frame_num(hs_ep);
                /* Update current frame number value. */
                hsotg->frame_number = dwc2_hsotg_read_frameno(hsotg);
@@ -2912,8 +2917,11 @@ static void dwc2_gadget_handle_out_token_ep_disabled(struct dwc2_hsotg_ep *ep)
 
        while (dwc2_gadget_target_frame_elapsed(ep)) {
                hs_req = get_ep_head(ep);
-               if (hs_req)
+               if (hs_req) {
+                       hs_req->req.frame_number = ep->target_frame;
+                       hs_req->req.actual = 0;
                        dwc2_hsotg_complete_request(hsotg, ep, hs_req, -ENODATA);
+               }
 
                dwc2_gadget_incr_frame_num(ep);
                /* Update current frame number value. */
@@ -3002,8 +3010,11 @@ static void dwc2_gadget_handle_nak(struct dwc2_hsotg_ep *hs_ep)
 
        while (dwc2_gadget_target_frame_elapsed(hs_ep)) {
                hs_req = get_ep_head(hs_ep);
-               if (hs_req)
+               if (hs_req) {
+                       hs_req->req.frame_number = hs_ep->target_frame;
+                       hs_req->req.actual = 0;
                        dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, -ENODATA);
+               }
 
                dwc2_gadget_incr_frame_num(hs_ep);
                /* Update current frame number value. */
index 89a7883..24beff6 100644 (file)
@@ -59,7 +59,7 @@
 #define DWC2_UNRESERVE_DELAY (msecs_to_jiffies(5))
 
 /* If we get a NAK, wait this long before retrying */
-#define DWC2_RETRY_WAIT_DELAY (1 * 1E6L)
+#define DWC2_RETRY_WAIT_DELAY (1 * NSEC_PER_MSEC)
 
 /**
  * dwc2_periodic_channel_available() - Checks that a channel is available for a
index 643239d..f4c0995 100644 (file)
@@ -1594,9 +1594,11 @@ static int dwc3_probe(struct platform_device *pdev)
 
        dwc3_get_properties(dwc);
 
-       ret = dma_set_mask_and_coherent(dwc->sysdev, DMA_BIT_MASK(64));
-       if (ret)
-               return ret;
+       if (!dwc->sysdev_is_parent) {
+               ret = dma_set_mask_and_coherent(dwc->sysdev, DMA_BIT_MASK(64));
+               if (ret)
+                       return ret;
+       }
 
        dwc->reset = devm_reset_control_array_get_optional_shared(dev);
        if (IS_ERR(dwc->reset))
index 620c8d3..5c491d0 100644 (file)
 #define DWC3_GHWPARAMS8                0xc600
 #define DWC3_GUCTL3            0xc60c
 #define DWC3_GFLADJ            0xc630
-#define DWC3_GHWPARAMS9                0xc680
+#define DWC3_GHWPARAMS9                0xc6e0
 
 /* Device Registers */
 #define DWC3_DCFG              0xc700
index 23de2a5..7e3db00 100644 (file)
@@ -310,13 +310,24 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
        if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_STARTTRANSFER) {
                int link_state;
 
+               /*
+                * Initiate remote wakeup if the link state is in U3 when
+                * operating in SS/SSP or L1/L2 when operating in HS/FS. If the
+                * link state is in U1/U2, no remote wakeup is needed. The Start
+                * Transfer command will initiate the link recovery.
+                */
                link_state = dwc3_gadget_get_link_state(dwc);
-               if (link_state == DWC3_LINK_STATE_U1 ||
-                   link_state == DWC3_LINK_STATE_U2 ||
-                   link_state == DWC3_LINK_STATE_U3) {
+               switch (link_state) {
+               case DWC3_LINK_STATE_U2:
+                       if (dwc->gadget->speed >= USB_SPEED_SUPER)
+                               break;
+
+                       fallthrough;
+               case DWC3_LINK_STATE_U3:
                        ret = __dwc3_gadget_wakeup(dwc);
                        dev_WARN_ONCE(dwc->dev, ret, "wakeup failed --> %d\n",
                                        ret);
+                       break;
                }
        }
 
@@ -3252,6 +3263,9 @@ static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep,
        struct dwc3             *dwc = dep->dwc;
        bool                    no_started_trb = true;
 
+       if (!dep->endpoint.desc)
+               return no_started_trb;
+
        dwc3_gadget_ep_cleanup_completed_requests(dep, event, status);
 
        if (dep->flags & DWC3_EP_END_TRANSFER_PENDING)
@@ -3299,6 +3313,9 @@ static void dwc3_gadget_endpoint_transfer_in_progress(struct dwc3_ep *dep,
 {
        int status = 0;
 
+       if (!dep->endpoint.desc)
+               return;
+
        if (usb_endpoint_xfer_isoc(dep->endpoint.desc))
                dwc3_gadget_endpoint_frame_from_event(dep, event);
 
@@ -3352,6 +3369,14 @@ static void dwc3_gadget_endpoint_command_complete(struct dwc3_ep *dep,
        if (cmd != DWC3_DEPCMD_ENDTRANSFER)
                return;
 
+       /*
+        * The END_TRANSFER command will cause the controller to generate a
+        * NoStream Event, and it's not due to the host DP NoStream rejection.
+        * Ignore the next NoStream event.
+        */
+       if (dep->stream_capable)
+               dep->flags |= DWC3_EP_IGNORE_NEXT_NOSTREAM;
+
        dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
        dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
        dwc3_gadget_ep_cleanup_cancelled_requests(dep);
@@ -3574,14 +3599,6 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
        WARN_ON_ONCE(ret);
        dep->resource_index = 0;
 
-       /*
-        * The END_TRANSFER command will cause the controller to generate a
-        * NoStream Event, and it's not due to the host DP NoStream rejection.
-        * Ignore the next NoStream event.
-        */
-       if (dep->stream_capable)
-               dep->flags |= DWC3_EP_IGNORE_NEXT_NOSTREAM;
-
        if (!interrupt)
                dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
        else
index f5ca670..857159d 100644 (file)
@@ -2136,7 +2136,7 @@ static int xudc_probe(struct platform_device *pdev)
 
        ret = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
        if (ret)
-               goto fail;
+               goto err_disable_unprepare_clk;
 
        udc->dev = &udc->gadget.dev;
 
@@ -2155,6 +2155,9 @@ static int xudc_probe(struct platform_device *pdev)
                 udc->dma_enabled ? "with DMA" : "without DMA");
 
        return 0;
+
+err_disable_unprepare_clk:
+       clk_disable_unprepare(udc->clk);
 fail:
        dev_err(&pdev->dev, "probe failed, %d\n", ret);
        return ret;
index 1bf494b..c8af2cd 100644 (file)
@@ -1400,6 +1400,7 @@ static void tegra_xusb_deinit_usb_phy(struct tegra_xusb *tegra)
 
 static int tegra_xusb_probe(struct platform_device *pdev)
 {
+       struct of_phandle_args args;
        struct tegra_xusb *tegra;
        struct device_node *np;
        struct resource *regs;
@@ -1454,10 +1455,17 @@ static int tegra_xusb_probe(struct platform_device *pdev)
                goto put_padctl;
        }
 
-       tegra->padctl_irq = of_irq_get(np, 0);
-       if (tegra->padctl_irq <= 0) {
-               err = (tegra->padctl_irq == 0) ? -ENODEV : tegra->padctl_irq;
-               goto put_padctl;
+       /* Older device-trees don't have padctrl interrupt */
+       err = of_irq_parse_one(np, 0, &args);
+       if (!err) {
+               tegra->padctl_irq = of_irq_get(np, 0);
+               if (tegra->padctl_irq <= 0) {
+                       err = (tegra->padctl_irq == 0) ? -ENODEV : tegra->padctl_irq;
+                       goto put_padctl;
+               }
+       } else {
+               dev_dbg(&pdev->dev,
+                       "%pOF is missing an interrupt, disabling PM support\n", np);
        }
 
        tegra->host_clk = devm_clk_get(&pdev->dev, "xusb_host");
@@ -1696,11 +1704,15 @@ static int tegra_xusb_probe(struct platform_device *pdev)
                goto remove_usb3;
        }
 
-       err = devm_request_threaded_irq(&pdev->dev, tegra->padctl_irq, NULL, tegra_xusb_padctl_irq,
-                                       IRQF_ONESHOT, dev_name(&pdev->dev), tegra);
-       if (err < 0) {
-               dev_err(&pdev->dev, "failed to request padctl IRQ: %d\n", err);
-               goto remove_usb3;
+       if (tegra->padctl_irq) {
+               err = devm_request_threaded_irq(&pdev->dev, tegra->padctl_irq,
+                                               NULL, tegra_xusb_padctl_irq,
+                                               IRQF_ONESHOT, dev_name(&pdev->dev),
+                                               tegra);
+               if (err < 0) {
+                       dev_err(&pdev->dev, "failed to request padctl IRQ: %d\n", err);
+                       goto remove_usb3;
+               }
        }
 
        err = tegra_xusb_enable_firmware_messages(tegra);
@@ -1718,13 +1730,16 @@ static int tegra_xusb_probe(struct platform_device *pdev)
        /* Enable wake for both USB 2.0 and USB 3.0 roothubs */
        device_init_wakeup(&tegra->hcd->self.root_hub->dev, true);
        device_init_wakeup(&xhci->shared_hcd->self.root_hub->dev, true);
-       device_init_wakeup(tegra->dev, true);
 
        pm_runtime_use_autosuspend(tegra->dev);
        pm_runtime_set_autosuspend_delay(tegra->dev, 2000);
        pm_runtime_mark_last_busy(tegra->dev);
        pm_runtime_set_active(tegra->dev);
-       pm_runtime_enable(tegra->dev);
+
+       if (tegra->padctl_irq) {
+               device_init_wakeup(tegra->dev, true);
+               pm_runtime_enable(tegra->dev);
+       }
 
        return 0;
 
@@ -1772,7 +1787,9 @@ static int tegra_xusb_remove(struct platform_device *pdev)
        dma_free_coherent(&pdev->dev, tegra->fw.size, tegra->fw.virt,
                          tegra->fw.phys);
 
-       pm_runtime_disable(&pdev->dev);
+       if (tegra->padctl_irq)
+               pm_runtime_disable(&pdev->dev);
+
        pm_runtime_put(&pdev->dev);
 
        tegra_xusb_powergate_partitions(tegra);
index a484ff5..546fce4 100644 (file)
@@ -1267,6 +1267,8 @@ static const struct usb_device_id option_ids[] = {
          .driver_info = NCTRL(2) },
        { USB_DEVICE(TELIT_VENDOR_ID, 0x9010),                          /* Telit SBL FN980 flashing device */
          .driver_info = NCTRL(0) | ZLP },
+       { USB_DEVICE(TELIT_VENDOR_ID, 0x9200),                          /* Telit LE910S1 flashing device */
+         .driver_info = NCTRL(0) | ZLP },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff),
          .driver_info = RSVD(1) },
@@ -2094,6 +2096,9 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0xff, 0x30) },    /* Fibocom FG150 Diag */
        { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0, 0) },          /* Fibocom FG150 AT */
        { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) },                   /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */
+       { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a2, 0xff) },                   /* Fibocom FM101-GL (laptop MBIM) */
+       { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a4, 0xff),                     /* Fibocom FM101-GL (laptop MBIM) */
+         .driver_info = RSVD(4) },
        { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) },                   /* LongSung M5710 */
        { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) },                   /* GosunCn GM500 RNDIS */
        { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) },                   /* GosunCn GM500 MBIM */
index f45ca7d..a70fd86 100644 (file)
@@ -432,6 +432,7 @@ static int pl2303_detect_type(struct usb_serial *serial)
        case 0x200:
                switch (bcdDevice) {
                case 0x100:
+               case 0x105:
                case 0x305:
                case 0x405:
                        /*
index 7a2a178..72f9001 100644 (file)
@@ -669,25 +669,27 @@ static int tcpm_set_cc(struct tcpc_dev *dev, enum typec_cc_status cc)
                ret = fusb302_i2c_mask_write(chip, FUSB_REG_MASK,
                                             FUSB_REG_MASK_BC_LVL |
                                             FUSB_REG_MASK_COMP_CHNG,
-                                            FUSB_REG_MASK_COMP_CHNG);
+                                            FUSB_REG_MASK_BC_LVL);
                if (ret < 0) {
                        fusb302_log(chip, "cannot set SRC interrupt, ret=%d",
                                    ret);
                        goto done;
                }
                chip->intr_comp_chng = true;
+               chip->intr_bc_lvl = false;
                break;
        case TYPEC_CC_RD:
                ret = fusb302_i2c_mask_write(chip, FUSB_REG_MASK,
                                             FUSB_REG_MASK_BC_LVL |
                                             FUSB_REG_MASK_COMP_CHNG,
-                                            FUSB_REG_MASK_BC_LVL);
+                                            FUSB_REG_MASK_COMP_CHNG);
                if (ret < 0) {
                        fusb302_log(chip, "cannot set SRC interrupt, ret=%d",
                                    ret);
                        goto done;
                }
                chip->intr_bc_lvl = true;
+               chip->intr_comp_chng = false;
                break;
        default:
                break;
index fb8ef12..6d27a5b 100644 (file)
@@ -653,7 +653,7 @@ static int cd321x_switch_power_state(struct tps6598x *tps, u8 target_state)
        if (state == target_state)
                return 0;
 
-       ret = tps6598x_exec_cmd(tps, "SPSS", sizeof(u8), &target_state, 0, NULL);
+       ret = tps6598x_exec_cmd(tps, "SSPS", sizeof(u8), &target_state, 0, NULL);
        if (ret)
                return ret;
 
@@ -707,6 +707,7 @@ static int tps6598x_probe(struct i2c_client *client)
        u32 conf;
        u32 vid;
        int ret;
+       u64 mask1;
 
        tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
        if (!tps)
@@ -730,11 +731,6 @@ static int tps6598x_probe(struct i2c_client *client)
        if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
                tps->i2c_protocol = true;
 
-       /* Make sure the controller has application firmware running */
-       ret = tps6598x_check_mode(tps);
-       if (ret)
-               return ret;
-
        if (np && of_device_is_compatible(np, "apple,cd321x")) {
                /* Switch CD321X chips to the correct system power state */
                ret = cd321x_switch_power_state(tps, TPS_SYSTEM_POWER_STATE_S0);
@@ -742,24 +738,27 @@ static int tps6598x_probe(struct i2c_client *client)
                        return ret;
 
                /* CD321X chips have all interrupts masked initially */
-               ret = tps6598x_write64(tps, TPS_REG_INT_MASK1,
-                                       APPLE_CD_REG_INT_POWER_STATUS_UPDATE |
-                                       APPLE_CD_REG_INT_DATA_STATUS_UPDATE |
-                                       APPLE_CD_REG_INT_PLUG_EVENT);
-               if (ret)
-                       return ret;
+               mask1 = APPLE_CD_REG_INT_POWER_STATUS_UPDATE |
+                       APPLE_CD_REG_INT_DATA_STATUS_UPDATE |
+                       APPLE_CD_REG_INT_PLUG_EVENT;
 
                irq_handler = cd321x_interrupt;
        } else {
                /* Enable power status, data status and plug event interrupts */
-               ret = tps6598x_write64(tps, TPS_REG_INT_MASK1,
-                                      TPS_REG_INT_POWER_STATUS_UPDATE |
-                                      TPS_REG_INT_DATA_STATUS_UPDATE |
-                                      TPS_REG_INT_PLUG_EVENT);
-               if (ret)
-                       return ret;
+               mask1 = TPS_REG_INT_POWER_STATUS_UPDATE |
+                       TPS_REG_INT_DATA_STATUS_UPDATE |
+                       TPS_REG_INT_PLUG_EVENT;
        }
 
+       /* Make sure the controller has application firmware running */
+       ret = tps6598x_check_mode(tps);
+       if (ret)
+               return ret;
+
+       ret = tps6598x_write64(tps, TPS_REG_INT_MASK1, mask1);
+       if (ret)
+               return ret;
+
        ret = tps6598x_read32(tps, TPS_REG_STATUS, &status);
        if (ret < 0)
                return ret;
index 5f484ff..41b0cd1 100644 (file)
@@ -591,8 +591,11 @@ static void vdpasim_free(struct vdpa_device *vdpa)
                vringh_kiov_cleanup(&vdpasim->vqs[i].in_iov);
        }
 
-       put_iova_domain(&vdpasim->iova);
-       iova_cache_put();
+       if (vdpa_get_dma_dev(vdpa)) {
+               put_iova_domain(&vdpasim->iova);
+               iova_cache_put();
+       }
+
        kvfree(vdpasim->buffer);
        if (vdpasim->iommu)
                vhost_iotlb_free(vdpasim->iommu);
index 01c59ce..29cced1 100644 (file)
@@ -1014,12 +1014,12 @@ static int vhost_vdpa_release(struct inode *inode, struct file *filep)
 
        mutex_lock(&d->mutex);
        filep->private_data = NULL;
+       vhost_vdpa_clean_irq(v);
        vhost_vdpa_reset(v);
        vhost_dev_stop(&v->vdev);
        vhost_vdpa_iotlb_free(v);
        vhost_vdpa_free_domain(v);
        vhost_vdpa_config_put(v);
-       vhost_vdpa_clean_irq(v);
        vhost_dev_cleanup(&v->vdev);
        kfree(v->vdev.vqs);
        mutex_unlock(&d->mutex);
index 938aefb..d6ca1c7 100644 (file)
@@ -511,8 +511,6 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work)
 
        vhost_disable_notify(&vsock->dev, vq);
        do {
-               u32 len;
-
                if (!vhost_vsock_more_replies(vsock)) {
                        /* Stop tx until the device processes already
                         * pending replies.  Leave tx virtqueue
@@ -540,7 +538,7 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work)
                        continue;
                }
 
-               len = pkt->len;
+               total_len += sizeof(pkt->hdr) + pkt->len;
 
                /* Deliver to monitoring devices all received packets */
                virtio_transport_deliver_tap_pkt(pkt);
@@ -553,9 +551,7 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work)
                else
                        virtio_transport_free_pkt(pkt);
 
-               len += sizeof(pkt->hdr);
-               vhost_add_used(vq, head, len);
-               total_len += len;
+               vhost_add_used(vq, head, 0);
                added = true;
        } while(likely(!vhost_exceeds_weight(vq, ++pkts, total_len)));
 
index 1b45116..40496e9 100644 (file)
@@ -332,13 +332,13 @@ static u8 sticon_build_attr(struct vc_data *conp, u8 color,
                            bool blink, bool underline, bool reverse,
                            bool italic)
 {
-    u8 attr = ((color & 0x70) >> 1) | ((color & 7));
+       u8 fg = color & 7;
+       u8 bg = (color & 0x70) >> 4;
 
-    if (reverse) {
-       color = ((color >> 3) & 0x7) | ((color & 0x7) << 3);
-    }
-
-    return attr;
+       if (reverse)
+               return (fg << 3) | bg;
+       else
+               return (bg << 3) | fg;
 }
 
 static void sticon_invert_region(struct vc_data *conp, u16 *p, int count)
index edca370..ea42ba6 100644 (file)
@@ -351,6 +351,17 @@ static int efifb_probe(struct platform_device *dev)
        char *option = NULL;
        efi_memory_desc_t md;
 
+       /*
+        * Generic drivers must not be registered if a framebuffer exists.
+        * If a native driver was probed, the display hardware was already
+        * taken and attempting to use the system framebuffer is dangerous.
+        */
+       if (num_registered_fb > 0) {
+               dev_err(&dev->dev,
+                       "efifb: a framebuffer is already registered\n");
+               return -EINVAL;
+       }
+
        if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
                return -ENODEV;
 
index 62f0ded..b63074f 100644 (file)
@@ -407,6 +407,17 @@ static int simplefb_probe(struct platform_device *pdev)
        struct simplefb_par *par;
        struct resource *mem;
 
+       /*
+        * Generic drivers must not be registered if a framebuffer exists.
+        * If a native driver was probed, the display hardware was already
+        * taken and attempting to use the system framebuffer is dangerous.
+        */
+       if (num_registered_fb > 0) {
+               dev_err(&pdev->dev,
+                       "simplefb: a framebuffer is already registered\n");
+               return -EINVAL;
+       }
+
        if (fb_get_options("simplefb", NULL))
                return -ENODEV;
 
index 5ec5144..6826f98 100644 (file)
@@ -695,6 +695,7 @@ static struct xenbus_driver xenfb_driver = {
        .remove = xenfb_remove,
        .resume = xenfb_resume,
        .otherend_changed = xenfb_backend_changed,
+       .not_essential = true,
 };
 
 static int __init xenfb_init(void)
index 00f64f2..6d2614e 100644 (file)
@@ -14,9 +14,6 @@
 #include <linux/spinlock.h>
 #include <xen/xen.h>
 
-static bool force_used_validation = false;
-module_param(force_used_validation, bool, 0444);
-
 #ifdef DEBUG
 /* For development, we want to crash whenever the ring is screwed. */
 #define BAD_RING(_vq, fmt, args...)                            \
@@ -185,9 +182,6 @@ struct vring_virtqueue {
                } packed;
        };
 
-       /* Per-descriptor in buffer length */
-       u32 *buflen;
-
        /* How to notify other side. FIXME: commonalize hcalls! */
        bool (*notify)(struct virtqueue *vq);
 
@@ -496,7 +490,6 @@ static inline int virtqueue_add_split(struct virtqueue *_vq,
        unsigned int i, n, avail, descs_used, prev, err_idx;
        int head;
        bool indirect;
-       u32 buflen = 0;
 
        START_USE(vq);
 
@@ -578,7 +571,6 @@ static inline int virtqueue_add_split(struct virtqueue *_vq,
                                                     VRING_DESC_F_NEXT |
                                                     VRING_DESC_F_WRITE,
                                                     indirect);
-                       buflen += sg->length;
                }
        }
        /* Last one doesn't continue. */
@@ -618,10 +610,6 @@ static inline int virtqueue_add_split(struct virtqueue *_vq,
        else
                vq->split.desc_state[head].indir_desc = ctx;
 
-       /* Store in buffer length if necessary */
-       if (vq->buflen)
-               vq->buflen[head] = buflen;
-
        /* Put entry in available array (but don't update avail->idx until they
         * do sync). */
        avail = vq->split.avail_idx_shadow & (vq->split.vring.num - 1);
@@ -796,11 +784,6 @@ static void *virtqueue_get_buf_ctx_split(struct virtqueue *_vq,
                BAD_RING(vq, "id %u is not a head!\n", i);
                return NULL;
        }
-       if (vq->buflen && unlikely(*len > vq->buflen[i])) {
-               BAD_RING(vq, "used len %d is larger than in buflen %u\n",
-                       *len, vq->buflen[i]);
-               return NULL;
-       }
 
        /* detach_buf_split clears data, so grab it now. */
        ret = vq->split.desc_state[i].data;
@@ -1079,7 +1062,6 @@ static int virtqueue_add_indirect_packed(struct vring_virtqueue *vq,
        unsigned int i, n, err_idx;
        u16 head, id;
        dma_addr_t addr;
-       u32 buflen = 0;
 
        head = vq->packed.next_avail_idx;
        desc = alloc_indirect_packed(total_sg, gfp);
@@ -1109,8 +1091,6 @@ static int virtqueue_add_indirect_packed(struct vring_virtqueue *vq,
                        desc[i].addr = cpu_to_le64(addr);
                        desc[i].len = cpu_to_le32(sg->length);
                        i++;
-                       if (n >= out_sgs)
-                               buflen += sg->length;
                }
        }
 
@@ -1164,10 +1144,6 @@ static int virtqueue_add_indirect_packed(struct vring_virtqueue *vq,
        vq->packed.desc_state[id].indir_desc = desc;
        vq->packed.desc_state[id].last = id;
 
-       /* Store in buffer length if necessary */
-       if (vq->buflen)
-               vq->buflen[id] = buflen;
-
        vq->num_added += 1;
 
        pr_debug("Added buffer head %i to %p\n", head, vq);
@@ -1203,7 +1179,6 @@ static inline int virtqueue_add_packed(struct virtqueue *_vq,
        __le16 head_flags, flags;
        u16 head, id, prev, curr, avail_used_flags;
        int err;
-       u32 buflen = 0;
 
        START_USE(vq);
 
@@ -1283,8 +1258,6 @@ static inline int virtqueue_add_packed(struct virtqueue *_vq,
                                        1 << VRING_PACKED_DESC_F_AVAIL |
                                        1 << VRING_PACKED_DESC_F_USED;
                        }
-                       if (n >= out_sgs)
-                               buflen += sg->length;
                }
        }
 
@@ -1304,10 +1277,6 @@ static inline int virtqueue_add_packed(struct virtqueue *_vq,
        vq->packed.desc_state[id].indir_desc = ctx;
        vq->packed.desc_state[id].last = prev;
 
-       /* Store in buffer length if necessary */
-       if (vq->buflen)
-               vq->buflen[id] = buflen;
-
        /*
         * A driver MUST NOT make the first descriptor in the list
         * available before all subsequent descriptors comprising
@@ -1494,11 +1463,6 @@ static void *virtqueue_get_buf_ctx_packed(struct virtqueue *_vq,
                BAD_RING(vq, "id %u is not a head!\n", id);
                return NULL;
        }
-       if (vq->buflen && unlikely(*len > vq->buflen[id])) {
-               BAD_RING(vq, "used len %d is larger than in buflen %u\n",
-                       *len, vq->buflen[id]);
-               return NULL;
-       }
 
        /* detach_buf_packed clears data, so grab it now. */
        ret = vq->packed.desc_state[id].data;
@@ -1704,7 +1668,6 @@ static struct virtqueue *vring_create_virtqueue_packed(
        struct vring_virtqueue *vq;
        struct vring_packed_desc *ring;
        struct vring_packed_desc_event *driver, *device;
-       struct virtio_driver *drv = drv_to_virtio(vdev->dev.driver);
        dma_addr_t ring_dma_addr, driver_event_dma_addr, device_event_dma_addr;
        size_t ring_size_in_bytes, event_size_in_bytes;
 
@@ -1794,15 +1757,6 @@ static struct virtqueue *vring_create_virtqueue_packed(
        if (!vq->packed.desc_extra)
                goto err_desc_extra;
 
-       if (!drv->suppress_used_validation || force_used_validation) {
-               vq->buflen = kmalloc_array(num, sizeof(*vq->buflen),
-                                          GFP_KERNEL);
-               if (!vq->buflen)
-                       goto err_buflen;
-       } else {
-               vq->buflen = NULL;
-       }
-
        /* No callback?  Tell other side not to bother us. */
        if (!callback) {
                vq->packed.event_flags_shadow = VRING_PACKED_EVENT_FLAG_DISABLE;
@@ -1815,8 +1769,6 @@ static struct virtqueue *vring_create_virtqueue_packed(
        spin_unlock(&vdev->vqs_list_lock);
        return &vq->vq;
 
-err_buflen:
-       kfree(vq->packed.desc_extra);
 err_desc_extra:
        kfree(vq->packed.desc_state);
 err_desc_state:
@@ -2224,7 +2176,6 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index,
                                        void (*callback)(struct virtqueue *),
                                        const char *name)
 {
-       struct virtio_driver *drv = drv_to_virtio(vdev->dev.driver);
        struct vring_virtqueue *vq;
 
        if (virtio_has_feature(vdev, VIRTIO_F_RING_PACKED))
@@ -2284,15 +2235,6 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index,
        if (!vq->split.desc_extra)
                goto err_extra;
 
-       if (!drv->suppress_used_validation || force_used_validation) {
-               vq->buflen = kmalloc_array(vring.num, sizeof(*vq->buflen),
-                                          GFP_KERNEL);
-               if (!vq->buflen)
-                       goto err_buflen;
-       } else {
-               vq->buflen = NULL;
-       }
-
        /* Put everything in free lists. */
        vq->free_head = 0;
        memset(vq->split.desc_state, 0, vring.num *
@@ -2303,8 +2245,6 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index,
        spin_unlock(&vdev->vqs_list_lock);
        return &vq->vq;
 
-err_buflen:
-       kfree(vq->split.desc_extra);
 err_extra:
        kfree(vq->split.desc_state);
 err_state:
index a1b11c6..33e941e 100644 (file)
@@ -259,9 +259,15 @@ config XEN_SCSI_BACKEND
          if guests need generic access to SCSI devices.
 
 config XEN_PRIVCMD
-       tristate
+       tristate "Xen hypercall passthrough driver"
        depends on XEN
        default m
+       help
+         The hypercall passthrough driver allows privileged user programs to
+         perform Xen hypercalls. This driver is normally required for systems
+         running as Dom0 to perform privileged operations, but in some
+         disaggregated Xen setups this driver might be needed for other
+         domains, too.
 
 config XEN_ACPI_PROCESSOR
        tristate "Xen ACPI processor"
index 7984645..3c9ae15 100644 (file)
@@ -1275,6 +1275,7 @@ static struct xenbus_driver pvcalls_front_driver = {
        .probe = pvcalls_front_probe,
        .remove = pvcalls_front_remove,
        .otherend_changed = pvcalls_front_changed,
+       .not_essential = true,
 };
 
 static int __init pvcalls_frontend_init(void)
index bd003ca..fe360c3 100644 (file)
@@ -909,7 +909,7 @@ static struct notifier_block xenbus_resume_nb = {
 
 static int __init xenbus_init(void)
 {
-       int err = 0;
+       int err;
        uint64_t v = 0;
        xen_store_domain_type = XS_UNKNOWN;
 
@@ -949,6 +949,29 @@ static int __init xenbus_init(void)
                err = hvm_get_parameter(HVM_PARAM_STORE_PFN, &v);
                if (err)
                        goto out_error;
+               /*
+                * Uninitialized hvm_params are zero and return no error.
+                * Although it is theoretically possible to have
+                * HVM_PARAM_STORE_PFN set to zero on purpose, in reality it is
+                * not zero when valid. If zero, it means that Xenstore hasn't
+                * been properly initialized. Instead of attempting to map a
+                * wrong guest physical address return error.
+                *
+                * Also recognize all bits set as an invalid value.
+                */
+               if (!v || !~v) {
+                       err = -ENOENT;
+                       goto out_error;
+               }
+               /* Avoid truncation on 32-bit. */
+#if BITS_PER_LONG == 32
+               if (v > ULONG_MAX) {
+                       pr_err("%s: cannot handle HVM_PARAM_STORE_PFN=%llx > ULONG_MAX\n",
+                              __func__, v);
+                       err = -EINVAL;
+                       goto out_error;
+               }
+#endif
                xen_store_gfn = (unsigned long)v;
                xen_store_interface =
                        xen_remap(xen_store_gfn << XEN_PAGE_SHIFT,
@@ -983,8 +1006,10 @@ static int __init xenbus_init(void)
         */
        proc_create_mount_point("xen");
 #endif
+       return 0;
 
 out_error:
+       xen_store_domain_type = XS_UNKNOWN;
        return err;
 }
 
index 4809446..07b010a 100644 (file)
@@ -211,19 +211,11 @@ static int is_device_connecting(struct device *dev, void *data, bool ignore_none
        if (drv && (dev->driver != drv))
                return 0;
 
-       if (ignore_nonessential) {
-               /* With older QEMU, for PVonHVM guests the guest config files
-                * could contain: vfb = [ 'vnc=1, vnclisten=0.0.0.0']
-                * which is nonsensical as there is no PV FB (there can be
-                * a PVKB) running as HVM guest. */
+       xendrv = to_xenbus_driver(dev->driver);
 
-               if ((strncmp(xendev->nodename, "device/vkbd", 11) == 0))
-                       return 0;
+       if (ignore_nonessential && xendrv->not_essential)
+               return 0;
 
-               if ((strncmp(xendev->nodename, "device/vfb", 10) == 0))
-                       return 0;
-       }
-       xendrv = to_xenbus_driver(dev->driver);
        return (xendev->state < XenbusStateConnected ||
                (xendev->state == XenbusStateConnected &&
                 xendrv->is_ready && !xendrv->is_ready(xendev)));
index 473d21b..66899b6 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -35,7 +35,7 @@ static bool chown_ok(struct user_namespace *mnt_userns,
                     kuid_t uid)
 {
        kuid_t kuid = i_uid_into_mnt(mnt_userns, inode);
-       if (uid_eq(current_fsuid(), kuid) && uid_eq(uid, kuid))
+       if (uid_eq(current_fsuid(), kuid) && uid_eq(uid, inode->i_uid))
                return true;
        if (capable_wrt_inode_uidgid(mnt_userns, inode, CAP_CHOWN))
                return true;
@@ -62,7 +62,7 @@ static bool chgrp_ok(struct user_namespace *mnt_userns,
 {
        kgid_t kgid = i_gid_into_mnt(mnt_userns, inode);
        if (uid_eq(current_fsuid(), i_uid_into_mnt(mnt_userns, inode)) &&
-           (in_group_p(gid) || gid_eq(gid, kgid)))
+           (in_group_p(gid) || gid_eq(gid, inode->i_gid)))
                return true;
        if (capable_wrt_inode_uidgid(mnt_userns, inode, CAP_CHOWN))
                return true;
index 309516e..43c8995 100644 (file)
@@ -234,6 +234,13 @@ static void run_ordered_work(struct __btrfs_workqueue *wq,
                                  ordered_list);
                if (!test_bit(WORK_DONE_BIT, &work->flags))
                        break;
+               /*
+                * Orders all subsequent loads after reading WORK_DONE_BIT,
+                * paired with the smp_mb__before_atomic in btrfs_work_helper
+                * this guarantees that the ordered function will see all
+                * updates from ordinary work function.
+                */
+               smp_rmb();
 
                /*
                 * we are going to call the ordered done function, but
@@ -317,6 +324,13 @@ static void btrfs_work_helper(struct work_struct *normal_work)
        thresh_exec_hook(wq);
        work->func(work);
        if (need_order) {
+               /*
+                * Ensures all memory accesses done in the work function are
+                * ordered before setting the WORK_DONE_BIT. Ensuring the thread
+                * which is going to executed the ordered work sees them.
+                * Pairs with the smp_rmb in run_ordered_work.
+                */
+               smp_mb__before_atomic();
                set_bit(WORK_DONE_BIT, &work->flags);
                run_ordered_work(wq, work);
        } else {
index 59c3be8..514ead6 100644 (file)
@@ -3978,11 +3978,23 @@ static void btrfs_end_empty_barrier(struct bio *bio)
  */
 static void write_dev_flush(struct btrfs_device *device)
 {
-       struct request_queue *q = bdev_get_queue(device->bdev);
        struct bio *bio = device->flush_bio;
 
+#ifndef CONFIG_BTRFS_FS_CHECK_INTEGRITY
+       /*
+        * When a disk has write caching disabled, we skip submission of a bio
+        * with flush and sync requests before writing the superblock, since
+        * it's not needed. However when the integrity checker is enabled, this
+        * results in reports that there are metadata blocks referred by a
+        * superblock that were not properly flushed. So don't skip the bio
+        * submission only when the integrity checker is enabled for the sake
+        * of simplicity, since this is a debug tool and not meant for use in
+        * non-debug builds.
+        */
+       struct request_queue *q = bdev_get_queue(device->bdev);
        if (!test_bit(QUEUE_FLAG_WC, &q->queue_flags))
                return;
+#endif
 
        bio_reset(bio);
        bio->bi_end_io = btrfs_end_empty_barrier;
index fb8cc96..92138ac 100644 (file)
@@ -3985,6 +3985,10 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
        bool need_unlock; /* for mut. excl. ops lock */
        int ret;
 
+       if (!arg)
+               btrfs_warn(fs_info,
+       "IOC_BALANCE ioctl (v1) is deprecated and will be removed in kernel 5.18");
+
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
index 65cb076..0fb90cb 100644 (file)
@@ -125,6 +125,7 @@ static inline size_t read_compress_length(const char *buf)
 static int copy_compressed_data_to_page(char *compressed_data,
                                        size_t compressed_size,
                                        struct page **out_pages,
+                                       unsigned long max_nr_page,
                                        u32 *cur_out,
                                        const u32 sectorsize)
 {
@@ -133,6 +134,9 @@ static int copy_compressed_data_to_page(char *compressed_data,
        struct page *cur_page;
        char *kaddr;
 
+       if ((*cur_out / PAGE_SIZE) >= max_nr_page)
+               return -E2BIG;
+
        /*
         * We never allow a segment header crossing sector boundary, previous
         * run should ensure we have enough space left inside the sector.
@@ -161,6 +165,10 @@ static int copy_compressed_data_to_page(char *compressed_data,
                                     orig_out + compressed_size - *cur_out);
 
                kunmap(cur_page);
+
+               if ((*cur_out / PAGE_SIZE) >= max_nr_page)
+                       return -E2BIG;
+
                cur_page = out_pages[*cur_out / PAGE_SIZE];
                /* Allocate a new page */
                if (!cur_page) {
@@ -203,6 +211,7 @@ int lzo_compress_pages(struct list_head *ws, struct address_space *mapping,
        const u32 sectorsize = btrfs_sb(mapping->host->i_sb)->sectorsize;
        struct page *page_in = NULL;
        char *sizes_ptr;
+       const unsigned long max_nr_page = *out_pages;
        int ret = 0;
        /* Points to the file offset of input data */
        u64 cur_in = start;
@@ -210,6 +219,7 @@ int lzo_compress_pages(struct list_head *ws, struct address_space *mapping,
        u32 cur_out = 0;
        u32 len = *total_out;
 
+       ASSERT(max_nr_page > 0);
        *out_pages = 0;
        *total_out = 0;
        *total_in = 0;
@@ -248,7 +258,8 @@ int lzo_compress_pages(struct list_head *ws, struct address_space *mapping,
                }
 
                ret = copy_compressed_data_to_page(workspace->cbuf, out_len,
-                                                  pages, &cur_out, sectorsize);
+                                                  pages, max_nr_page,
+                                                  &cur_out, sectorsize);
                if (ret < 0)
                        goto out;
 
@@ -279,6 +290,8 @@ int lzo_compress_pages(struct list_head *ws, struct address_space *mapping,
        *total_out = cur_out;
        *total_in = cur_in - start;
 out:
+       if (page_in)
+               put_page(page_in);
        *out_pages = DIV_ROUND_UP(cur_out, PAGE_SIZE);
        return ret;
 }
index cf82ea6..8f6ceea 100644 (file)
@@ -73,8 +73,8 @@ struct scrub_page {
        u64                     physical_for_dev_replace;
        atomic_t                refs;
        u8                      mirror_num;
-       int                     have_csum:1;
-       int                     io_error:1;
+       unsigned int            have_csum:1;
+       unsigned int            io_error:1;
        u8                      csum[BTRFS_CSUM_SIZE];
 
        struct scrub_recover    *recover;
index 61ac57b..0997e3c 100644 (file)
@@ -7558,6 +7558,19 @@ int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info)
         */
        fs_info->fs_devices->total_rw_bytes = 0;
 
+       /*
+        * Lockdep complains about possible circular locking dependency between
+        * a disk's open_mutex (struct gendisk.open_mutex), the rw semaphores
+        * used for freeze procection of a fs (struct super_block.s_writers),
+        * which we take when starting a transaction, and extent buffers of the
+        * chunk tree if we call read_one_dev() while holding a lock on an
+        * extent buffer of the chunk tree. Since we are mounting the filesystem
+        * and at this point there can't be any concurrent task modifying the
+        * chunk tree, to keep it simple, just skip locking on the chunk tree.
+        */
+       ASSERT(!test_bit(BTRFS_FS_OPEN, &fs_info->flags));
+       path->skip_locking = 1;
+
        /*
         * Read all device items, and then all the chunk items. All
         * device items are found before any chunk item (their object id
@@ -7583,10 +7596,6 @@ int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info)
                                goto error;
                        break;
                }
-               /*
-                * The nodes on level 1 are not locked but we don't need to do
-                * that during mount time as nothing else can access the tree
-                */
                node = path->nodes[1];
                if (node) {
                        if (last_ra_node != node->start) {
@@ -7614,7 +7623,6 @@ int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info)
                         * requirement for chunk allocation, see the comment on
                         * top of btrfs_chunk_alloc() for details.
                         */
-                       ASSERT(!test_bit(BTRFS_FS_OPEN, &fs_info->flags));
                        chunk = btrfs_item_ptr(leaf, slot, struct btrfs_chunk);
                        ret = read_one_chunk(&found_key, leaf, chunk);
                        if (ret)
index 12bde7b..23a1ed2 100644 (file)
@@ -393,26 +393,14 @@ static void cifs_put_swn_reg(struct cifs_swn_reg *swnreg)
 
 static int cifs_swn_resource_state_changed(struct cifs_swn_reg *swnreg, const char *name, int state)
 {
-       int i;
-
        switch (state) {
        case CIFS_SWN_RESOURCE_STATE_UNAVAILABLE:
                cifs_dbg(FYI, "%s: resource name '%s' become unavailable\n", __func__, name);
-               for (i = 0; i < swnreg->tcon->ses->chan_count; i++) {
-                       spin_lock(&GlobalMid_Lock);
-                       if (swnreg->tcon->ses->chans[i].server->tcpStatus != CifsExiting)
-                               swnreg->tcon->ses->chans[i].server->tcpStatus = CifsNeedReconnect;
-                       spin_unlock(&GlobalMid_Lock);
-               }
+               cifs_ses_mark_for_reconnect(swnreg->tcon->ses);
                break;
        case CIFS_SWN_RESOURCE_STATE_AVAILABLE:
                cifs_dbg(FYI, "%s: resource name '%s' become available\n", __func__, name);
-               for (i = 0; i < swnreg->tcon->ses->chan_count; i++) {
-                       spin_lock(&GlobalMid_Lock);
-                       if (swnreg->tcon->ses->chans[i].server->tcpStatus != CifsExiting)
-                               swnreg->tcon->ses->chans[i].server->tcpStatus = CifsNeedReconnect;
-                       spin_unlock(&GlobalMid_Lock);
-               }
+               cifs_ses_mark_for_reconnect(swnreg->tcon->ses);
                break;
        case CIFS_SWN_RESOURCE_STATE_UNKNOWN:
                cifs_dbg(FYI, "%s: resource name '%s' changed to unknown state\n", __func__, name);
index b50da19..9e5d9e1 100644 (file)
@@ -152,5 +152,5 @@ extern struct dentry *cifs_smb3_do_mount(struct file_system_type *fs_type,
 extern const struct export_operations cifs_export_ops;
 #endif /* CONFIG_CIFS_NFSD_EXPORT */
 
-#define CIFS_VERSION   "2.33"
+#define CIFS_VERSION   "2.34"
 #endif                         /* _CIFSFS_H */
index f3073a6..4f5a3e8 100644 (file)
@@ -599,6 +599,7 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses)
 bool is_server_using_iface(struct TCP_Server_Info *server,
                           struct cifs_server_iface *iface);
 bool is_ses_using_iface(struct cifs_ses *ses, struct cifs_server_iface *iface);
+void cifs_ses_mark_for_reconnect(struct cifs_ses *ses);
 
 void extract_unc_hostname(const char *unc, const char **h, size_t *len);
 int copy_path_name(char *dst, const char *src);
index 82577a7..6b70502 100644 (file)
@@ -1271,10 +1271,8 @@ static int match_server(struct TCP_Server_Info *server, struct smb3_fs_context *
 {
        struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr;
 
-       if (ctx->nosharesock) {
-               server->nosharesock = true;
+       if (ctx->nosharesock)
                return 0;
-       }
 
        /* this server does not share socket */
        if (server->nosharesock)
@@ -1438,6 +1436,9 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
                goto out_err;
        }
 
+       if (ctx->nosharesock)
+               tcp_ses->nosharesock = true;
+
        tcp_ses->ops = ctx->ops;
        tcp_ses->vals = ctx->vals;
        cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns));
@@ -1452,8 +1453,10 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
        tcp_ses->max_in_flight = 0;
        tcp_ses->credits = 1;
        if (primary_server) {
+               spin_lock(&cifs_tcp_ses_lock);
                ++primary_server->srv_count;
                tcp_ses->primary_server = primary_server;
+               spin_unlock(&cifs_tcp_ses_lock);
        }
        init_waitqueue_head(&tcp_ses->response_q);
        init_waitqueue_head(&tcp_ses->request_q);
@@ -4111,18 +4114,6 @@ cifs_prune_tlinks(struct work_struct *work)
 }
 
 #ifdef CONFIG_CIFS_DFS_UPCALL
-static void mark_tcon_tcp_ses_for_reconnect(struct cifs_tcon *tcon)
-{
-       int i;
-
-       for (i = 0; i < tcon->ses->chan_count; i++) {
-               spin_lock(&GlobalMid_Lock);
-               if (tcon->ses->chans[i].server->tcpStatus != CifsExiting)
-                       tcon->ses->chans[i].server->tcpStatus = CifsNeedReconnect;
-               spin_unlock(&GlobalMid_Lock);
-       }
-}
-
 /* Update dfs referral path of superblock */
 static int update_server_fullpath(struct TCP_Server_Info *server, struct cifs_sb_info *cifs_sb,
                                  const char *target)
@@ -4299,7 +4290,7 @@ static int tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *tco
         */
        if (rc && server->current_fullpath != server->origin_fullpath) {
                server->current_fullpath = server->origin_fullpath;
-               mark_tcon_tcp_ses_for_reconnect(tcon);
+               cifs_ses_mark_for_reconnect(tcon->ses);
        }
 
        dfs_cache_free_tgts(tl);
index 5c1259d..e9b0fa2 100644 (file)
@@ -1355,12 +1355,7 @@ static void mark_for_reconnect_if_needed(struct cifs_tcon *tcon, struct dfs_cach
        }
 
        cifs_dbg(FYI, "%s: no cached or matched targets. mark dfs share for reconnect.\n", __func__);
-       for (i = 0; i < tcon->ses->chan_count; i++) {
-               spin_lock(&GlobalMid_Lock);
-               if (tcon->ses->chans[i].server->tcpStatus != CifsExiting)
-                       tcon->ses->chans[i].server->tcpStatus = CifsNeedReconnect;
-               spin_unlock(&GlobalMid_Lock);
-       }
+       cifs_ses_mark_for_reconnect(tcon->ses);
 }
 
 /* Refresh dfs referral of tcon and mark it for reconnect if needed */
index 2c10b18..af63548 100644 (file)
@@ -95,9 +95,9 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses)
        }
 
        if (!(ses->server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
-               cifs_dbg(VFS, "server %s does not support multichannel\n", ses->server->hostname);
                ses->chan_max = 1;
                spin_unlock(&ses->chan_lock);
+               cifs_dbg(VFS, "server %s does not support multichannel\n", ses->server->hostname);
                return 0;
        }
        spin_unlock(&ses->chan_lock);
@@ -222,6 +222,7 @@ cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
        /* Auth */
        ctx.domainauto = ses->domainAuto;
        ctx.domainname = ses->domainName;
+       ctx.server_hostname = ses->server->hostname;
        ctx.username = ses->user_name;
        ctx.password = ses->password;
        ctx.sectype = ses->sectype;
@@ -318,6 +319,19 @@ out:
        return rc;
 }
 
+/* Mark all session channels for reconnect */
+void cifs_ses_mark_for_reconnect(struct cifs_ses *ses)
+{
+       int i;
+
+       for (i = 0; i < ses->chan_count; i++) {
+               spin_lock(&GlobalMid_Lock);
+               if (ses->chans[i].server->tcpStatus != CifsExiting)
+                       ses->chans[i].server->tcpStatus = CifsNeedReconnect;
+               spin_unlock(&GlobalMid_Lock);
+       }
+}
+
 static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB)
 {
        __u32 capabilities = 0;
index 2f5f2c4..8b36703 100644 (file)
@@ -142,7 +142,7 @@ static int
 smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
               struct TCP_Server_Info *server)
 {
-       int rc;
+       int rc = 0;
        struct nls_table *nls_codepage;
        struct cifs_ses *ses;
        int retries;
index 84da2c2..ec9a1d7 100644 (file)
@@ -150,7 +150,7 @@ static bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi,
         * however in order to avoid some race conditions, add a
         * DBG_BUGON to observe this in advance.
         */
-       DBG_BUGON(xa_erase(&sbi->managed_pslots, grp->index) != grp);
+       DBG_BUGON(__xa_erase(&sbi->managed_pslots, grp->index) != grp);
 
        /* last refcount should be connected with its managed pslot.  */
        erofs_workgroup_unfreeze(grp, 0);
@@ -165,15 +165,19 @@ static unsigned long erofs_shrink_workstation(struct erofs_sb_info *sbi,
        unsigned int freed = 0;
        unsigned long index;
 
+       xa_lock(&sbi->managed_pslots);
        xa_for_each(&sbi->managed_pslots, index, grp) {
                /* try to shrink each valid workgroup */
                if (!erofs_try_to_release_workgroup(sbi, grp))
                        continue;
+               xa_unlock(&sbi->managed_pslots);
 
                ++freed;
                if (!--nr_shrink)
-                       break;
+                       return freed;
+               xa_lock(&sbi->managed_pslots);
        }
+       xa_unlock(&sbi->managed_pslots);
        return freed;
 }
 
index 79f7eda..cd54a52 100644 (file)
@@ -847,17 +847,17 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
 
        replace_page_cache_page(oldpage, newpage);
 
+       get_page(newpage);
+
+       if (!(buf->flags & PIPE_BUF_FLAG_LRU))
+               lru_cache_add(newpage);
+
        /*
         * Release while we have extra ref on stolen page.  Otherwise
         * anon_pipe_buf_release() might think the page can be reused.
         */
        pipe_buf_release(cs->pipe, buf);
 
-       get_page(newpage);
-
-       if (!(buf->flags & PIPE_BUF_FLAG_LRU))
-               lru_cache_add(newpage);
-
        err = 0;
        spin_lock(&cs->req->waitq.lock);
        if (test_bit(FR_ABORTED, &cs->req->flags))
index 7235d53..d671084 100644 (file)
@@ -940,7 +940,7 @@ do_alloc:
                else if (height == ip->i_height)
                        ret = gfs2_hole_size(inode, lblock, len, mp, iomap);
                else
-                       iomap->length = size - pos;
+                       iomap->length = size - iomap->offset;
        } else if (flags & IOMAP_WRITE) {
                u64 alloc_size;
 
index adafaaf..3e718cf 100644 (file)
@@ -773,8 +773,8 @@ static inline bool should_fault_in_pages(ssize_t ret, struct iov_iter *i,
                                         size_t *prev_count,
                                         size_t *window_size)
 {
-       char __user *p = i->iov[0].iov_base + i->iov_offset;
        size_t count = iov_iter_count(i);
+       char __user *p;
        int pages = 1;
 
        if (likely(!count))
@@ -787,14 +787,14 @@ static inline bool should_fault_in_pages(ssize_t ret, struct iov_iter *i,
        if (*prev_count != count || !*window_size) {
                int pages, nr_dirtied;
 
-               pages = min_t(int, BIO_MAX_VECS,
-                             DIV_ROUND_UP(iov_iter_count(i), PAGE_SIZE));
+               pages = min_t(int, BIO_MAX_VECS, DIV_ROUND_UP(count, PAGE_SIZE));
                nr_dirtied = max(current->nr_dirtied_pause -
                                 current->nr_dirtied, 1);
                pages = min(pages, nr_dirtied);
        }
 
        *prev_count = count;
+       p = i->iov[0].iov_base + i->iov_offset;
        *window_size = (size_t)PAGE_SIZE * pages - offset_in_page(p);
        return true;
 }
@@ -1013,6 +1013,7 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb,
        struct gfs2_sbd *sdp = GFS2_SB(inode);
        struct gfs2_holder *statfs_gh = NULL;
        size_t prev_count = 0, window_size = 0;
+       size_t orig_count = iov_iter_count(from);
        size_t read = 0;
        ssize_t ret;
 
@@ -1057,6 +1058,7 @@ retry_under_glock:
        if (inode == sdp->sd_rindex)
                gfs2_glock_dq_uninit(statfs_gh);
 
+       from->count = orig_count - read;
        if (should_fault_in_pages(ret, from, &prev_count, &window_size)) {
                size_t leftover;
 
@@ -1064,6 +1066,7 @@ retry_under_glock:
                leftover = fault_in_iov_iter_readable(from, window_size);
                gfs2_holder_disallow_demote(gh);
                if (leftover != window_size) {
+                       from->count = min(from->count, window_size - leftover);
                        if (!gfs2_holder_queued(gh)) {
                                if (read)
                                        goto out_uninit;
index 19f38ae..8dbd6fe 100644 (file)
@@ -411,14 +411,14 @@ static void do_error(struct gfs2_glock *gl, const int ret)
 static void demote_incompat_holders(struct gfs2_glock *gl,
                                    struct gfs2_holder *new_gh)
 {
-       struct gfs2_holder *gh;
+       struct gfs2_holder *gh, *tmp;
 
        /*
         * Demote incompatible holders before we make ourselves eligible.
         * (This holder may or may not allow auto-demoting, but we don't want
         * to demote the new holder before it's even granted.)
         */
-       list_for_each_entry(gh, &gl->gl_holders, gh_list) {
+       list_for_each_entry_safe(gh, tmp, &gl->gl_holders, gh_list) {
                /*
                 * Since holders are at the front of the list, we stop when we
                 * find the first non-holder.
@@ -496,7 +496,7 @@ again:
         * Since we unlock the lockref lock, we set a flag to indicate
         * instantiate is in progress.
         */
-       if (test_bit(GLF_INSTANTIATE_IN_PROG, &gl->gl_flags)) {
+       if (test_and_set_bit(GLF_INSTANTIATE_IN_PROG, &gl->gl_flags)) {
                wait_on_bit(&gl->gl_flags, GLF_INSTANTIATE_IN_PROG,
                            TASK_UNINTERRUPTIBLE);
                /*
@@ -509,14 +509,10 @@ again:
                goto again;
        }
 
-       set_bit(GLF_INSTANTIATE_IN_PROG, &gl->gl_flags);
-
        ret = glops->go_instantiate(gh);
        if (!ret)
                clear_bit(GLF_INSTANTIATE_NEEDED, &gl->gl_flags);
-       clear_bit(GLF_INSTANTIATE_IN_PROG, &gl->gl_flags);
-       smp_mb__after_atomic();
-       wake_up_bit(&gl->gl_flags, GLF_INSTANTIATE_IN_PROG);
+       clear_and_wake_up_bit(GLF_INSTANTIATE_IN_PROG, &gl->gl_flags);
        return ret;
 }
 
index 5b12137..0f93e8b 100644 (file)
@@ -1402,13 +1402,6 @@ out:
        gfs2_ordered_del_inode(ip);
        clear_inode(inode);
        gfs2_dir_hash_inval(ip);
-       if (ip->i_gl) {
-               glock_clear_object(ip->i_gl, ip);
-               wait_on_bit_io(&ip->i_flags, GIF_GLOP_PENDING, TASK_UNINTERRUPTIBLE);
-               gfs2_glock_add_to_lru(ip->i_gl);
-               gfs2_glock_put_eventually(ip->i_gl);
-               ip->i_gl = NULL;
-       }
        if (gfs2_holder_initialized(&ip->i_iopen_gh)) {
                struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;
 
@@ -1421,6 +1414,13 @@ out:
                gfs2_holder_uninit(&ip->i_iopen_gh);
                gfs2_glock_put_eventually(gl);
        }
+       if (ip->i_gl) {
+               glock_clear_object(ip->i_gl, ip);
+               wait_on_bit_io(&ip->i_flags, GIF_GLOP_PENDING, TASK_UNINTERRUPTIBLE);
+               gfs2_glock_add_to_lru(ip->i_gl);
+               gfs2_glock_put_eventually(ip->i_gl);
+               ip->i_gl = NULL;
+       }
 }
 
 static struct inode *gfs2_alloc_inode(struct super_block *sb)
index 3eba094..6b80a51 100644 (file)
@@ -180,8 +180,6 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
        mapping->a_ops = &empty_aops;
        mapping->host = inode;
        mapping->flags = 0;
-       if (sb->s_type->fs_flags & FS_THP_SUPPORT)
-               __set_bit(AS_THP_SUPPORT, &mapping->flags);
        mapping->wb_err = 0;
        atomic_set(&mapping->i_mmap_writable, 0);
 #ifdef CONFIG_READ_ONLY_THP_FOR_FS
index b07196b..c4f2176 100644 (file)
@@ -1278,6 +1278,7 @@ static void io_refs_resurrect(struct percpu_ref *ref, struct completion *compl)
 
 static bool io_match_task(struct io_kiocb *head, struct task_struct *task,
                          bool cancel_all)
+       __must_hold(&req->ctx->timeout_lock)
 {
        struct io_kiocb *req;
 
@@ -1293,6 +1294,44 @@ static bool io_match_task(struct io_kiocb *head, struct task_struct *task,
        return false;
 }
 
+static bool io_match_linked(struct io_kiocb *head)
+{
+       struct io_kiocb *req;
+
+       io_for_each_link(req, head) {
+               if (req->flags & REQ_F_INFLIGHT)
+                       return true;
+       }
+       return false;
+}
+
+/*
+ * As io_match_task() but protected against racing with linked timeouts.
+ * User must not hold timeout_lock.
+ */
+static bool io_match_task_safe(struct io_kiocb *head, struct task_struct *task,
+                              bool cancel_all)
+{
+       bool matched;
+
+       if (task && head->task != task)
+               return false;
+       if (cancel_all)
+               return true;
+
+       if (head->flags & REQ_F_LINK_TIMEOUT) {
+               struct io_ring_ctx *ctx = head->ctx;
+
+               /* protect against races with linked timeouts */
+               spin_lock_irq(&ctx->timeout_lock);
+               matched = io_match_linked(head);
+               spin_unlock_irq(&ctx->timeout_lock);
+       } else {
+               matched = io_match_linked(head);
+       }
+       return matched;
+}
+
 static inline bool req_has_async_data(struct io_kiocb *req)
 {
        return req->flags & REQ_F_ASYNC_DATA;
@@ -1502,10 +1541,10 @@ static void io_prep_async_link(struct io_kiocb *req)
        if (req->flags & REQ_F_LINK_TIMEOUT) {
                struct io_ring_ctx *ctx = req->ctx;
 
-               spin_lock(&ctx->completion_lock);
+               spin_lock_irq(&ctx->timeout_lock);
                io_for_each_link(cur, req)
                        io_prep_async_work(cur);
-               spin_unlock(&ctx->completion_lock);
+               spin_unlock_irq(&ctx->timeout_lock);
        } else {
                io_for_each_link(cur, req)
                        io_prep_async_work(cur);
@@ -4327,6 +4366,7 @@ static int __io_remove_buffers(struct io_ring_ctx *ctx, struct io_buffer *buf,
                kfree(nxt);
                if (++i == nbufs)
                        return i;
+               cond_resched();
        }
        i++;
        kfree(buf);
@@ -5704,7 +5744,7 @@ static __cold bool io_poll_remove_all(struct io_ring_ctx *ctx,
 
                list = &ctx->cancel_hash[i];
                hlist_for_each_entry_safe(req, tmp, list, hash_node) {
-                       if (io_match_task(req, tsk, cancel_all))
+                       if (io_match_task_safe(req, tsk, cancel_all))
                                posted += io_poll_remove_one(req);
                }
        }
@@ -6156,6 +6196,9 @@ static int io_timeout_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe,
        if (get_timespec64(&data->ts, u64_to_user_ptr(sqe->addr)))
                return -EFAULT;
 
+       if (data->ts.tv_sec < 0 || data->ts.tv_nsec < 0)
+               return -EINVAL;
+
        data->mode = io_translate_timeout_mode(flags);
        hrtimer_init(&data->timer, io_timeout_get_clock(data), data->mode);
 
@@ -6880,10 +6923,11 @@ static inline struct file *io_file_get(struct io_ring_ctx *ctx,
 static void io_req_task_link_timeout(struct io_kiocb *req, bool *locked)
 {
        struct io_kiocb *prev = req->timeout.prev;
-       int ret;
+       int ret = -ENOENT;
 
        if (prev) {
-               ret = io_try_cancel_userdata(req, prev->user_data);
+               if (!(req->task->flags & PF_EXITING))
+                       ret = io_try_cancel_userdata(req, prev->user_data);
                io_req_complete_post(req, ret ?: -ETIME, 0);
                io_put_req(prev);
        } else {
@@ -9255,10 +9299,8 @@ static void io_destroy_buffers(struct io_ring_ctx *ctx)
        struct io_buffer *buf;
        unsigned long index;
 
-       xa_for_each(&ctx->io_buffers, index, buf) {
+       xa_for_each(&ctx->io_buffers, index, buf)
                __io_remove_buffers(ctx, buf, index, -1U);
-               cond_resched();
-       }
 }
 
 static void io_req_caches_free(struct io_ring_ctx *ctx)
@@ -9562,19 +9604,8 @@ static bool io_cancel_task_cb(struct io_wq_work *work, void *data)
 {
        struct io_kiocb *req = container_of(work, struct io_kiocb, work);
        struct io_task_cancel *cancel = data;
-       bool ret;
 
-       if (!cancel->all && (req->flags & REQ_F_LINK_TIMEOUT)) {
-               struct io_ring_ctx *ctx = req->ctx;
-
-               /* protect against races with linked timeouts */
-               spin_lock(&ctx->completion_lock);
-               ret = io_match_task(req, cancel->task, cancel->all);
-               spin_unlock(&ctx->completion_lock);
-       } else {
-               ret = io_match_task(req, cancel->task, cancel->all);
-       }
-       return ret;
+       return io_match_task_safe(req, cancel->task, cancel->all);
 }
 
 static __cold bool io_cancel_defer_files(struct io_ring_ctx *ctx,
@@ -9586,7 +9617,7 @@ static __cold bool io_cancel_defer_files(struct io_ring_ctx *ctx,
 
        spin_lock(&ctx->completion_lock);
        list_for_each_entry_reverse(de, &ctx->defer_list, list) {
-               if (io_match_task(de->req, task, cancel_all)) {
+               if (io_match_task_safe(de->req, task, cancel_all)) {
                        list_cut_position(&list, &ctx->defer_list, &de->list);
                        break;
                }
@@ -9764,7 +9795,7 @@ static __cold void io_uring_clean_tctx(struct io_uring_task *tctx)
        }
        if (wq) {
                /*
-                * Must be after io_uring_del_task_file() (removes nodes under
+                * Must be after io_uring_del_tctx_node() (removes nodes under
                 * uring_lock) to avoid race with io_uring_try_cancel_iowq().
                 */
                io_wq_put_and_exit(wq);
index 1753c26..71a36ae 100644 (file)
@@ -205,7 +205,16 @@ struct iomap_readpage_ctx {
        struct readahead_control *rac;
 };
 
-static loff_t iomap_read_inline_data(const struct iomap_iter *iter,
+/**
+ * iomap_read_inline_data - copy inline data into the page cache
+ * @iter: iteration structure
+ * @page: page to copy to
+ *
+ * Copy the inline data in @iter into @page and zero out the rest of the page.
+ * Only a single IOMAP_INLINE extent is allowed at the end of each file.
+ * Returns zero for success to complete the read, or the usual negative errno.
+ */
+static int iomap_read_inline_data(const struct iomap_iter *iter,
                struct page *page)
 {
        const struct iomap *iomap = iomap_iter_srcmap(iter);
@@ -214,7 +223,7 @@ static loff_t iomap_read_inline_data(const struct iomap_iter *iter,
        void *addr;
 
        if (PageUptodate(page))
-               return PAGE_SIZE - poff;
+               return 0;
 
        if (WARN_ON_ONCE(size > PAGE_SIZE - poff))
                return -EIO;
@@ -231,7 +240,7 @@ static loff_t iomap_read_inline_data(const struct iomap_iter *iter,
        memset(addr + size, 0, PAGE_SIZE - poff - size);
        kunmap_local(addr);
        iomap_set_range_uptodate(page, poff, PAGE_SIZE - poff);
-       return PAGE_SIZE - poff;
+       return 0;
 }
 
 static inline bool iomap_block_needs_zeroing(const struct iomap_iter *iter,
@@ -257,7 +266,7 @@ static loff_t iomap_readpage_iter(const struct iomap_iter *iter,
        sector_t sector;
 
        if (iomap->type == IOMAP_INLINE)
-               return min(iomap_read_inline_data(iter, page), length);
+               return iomap_read_inline_data(iter, page);
 
        /* zero post-eof blocks as the page may be mapped */
        iop = iomap_page_create(iter->inode, page);
@@ -370,6 +379,8 @@ static loff_t iomap_readahead_iter(const struct iomap_iter *iter,
                        ctx->cur_page_in_bio = false;
                }
                ret = iomap_readpage_iter(iter, ctx, done);
+               if (ret <= 0)
+                       return ret;
        }
 
        return done;
@@ -580,15 +591,10 @@ static int __iomap_write_begin(const struct iomap_iter *iter, loff_t pos,
 static int iomap_write_begin_inline(const struct iomap_iter *iter,
                struct page *page)
 {
-       int ret;
-
        /* needs more work for the tailpacking case; disable for now */
        if (WARN_ON_ONCE(iomap_iter_srcmap(iter)->offset != 0))
                return -EIO;
-       ret = iomap_read_inline_data(iter, page);
-       if (ret < 0)
-               return ret;
-       return 0;
+       return iomap_read_inline_data(iter, page);
 }
 
 static int iomap_write_begin(const struct iomap_iter *iter, loff_t pos,
index 121f8e8..49c9da3 100644 (file)
@@ -1697,8 +1697,10 @@ int smb2_sess_setup(struct ksmbd_work *work)
        negblob_off = le16_to_cpu(req->SecurityBufferOffset);
        negblob_len = le16_to_cpu(req->SecurityBufferLength);
        if (negblob_off < offsetof(struct smb2_sess_setup_req, Buffer) ||
-           negblob_len < offsetof(struct negotiate_message, NegotiateFlags))
-               return -EINVAL;
+           negblob_len < offsetof(struct negotiate_message, NegotiateFlags)) {
+               rc = -EINVAL;
+               goto out_err;
+       }
 
        negblob = (struct negotiate_message *)((char *)&req->hdr.ProtocolId +
                        negblob_off);
@@ -4457,6 +4459,12 @@ static void get_file_stream_info(struct ksmbd_work *work,
                         &stat);
        file_info = (struct smb2_file_stream_info *)rsp->Buffer;
 
+       buf_free_len =
+               smb2_calc_max_out_buf_len(work, 8,
+                                         le32_to_cpu(req->OutputBufferLength));
+       if (buf_free_len < 0)
+               goto out;
+
        xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
        if (xattr_list_len < 0) {
                goto out;
@@ -4465,12 +4473,6 @@ static void get_file_stream_info(struct ksmbd_work *work,
                goto out;
        }
 
-       buf_free_len =
-               smb2_calc_max_out_buf_len(work, 8,
-                                         le32_to_cpu(req->OutputBufferLength));
-       if (buf_free_len < 0)
-               goto out;
-
        while (idx < xattr_list_len) {
                stream_name = xattr_list + idx;
                streamlen = strlen(stream_name);
@@ -4496,8 +4498,10 @@ static void get_file_stream_info(struct ksmbd_work *work,
                                     ":%s", &stream_name[XATTR_NAME_STREAM_LEN]);
 
                next = sizeof(struct smb2_file_stream_info) + streamlen * 2;
-               if (next > buf_free_len)
+               if (next > buf_free_len) {
+                       kfree(stream_buf);
                        break;
+               }
 
                file_info = (struct smb2_file_stream_info *)&rsp->Buffer[nbytes];
                streamlen  = smbConvertToUTF16((__le16 *)file_info->StreamName,
@@ -4514,6 +4518,7 @@ static void get_file_stream_info(struct ksmbd_work *work,
                file_info->NextEntryOffset = cpu_to_le32(next);
        }
 
+out:
        if (!S_ISDIR(stat.mode) &&
            buf_free_len >= sizeof(struct smb2_file_stream_info) + 7 * 2) {
                file_info = (struct smb2_file_stream_info *)
@@ -4522,14 +4527,13 @@ static void get_file_stream_info(struct ksmbd_work *work,
                                              "::$DATA", 7, conn->local_nls, 0);
                streamlen *= 2;
                file_info->StreamNameLength = cpu_to_le32(streamlen);
-               file_info->StreamSize = 0;
-               file_info->StreamAllocationSize = 0;
+               file_info->StreamSize = cpu_to_le64(stat.size);
+               file_info->StreamAllocationSize = cpu_to_le64(stat.blocks << 9);
                nbytes += sizeof(struct smb2_file_stream_info) + streamlen;
        }
 
        /* last entry offset should be 0 */
        file_info->NextEntryOffset = 0;
-out:
        kvfree(xattr_list);
 
        rsp->OutputBufferLength = cpu_to_le32(nbytes);
@@ -5068,7 +5072,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
        if (addition_info & ~(OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO |
                              PROTECTED_DACL_SECINFO |
                              UNPROTECTED_DACL_SECINFO)) {
-               pr_err("Unsupported addition info: 0x%x)\n",
+               ksmbd_debug(SMB, "Unsupported addition info: 0x%x)\n",
                       addition_info);
 
                pntsd->revision = cpu_to_le16(1);
index dd53704..fda530d 100644 (file)
@@ -219,6 +219,7 @@ void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)
                                          NFS_INO_DATA_INVAL_DEFER);
        else if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
                nfsi->cache_validity &= ~NFS_INO_DATA_INVAL_DEFER;
+       trace_nfs_set_cache_invalid(inode, 0);
 }
 EXPORT_SYMBOL_GPL(nfs_set_cache_invalid);
 
index 08355b6..8b21ff1 100644 (file)
@@ -289,7 +289,9 @@ static void nfs42_copy_dest_done(struct inode *inode, loff_t pos, loff_t len)
        loff_t newsize = pos + len;
        loff_t end = newsize - 1;
 
-       truncate_pagecache_range(inode, pos, end);
+       WARN_ON_ONCE(invalidate_inode_pages2_range(inode->i_mapping,
+                               pos >> PAGE_SHIFT, end >> PAGE_SHIFT));
+
        spin_lock(&inode->i_lock);
        if (newsize > i_size_read(inode))
                i_size_write(inode, newsize);
index c8bad73..271e5f9 100644 (file)
@@ -1434,8 +1434,7 @@ static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp,
        status = decode_clone(xdr);
        if (status)
                goto out;
-       status = decode_getfattr(xdr, res->dst_fattr, res->server);
-
+       decode_getfattr(xdr, res->dst_fattr, res->server);
 out:
        res->rpc_status = status;
        return status;
index ecc4594..f63dfa0 100644 (file)
@@ -1998,6 +1998,10 @@ static int nfs4_handle_reclaim_lease_error(struct nfs_client *clp, int status)
                dprintk("%s: exit with error %d for server %s\n",
                                __func__, -EPROTONOSUPPORT, clp->cl_hostname);
                return -EPROTONOSUPPORT;
+       case -ENOSPC:
+               if (clp->cl_cons_state == NFS_CS_SESSION_INITING)
+                       nfs_mark_client_ready(clp, -EIO);
+               return -EIO;
        case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
                                 * in nfs4_exchange_id */
        default:
index 21dac84..b3aee26 100644 (file)
@@ -162,6 +162,7 @@ DEFINE_NFS_INODE_EVENT_DONE(nfs_writeback_inode_exit);
 DEFINE_NFS_INODE_EVENT(nfs_fsync_enter);
 DEFINE_NFS_INODE_EVENT_DONE(nfs_fsync_exit);
 DEFINE_NFS_INODE_EVENT(nfs_access_enter);
+DEFINE_NFS_INODE_EVENT_DONE(nfs_set_cache_invalid);
 
 TRACE_EVENT(nfs_access_exit,
                TP_PROTO(
index b2a1d96..5a93a5d 100644 (file)
@@ -288,11 +288,8 @@ nfsd4_decode_bitmap4(struct nfsd4_compoundargs *argp, u32 *bmval, u32 bmlen)
        p = xdr_inline_decode(argp->xdr, count << 2);
        if (!p)
                return nfserr_bad_xdr;
-       i = 0;
-       while (i < count)
-               bmval[i++] = be32_to_cpup(p++);
-       while (i < bmlen)
-               bmval[i++] = 0;
+       for (i = 0; i < bmlen; i++)
+               bmval[i] = (i < count) ? be32_to_cpup(p++) : 0;
 
        return nfs_ok;
 }
index 1667a7e..f93e69a 100644 (file)
@@ -52,6 +52,7 @@ config NTFS_DEBUG
 config NTFS_RW
        bool "NTFS write support"
        depends on NTFS_FS
+       depends on PAGE_SIZE_LESS_THAN_64KB
        help
          This enables the partial, but safe, write support in the NTFS driver.
 
index 30a3b66..509f851 100644 (file)
@@ -154,9 +154,13 @@ ssize_t read_from_oldmem(char *buf, size_t count,
                        nr_bytes = count;
 
                /* If pfn is not ram, return zeros for sparse dump files */
-               if (!pfn_is_ram(pfn))
-                       memset(buf, 0, nr_bytes);
-               else {
+               if (!pfn_is_ram(pfn)) {
+                       tmp = 0;
+                       if (!userbuf)
+                               memset(buf, 0, nr_bytes);
+                       else if (clear_user(buf, nr_bytes))
+                               tmp = -EFAULT;
+               } else {
                        if (encrypted)
                                tmp = copy_oldmem_page_encrypted(pfn, buf,
                                                                 nr_bytes,
@@ -165,12 +169,12 @@ ssize_t read_from_oldmem(char *buf, size_t count,
                        else
                                tmp = copy_oldmem_page(pfn, buf, nr_bytes,
                                                       offset, userbuf);
-
-                       if (tmp < 0) {
-                               up_read(&vmcore_cb_rwsem);
-                               return tmp;
-                       }
                }
+               if (tmp < 0) {
+                       up_read(&vmcore_cb_rwsem);
+                       return tmp;
+               }
+
                *ppos += nr_bytes;
                count -= nr_bytes;
                buf += nr_bytes;
index 328da35..8adabde 100644 (file)
@@ -173,7 +173,6 @@ config PSTORE_BLK
        tristate "Log panic/oops to a block device"
        depends on PSTORE
        depends on BLOCK
-       depends on BROKEN
        select PSTORE_ZONE
        default n
        help
index 5d1fbaf..4ae0cfc 100644 (file)
@@ -309,7 +309,7 @@ static int __init __best_effort_init(void)
        if (ret)
                kfree(best_effort_dev);
        else
-               pr_info("attached %s (%zu) (no dedicated panic_write!)\n",
+               pr_info("attached %s (%lu) (no dedicated panic_write!)\n",
                        blkdev, best_effort_dev->zone.total_size);
 
        return ret;
index 70abdfa..42e3e55 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/bio.h>
+#include <linux/iversion.h>
 
 #include "udf_i.h"
 #include "udf_sb.h"
@@ -43,7 +44,7 @@ static int udf_readdir(struct file *file, struct dir_context *ctx)
        struct fileIdentDesc *fi = NULL;
        struct fileIdentDesc cfi;
        udf_pblk_t block, iblock;
-       loff_t nf_pos;
+       loff_t nf_pos, emit_pos = 0;
        int flen;
        unsigned char *fname = NULL, *copy_name = NULL;
        unsigned char *nameptr;
@@ -57,6 +58,7 @@ static int udf_readdir(struct file *file, struct dir_context *ctx)
        int i, num, ret = 0;
        struct extent_position epos = { NULL, 0, {0, 0} };
        struct super_block *sb = dir->i_sb;
+       bool pos_valid = false;
 
        if (ctx->pos == 0) {
                if (!dir_emit_dot(file, ctx))
@@ -67,6 +69,21 @@ static int udf_readdir(struct file *file, struct dir_context *ctx)
        if (nf_pos >= size)
                goto out;
 
+       /*
+        * Something changed since last readdir (either lseek was called or dir
+        * changed)?  We need to verify the position correctly points at the
+        * beginning of some dir entry so that the directory parsing code does
+        * not get confused. Since UDF does not have any reliable way of
+        * identifying beginning of dir entry (names are under user control),
+        * we need to scan the directory from the beginning.
+        */
+       if (!inode_eq_iversion(dir, file->f_version)) {
+               emit_pos = nf_pos;
+               nf_pos = 0;
+       } else {
+               pos_valid = true;
+       }
+
        fname = kmalloc(UDF_NAME_LEN, GFP_NOFS);
        if (!fname) {
                ret = -ENOMEM;
@@ -122,13 +139,21 @@ static int udf_readdir(struct file *file, struct dir_context *ctx)
 
        while (nf_pos < size) {
                struct kernel_lb_addr tloc;
+               loff_t cur_pos = nf_pos;
 
-               ctx->pos = (nf_pos >> 2) + 1;
+               /* Update file position only if we got past the current one */
+               if (nf_pos >= emit_pos) {
+                       ctx->pos = (nf_pos >> 2) + 1;
+                       pos_valid = true;
+               }
 
                fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc,
                                        &elen, &offset);
                if (!fi)
                        goto out;
+               /* Still not at offset where user asked us to read from? */
+               if (cur_pos < emit_pos)
+                       continue;
 
                liu = le16_to_cpu(cfi.lengthOfImpUse);
                lfi = cfi.lengthFileIdent;
@@ -186,8 +211,11 @@ static int udf_readdir(struct file *file, struct dir_context *ctx)
        } /* end while */
 
        ctx->pos = (nf_pos >> 2) + 1;
+       pos_valid = true;
 
 out:
+       if (pos_valid)
+               file->f_version = inode_query_iversion(dir);
        if (fibh.sbh != fibh.ebh)
                brelse(fibh.ebh);
        brelse(fibh.sbh);
index caeef08..0ed4861 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/sched.h>
 #include <linux/crc-itu-t.h>
 #include <linux/exportfs.h>
+#include <linux/iversion.h>
 
 static inline int udf_match(int len1, const unsigned char *name1, int len2,
                            const unsigned char *name2)
@@ -134,6 +135,8 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi,
                        mark_buffer_dirty_inode(fibh->ebh, inode);
                mark_buffer_dirty_inode(fibh->sbh, inode);
        }
+       inode_inc_iversion(inode);
+
        return 0;
 }
 
index 34247fb..f26b5e0 100644 (file)
@@ -57,6 +57,7 @@
 #include <linux/crc-itu-t.h>
 #include <linux/log2.h>
 #include <asm/byteorder.h>
+#include <linux/iversion.h>
 
 #include "udf_sb.h"
 #include "udf_i.h"
@@ -149,6 +150,7 @@ static struct inode *udf_alloc_inode(struct super_block *sb)
        init_rwsem(&ei->i_data_sem);
        ei->cached_extent.lstart = -1;
        spin_lock_init(&ei->i_extent_cache_lock);
+       inode_set_iversion(&ei->vfs_inode, 1);
 
        return &ei->vfs_inode;
 }
index fbc9d81..23523b8 100644 (file)
@@ -1077,21 +1077,18 @@ xfs_attr_node_hasname(
 
        state = xfs_da_state_alloc(args);
        if (statep != NULL)
-               *statep = NULL;
+               *statep = state;
 
        /*
         * Search to see if name exists, and get back a pointer to it.
         */
        error = xfs_da3_node_lookup_int(state, &retval);
-       if (error) {
-               xfs_da_state_free(state);
-               return error;
-       }
+       if (error)
+               retval = error;
 
-       if (statep != NULL)
-               *statep = state;
-       else
+       if (!statep)
                xfs_da_state_free(state);
+
        return retval;
 }
 
@@ -1112,7 +1109,7 @@ xfs_attr_node_addname_find_attr(
         */
        retval = xfs_attr_node_hasname(args, &dac->da_state);
        if (retval != -ENOATTR && retval != -EEXIST)
-               return retval;
+               goto error;
 
        if (retval == -ENOATTR && (args->attr_flags & XATTR_REPLACE))
                goto error;
@@ -1337,7 +1334,7 @@ int xfs_attr_node_removename_setup(
 
        error = xfs_attr_node_hasname(args, state);
        if (error != -EEXIST)
-               return error;
+               goto out;
        error = 0;
 
        ASSERT((*state)->path.blk[(*state)->path.active - 1].bp != NULL);
index e147200..da4af21 100644 (file)
@@ -289,22 +289,6 @@ xfs_perag_clear_inode_tag(
        trace_xfs_perag_clear_inode_tag(mp, pag->pag_agno, tag, _RET_IP_);
 }
 
-static inline void
-xfs_inew_wait(
-       struct xfs_inode        *ip)
-{
-       wait_queue_head_t *wq = bit_waitqueue(&ip->i_flags, __XFS_INEW_BIT);
-       DEFINE_WAIT_BIT(wait, &ip->i_flags, __XFS_INEW_BIT);
-
-       do {
-               prepare_to_wait(wq, &wait.wq_entry, TASK_UNINTERRUPTIBLE);
-               if (!xfs_iflags_test(ip, XFS_INEW))
-                       break;
-               schedule();
-       } while (true);
-       finish_wait(wq, &wait.wq_entry);
-}
-
 /*
  * When we recycle a reclaimable inode, we need to re-initialise the VFS inode
  * part of the structure. This is made more complex by the fact we store
@@ -368,18 +352,13 @@ xfs_iget_recycle(
        ASSERT(!rwsem_is_locked(&inode->i_rwsem));
        error = xfs_reinit_inode(mp, inode);
        if (error) {
-               bool    wake;
-
                /*
                 * Re-initializing the inode failed, and we are in deep
                 * trouble.  Try to re-add it to the reclaim list.
                 */
                rcu_read_lock();
                spin_lock(&ip->i_flags_lock);
-               wake = !!__xfs_iflags_test(ip, XFS_INEW);
                ip->i_flags &= ~(XFS_INEW | XFS_IRECLAIM);
-               if (wake)
-                       wake_up_bit(&ip->i_flags, __XFS_INEW_BIT);
                ASSERT(ip->i_flags & XFS_IRECLAIMABLE);
                spin_unlock(&ip->i_flags_lock);
                rcu_read_unlock();
index e635a3d..c447bf0 100644 (file)
@@ -231,8 +231,7 @@ static inline bool xfs_inode_has_bigtime(struct xfs_inode *ip)
 #define XFS_IRECLAIM           (1 << 0) /* started reclaiming this inode */
 #define XFS_ISTALE             (1 << 1) /* inode has been staled */
 #define XFS_IRECLAIMABLE       (1 << 2) /* inode can be reclaimed */
-#define __XFS_INEW_BIT         3        /* inode has just been allocated */
-#define XFS_INEW               (1 << __XFS_INEW_BIT)
+#define XFS_INEW               (1 << 3) /* inode has just been allocated */
 #define XFS_IPRESERVE_DM_FIELDS        (1 << 4) /* has legacy DMAPI fields set */
 #define XFS_ITRUNCATED         (1 << 5) /* truncated down so flush-on-close */
 #define XFS_IDIRTY_RELEASE     (1 << 6) /* dirty release already seen */
@@ -492,7 +491,6 @@ static inline void xfs_finish_inode_setup(struct xfs_inode *ip)
        xfs_iflags_clear(ip, XFS_INEW);
        barrier();
        unlock_new_inode(VFS_I(ip));
-       wake_up_bit(&ip->i_flags, __XFS_INEW_BIT);
 }
 
 static inline void xfs_setup_existing_inode(struct xfs_inode *ip)
index fedc0df..4f07afa 100644 (file)
@@ -50,13 +50,7 @@ static inline void flush_dcache_page(struct page *page)
 {
 }
 
-static inline void flush_dcache_folio(struct folio *folio) { }
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_FOLIO
-#endif
-
-#ifndef ARCH_IMPLEMENTS_FLUSH_DCACHE_FOLIO
-void flush_dcache_folio(struct folio *folio);
 #endif
 
 #ifndef flush_dcache_mmap_lock
index 143ce7e..b28f879 100644 (file)
@@ -974,6 +974,15 @@ static inline int acpi_get_local_address(acpi_handle handle, u32 *addr)
        return -ENODEV;
 }
 
+static inline int acpi_register_wakeup_handler(int wake_irq,
+       bool (*wakeup)(void *context), void *context)
+{
+       return -ENXIO;
+}
+
+static inline void acpi_unregister_wakeup_handler(
+       bool (*wakeup)(void *context), void *context) { }
+
 #endif /* !CONFIG_ACPI */
 
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
@@ -1173,7 +1182,6 @@ int acpi_node_prop_get(const struct fwnode_handle *fwnode, const char *propname,
 
 struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode,
                                            struct fwnode_handle *child);
-struct fwnode_handle *acpi_node_get_parent(const struct fwnode_handle *fwnode);
 
 struct acpi_probe_entry;
 typedef bool (*acpi_probe_entry_validate_subtbl)(struct acpi_subtable_header *,
@@ -1278,12 +1286,6 @@ acpi_get_next_subnode(const struct fwnode_handle *fwnode,
        return NULL;
 }
 
-static inline struct fwnode_handle *
-acpi_node_get_parent(const struct fwnode_handle *fwnode)
-{
-       return NULL;
-}
-
 static inline struct fwnode_handle *
 acpi_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
                             struct fwnode_handle *prev)
index f715e88..e7a163a 100644 (file)
@@ -193,7 +193,7 @@ struct bpf_map {
        atomic64_t usercnt;
        struct work_struct work;
        struct mutex freeze_mutex;
-       u64 writecnt; /* writable mmap cnt; protected by freeze_mutex */
+       atomic64_t writecnt;
 };
 
 static inline bool map_value_has_spin_lock(const struct bpf_map *map)
@@ -1419,6 +1419,7 @@ void bpf_map_put(struct bpf_map *map);
 void *bpf_map_area_alloc(u64 size, int numa_node);
 void *bpf_map_area_mmapable_alloc(u64 size, int numa_node);
 void bpf_map_area_free(void *base);
+bool bpf_map_write_active(const struct bpf_map *map);
 void bpf_map_init_from_attr(struct bpf_map *map, union bpf_attr *attr);
 int  generic_map_lookup_batch(struct bpf_map *map,
                              const union bpf_attr *attr,
diff --git a/include/linux/cacheflush.h b/include/linux/cacheflush.h
new file mode 100644 (file)
index 0000000..fef8b60
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_CACHEFLUSH_H
+#define _LINUX_CACHEFLUSH_H
+
+#include <asm/cacheflush.h>
+
+#if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
+#ifndef ARCH_IMPLEMENTS_FLUSH_DCACHE_FOLIO
+void flush_dcache_folio(struct folio *folio);
+#endif
+#else
+static inline void flush_dcache_folio(struct folio *folio)
+{
+}
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_FOLIO 0
+#endif /* ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE */
+
+#endif /* _LINUX_CACHEFLUSH_H */
index 1cb616f..bbf812c 100644 (file)
@@ -2518,7 +2518,6 @@ struct file_system_type {
 #define FS_USERNS_MOUNT                8       /* Can be mounted by userns root */
 #define FS_DISALLOW_NOTIFY_PERM        16      /* Disable fanotify permission events */
 #define FS_ALLOW_IDMAP         32      /* FS has been updated to handle vfs idmappings. */
-#define FS_THP_SUPPORT         8192    /* Remove once all fs converted */
 #define FS_RENAME_DOES_D_MOVE  32768   /* FS will handle d_move() during rename() internally. */
        int (*init_fs_context)(struct fs_context *);
        const struct fs_parameter_spec *parameters;
index 25aff0f..39bb9b4 100644 (file)
@@ -5,12 +5,11 @@
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/bug.h>
+#include <linux/cacheflush.h>
 #include <linux/mm.h>
 #include <linux/uaccess.h>
 #include <linux/hardirq.h>
 
-#include <asm/cacheflush.h>
-
 #include "highmem-internal.h"
 
 /**
@@ -231,10 +230,10 @@ static inline void tag_clear_highpage(struct page *page)
  * If we pass in a base or tail page, we can zero up to PAGE_SIZE.
  * If we pass in a head page, we can zero up to the size of the compound page.
  */
-#if defined(CONFIG_HIGHMEM) && defined(CONFIG_TRANSPARENT_HUGEPAGE)
+#ifdef CONFIG_HIGHMEM
 void zero_user_segments(struct page *page, unsigned start1, unsigned end1,
                unsigned start2, unsigned end2);
-#else /* !HIGHMEM || !TRANSPARENT_HUGEPAGE */
+#else
 static inline void zero_user_segments(struct page *page,
                unsigned start1, unsigned end1,
                unsigned start2, unsigned end2)
@@ -254,7 +253,7 @@ static inline void zero_user_segments(struct page *page,
        for (i = 0; i < compound_nr(page); i++)
                flush_dcache_page(page + i);
 }
-#endif /* !HIGHMEM || !TRANSPARENT_HUGEPAGE */
+#endif
 
 static inline void zero_user_segment(struct page *page,
        unsigned start, unsigned end)
@@ -364,4 +363,42 @@ static inline void memzero_page(struct page *page, size_t offset, size_t len)
        kunmap_local(addr);
 }
 
+/**
+ * folio_zero_segments() - Zero two byte ranges in a folio.
+ * @folio: The folio to write to.
+ * @start1: The first byte to zero.
+ * @xend1: One more than the last byte in the first range.
+ * @start2: The first byte to zero in the second range.
+ * @xend2: One more than the last byte in the second range.
+ */
+static inline void folio_zero_segments(struct folio *folio,
+               size_t start1, size_t xend1, size_t start2, size_t xend2)
+{
+       zero_user_segments(&folio->page, start1, xend1, start2, xend2);
+}
+
+/**
+ * folio_zero_segment() - Zero a byte range in a folio.
+ * @folio: The folio to write to.
+ * @start: The first byte to zero.
+ * @xend: One more than the last byte to zero.
+ */
+static inline void folio_zero_segment(struct folio *folio,
+               size_t start, size_t xend)
+{
+       zero_user_segments(&folio->page, start, xend, 0, 0);
+}
+
+/**
+ * folio_zero_range() - Zero a byte range in a folio.
+ * @folio: The folio to write to.
+ * @start: The first byte to zero.
+ * @length: The number of bytes to zero.
+ */
+static inline void folio_zero_range(struct folio *folio,
+               size_t start, size_t length)
+{
+       zero_user_segments(&folio->page, start, start + length, 0, 0);
+}
+
 #endif /* _LINUX_HIGHMEM_H */
index c137396..ba025ae 100644 (file)
@@ -128,6 +128,13 @@ static inline void resv_map_dup_hugetlb_cgroup_uncharge_info(
                css_get(resv_map->css);
 }
 
+static inline void resv_map_put_hugetlb_cgroup_uncharge_info(
+                                               struct resv_map *resv_map)
+{
+       if (resv_map->css)
+               css_put(resv_map->css);
+}
+
 extern int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages,
                                        struct hugetlb_cgroup **ptr);
 extern int hugetlb_cgroup_charge_cgroup_rsvd(int idx, unsigned long nr_pages,
@@ -211,6 +218,11 @@ static inline void resv_map_dup_hugetlb_cgroup_uncharge_info(
 {
 }
 
+static inline void resv_map_put_hugetlb_cgroup_uncharge_info(
+                                               struct resv_map *resv_map)
+{
+}
+
 static inline int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages,
                                               struct hugetlb_cgroup **ptr)
 {
index aee8ff4..f45f133 100644 (file)
@@ -9,7 +9,7 @@
 #define _INTEL_ISH_CLIENT_IF_H_
 
 #include <linux/device.h>
-#include <linux/uuid.h>
+#include <linux/mod_devicetable.h>
 
 struct ishtp_cl_device;
 struct ishtp_device;
@@ -40,7 +40,7 @@ enum cl_state {
 struct ishtp_cl_driver {
        struct device_driver driver;
        const char *name;
-       const guid_t *guid;
+       const struct ishtp_device_id *id;
        int (*probe)(struct ishtp_cl_device *dev);
        void (*remove)(struct ishtp_cl_device *dev);
        int (*reset)(struct ishtp_cl_device *dev);
index 05e2277..b75395e 100644 (file)
@@ -131,6 +131,16 @@ static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
        return ns;
 }
 
+static inline struct ipc_namespace *get_ipc_ns_not_zero(struct ipc_namespace *ns)
+{
+       if (ns) {
+               if (refcount_inc_not_zero(&ns->ns.count))
+                       return ns;
+       }
+
+       return NULL;
+}
+
 extern void put_ipc_ns(struct ipc_namespace *ns);
 #else
 static inline struct ipc_namespace *copy_ipcs(unsigned long flags,
@@ -147,6 +157,11 @@ static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
        return ns;
 }
 
+static inline struct ipc_namespace *get_ipc_ns_not_zero(struct ipc_namespace *ns)
+{
+       return ns;
+}
+
 static inline void put_ipc_ns(struct ipc_namespace *ns)
 {
 }
index 9e0667e..c310648 100644 (file)
@@ -874,7 +874,7 @@ void kvm_release_pfn_dirty(kvm_pfn_t pfn);
 void kvm_set_pfn_dirty(kvm_pfn_t pfn);
 void kvm_set_pfn_accessed(kvm_pfn_t pfn);
 
-void kvm_release_pfn(kvm_pfn_t pfn, bool dirty, struct gfn_to_pfn_cache *cache);
+void kvm_release_pfn(kvm_pfn_t pfn, bool dirty);
 int kvm_read_guest_page(struct kvm *kvm, gfn_t gfn, void *data, int offset,
                        int len);
 int kvm_read_guest(struct kvm *kvm, gpa_t gpa, void *data, unsigned long len);
@@ -950,12 +950,8 @@ struct kvm_memory_slot *kvm_vcpu_gfn_to_memslot(struct kvm_vcpu *vcpu, gfn_t gfn
 kvm_pfn_t kvm_vcpu_gfn_to_pfn_atomic(struct kvm_vcpu *vcpu, gfn_t gfn);
 kvm_pfn_t kvm_vcpu_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn);
 int kvm_vcpu_map(struct kvm_vcpu *vcpu, gpa_t gpa, struct kvm_host_map *map);
-int kvm_map_gfn(struct kvm_vcpu *vcpu, gfn_t gfn, struct kvm_host_map *map,
-               struct gfn_to_pfn_cache *cache, bool atomic);
 struct page *kvm_vcpu_gfn_to_page(struct kvm_vcpu *vcpu, gfn_t gfn);
 void kvm_vcpu_unmap(struct kvm_vcpu *vcpu, struct kvm_host_map *map, bool dirty);
-int kvm_unmap_gfn(struct kvm_vcpu *vcpu, struct kvm_host_map *map,
-                 struct gfn_to_pfn_cache *cache, bool dirty, bool atomic);
 unsigned long kvm_vcpu_gfn_to_hva(struct kvm_vcpu *vcpu, gfn_t gfn);
 unsigned long kvm_vcpu_gfn_to_hva_prot(struct kvm_vcpu *vcpu, gfn_t gfn, bool *writable);
 int kvm_vcpu_read_guest_page(struct kvm_vcpu *vcpu, gfn_t gfn, void *data, int offset,
index 2237abb..234eab0 100644 (file)
@@ -53,13 +53,6 @@ struct gfn_to_hva_cache {
        struct kvm_memory_slot *memslot;
 };
 
-struct gfn_to_pfn_cache {
-       u64 generation;
-       gfn_t gfn;
-       kvm_pfn_t pfn;
-       bool dirty;
-};
-
 #ifdef KVM_ARCH_NR_OBJS_PER_MEMORY_CACHE
 /*
  * Memory caches are used to preallocate memory ahead of various MMU flows,
index 97afcea..8b18fe9 100644 (file)
@@ -145,13 +145,13 @@ u32 mlx5_eswitch_get_vport_metadata_for_set(struct mlx5_eswitch *esw,
        GENMASK(31 - ESW_TUN_ID_BITS - ESW_RESERVED_BITS, \
                ESW_TUN_OPTS_OFFSET + 1)
 
-u8 mlx5_eswitch_mode(struct mlx5_core_dev *dev);
+u8 mlx5_eswitch_mode(const struct mlx5_core_dev *dev);
 u16 mlx5_eswitch_get_total_vports(const struct mlx5_core_dev *dev);
 struct mlx5_core_dev *mlx5_eswitch_get_core_dev(struct mlx5_eswitch *esw);
 
 #else  /* CONFIG_MLX5_ESWITCH */
 
-static inline u8 mlx5_eswitch_mode(struct mlx5_core_dev *dev)
+static inline u8 mlx5_eswitch_mode(const struct mlx5_core_dev *dev)
 {
        return MLX5_ESWITCH_NONE;
 }
index bb8c6f5..c3a6e62 100644 (file)
@@ -105,7 +105,18 @@ struct page {
                        struct page_pool *pp;
                        unsigned long _pp_mapping_pad;
                        unsigned long dma_addr;
-                       atomic_long_t pp_frag_count;
+                       union {
+                               /**
+                                * dma_addr_upper: might require a 64-bit
+                                * value on 32-bit architectures.
+                                */
+                               unsigned long dma_addr_upper;
+                               /**
+                                * For frag page support, not supported in
+                                * 32-bit architectures with 64-bit DMA.
+                                */
+                               atomic_long_t pp_frag_count;
+                       };
                };
                struct {        /* slab, slob and slub */
                        union {
index ae2e75d..4bb7197 100644 (file)
@@ -895,4 +895,18 @@ struct dfl_device_id {
        kernel_ulong_t driver_data;
 };
 
+/* ISHTP (Integrated Sensor Hub Transport Protocol) */
+
+#define ISHTP_MODULE_PREFIX    "ishtp:"
+
+/**
+ * struct ishtp_device_id - ISHTP device identifier
+ * @guid: GUID of the device.
+ * @driver_data: pointer to driver specific data
+ */
+struct ishtp_device_id {
+       guid_t guid;
+       kernel_ulong_t driver_data;
+};
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
index 52ec4b5..b5f14d5 100644 (file)
@@ -686,13 +686,13 @@ static inline bool test_set_page_writeback(struct page *page)
 
 __PAGEFLAG(Head, head, PF_ANY) CLEARPAGEFLAG(Head, head, PF_ANY)
 
-/* Whether there are one or multiple pages in a folio */
-static inline bool folio_test_single(struct folio *folio)
-{
-       return !folio_test_head(folio);
-}
-
-static inline bool folio_test_multi(struct folio *folio)
+/**
+ * folio_test_large() - Does this folio contain more than one page?
+ * @folio: The folio to test.
+ *
+ * Return: True if the folio is larger than one page.
+ */
+static inline bool folio_test_large(struct folio *folio)
 {
        return folio_test_head(folio);
 }
index 1a0c646..6052464 100644 (file)
@@ -84,7 +84,7 @@ enum mapping_flags {
        AS_EXITING      = 4,    /* final truncate in progress */
        /* writeback related tags are not used */
        AS_NO_WRITEBACK_TAGS = 5,
-       AS_THP_SUPPORT = 6,     /* THPs supported */
+       AS_LARGE_FOLIO_SUPPORT = 6,
 };
 
 /**
@@ -176,9 +176,25 @@ static inline void mapping_set_gfp_mask(struct address_space *m, gfp_t mask)
        m->gfp_mask = mask;
 }
 
-static inline bool mapping_thp_support(struct address_space *mapping)
+/**
+ * mapping_set_large_folios() - Indicate the file supports large folios.
+ * @mapping: The file.
+ *
+ * The filesystem should call this function in its inode constructor to
+ * indicate that the VFS can use large folios to cache the contents of
+ * the file.
+ *
+ * Context: This should not be called while the inode is active as it
+ * is non-atomic.
+ */
+static inline void mapping_set_large_folios(struct address_space *mapping)
+{
+       __set_bit(AS_LARGE_FOLIO_SUPPORT, &mapping->flags);
+}
+
+static inline bool mapping_large_folio_support(struct address_space *mapping)
 {
-       return test_bit(AS_THP_SUPPORT, &mapping->flags);
+       return test_bit(AS_LARGE_FOLIO_SUPPORT, &mapping->flags);
 }
 
 static inline int filemap_nr_thps(struct address_space *mapping)
@@ -193,7 +209,7 @@ static inline int filemap_nr_thps(struct address_space *mapping)
 static inline void filemap_nr_thps_inc(struct address_space *mapping)
 {
 #ifdef CONFIG_READ_ONLY_THP_FOR_FS
-       if (!mapping_thp_support(mapping))
+       if (!mapping_large_folio_support(mapping))
                atomic_inc(&mapping->nr_thps);
 #else
        WARN_ON_ONCE(1);
@@ -203,7 +219,7 @@ static inline void filemap_nr_thps_inc(struct address_space *mapping)
 static inline void filemap_nr_thps_dec(struct address_space *mapping)
 {
 #ifdef CONFIG_READ_ONLY_THP_FOR_FS
-       if (!mapping_thp_support(mapping))
+       if (!mapping_large_folio_support(mapping))
                atomic_dec(&mapping->nr_thps);
 #else
        WARN_ON_ONCE(1);
index 98a9371..ae4004e 100644 (file)
@@ -6,7 +6,6 @@
 #include <linux/preempt.h>
 #include <linux/smp.h>
 #include <linux/cpumask.h>
-#include <linux/printk.h>
 #include <linux/pfn.h>
 #include <linux/init.h>
 
index 85b656f..9497f6b 100644 (file)
@@ -198,6 +198,7 @@ void dump_stack_print_info(const char *log_lvl);
 void show_regs_print_info(const char *log_lvl);
 extern asmlinkage void dump_stack_lvl(const char *log_lvl) __cold;
 extern asmlinkage void dump_stack(void) __cold;
+void printk_trigger_flush(void);
 #else
 static inline __printf(1, 0)
 int vprintk(const char *s, va_list args)
@@ -274,6 +275,9 @@ static inline void dump_stack_lvl(const char *log_lvl)
 static inline void dump_stack(void)
 {
 }
+static inline void printk_trigger_flush(void)
+{
+}
 #endif
 
 #ifdef CONFIG_SMP
index ae04968..9afd34a 100644 (file)
@@ -37,6 +37,7 @@
 #define PTP_MSGTYPE_PDELAY_RESP 0x3
 
 #define PTP_EV_PORT 319
+#define PTP_GEN_PORT 320
 #define PTP_GEN_BIT 0x08 /* indicates general message, if set in message type */
 
 #define OFF_PTP_SOURCE_UUID    22 /* PTPv1 only */
index 2350539..33a5064 100644 (file)
@@ -352,6 +352,7 @@ extern __must_check bool do_notify_parent(struct task_struct *, int);
 extern void __wake_up_parent(struct task_struct *p, struct task_struct *parent);
 extern void force_sig(int);
 extern void force_fatal_sig(int);
+extern void force_exit_sig(int);
 extern int send_sig(int, struct task_struct *, int);
 extern int zap_other_threads(struct task_struct *p);
 extern struct sigqueue *sigqueue_alloc(void);
index ba88a69..058d7f3 100644 (file)
@@ -158,7 +158,7 @@ static inline struct vm_struct *task_stack_vm_area(const struct task_struct *t)
  * Protects ->fs, ->files, ->mm, ->group_info, ->comm, keyring
  * subscriptions and synchronises with wait4().  Also used in procfs.  Also
  * pins the final release of task.io_context.  Also protects ->cpuset and
- * ->cgroup.subsys[]. And ->vfork_done.
+ * ->cgroup.subsys[]. And ->vfork_done. And ->sysvshm.shm_clist.
  *
  * Nests both inside and outside of read_lock(&tasklist_lock).
  * It must not be nested with write_lock_irq(&tasklist_lock),
diff --git a/include/linux/sdb.h b/include/linux/sdb.h
deleted file mode 100644 (file)
index a2404a2..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * This is the official version 1.1 of sdb.h
- */
-#ifndef __SDB_H__
-#define __SDB_H__
-#ifdef __KERNEL__
-#include <linux/types.h>
-#else
-#include <stdint.h>
-#endif
-
-/*
- * All structures are 64 bytes long and are expected
- * to live in an array, one for each interconnect.
- * Most fields of the structures are shared among the
- * various types, and most-specific fields are at the
- * beginning (for alignment reasons, and to keep the
- * magic number at the head of the interconnect record
- */
-
-/* Product, 40 bytes at offset 24, 8-byte aligned
- *
- * device_id is vendor-assigned; version is device-specific,
- * date is hex (e.g 0x20120501), name is UTF-8, blank-filled
- * and not terminated with a 0 byte.
- */
-struct sdb_product {
-       uint64_t                vendor_id;      /* 0x18..0x1f */
-       uint32_t                device_id;      /* 0x20..0x23 */
-       uint32_t                version;        /* 0x24..0x27 */
-       uint32_t                date;           /* 0x28..0x2b */
-       uint8_t                 name[19];       /* 0x2c..0x3e */
-       uint8_t                 record_type;    /* 0x3f */
-};
-
-/*
- * Component, 56 bytes at offset 8, 8-byte aligned
- *
- * The address range is first to last, inclusive
- * (for example 0x100000 - 0x10ffff)
- */
-struct sdb_component {
-       uint64_t                addr_first;     /* 0x08..0x0f */
-       uint64_t                addr_last;      /* 0x10..0x17 */
-       struct sdb_product      product;        /* 0x18..0x3f */
-};
-
-/* Type of the SDB record */
-enum sdb_record_type {
-       sdb_type_interconnect   = 0x00,
-       sdb_type_device         = 0x01,
-       sdb_type_bridge         = 0x02,
-       sdb_type_integration    = 0x80,
-       sdb_type_repo_url       = 0x81,
-       sdb_type_synthesis      = 0x82,
-       sdb_type_empty          = 0xFF,
-};
-
-/* Type 0: interconnect (first of the array)
- *
- * sdb_records is the length of the table including this first
- * record, version is 1. The bus type is enumerated later.
- */
-#define                                SDB_MAGIC       0x5344422d /* "SDB-" */
-struct sdb_interconnect {
-       uint32_t                sdb_magic;      /* 0x00-0x03 */
-       uint16_t                sdb_records;    /* 0x04-0x05 */
-       uint8_t                 sdb_version;    /* 0x06 */
-       uint8_t                 sdb_bus_type;   /* 0x07 */
-       struct sdb_component    sdb_component;  /* 0x08-0x3f */
-};
-
-/* Type 1: device
- *
- * class is 0 for "custom device", other values are
- * to be standardized; ABI version is for the driver,
- * bus-specific bits are defined by each bus (see below)
- */
-struct sdb_device {
-       uint16_t                abi_class;      /* 0x00-0x01 */
-       uint8_t                 abi_ver_major;  /* 0x02 */
-       uint8_t                 abi_ver_minor;  /* 0x03 */
-       uint32_t                bus_specific;   /* 0x04-0x07 */
-       struct sdb_component    sdb_component;  /* 0x08-0x3f */
-};
-
-/* Type 2: bridge
- *
- * child is the address of the nested SDB table
- */
-struct sdb_bridge {
-       uint64_t                sdb_child;      /* 0x00-0x07 */
-       struct sdb_component    sdb_component;  /* 0x08-0x3f */
-};
-
-/* Type 0x80: integration
- *
- * all types with bit 7 set are meta-information, so
- * software can ignore the types it doesn't know. Here we
- * just provide product information for an aggregate device
- */
-struct sdb_integration {
-       uint8_t                 reserved[24];   /* 0x00-0x17 */
-       struct sdb_product      product;        /* 0x08-0x3f */
-};
-
-/* Type 0x81: Top module repository url
- *
- * again, an informative field that software can ignore
- */
-struct sdb_repo_url {
-       uint8_t                 repo_url[63];   /* 0x00-0x3e */
-       uint8_t                 record_type;    /* 0x3f */
-};
-
-/* Type 0x82: Synthesis tool information
- *
- * this informative record
- */
-struct sdb_synthesis {
-       uint8_t                 syn_name[16];   /* 0x00-0x0f */
-       uint8_t                 commit_id[16];  /* 0x10-0x1f */
-       uint8_t                 tool_name[8];   /* 0x20-0x27 */
-       uint32_t                tool_version;   /* 0x28-0x2b */
-       uint32_t                date;           /* 0x2c-0x2f */
-       uint8_t                 user_name[15];  /* 0x30-0x3e */
-       uint8_t                 record_type;    /* 0x3f */
-};
-
-/* Type 0xff: empty
- *
- * this allows keeping empty slots during development,
- * so they can be filled later with minimal efforts and
- * no misleading description is ever shipped -- hopefully.
- * It can also be used to pad a table to a desired length.
- */
-struct sdb_empty {
-       uint8_t                 reserved[63];   /* 0x00-0x3e */
-       uint8_t                 record_type;    /* 0x3f */
-};
-
-/* The type of bus, for bus-specific flags */
-enum sdb_bus_type {
-       sdb_wishbone = 0x00,
-       sdb_data     = 0x01,
-};
-
-#define SDB_WB_WIDTH_MASK      0x0f
-#define SDB_WB_ACCESS8                 0x01
-#define SDB_WB_ACCESS16                        0x02
-#define SDB_WB_ACCESS32                        0x04
-#define SDB_WB_ACCESS64                        0x08
-#define SDB_WB_LITTLE_ENDIAN   0x80
-
-#define SDB_DATA_READ          0x04
-#define SDB_DATA_WRITE         0x02
-#define SDB_DATA_EXEC          0x01
-
-#endif /* __SDB_H__ */
index 686a666..c8cb7e6 100644 (file)
@@ -4226,7 +4226,7 @@ static inline void skb_remcsum_process(struct sk_buff *skb, void *ptr,
                return;
        }
 
-        if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) {
+       if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) {
                __skb_checksum_complete(skb);
                skb_postpull_rcsum(skb, skb->data, ptr - (void *)skb->data);
        }
index 50453b2..2d167ac 100644 (file)
@@ -673,7 +673,7 @@ struct trace_event_file {
 
 #define PERF_MAX_TRACE_SIZE    8192
 
-#define MAX_FILTER_STR_VAL     256     /* Should handle KSYM_SYMBOL_LEN */
+#define MAX_FILTER_STR_VAL     256U    /* Should handle KSYM_SYMBOL_LEN */
 
 enum event_trigger_type {
        ETT_NONE                = (0),
index 44d0e09..41edbc0 100644 (file)
@@ -152,7 +152,6 @@ size_t virtio_max_dma_size(struct virtio_device *vdev);
  * @feature_table_size: number of entries in the feature table array.
  * @feature_table_legacy: same as feature_table but when working in legacy mode.
  * @feature_table_size_legacy: number of entries in feature table legacy array.
- * @suppress_used_validation: set to not have core validate used length
  * @probe: the function to call when a device is found.  Returns 0 or -errno.
  * @scan: optional function to call after successful probe; intended
  *    for virtio-scsi to invoke a scan.
@@ -169,7 +168,6 @@ struct virtio_driver {
        unsigned int feature_table_size;
        const unsigned int *feature_table_legacy;
        unsigned int feature_table_size_legacy;
-       bool suppress_used_validation;
        int (*validate)(struct virtio_device *dev);
        int (*probe)(struct virtio_device *dev);
        void (*scan)(struct virtio_device *dev);
index b465f8f..04e87f4 100644 (file)
@@ -120,10 +120,15 @@ retry:
 
        if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
                u16 gso_size = __virtio16_to_cpu(little_endian, hdr->gso_size);
+               unsigned int nh_off = p_off;
                struct skb_shared_info *shinfo = skb_shinfo(skb);
 
+               /* UFO may not include transport header in gso_size. */
+               if (gso_type & SKB_GSO_UDP)
+                       nh_off -= thlen;
+
                /* Too small packets are not really GSO ones. */
-               if (skb->len - p_off > gso_size) {
+               if (skb->len - nh_off > gso_size) {
                        shinfo->gso_size = gso_size;
                        shinfo->gso_type = gso_type;
 
index c412dde..83b8070 100644 (file)
@@ -485,6 +485,7 @@ int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh,
                 struct fib6_config *cfg, gfp_t gfp_flags,
                 struct netlink_ext_ack *extack);
 void fib6_nh_release(struct fib6_nh *fib6_nh);
+void fib6_nh_release_dsts(struct fib6_nh *fib6_nh);
 
 int call_fib6_entry_notifiers(struct net *net,
                              enum fib_event_type event_type,
index afbce90..45e0339 100644 (file)
@@ -47,6 +47,7 @@ struct ipv6_stub {
                            struct fib6_config *cfg, gfp_t gfp_flags,
                            struct netlink_ext_ack *extack);
        void (*fib6_nh_release)(struct fib6_nh *fib6_nh);
+       void (*fib6_nh_release_dsts)(struct fib6_nh *fib6_nh);
        void (*fib6_update_sernum)(struct net *net, struct fib6_info *rt);
        int (*ip6_del_rt)(struct net *net, struct fib6_info *rt, bool skip_notify);
        void (*fib6_rt_update)(struct net *net, struct fib6_info *rt,
index a964dae..ea85956 100644 (file)
@@ -30,6 +30,7 @@ enum nci_flag {
        NCI_UP,
        NCI_DATA_EXCHANGE,
        NCI_DATA_EXCHANGE_TO,
+       NCI_UNREG,
 };
 
 /* NCI device states */
index ddcee12..145acb8 100644 (file)
@@ -19,6 +19,8 @@
  *
  */
 
+#include <linux/types.h>
+
 #define NL802154_GENL_NAME "nl802154"
 
 enum nl802154_commands {
@@ -150,10 +152,9 @@ enum nl802154_attrs {
 };
 
 enum nl802154_iftype {
-       /* for backwards compatibility TODO */
-       NL802154_IFTYPE_UNSPEC = -1,
+       NL802154_IFTYPE_UNSPEC = (~(__u32)0),
 
-       NL802154_IFTYPE_NODE,
+       NL802154_IFTYPE_NODE = 0,
        NL802154_IFTYPE_MONITOR,
        NL802154_IFTYPE_COORD,
 
index 3855f06..a408240 100644 (file)
@@ -216,14 +216,24 @@ static inline void page_pool_recycle_direct(struct page_pool *pool,
        page_pool_put_full_page(pool, page, true);
 }
 
+#define PAGE_POOL_DMA_USE_PP_FRAG_COUNT        \
+               (sizeof(dma_addr_t) > sizeof(unsigned long))
+
 static inline dma_addr_t page_pool_get_dma_addr(struct page *page)
 {
-       return page->dma_addr;
+       dma_addr_t ret = page->dma_addr;
+
+       if (PAGE_POOL_DMA_USE_PP_FRAG_COUNT)
+               ret |= (dma_addr_t)page->dma_addr_upper << 16 << 16;
+
+       return ret;
 }
 
 static inline void page_pool_set_dma_addr(struct page *page, dma_addr_t addr)
 {
        page->dma_addr = addr;
+       if (PAGE_POOL_DMA_USE_PP_FRAG_COUNT)
+               page->dma_addr_upper = upper_32_bits(addr);
 }
 
 static inline void page_pool_set_frag_count(struct page *page, long nr)
index 2758d9d..c2a79ae 100644 (file)
@@ -30,7 +30,7 @@ enum rdma_nl_flags {
  * constant as well and the compiler checks they are the same.
  */
 #define MODULE_ALIAS_RDMA_NETLINK(_index, _val)                                \
-       static inline void __chk_##_index(void)                                \
+       static inline void __maybe_unused __chk_##_index(void)                 \
        {                                                                      \
                BUILD_BUG_ON(_index != _val);                                  \
        }                                                                      \
index eeb1142..4d1dfa1 100644 (file)
@@ -703,6 +703,8 @@ int ocelot_vcap_filter_add(struct ocelot *ocelot,
                           struct netlink_ext_ack *extack);
 int ocelot_vcap_filter_del(struct ocelot *ocelot,
                           struct ocelot_vcap_filter *rule);
+int ocelot_vcap_filter_replace(struct ocelot *ocelot,
+                              struct ocelot_vcap_filter *filter);
 struct ocelot_vcap_filter *
 ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block,
                                    unsigned long cookie, bool tc_offload);
index 3ba6331..c9048f3 100644 (file)
@@ -8,7 +8,7 @@
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM rpcgss
 
-#if !defined(_TRACE_RPCRDMA_H) || defined(TRACE_HEADER_MULTI_READ)
+#if !defined(_TRACE_RPCGSS_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_RPCGSS_H
 
 #include <linux/tracepoint.h>
index b94074c..b13eb86 100644 (file)
@@ -112,6 +112,7 @@ struct xenbus_driver {
        const char *name;       /* defaults to ids[0].devicetype */
        const struct xenbus_device_id *ids;
        bool allow_rebind; /* avoid setting xenstore closed during remove */
+       bool not_essential;     /* is not mandatory for boot progress */
        int (*probe)(struct xenbus_device *dev,
                     const struct xenbus_device_id *id);
        void (*otherend_changed)(struct xenbus_device *dev,
index 036b750..4b7bac1 100644 (file)
@@ -887,7 +887,7 @@ config CC_HAS_INT128
 
 config CC_IMPLICIT_FALLTHROUGH
        string
-       default "-Wimplicit-fallthrough=5" if CC_IS_GCC
+       default "-Wimplicit-fallthrough=5" if CC_IS_GCC && $(cc-option,-Wimplicit-fallthrough=5)
        default "-Wimplicit-fallthrough" if CC_IS_CLANG && $(cc-option,-Wunreachable-code-fallthrough)
 
 #
index 4942bdd..b3048eb 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -62,9 +62,18 @@ struct shmid_kernel /* private to the kernel */
        struct pid              *shm_lprid;
        struct ucounts          *mlock_ucounts;
 
-       /* The task created the shm object.  NULL if the task is dead. */
+       /*
+        * The task created the shm object, for
+        * task_lock(shp->shm_creator)
+        */
        struct task_struct      *shm_creator;
-       struct list_head        shm_clist;      /* list by creator */
+
+       /*
+        * List by creator. task_lock(->shm_creator) required for read/write.
+        * If list_empty(), then the creator is dead already.
+        */
+       struct list_head        shm_clist;
+       struct ipc_namespace    *ns;
 } __randomize_layout;
 
 /* shm_mode upper byte flags */
@@ -115,6 +124,7 @@ static void do_shm_rmid(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
        struct shmid_kernel *shp;
 
        shp = container_of(ipcp, struct shmid_kernel, shm_perm);
+       WARN_ON(ns != shp->ns);
 
        if (shp->shm_nattch) {
                shp->shm_perm.mode |= SHM_DEST;
@@ -225,10 +235,43 @@ static void shm_rcu_free(struct rcu_head *head)
        kfree(shp);
 }
 
-static inline void shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *s)
+/*
+ * It has to be called with shp locked.
+ * It must be called before ipc_rmid()
+ */
+static inline void shm_clist_rm(struct shmid_kernel *shp)
 {
-       list_del(&s->shm_clist);
-       ipc_rmid(&shm_ids(ns), &s->shm_perm);
+       struct task_struct *creator;
+
+       /* ensure that shm_creator does not disappear */
+       rcu_read_lock();
+
+       /*
+        * A concurrent exit_shm may do a list_del_init() as well.
+        * Just do nothing if exit_shm already did the work
+        */
+       if (!list_empty(&shp->shm_clist)) {
+               /*
+                * shp->shm_creator is guaranteed to be valid *only*
+                * if shp->shm_clist is not empty.
+                */
+               creator = shp->shm_creator;
+
+               task_lock(creator);
+               /*
+                * list_del_init() is a nop if the entry was already removed
+                * from the list.
+                */
+               list_del_init(&shp->shm_clist);
+               task_unlock(creator);
+       }
+       rcu_read_unlock();
+}
+
+static inline void shm_rmid(struct shmid_kernel *s)
+{
+       shm_clist_rm(s);
+       ipc_rmid(&shm_ids(s->ns), &s->shm_perm);
 }
 
 
@@ -283,7 +326,7 @@ static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
        shm_file = shp->shm_file;
        shp->shm_file = NULL;
        ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
-       shm_rmid(ns, shp);
+       shm_rmid(shp);
        shm_unlock(shp);
        if (!is_file_hugepages(shm_file))
                shmem_lock(shm_file, 0, shp->mlock_ucounts);
@@ -303,10 +346,10 @@ static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
  *
  * 2) sysctl kernel.shm_rmid_forced is set to 1.
  */
-static bool shm_may_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
+static bool shm_may_destroy(struct shmid_kernel *shp)
 {
        return (shp->shm_nattch == 0) &&
-              (ns->shm_rmid_forced ||
+              (shp->ns->shm_rmid_forced ||
                (shp->shm_perm.mode & SHM_DEST));
 }
 
@@ -337,7 +380,7 @@ static void shm_close(struct vm_area_struct *vma)
        ipc_update_pid(&shp->shm_lprid, task_tgid(current));
        shp->shm_dtim = ktime_get_real_seconds();
        shp->shm_nattch--;
-       if (shm_may_destroy(ns, shp))
+       if (shm_may_destroy(shp))
                shm_destroy(ns, shp);
        else
                shm_unlock(shp);
@@ -358,10 +401,10 @@ static int shm_try_destroy_orphaned(int id, void *p, void *data)
         *
         * As shp->* are changed under rwsem, it's safe to skip shp locking.
         */
-       if (shp->shm_creator != NULL)
+       if (!list_empty(&shp->shm_clist))
                return 0;
 
-       if (shm_may_destroy(ns, shp)) {
+       if (shm_may_destroy(shp)) {
                shm_lock_by_ptr(shp);
                shm_destroy(ns, shp);
        }
@@ -379,48 +422,97 @@ void shm_destroy_orphaned(struct ipc_namespace *ns)
 /* Locking assumes this will only be called with task == current */
 void exit_shm(struct task_struct *task)
 {
-       struct ipc_namespace *ns = task->nsproxy->ipc_ns;
-       struct shmid_kernel *shp, *n;
+       for (;;) {
+               struct shmid_kernel *shp;
+               struct ipc_namespace *ns;
 
-       if (list_empty(&task->sysvshm.shm_clist))
-               return;
+               task_lock(task);
+
+               if (list_empty(&task->sysvshm.shm_clist)) {
+                       task_unlock(task);
+                       break;
+               }
+
+               shp = list_first_entry(&task->sysvshm.shm_clist, struct shmid_kernel,
+                               shm_clist);
 
-       /*
-        * If kernel.shm_rmid_forced is not set then only keep track of
-        * which shmids are orphaned, so that a later set of the sysctl
-        * can clean them up.
-        */
-       if (!ns->shm_rmid_forced) {
-               down_read(&shm_ids(ns).rwsem);
-               list_for_each_entry(shp, &task->sysvshm.shm_clist, shm_clist)
-                       shp->shm_creator = NULL;
                /*
-                * Only under read lock but we are only called on current
-                * so no entry on the list will be shared.
+                * 1) Get pointer to the ipc namespace. It is worth to say
+                * that this pointer is guaranteed to be valid because
+                * shp lifetime is always shorter than namespace lifetime
+                * in which shp lives.
+                * We taken task_lock it means that shp won't be freed.
                 */
-               list_del(&task->sysvshm.shm_clist);
-               up_read(&shm_ids(ns).rwsem);
-               return;
-       }
+               ns = shp->ns;
 
-       /*
-        * Destroy all already created segments, that were not yet mapped,
-        * and mark any mapped as orphan to cover the sysctl toggling.
-        * Destroy is skipped if shm_may_destroy() returns false.
-        */
-       down_write(&shm_ids(ns).rwsem);
-       list_for_each_entry_safe(shp, n, &task->sysvshm.shm_clist, shm_clist) {
-               shp->shm_creator = NULL;
+               /*
+                * 2) If kernel.shm_rmid_forced is not set then only keep track of
+                * which shmids are orphaned, so that a later set of the sysctl
+                * can clean them up.
+                */
+               if (!ns->shm_rmid_forced)
+                       goto unlink_continue;
 
-               if (shm_may_destroy(ns, shp)) {
-                       shm_lock_by_ptr(shp);
-                       shm_destroy(ns, shp);
+               /*
+                * 3) get a reference to the namespace.
+                *    The refcount could be already 0. If it is 0, then
+                *    the shm objects will be free by free_ipc_work().
+                */
+               ns = get_ipc_ns_not_zero(ns);
+               if (!ns) {
+unlink_continue:
+                       list_del_init(&shp->shm_clist);
+                       task_unlock(task);
+                       continue;
                }
-       }
 
-       /* Remove the list head from any segments still attached. */
-       list_del(&task->sysvshm.shm_clist);
-       up_write(&shm_ids(ns).rwsem);
+               /*
+                * 4) get a reference to shp.
+                *   This cannot fail: shm_clist_rm() is called before
+                *   ipc_rmid(), thus the refcount cannot be 0.
+                */
+               WARN_ON(!ipc_rcu_getref(&shp->shm_perm));
+
+               /*
+                * 5) unlink the shm segment from the list of segments
+                *    created by current.
+                *    This must be done last. After unlinking,
+                *    only the refcounts obtained above prevent IPC_RMID
+                *    from destroying the segment or the namespace.
+                */
+               list_del_init(&shp->shm_clist);
+
+               task_unlock(task);
+
+               /*
+                * 6) we have all references
+                *    Thus lock & if needed destroy shp.
+                */
+               down_write(&shm_ids(ns).rwsem);
+               shm_lock_by_ptr(shp);
+               /*
+                * rcu_read_lock was implicitly taken in shm_lock_by_ptr, it's
+                * safe to call ipc_rcu_putref here
+                */
+               ipc_rcu_putref(&shp->shm_perm, shm_rcu_free);
+
+               if (ipc_valid_object(&shp->shm_perm)) {
+                       if (shm_may_destroy(shp))
+                               shm_destroy(ns, shp);
+                       else
+                               shm_unlock(shp);
+               } else {
+                       /*
+                        * Someone else deleted the shp from namespace
+                        * idr/kht while we have waited.
+                        * Just unlock and continue.
+                        */
+                       shm_unlock(shp);
+               }
+
+               up_write(&shm_ids(ns).rwsem);
+               put_ipc_ns(ns); /* paired with get_ipc_ns_not_zero */
+       }
 }
 
 static vm_fault_t shm_fault(struct vm_fault *vmf)
@@ -676,7 +768,11 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
        if (error < 0)
                goto no_id;
 
+       shp->ns = ns;
+
+       task_lock(current);
        list_add(&shp->shm_clist, &current->sysvshm.shm_clist);
+       task_unlock(current);
 
        /*
         * shmid gets reported as "inode#" in /proc/pid/maps.
@@ -1567,7 +1663,8 @@ out_nattch:
        down_write(&shm_ids(ns).rwsem);
        shp = shm_lock(ns, shmid);
        shp->shm_nattch--;
-       if (shm_may_destroy(ns, shp))
+
+       if (shm_may_destroy(shp))
                shm_destroy(ns, shp);
        else
                shm_unlock(shp);
index d48d8cf..fa2d86e 100644 (file)
@@ -447,8 +447,8 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
 static void ipc_kht_remove(struct ipc_ids *ids, struct kern_ipc_perm *ipcp)
 {
        if (ipcp->key != IPC_PRIVATE)
-               rhashtable_remove_fast(&ids->key_ht, &ipcp->khtnode,
-                                      ipc_kht_params);
+               WARN_ON_ONCE(rhashtable_remove_fast(&ids->key_ht, &ipcp->khtnode,
+                                      ipc_kht_params));
 }
 
 /**
@@ -498,7 +498,7 @@ void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp)
 {
        int idx = ipcid_to_idx(ipcp->id);
 
-       idr_remove(&ids->ipcs_idr, idx);
+       WARN_ON_ONCE(idr_remove(&ids->ipcs_idr, idx) != ipcp);
        ipc_kht_remove(ids, ipcp);
        ids->in_use--;
        ipcp->deleted = true;
index 2ca643a..43eb350 100644 (file)
@@ -1809,6 +1809,8 @@ sysctl_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
                return &bpf_sysctl_get_new_value_proto;
        case BPF_FUNC_sysctl_set_new_value:
                return &bpf_sysctl_set_new_value_proto;
+       case BPF_FUNC_ktime_get_coarse_ns:
+               return &bpf_ktime_get_coarse_ns_proto;
        default:
                return cgroup_base_func_proto(func_id, prog);
        }
index 1ffd469..649f076 100644 (file)
@@ -1364,8 +1364,6 @@ bpf_base_func_proto(enum bpf_func_id func_id)
                return &bpf_ktime_get_ns_proto;
        case BPF_FUNC_ktime_get_boot_ns:
                return &bpf_ktime_get_boot_ns_proto;
-       case BPF_FUNC_ktime_get_coarse_ns:
-               return &bpf_ktime_get_coarse_ns_proto;
        case BPF_FUNC_ringbuf_output:
                return &bpf_ringbuf_output_proto;
        case BPF_FUNC_ringbuf_reserve:
index 50f96ea..1033ee8 100644 (file)
@@ -132,6 +132,21 @@ static struct bpf_map *find_and_alloc_map(union bpf_attr *attr)
        return map;
 }
 
+static void bpf_map_write_active_inc(struct bpf_map *map)
+{
+       atomic64_inc(&map->writecnt);
+}
+
+static void bpf_map_write_active_dec(struct bpf_map *map)
+{
+       atomic64_dec(&map->writecnt);
+}
+
+bool bpf_map_write_active(const struct bpf_map *map)
+{
+       return atomic64_read(&map->writecnt) != 0;
+}
+
 static u32 bpf_map_value_size(const struct bpf_map *map)
 {
        if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
@@ -601,11 +616,8 @@ static void bpf_map_mmap_open(struct vm_area_struct *vma)
 {
        struct bpf_map *map = vma->vm_file->private_data;
 
-       if (vma->vm_flags & VM_MAYWRITE) {
-               mutex_lock(&map->freeze_mutex);
-               map->writecnt++;
-               mutex_unlock(&map->freeze_mutex);
-       }
+       if (vma->vm_flags & VM_MAYWRITE)
+               bpf_map_write_active_inc(map);
 }
 
 /* called for all unmapped memory region (including initial) */
@@ -613,11 +625,8 @@ static void bpf_map_mmap_close(struct vm_area_struct *vma)
 {
        struct bpf_map *map = vma->vm_file->private_data;
 
-       if (vma->vm_flags & VM_MAYWRITE) {
-               mutex_lock(&map->freeze_mutex);
-               map->writecnt--;
-               mutex_unlock(&map->freeze_mutex);
-       }
+       if (vma->vm_flags & VM_MAYWRITE)
+               bpf_map_write_active_dec(map);
 }
 
 static const struct vm_operations_struct bpf_map_default_vmops = {
@@ -668,7 +677,7 @@ static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma)
                goto out;
 
        if (vma->vm_flags & VM_MAYWRITE)
-               map->writecnt++;
+               bpf_map_write_active_inc(map);
 out:
        mutex_unlock(&map->freeze_mutex);
        return err;
@@ -1139,6 +1148,7 @@ static int map_update_elem(union bpf_attr *attr, bpfptr_t uattr)
        map = __bpf_map_get(f);
        if (IS_ERR(map))
                return PTR_ERR(map);
+       bpf_map_write_active_inc(map);
        if (!(map_get_sys_perms(map, f) & FMODE_CAN_WRITE)) {
                err = -EPERM;
                goto err_put;
@@ -1174,6 +1184,7 @@ free_value:
 free_key:
        kvfree(key);
 err_put:
+       bpf_map_write_active_dec(map);
        fdput(f);
        return err;
 }
@@ -1196,6 +1207,7 @@ static int map_delete_elem(union bpf_attr *attr)
        map = __bpf_map_get(f);
        if (IS_ERR(map))
                return PTR_ERR(map);
+       bpf_map_write_active_inc(map);
        if (!(map_get_sys_perms(map, f) & FMODE_CAN_WRITE)) {
                err = -EPERM;
                goto err_put;
@@ -1226,6 +1238,7 @@ static int map_delete_elem(union bpf_attr *attr)
 out:
        kvfree(key);
 err_put:
+       bpf_map_write_active_dec(map);
        fdput(f);
        return err;
 }
@@ -1533,6 +1546,7 @@ static int map_lookup_and_delete_elem(union bpf_attr *attr)
        map = __bpf_map_get(f);
        if (IS_ERR(map))
                return PTR_ERR(map);
+       bpf_map_write_active_inc(map);
        if (!(map_get_sys_perms(map, f) & FMODE_CAN_READ) ||
            !(map_get_sys_perms(map, f) & FMODE_CAN_WRITE)) {
                err = -EPERM;
@@ -1597,6 +1611,7 @@ free_value:
 free_key:
        kvfree(key);
 err_put:
+       bpf_map_write_active_dec(map);
        fdput(f);
        return err;
 }
@@ -1624,8 +1639,7 @@ static int map_freeze(const union bpf_attr *attr)
        }
 
        mutex_lock(&map->freeze_mutex);
-
-       if (map->writecnt) {
+       if (bpf_map_write_active(map)) {
                err = -EBUSY;
                goto err_put;
        }
@@ -4171,6 +4185,9 @@ static int bpf_map_do_batch(const union bpf_attr *attr,
                            union bpf_attr __user *uattr,
                            int cmd)
 {
+       bool has_read  = cmd == BPF_MAP_LOOKUP_BATCH ||
+                        cmd == BPF_MAP_LOOKUP_AND_DELETE_BATCH;
+       bool has_write = cmd != BPF_MAP_LOOKUP_BATCH;
        struct bpf_map *map;
        int err, ufd;
        struct fd f;
@@ -4183,16 +4200,13 @@ static int bpf_map_do_batch(const union bpf_attr *attr,
        map = __bpf_map_get(f);
        if (IS_ERR(map))
                return PTR_ERR(map);
-
-       if ((cmd == BPF_MAP_LOOKUP_BATCH ||
-            cmd == BPF_MAP_LOOKUP_AND_DELETE_BATCH) &&
-           !(map_get_sys_perms(map, f) & FMODE_CAN_READ)) {
+       if (has_write)
+               bpf_map_write_active_inc(map);
+       if (has_read && !(map_get_sys_perms(map, f) & FMODE_CAN_READ)) {
                err = -EPERM;
                goto err_put;
        }
-
-       if (cmd != BPF_MAP_LOOKUP_BATCH &&
-           !(map_get_sys_perms(map, f) & FMODE_CAN_WRITE)) {
+       if (has_write && !(map_get_sys_perms(map, f) & FMODE_CAN_WRITE)) {
                err = -EPERM;
                goto err_put;
        }
@@ -4205,8 +4219,9 @@ static int bpf_map_do_batch(const union bpf_attr *attr,
                BPF_DO_BATCH(map->ops->map_update_batch);
        else
                BPF_DO_BATCH(map->ops->map_delete_batch);
-
 err_put:
+       if (has_write)
+               bpf_map_write_active_dec(map);
        fdput(f);
        return err;
 }
index 890b3ec..50efda5 100644 (file)
@@ -1151,7 +1151,8 @@ static void mark_ptr_not_null_reg(struct bpf_reg_state *reg)
                        /* transfer reg's id which is unique for every map_lookup_elem
                         * as UID of the inner map.
                         */
-                       reg->map_uid = reg->id;
+                       if (map_value_has_timer(map->inner_map_meta))
+                               reg->map_uid = reg->id;
                } else if (map->map_type == BPF_MAP_TYPE_XSKMAP) {
                        reg->type = PTR_TO_XDP_SOCK;
                } else if (map->map_type == BPF_MAP_TYPE_SOCKMAP ||
@@ -4055,7 +4056,22 @@ static void coerce_reg_to_size(struct bpf_reg_state *reg, int size)
 
 static bool bpf_map_is_rdonly(const struct bpf_map *map)
 {
-       return (map->map_flags & BPF_F_RDONLY_PROG) && map->frozen;
+       /* A map is considered read-only if the following condition are true:
+        *
+        * 1) BPF program side cannot change any of the map content. The
+        *    BPF_F_RDONLY_PROG flag is throughout the lifetime of a map
+        *    and was set at map creation time.
+        * 2) The map value(s) have been initialized from user space by a
+        *    loader and then "frozen", such that no new map update/delete
+        *    operations from syscall side are possible for the rest of
+        *    the map's lifetime from that point onwards.
+        * 3) Any parallel/pending map update/delete operations from syscall
+        *    side have been completed. Only after that point, it's safe to
+        *    assume that map value(s) are immutable.
+        */
+       return (map->map_flags & BPF_F_RDONLY_PROG) &&
+              READ_ONCE(map->frozen) &&
+              !bpf_map_write_active(map);
 }
 
 static int bpf_map_direct_read(struct bpf_map *map, int off, int size, u64 *val)
@@ -11631,6 +11647,13 @@ static int check_map_prog_compatibility(struct bpf_verifier_env *env,
                }
        }
 
+       if (map_value_has_timer(map)) {
+               if (is_tracing_prog_type(prog_type)) {
+                       verbose(env, "tracing progs cannot use bpf_timer yet\n");
+                       return -EINVAL;
+               }
+       }
+
        if ((bpf_prog_is_dev_bound(prog->aux) || bpf_map_is_dev_bound(map)) &&
            !bpf_offload_prog_map_match(prog, map)) {
                verbose(env, "offload device mismatch between prog and map\n");
index 192e43a..407a256 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/smpboot.h>
 #include <linux/relay.h>
 #include <linux/slab.h>
+#include <linux/scs.h>
 #include <linux/percpu-rwsem.h>
 #include <linux/cpuset.h>
 
@@ -587,6 +588,12 @@ static int bringup_cpu(unsigned int cpu)
        struct task_struct *idle = idle_thread_get(cpu);
        int ret;
 
+       /*
+        * Reset stale stack state from the last time this CPU was online.
+        */
+       scs_task_reset(idle);
+       kasan_unpoison_task_stack(idle);
+
        /*
         * Some architectures have to walk the irq descriptors to
         * setup the vector space for the cpu which comes online.
index 4508201..0b6379a 100644 (file)
@@ -48,7 +48,7 @@ bool syscall_user_dispatch(struct pt_regs *regs)
                 * the selector is loaded by userspace.
                 */
                if (unlikely(__get_user(state, sd->selector))) {
-                       force_fatal_sig(SIGSEGV);
+                       force_exit_sig(SIGSEGV);
                        return true;
                }
 
@@ -56,7 +56,7 @@ bool syscall_user_dispatch(struct pt_regs *regs)
                        return false;
 
                if (state != SYSCALL_DISPATCH_FILTER_BLOCK) {
-                       force_fatal_sig(SIGSYS);
+                       force_exit_sig(SIGSYS);
                        return true;
                }
        }
index 523106a..30d94f6 100644 (file)
@@ -9759,6 +9759,9 @@ void perf_tp_event(u16 event_type, u64 count, void *record, int entry_size,
                                continue;
                        if (event->attr.config != entry->type)
                                continue;
+                       /* Cannot deliver synchronous signal to other task. */
+                       if (event->attr.sigtrap)
+                               continue;
                        if (perf_tp_event_match(event, &data, regs))
                                perf_swevent_event(event, count, &data, regs);
                }
index c51387a..04a74d0 100644 (file)
  * atomic_long_cmpxchg() will be used to obtain writer lock.
  *
  * There are three places where the lock handoff bit may be set or cleared.
- * 1) rwsem_mark_wake() for readers.
- * 2) rwsem_try_write_lock() for writers.
- * 3) Error path of rwsem_down_write_slowpath().
+ * 1) rwsem_mark_wake() for readers            -- set, clear
+ * 2) rwsem_try_write_lock() for writers       -- set, clear
+ * 3) rwsem_del_waiter()                       -- clear
  *
  * For all the above cases, wait_lock will be held. A writer must also
  * be the first one in the wait_list to be eligible for setting the handoff
@@ -334,6 +334,9 @@ struct rwsem_waiter {
        struct task_struct *task;
        enum rwsem_waiter_type type;
        unsigned long timeout;
+
+       /* Writer only, not initialized in reader */
+       bool handoff_set;
 };
 #define rwsem_first_waiter(sem) \
        list_first_entry(&sem->wait_list, struct rwsem_waiter, list)
@@ -344,12 +347,6 @@ enum rwsem_wake_type {
        RWSEM_WAKE_READ_OWNED   /* Waker thread holds the read lock */
 };
 
-enum writer_wait_state {
-       WRITER_NOT_FIRST,       /* Writer is not first in wait list */
-       WRITER_FIRST,           /* Writer is first in wait list     */
-       WRITER_HANDOFF          /* Writer is first & handoff needed */
-};
-
 /*
  * The typical HZ value is either 250 or 1000. So set the minimum waiting
  * time to at least 4ms or 1 jiffy (if it is higher than 4ms) in the wait
@@ -365,6 +362,31 @@ enum writer_wait_state {
  */
 #define MAX_READERS_WAKEUP     0x100
 
+static inline void
+rwsem_add_waiter(struct rw_semaphore *sem, struct rwsem_waiter *waiter)
+{
+       lockdep_assert_held(&sem->wait_lock);
+       list_add_tail(&waiter->list, &sem->wait_list);
+       /* caller will set RWSEM_FLAG_WAITERS */
+}
+
+/*
+ * Remove a waiter from the wait_list and clear flags.
+ *
+ * Both rwsem_mark_wake() and rwsem_try_write_lock() contain a full 'copy' of
+ * this function. Modify with care.
+ */
+static inline void
+rwsem_del_waiter(struct rw_semaphore *sem, struct rwsem_waiter *waiter)
+{
+       lockdep_assert_held(&sem->wait_lock);
+       list_del(&waiter->list);
+       if (likely(!list_empty(&sem->wait_list)))
+               return;
+
+       atomic_long_andnot(RWSEM_FLAG_HANDOFF | RWSEM_FLAG_WAITERS, &sem->count);
+}
+
 /*
  * handle the lock release when processes blocked on it that can now run
  * - if we come here from up_xxxx(), then the RWSEM_FLAG_WAITERS bit must
@@ -376,6 +398,8 @@ enum writer_wait_state {
  *   preferably when the wait_lock is released
  * - woken process blocks are discarded from the list after having task zeroed
  * - writers are only marked woken if downgrading is false
+ *
+ * Implies rwsem_del_waiter() for all woken readers.
  */
 static void rwsem_mark_wake(struct rw_semaphore *sem,
                            enum rwsem_wake_type wake_type,
@@ -490,18 +514,25 @@ static void rwsem_mark_wake(struct rw_semaphore *sem,
 
        adjustment = woken * RWSEM_READER_BIAS - adjustment;
        lockevent_cond_inc(rwsem_wake_reader, woken);
+
+       oldcount = atomic_long_read(&sem->count);
        if (list_empty(&sem->wait_list)) {
-               /* hit end of list above */
+               /*
+                * Combined with list_move_tail() above, this implies
+                * rwsem_del_waiter().
+                */
                adjustment -= RWSEM_FLAG_WAITERS;
+               if (oldcount & RWSEM_FLAG_HANDOFF)
+                       adjustment -= RWSEM_FLAG_HANDOFF;
+       } else if (woken) {
+               /*
+                * When we've woken a reader, we no longer need to force
+                * writers to give up the lock and we can clear HANDOFF.
+                */
+               if (oldcount & RWSEM_FLAG_HANDOFF)
+                       adjustment -= RWSEM_FLAG_HANDOFF;
        }
 
-       /*
-        * When we've woken a reader, we no longer need to force writers
-        * to give up the lock and we can clear HANDOFF.
-        */
-       if (woken && (atomic_long_read(&sem->count) & RWSEM_FLAG_HANDOFF))
-               adjustment -= RWSEM_FLAG_HANDOFF;
-
        if (adjustment)
                atomic_long_add(adjustment, &sem->count);
 
@@ -532,12 +563,12 @@ static void rwsem_mark_wake(struct rw_semaphore *sem,
  * race conditions between checking the rwsem wait list and setting the
  * sem->count accordingly.
  *
- * If wstate is WRITER_HANDOFF, it will make sure that either the handoff
- * bit is set or the lock is acquired with handoff bit cleared.
+ * Implies rwsem_del_waiter() on success.
  */
 static inline bool rwsem_try_write_lock(struct rw_semaphore *sem,
-                                       enum writer_wait_state wstate)
+                                       struct rwsem_waiter *waiter)
 {
+       bool first = rwsem_first_waiter(sem) == waiter;
        long count, new;
 
        lockdep_assert_held(&sem->wait_lock);
@@ -546,13 +577,19 @@ static inline bool rwsem_try_write_lock(struct rw_semaphore *sem,
        do {
                bool has_handoff = !!(count & RWSEM_FLAG_HANDOFF);
 
-               if (has_handoff && wstate == WRITER_NOT_FIRST)
-                       return false;
+               if (has_handoff) {
+                       if (!first)
+                               return false;
+
+                       /* First waiter inherits a previously set handoff bit */
+                       waiter->handoff_set = true;
+               }
 
                new = count;
 
                if (count & RWSEM_LOCK_MASK) {
-                       if (has_handoff || (wstate != WRITER_HANDOFF))
+                       if (has_handoff || (!rt_task(waiter->task) &&
+                                           !time_after(jiffies, waiter->timeout)))
                                return false;
 
                        new |= RWSEM_FLAG_HANDOFF;
@@ -569,9 +606,17 @@ static inline bool rwsem_try_write_lock(struct rw_semaphore *sem,
         * We have either acquired the lock with handoff bit cleared or
         * set the handoff bit.
         */
-       if (new & RWSEM_FLAG_HANDOFF)
+       if (new & RWSEM_FLAG_HANDOFF) {
+               waiter->handoff_set = true;
+               lockevent_inc(rwsem_wlock_handoff);
                return false;
+       }
 
+       /*
+        * Have rwsem_try_write_lock() fully imply rwsem_del_waiter() on
+        * success.
+        */
+       list_del(&waiter->list);
        rwsem_set_owner(sem);
        return true;
 }
@@ -956,7 +1001,7 @@ queue:
                }
                adjustment += RWSEM_FLAG_WAITERS;
        }
-       list_add_tail(&waiter.list, &sem->wait_list);
+       rwsem_add_waiter(sem, &waiter);
 
        /* we're now waiting on the lock, but no longer actively locking */
        count = atomic_long_add_return(adjustment, &sem->count);
@@ -1002,11 +1047,7 @@ queue:
        return sem;
 
 out_nolock:
-       list_del(&waiter.list);
-       if (list_empty(&sem->wait_list)) {
-               atomic_long_andnot(RWSEM_FLAG_WAITERS|RWSEM_FLAG_HANDOFF,
-                                  &sem->count);
-       }
+       rwsem_del_waiter(sem, &waiter);
        raw_spin_unlock_irq(&sem->wait_lock);
        __set_current_state(TASK_RUNNING);
        lockevent_inc(rwsem_rlock_fail);
@@ -1020,9 +1061,7 @@ static struct rw_semaphore *
 rwsem_down_write_slowpath(struct rw_semaphore *sem, int state)
 {
        long count;
-       enum writer_wait_state wstate;
        struct rwsem_waiter waiter;
-       struct rw_semaphore *ret = sem;
        DEFINE_WAKE_Q(wake_q);
 
        /* do optimistic spinning and steal lock if possible */
@@ -1038,16 +1077,13 @@ rwsem_down_write_slowpath(struct rw_semaphore *sem, int state)
        waiter.task = current;
        waiter.type = RWSEM_WAITING_FOR_WRITE;
        waiter.timeout = jiffies + RWSEM_WAIT_TIMEOUT;
+       waiter.handoff_set = false;
 
        raw_spin_lock_irq(&sem->wait_lock);
-
-       /* account for this before adding a new element to the list */
-       wstate = list_empty(&sem->wait_list) ? WRITER_FIRST : WRITER_NOT_FIRST;
-
-       list_add_tail(&waiter.list, &sem->wait_list);
+       rwsem_add_waiter(sem, &waiter);
 
        /* we're now waiting on the lock */
-       if (wstate == WRITER_NOT_FIRST) {
+       if (rwsem_first_waiter(sem) != &waiter) {
                count = atomic_long_read(&sem->count);
 
                /*
@@ -1083,13 +1119,16 @@ wait:
        /* wait until we successfully acquire the lock */
        set_current_state(state);
        for (;;) {
-               if (rwsem_try_write_lock(sem, wstate)) {
+               if (rwsem_try_write_lock(sem, &waiter)) {
                        /* rwsem_try_write_lock() implies ACQUIRE on success */
                        break;
                }
 
                raw_spin_unlock_irq(&sem->wait_lock);
 
+               if (signal_pending_state(state, current))
+                       goto out_nolock;
+
                /*
                 * After setting the handoff bit and failing to acquire
                 * the lock, attempt to spin on owner to accelerate lock
@@ -1098,7 +1137,7 @@ wait:
                 * In this case, we attempt to acquire the lock again
                 * without sleeping.
                 */
-               if (wstate == WRITER_HANDOFF) {
+               if (waiter.handoff_set) {
                        enum owner_state owner_state;
 
                        preempt_disable();
@@ -1109,66 +1148,26 @@ wait:
                                goto trylock_again;
                }
 
-               /* Block until there are no active lockers. */
-               for (;;) {
-                       if (signal_pending_state(state, current))
-                               goto out_nolock;
-
-                       schedule();
-                       lockevent_inc(rwsem_sleep_writer);
-                       set_current_state(state);
-                       /*
-                        * If HANDOFF bit is set, unconditionally do
-                        * a trylock.
-                        */
-                       if (wstate == WRITER_HANDOFF)
-                               break;
-
-                       if ((wstate == WRITER_NOT_FIRST) &&
-                           (rwsem_first_waiter(sem) == &waiter))
-                               wstate = WRITER_FIRST;
-
-                       count = atomic_long_read(&sem->count);
-                       if (!(count & RWSEM_LOCK_MASK))
-                               break;
-
-                       /*
-                        * The setting of the handoff bit is deferred
-                        * until rwsem_try_write_lock() is called.
-                        */
-                       if ((wstate == WRITER_FIRST) && (rt_task(current) ||
-                           time_after(jiffies, waiter.timeout))) {
-                               wstate = WRITER_HANDOFF;
-                               lockevent_inc(rwsem_wlock_handoff);
-                               break;
-                       }
-               }
+               schedule();
+               lockevent_inc(rwsem_sleep_writer);
+               set_current_state(state);
 trylock_again:
                raw_spin_lock_irq(&sem->wait_lock);
        }
        __set_current_state(TASK_RUNNING);
-       list_del(&waiter.list);
        raw_spin_unlock_irq(&sem->wait_lock);
        lockevent_inc(rwsem_wlock);
-
-       return ret;
+       return sem;
 
 out_nolock:
        __set_current_state(TASK_RUNNING);
        raw_spin_lock_irq(&sem->wait_lock);
-       list_del(&waiter.list);
-
-       if (unlikely(wstate == WRITER_HANDOFF))
-               atomic_long_add(-RWSEM_FLAG_HANDOFF,  &sem->count);
-
-       if (list_empty(&sem->wait_list))
-               atomic_long_andnot(RWSEM_FLAG_WAITERS, &sem->count);
-       else
+       rwsem_del_waiter(sem, &waiter);
+       if (!list_empty(&sem->wait_list))
                rwsem_mark_wake(sem, RWSEM_WAKE_ANY, &wake_q);
        raw_spin_unlock_irq(&sem->wait_lock);
        wake_up_q(&wake_q);
        lockevent_inc(rwsem_wlock_fail);
-
        return ERR_PTR(-EINTR);
 }
 
@@ -1249,17 +1248,14 @@ static inline int __down_read_trylock(struct rw_semaphore *sem)
 
        DEBUG_RWSEMS_WARN_ON(sem->magic != sem, sem);
 
-       /*
-        * Optimize for the case when the rwsem is not locked at all.
-        */
-       tmp = RWSEM_UNLOCKED_VALUE;
-       do {
+       tmp = atomic_long_read(&sem->count);
+       while (!(tmp & RWSEM_READ_FAILED_MASK)) {
                if (atomic_long_try_cmpxchg_acquire(&sem->count, &tmp,
-                                       tmp + RWSEM_READER_BIAS)) {
+                                                   tmp + RWSEM_READER_BIAS)) {
                        rwsem_set_reader_owned(sem);
                        return 1;
                }
-       } while (!(tmp & RWSEM_READ_FAILED_MASK));
+       }
        return 0;
 }
 
index 9ed9b74..e6af502 100644 (file)
@@ -693,7 +693,7 @@ static int load_image_and_restore(void)
                goto Unlock;
 
        error = swsusp_read(&flags);
-       swsusp_close(FMODE_READ);
+       swsusp_close(FMODE_READ | FMODE_EXCL);
        if (!error)
                error = hibernation_restore(flags & SF_PLATFORM_MODE);
 
@@ -983,7 +983,7 @@ static int software_resume(void)
        /* The snapshot device should not be opened while we're running */
        if (!hibernate_acquire()) {
                error = -EBUSY;
-               swsusp_close(FMODE_READ);
+               swsusp_close(FMODE_READ | FMODE_EXCL);
                goto Unlock;
        }
 
@@ -1018,7 +1018,7 @@ static int software_resume(void)
        pm_pr_dbg("Hibernation image not present or could not be loaded.\n");
        return error;
  Close_Finish:
-       swsusp_close(FMODE_READ);
+       swsusp_close(FMODE_READ | FMODE_EXCL);
        goto Finish;
 }
 
index 740723b..ad241b4 100644 (file)
@@ -177,7 +177,7 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
                if (res <= 0)
                        goto unlock;
        } else {
-               res = PAGE_SIZE - pg_offp;
+               res = PAGE_SIZE;
        }
 
        if (!data_of(data->handle)) {
index 013bfd6..57b132b 100644 (file)
@@ -3253,6 +3253,11 @@ void defer_console_output(void)
        preempt_enable();
 }
 
+void printk_trigger_flush(void)
+{
+       defer_console_output();
+}
+
 int vprintk_deferred(const char *fmt, va_list args)
 {
        int r;
index 3c9b0fd..76f9dee 100644 (file)
@@ -8619,9 +8619,6 @@ void __init init_idle(struct task_struct *idle, int cpu)
        idle->flags |= PF_IDLE | PF_KTHREAD | PF_NO_SETAFFINITY;
        kthread_set_per_cpu(idle, cpu);
 
-       scs_task_reset(idle);
-       kasan_unpoison_task_stack(idle);
-
 #ifdef CONFIG_SMP
        /*
         * It's possible that init_idle() gets called multiple times on a task,
@@ -8777,7 +8774,6 @@ void idle_task_exit(void)
                finish_arch_post_lock_switch();
        }
 
-       scs_task_reset(current);
        /* finish_cpu(), as ran on the BP, will clean up the active_mm state */
 }
 
index 7c4b7ae..a629b11 100644 (file)
@@ -1298,6 +1298,12 @@ int do_send_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *p
        return ret;
 }
 
+enum sig_handler {
+       HANDLER_CURRENT, /* If reachable use the current handler */
+       HANDLER_SIG_DFL, /* Always use SIG_DFL handler semantics */
+       HANDLER_EXIT,    /* Only visible as the process exit code */
+};
+
 /*
  * Force a signal that the process can't ignore: if necessary
  * we unblock the signal and change any SIG_IGN to SIG_DFL.
@@ -1310,7 +1316,8 @@ int do_send_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *p
  * that is why we also clear SIGNAL_UNKILLABLE.
  */
 static int
-force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t, bool sigdfl)
+force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t,
+       enum sig_handler handler)
 {
        unsigned long int flags;
        int ret, blocked, ignored;
@@ -1321,9 +1328,10 @@ force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t, bool
        action = &t->sighand->action[sig-1];
        ignored = action->sa.sa_handler == SIG_IGN;
        blocked = sigismember(&t->blocked, sig);
-       if (blocked || ignored || sigdfl) {
+       if (blocked || ignored || (handler != HANDLER_CURRENT)) {
                action->sa.sa_handler = SIG_DFL;
-               action->sa.sa_flags |= SA_IMMUTABLE;
+               if (handler == HANDLER_EXIT)
+                       action->sa.sa_flags |= SA_IMMUTABLE;
                if (blocked) {
                        sigdelset(&t->blocked, sig);
                        recalc_sigpending_and_wake(t);
@@ -1343,7 +1351,7 @@ force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t, bool
 
 int force_sig_info(struct kernel_siginfo *info)
 {
-       return force_sig_info_to_task(info, current, false);
+       return force_sig_info_to_task(info, current, HANDLER_CURRENT);
 }
 
 /*
@@ -1660,7 +1668,20 @@ void force_fatal_sig(int sig)
        info.si_code = SI_KERNEL;
        info.si_pid = 0;
        info.si_uid = 0;
-       force_sig_info_to_task(&info, current, true);
+       force_sig_info_to_task(&info, current, HANDLER_SIG_DFL);
+}
+
+void force_exit_sig(int sig)
+{
+       struct kernel_siginfo info;
+
+       clear_siginfo(&info);
+       info.si_signo = sig;
+       info.si_errno = 0;
+       info.si_code = SI_KERNEL;
+       info.si_pid = 0;
+       info.si_uid = 0;
+       force_sig_info_to_task(&info, current, HANDLER_EXIT);
 }
 
 /*
@@ -1693,7 +1714,7 @@ int force_sig_fault_to_task(int sig, int code, void __user *addr
        info.si_flags = flags;
        info.si_isr = isr;
 #endif
-       return force_sig_info_to_task(&info, t, false);
+       return force_sig_info_to_task(&info, t, HANDLER_CURRENT);
 }
 
 int force_sig_fault(int sig, int code, void __user *addr
@@ -1813,7 +1834,8 @@ int force_sig_seccomp(int syscall, int reason, bool force_coredump)
        info.si_errno = reason;
        info.si_arch = syscall_get_arch(current);
        info.si_syscall = syscall;
-       return force_sig_info_to_task(&info, current, force_coredump);
+       return force_sig_info_to_task(&info, current,
+               force_coredump ? HANDLER_EXIT : HANDLER_CURRENT);
 }
 
 /* For the crazy architectures that include trap information in
index 7396488..ae97550 100644 (file)
@@ -1111,8 +1111,6 @@ bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
                return &bpf_ktime_get_ns_proto;
        case BPF_FUNC_ktime_get_boot_ns:
                return &bpf_ktime_get_boot_ns_proto;
-       case BPF_FUNC_ktime_get_coarse_ns:
-               return &bpf_ktime_get_coarse_ns_proto;
        case BPF_FUNC_tail_call:
                return &bpf_tail_call_proto;
        case BPF_FUNC_get_current_pid_tgid:
index f9139dc..88de94d 100644 (file)
@@ -3812,6 +3812,18 @@ void trace_check_vprintf(struct trace_iterator *iter, const char *fmt,
                iter->fmt[i] = '\0';
                trace_seq_vprintf(&iter->seq, iter->fmt, ap);
 
+               /*
+                * If iter->seq is full, the above call no longer guarantees
+                * that ap is in sync with fmt processing, and further calls
+                * to va_arg() can return wrong positional arguments.
+                *
+                * Ensure that ap is no longer used in this case.
+                */
+               if (iter->seq.full) {
+                       p = "";
+                       break;
+               }
+
                if (star)
                        len = va_arg(ap, int);
 
@@ -6706,9 +6718,7 @@ waitagain:
                cnt = PAGE_SIZE - 1;
 
        /* reset all but tr, trace, and overruns */
-       memset(&iter->seq, 0,
-              sizeof(struct trace_iterator) -
-              offsetof(struct trace_iterator, seq));
+       memset_startat(iter, 0, seq);
        cpumask_clear(iter->started);
        trace_seq_init(&iter->seq);
        iter->pos = -1;
index 6b60ab9..38715aa 100644 (file)
@@ -1366,14 +1366,26 @@ __event_trigger_test_discard(struct trace_event_file *file,
        if (eflags & EVENT_FILE_FL_TRIGGER_COND)
                *tt = event_triggers_call(file, buffer, entry, event);
 
-       if (test_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT, &file->flags) ||
-           (unlikely(file->flags & EVENT_FILE_FL_FILTERED) &&
-            !filter_match_preds(file->filter, entry))) {
-               __trace_event_discard_commit(buffer, event);
-               return true;
-       }
+       if (likely(!(file->flags & (EVENT_FILE_FL_SOFT_DISABLED |
+                                   EVENT_FILE_FL_FILTERED |
+                                   EVENT_FILE_FL_PID_FILTER))))
+               return false;
+
+       if (file->flags & EVENT_FILE_FL_SOFT_DISABLED)
+               goto discard;
+
+       if (file->flags & EVENT_FILE_FL_FILTERED &&
+           !filter_match_preds(file->filter, entry))
+               goto discard;
+
+       if ((file->flags & EVENT_FILE_FL_PID_FILTER) &&
+           trace_event_ignore_this_pid(file))
+               goto discard;
 
        return false;
+ discard:
+       __trace_event_discard_commit(buffer, event);
+       return true;
 }
 
 /**
index 4021b9a..92be9cb 100644 (file)
@@ -2678,12 +2678,24 @@ static struct trace_event_file *
 trace_create_new_event(struct trace_event_call *call,
                       struct trace_array *tr)
 {
+       struct trace_pid_list *no_pid_list;
+       struct trace_pid_list *pid_list;
        struct trace_event_file *file;
+       unsigned int first;
 
        file = kmem_cache_alloc(file_cachep, GFP_TRACE);
        if (!file)
                return NULL;
 
+       pid_list = rcu_dereference_protected(tr->filtered_pids,
+                                            lockdep_is_held(&event_mutex));
+       no_pid_list = rcu_dereference_protected(tr->filtered_no_pids,
+                                            lockdep_is_held(&event_mutex));
+
+       if (!trace_pid_list_first(pid_list, &first) ||
+           !trace_pid_list_first(no_pid_list, &first))
+               file->flags |= EVENT_FILE_FL_PID_FILTER;
+
        file->event_call = call;
        file->tr = tr;
        atomic_set(&file->sm_ref, 0);
index 8a10046..9555b8e 100644 (file)
@@ -2576,28 +2576,27 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data,
 
        /* Split the expression string at the root operator */
        if (!sep)
-               goto free;
+               return ERR_PTR(-EINVAL);
+
        *sep = '\0';
        operand1_str = str;
        str = sep+1;
 
        /* Binary operator requires both operands */
        if (*operand1_str == '\0' || *str == '\0')
-               goto free;
+               return ERR_PTR(-EINVAL);
 
        operand_flags = 0;
 
        /* LHS of string is an expression e.g. a+b in a+b+c */
        operand1 = parse_expr(hist_data, file, operand1_str, operand_flags, NULL, n_subexprs);
-       if (IS_ERR(operand1)) {
-               ret = PTR_ERR(operand1);
-               operand1 = NULL;
-               goto free;
-       }
+       if (IS_ERR(operand1))
+               return ERR_CAST(operand1);
+
        if (operand1->flags & HIST_FIELD_FL_STRING) {
                hist_err(file->tr, HIST_ERR_INVALID_STR_OPERAND, errpos(operand1_str));
                ret = -EINVAL;
-               goto free;
+               goto free_op1;
        }
 
        /* RHS of string is another expression e.g. c in a+b+c */
@@ -2605,13 +2604,12 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data,
        operand2 = parse_expr(hist_data, file, str, operand_flags, NULL, n_subexprs);
        if (IS_ERR(operand2)) {
                ret = PTR_ERR(operand2);
-               operand2 = NULL;
-               goto free;
+               goto free_op1;
        }
        if (operand2->flags & HIST_FIELD_FL_STRING) {
                hist_err(file->tr, HIST_ERR_INVALID_STR_OPERAND, errpos(str));
                ret = -EINVAL;
-               goto free;
+               goto free_operands;
        }
 
        switch (field_op) {
@@ -2629,12 +2627,12 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data,
                break;
        default:
                ret = -EINVAL;
-               goto free;
+               goto free_operands;
        }
 
        ret = check_expr_operands(file->tr, operand1, operand2, &var1, &var2);
        if (ret)
-               goto free;
+               goto free_operands;
 
        operand_flags = var1 ? var1->flags : operand1->flags;
        operand2_flags = var2 ? var2->flags : operand2->flags;
@@ -2653,12 +2651,13 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data,
        expr = create_hist_field(hist_data, NULL, flags, var_name);
        if (!expr) {
                ret = -ENOMEM;
-               goto free;
+               goto free_operands;
        }
 
        operand1->read_once = true;
        operand2->read_once = true;
 
+       /* The operands are now owned and free'd by 'expr' */
        expr->operands[0] = operand1;
        expr->operands[1] = operand2;
 
@@ -2669,7 +2668,7 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data,
                if (!divisor) {
                        hist_err(file->tr, HIST_ERR_DIVISION_BY_ZERO, errpos(str));
                        ret = -EDOM;
-                       goto free;
+                       goto free_expr;
                }
 
                /*
@@ -2709,18 +2708,22 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data,
                expr->type = kstrdup_const(operand1->type, GFP_KERNEL);
                if (!expr->type) {
                        ret = -ENOMEM;
-                       goto free;
+                       goto free_expr;
                }
 
                expr->name = expr_str(expr, 0);
        }
 
        return expr;
-free:
-       destroy_hist_field(operand1, 0);
+
+free_operands:
        destroy_hist_field(operand2, 0);
-       destroy_hist_field(expr, 0);
+free_op1:
+       destroy_hist_field(operand1, 0);
+       return ERR_PTR(ret);
 
+free_expr:
+       destroy_hist_field(expr, 0);
        return ERR_PTR(ret);
 }
 
@@ -3026,8 +3029,10 @@ static inline void __update_field_vars(struct tracing_map_elt *elt,
                if (val->flags & HIST_FIELD_FL_STRING) {
                        char *str = elt_data->field_var_str[j++];
                        char *val_str = (char *)(uintptr_t)var_val;
+                       unsigned int size;
 
-                       strscpy(str, val_str, val->size);
+                       size = min(val->size, STR_VAR_LEN_MAX);
+                       strscpy(str, val_str, size);
                        var_val = (u64)(uintptr_t)str;
                }
                tracing_map_set_var(elt, var_idx, var_val);
@@ -4914,6 +4919,7 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data,
                        if (hist_field->flags & HIST_FIELD_FL_STRING) {
                                unsigned int str_start, var_str_idx, idx;
                                char *str, *val_str;
+                               unsigned int size;
 
                                str_start = hist_data->n_field_var_str +
                                        hist_data->n_save_var_str;
@@ -4922,7 +4928,9 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data,
 
                                str = elt_data->field_var_str[idx];
                                val_str = (char *)(uintptr_t)hist_val;
-                               strscpy(str, val_str, hist_field->size);
+
+                               size = min(hist_field->size, STR_VAR_LEN_MAX);
+                               strscpy(str, val_str, size);
 
                                hist_val = (u64)(uintptr_t)str;
                        }
index 0a5c0db..f5f0039 100644 (file)
@@ -1313,6 +1313,7 @@ static int uprobe_perf_open(struct trace_event_call *call,
                return 0;
 
        list_for_each_entry(pos, trace_probe_probe_list(tp), list) {
+               tu = container_of(pos, struct trace_uprobe, tp);
                err = uprobe_apply(tu->inode, tu->offset, &tu->consumer, true);
                if (err) {
                        uprobe_perf_close(call, event);
index 9ef7ce1..5c12bde 100644 (file)
@@ -346,8 +346,9 @@ config FRAME_WARN
        int "Warn for stack frames larger than"
        range 0 8192
        default 2048 if GCC_PLUGIN_LATENT_ENTROPY
-       default 1536 if (!64BIT && (PARISC || XTENSA))
-       default 1024 if (!64BIT && !PARISC)
+       default 2048 if PARISC
+       default 1536 if (!64BIT && XTENSA)
+       default 1024 if !64BIT
        default 2048 if 64BIT
        help
          Tell gcc to warn at build time for stack frames larger than this.
index f9e8900..199ab20 100644 (file)
@@ -75,6 +75,12 @@ void nmi_trigger_cpumask_backtrace(const cpumask_t *mask,
                touch_softlockup_watchdog();
        }
 
+       /*
+        * Force flush any remote buffers that might be stuck in IRQ context
+        * and therefore could not run their irq_work.
+        */
+       printk_trigger_flush();
+
        clear_bit_unlock(0, &backtrace_flag);
        put_cpu();
 }
index 67ed689..0643573 100644 (file)
@@ -869,6 +869,7 @@ static void kasan_memchr(struct kunit *test)
        ptr = kmalloc(size, GFP_KERNEL | __GFP_ZERO);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
 
+       OPTIMIZER_HIDE_VAR(size);
        KUNIT_EXPECT_KASAN_FAIL(test,
                kasan_ptr_result = memchr(ptr, '1', size + 1));
 
@@ -894,6 +895,7 @@ static void kasan_memcmp(struct kunit *test)
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
        memset(arr, 0, sizeof(arr));
 
+       OPTIMIZER_HIDE_VAR(size);
        KUNIT_EXPECT_KASAN_FAIL(test,
                kasan_int_result = memcmp(ptr, arr, size+1));
        kfree(ptr);
index 65218ec..fc45339 100644 (file)
@@ -11,8 +11,6 @@
 obj-$(CONFIG_ZSTD_COMPRESS) += zstd_compress.o
 obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd_decompress.o
 
-ccflags-y += -O3
-
 zstd_compress-y := \
                zstd_compress_module.o \
                common/debug.o \
index a1a051e..f5a9c70 100644 (file)
@@ -16,6 +16,7 @@
 *********************************************************/
 /* force inlining */
 
+#if !defined(ZSTD_NO_INLINE)
 #if (defined(__GNUC__) && !defined(__STRICT_ANSI__)) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L   /* C99 */
 #  define INLINE_KEYWORD inline
 #else
 
 #define FORCE_INLINE_ATTR __attribute__((always_inline))
 
+#else
+
+#define INLINE_KEYWORD
+#define FORCE_INLINE_ATTR
+
+#endif
 
 /*
   On MSVC qsort requires that functions passed into it use the __cdecl calling conversion(CC).
index ee03e0a..b0610b2 100644 (file)
@@ -411,6 +411,8 @@ static size_t ZSTD_seqDecompressedSize(seqStore_t const* seqStore, const seqDef*
     const seqDef* sp = sstart;
     size_t matchLengthSum = 0;
     size_t litLengthSum = 0;
+    /* Only used by assert(), suppress unused variable warnings in production. */
+    (void)litLengthSum;
     while (send-sp > 0) {
         ZSTD_sequenceLength const seqLen = ZSTD_getSequenceLength(seqStore, sp);
         litLengthSum += seqLen.litLength;
index 0433705..dfc55e3 100644 (file)
@@ -8,6 +8,18 @@
  * You may select, at your option, one of the above-listed licenses.
  */
 
+/*
+ * Disable inlining for the optimal parser for the kernel build.
+ * It is unlikely to be used in the kernel, and where it is used
+ * latency shouldn't matter because it is very slow to begin with.
+ * We prefer a ~180KB binary size win over faster optimal parsing.
+ *
+ * TODO(https://github.com/facebook/zstd/issues/2862):
+ * Improve the code size of the optimal parser in general, so we
+ * don't need this hack for the kernel build.
+ */
+#define ZSTD_NO_INLINE 1
+
 #include "zstd_compress_internal.h"
 #include "hist.h"
 #include "zstd_opt.h"
index 068ce59..28edafc 100644 (file)
@@ -890,6 +890,9 @@ config MAPPING_DIRTY_HELPERS
 config KMAP_LOCAL
        bool
 
+config KMAP_LOCAL_NON_LINEAR_PTE_ARRAY
+       bool
+
 # struct io_mapping based helper.  Selected by drivers that need them
 config IO_MAPPING
        bool
index eccc14b..9b520bb 100644 (file)
@@ -32,7 +32,7 @@ static char *user_input_str(const char __user *buf, size_t count, loff_t *ppos)
        if (*ppos)
                return ERR_PTR(-EINVAL);
 
-       kbuf = kmalloc(count + 1, GFP_KERNEL);
+       kbuf = kmalloc(count + 1, GFP_KERNEL | __GFP_NOWARN);
        if (!kbuf)
                return ERR_PTR(-ENOMEM);
 
@@ -133,7 +133,7 @@ static ssize_t dbgfs_schemes_read(struct file *file, char __user *buf,
        char *kbuf;
        ssize_t len;
 
-       kbuf = kmalloc(count, GFP_KERNEL);
+       kbuf = kmalloc(count, GFP_KERNEL | __GFP_NOWARN);
        if (!kbuf)
                return -ENOMEM;
 
@@ -452,7 +452,7 @@ static ssize_t dbgfs_init_regions_read(struct file *file, char __user *buf,
        char *kbuf;
        ssize_t len;
 
-       kbuf = kmalloc(count, GFP_KERNEL);
+       kbuf = kmalloc(count, GFP_KERNEL | __GFP_NOWARN);
        if (!kbuf)
                return -ENOMEM;
 
@@ -578,7 +578,7 @@ static ssize_t dbgfs_kdamond_pid_read(struct file *file,
        char *kbuf;
        ssize_t len;
 
-       kbuf = kmalloc(count, GFP_KERNEL);
+       kbuf = kmalloc(count, GFP_KERNEL | __GFP_NOWARN);
        if (!kbuf)
                return -ENOMEM;
 
@@ -877,12 +877,14 @@ static ssize_t dbgfs_monitor_on_write(struct file *file,
                return -EINVAL;
        }
 
+       mutex_lock(&damon_dbgfs_lock);
        if (!strncmp(kbuf, "on", count)) {
                int i;
 
                for (i = 0; i < dbgfs_nr_ctxs; i++) {
                        if (damon_targets_empty(dbgfs_ctxs[i])) {
                                kfree(kbuf);
+                               mutex_unlock(&damon_dbgfs_lock);
                                return -EINVAL;
                        }
                }
@@ -892,6 +894,7 @@ static ssize_t dbgfs_monitor_on_write(struct file *file,
        } else {
                ret = -EINVAL;
        }
+       mutex_unlock(&damon_dbgfs_lock);
 
        if (!ret)
                ret = count;
@@ -944,15 +947,16 @@ static int __init __damon_dbgfs_init(void)
 
 static int __init damon_dbgfs_init(void)
 {
-       int rc;
+       int rc = -ENOMEM;
 
+       mutex_lock(&damon_dbgfs_lock);
        dbgfs_ctxs = kmalloc(sizeof(*dbgfs_ctxs), GFP_KERNEL);
        if (!dbgfs_ctxs)
-               return -ENOMEM;
+               goto out;
        dbgfs_ctxs[0] = dbgfs_new_ctx();
        if (!dbgfs_ctxs[0]) {
                kfree(dbgfs_ctxs);
-               return -ENOMEM;
+               goto out;
        }
        dbgfs_nr_ctxs = 1;
 
@@ -963,6 +967,8 @@ static int __init damon_dbgfs_init(void)
                pr_err("%s: dbgfs init failed\n", __func__);
        }
 
+out:
+       mutex_unlock(&damon_dbgfs_lock);
        return rc;
 }
 
index 88f65f1..7626790 100644 (file)
@@ -359,7 +359,6 @@ void kunmap_high(struct page *page)
 }
 EXPORT_SYMBOL(kunmap_high);
 
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 void zero_user_segments(struct page *page, unsigned start1, unsigned end1,
                unsigned start2, unsigned end2)
 {
@@ -416,7 +415,6 @@ void zero_user_segments(struct page *page, unsigned start1, unsigned end1,
        BUG_ON((start1 | start2 | end1 | end2) != 0);
 }
 EXPORT_SYMBOL(zero_user_segments);
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 #endif /* CONFIG_HIGHMEM */
 
 #ifdef CONFIG_KMAP_LOCAL
@@ -503,16 +501,22 @@ static inline int kmap_local_calc_idx(int idx)
 
 static pte_t *__kmap_pte;
 
-static pte_t *kmap_get_pte(void)
+static pte_t *kmap_get_pte(unsigned long vaddr, int idx)
 {
+       if (IS_ENABLED(CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY))
+               /*
+                * Set by the arch if __kmap_pte[-idx] does not produce
+                * the correct entry.
+                */
+               return virt_to_kpte(vaddr);
        if (!__kmap_pte)
                __kmap_pte = virt_to_kpte(__fix_to_virt(FIX_KMAP_BEGIN));
-       return __kmap_pte;
+       return &__kmap_pte[-idx];
 }
 
 void *__kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot)
 {
-       pte_t pteval, *kmap_pte = kmap_get_pte();
+       pte_t pteval, *kmap_pte;
        unsigned long vaddr;
        int idx;
 
@@ -524,9 +528,10 @@ void *__kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot)
        preempt_disable();
        idx = arch_kmap_local_map_idx(kmap_local_idx_push(), pfn);
        vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
-       BUG_ON(!pte_none(*(kmap_pte - idx)));
+       kmap_pte = kmap_get_pte(vaddr, idx);
+       BUG_ON(!pte_none(*kmap_pte));
        pteval = pfn_pte(pfn, prot);
-       arch_kmap_local_set_pte(&init_mm, vaddr, kmap_pte - idx, pteval);
+       arch_kmap_local_set_pte(&init_mm, vaddr, kmap_pte, pteval);
        arch_kmap_local_post_map(vaddr, pteval);
        current->kmap_ctrl.pteval[kmap_local_idx()] = pteval;
        preempt_enable();
@@ -559,7 +564,7 @@ EXPORT_SYMBOL(__kmap_local_page_prot);
 void kunmap_local_indexed(void *vaddr)
 {
        unsigned long addr = (unsigned long) vaddr & PAGE_MASK;
-       pte_t *kmap_pte = kmap_get_pte();
+       pte_t *kmap_pte;
        int idx;
 
        if (addr < __fix_to_virt(FIX_KMAP_END) ||
@@ -584,8 +589,9 @@ void kunmap_local_indexed(void *vaddr)
        idx = arch_kmap_local_unmap_idx(kmap_local_idx(), addr);
        WARN_ON_ONCE(addr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
 
+       kmap_pte = kmap_get_pte(addr, idx);
        arch_kmap_local_pre_unmap(addr);
-       pte_clear(&init_mm, addr, kmap_pte - idx);
+       pte_clear(&init_mm, addr, kmap_pte);
        arch_kmap_local_post_unmap(addr);
        current->kmap_ctrl.pteval[kmap_local_idx()] = __pte(0);
        kmap_local_idx_pop();
@@ -607,7 +613,7 @@ EXPORT_SYMBOL(kunmap_local_indexed);
 void __kmap_local_sched_out(void)
 {
        struct task_struct *tsk = current;
-       pte_t *kmap_pte = kmap_get_pte();
+       pte_t *kmap_pte;
        int i;
 
        /* Clear kmaps */
@@ -634,8 +640,9 @@ void __kmap_local_sched_out(void)
                idx = arch_kmap_local_map_idx(i, pte_pfn(pteval));
 
                addr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+               kmap_pte = kmap_get_pte(addr, idx);
                arch_kmap_local_pre_unmap(addr);
-               pte_clear(&init_mm, addr, kmap_pte - idx);
+               pte_clear(&init_mm, addr, kmap_pte);
                arch_kmap_local_post_unmap(addr);
        }
 }
@@ -643,7 +650,7 @@ void __kmap_local_sched_out(void)
 void __kmap_local_sched_in(void)
 {
        struct task_struct *tsk = current;
-       pte_t *kmap_pte = kmap_get_pte();
+       pte_t *kmap_pte;
        int i;
 
        /* Restore kmaps */
@@ -663,7 +670,8 @@ void __kmap_local_sched_in(void)
                /* See comment in __kmap_local_sched_out() */
                idx = arch_kmap_local_map_idx(i, pte_pfn(pteval));
                addr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
-               set_pte_at(&init_mm, addr, kmap_pte - idx, pteval);
+               kmap_pte = kmap_get_pte(addr, idx);
+               set_pte_at(&init_mm, addr, kmap_pte, pteval);
                arch_kmap_local_post_map(addr, pteval);
        }
 }
index e09159c..abcd178 100644 (file)
@@ -1037,8 +1037,10 @@ void clear_vma_resv_huge_pages(struct vm_area_struct *vma)
         */
        struct resv_map *reservations = vma_resv_map(vma);
 
-       if (reservations && is_vma_resv_set(vma, HPAGE_RESV_OWNER))
+       if (reservations && is_vma_resv_set(vma, HPAGE_RESV_OWNER)) {
+               resv_map_put_hugetlb_cgroup_uncharge_info(reservations);
                kref_put(&reservations->refs, resv_map_release);
+       }
 
        reset_vma_resv_huge_pages(vma);
 }
@@ -4917,9 +4919,9 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma,
 
                move_huge_pte(vma, old_addr, new_addr, src_pte);
        }
-       i_mmap_unlock_write(mapping);
        flush_tlb_range(vma, old_end - len, old_end);
        mmu_notifier_invalidate_range_end(&range);
+       i_mmap_unlock_write(mapping);
 
        return len + old_addr - old_end;
 }
@@ -4937,6 +4939,7 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct
        struct hstate *h = hstate_vma(vma);
        unsigned long sz = huge_page_size(h);
        struct mmu_notifier_range range;
+       bool force_flush = false;
 
        WARN_ON(!is_vm_hugetlb_page(vma));
        BUG_ON(start & ~huge_page_mask(h));
@@ -4965,10 +4968,8 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct
                ptl = huge_pte_lock(h, mm, ptep);
                if (huge_pmd_unshare(mm, vma, &address, ptep)) {
                        spin_unlock(ptl);
-                       /*
-                        * We just unmapped a page of PMDs by clearing a PUD.
-                        * The caller's TLB flush range should cover this area.
-                        */
+                       tlb_flush_pmd_range(tlb, address & PUD_MASK, PUD_SIZE);
+                       force_flush = true;
                        continue;
                }
 
@@ -5025,6 +5026,22 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct
        }
        mmu_notifier_invalidate_range_end(&range);
        tlb_end_vma(tlb, vma);
+
+       /*
+        * If we unshared PMDs, the TLB flush was not recorded in mmu_gather. We
+        * could defer the flush until now, since by holding i_mmap_rwsem we
+        * guaranteed that the last refernece would not be dropped. But we must
+        * do the flushing before we return, as otherwise i_mmap_rwsem will be
+        * dropped and the last reference to the shared PMDs page might be
+        * dropped as well.
+        *
+        * In theory we could defer the freeing of the PMD pages as well, but
+        * huge_pmd_unshare() relies on the exact page_count for the PMD page to
+        * detect sharing, so we cannot defer the release of the page either.
+        * Instead, do flush now.
+        */
+       if (force_flush)
+               tlb_flush_mmu_tlbonly(tlb);
 }
 
 void __unmap_hugepage_range_final(struct mmu_gather *tlb,
@@ -5734,13 +5751,14 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm,
        int ret = -ENOMEM;
        struct page *page;
        int writable;
-       bool new_pagecache_page = false;
+       bool page_in_pagecache = false;
 
        if (is_continue) {
                ret = -EFAULT;
                page = find_lock_page(mapping, idx);
                if (!page)
                        goto out;
+               page_in_pagecache = true;
        } else if (!*pagep) {
                /* If a page already exists, then it's UFFDIO_COPY for
                 * a non-missing case. Return -EEXIST.
@@ -5828,7 +5846,7 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm,
                ret = huge_add_to_page_cache(page, mapping, idx);
                if (ret)
                        goto out_release_nounlock;
-               new_pagecache_page = true;
+               page_in_pagecache = true;
        }
 
        ptl = huge_pte_lockptr(h, dst_mm, dst_pte);
@@ -5892,7 +5910,7 @@ out_release_unlock:
        if (vm_shared || is_continue)
                unlock_page(page);
 out_release_nounlock:
-       if (!new_pagecache_page)
+       if (!page_in_pagecache)
                restore_reserve_on_error(h, dst_vma, dst_addr, page);
        put_page(page);
        goto out;
index 781605e..6863a83 100644 (file)
@@ -5558,7 +5558,7 @@ static int mem_cgroup_move_account(struct page *page,
 
        VM_BUG_ON(from == to);
        VM_BUG_ON_FOLIO(folio_test_lru(folio), folio);
-       VM_BUG_ON(compound && !folio_test_multi(folio));
+       VM_BUG_ON(compound && !folio_test_large(folio));
 
        /*
         * Prevent mem_cgroup_migrate() from looking at
index dc038ce..18f93c2 100644 (file)
@@ -2303,6 +2303,7 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode
                INIT_LIST_HEAD(&info->swaplist);
                simple_xattrs_init(&info->xattrs);
                cache_no_acl(inode);
+               mapping_set_large_folios(inode->i_mapping);
 
                switch (mode & S_IFMT) {
                default:
@@ -3870,7 +3871,7 @@ static struct file_system_type shmem_fs_type = {
        .parameters     = shmem_fs_parameters,
 #endif
        .kill_sb        = kill_litter_super,
-       .fs_flags       = FS_USERNS_MOUNT | FS_THP_SUPPORT,
+       .fs_flags       = FS_USERNS_MOUNT,
 };
 
 int __init shmem_init(void)
index da132a9..ca4822f 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3733,14 +3733,13 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp)
        if (!cachep)
                return;
 
+       trace_kmem_cache_free(_RET_IP_, objp, cachep->name);
        local_irq_save(flags);
        debug_check_no_locks_freed(objp, cachep->object_size);
        if (!(cachep->flags & SLAB_DEBUG_OBJECTS))
                debug_check_no_obj_freed(objp, cachep->object_size);
        __cache_free(cachep, objp, _RET_IP_);
        local_irq_restore(flags);
-
-       trace_kmem_cache_free(_RET_IP_, objp, cachep->name);
 }
 EXPORT_SYMBOL(kmem_cache_free);
 
index 58c01a3..56ad7ee 100644 (file)
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -147,7 +147,7 @@ static inline slab_flags_t kmem_cache_flags(unsigned int object_size,
 #define SLAB_CACHE_FLAGS (SLAB_NOLEAKTRACE | SLAB_RECLAIM_ACCOUNT | \
                          SLAB_TEMPORARY | SLAB_ACCOUNT)
 #else
-#define SLAB_CACHE_FLAGS (0)
+#define SLAB_CACHE_FLAGS (SLAB_NOLEAKTRACE)
 #endif
 
 /* Common flags available with current configuration */
index 74d3f6e..03deee1 100644 (file)
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -666,6 +666,7 @@ static void kmem_rcu_free(struct rcu_head *head)
 void kmem_cache_free(struct kmem_cache *c, void *b)
 {
        kmemleak_free_recursive(b, c->flags);
+       trace_kmem_cache_free(_RET_IP_, b, c->name);
        if (unlikely(c->flags & SLAB_TYPESAFE_BY_RCU)) {
                struct slob_rcu *slob_rcu;
                slob_rcu = b + (c->size - sizeof(struct slob_rcu));
@@ -674,8 +675,6 @@ void kmem_cache_free(struct kmem_cache *c, void *b)
        } else {
                __kmem_cache_free(b, c->size);
        }
-
-       trace_kmem_cache_free(_RET_IP_, b, c->name);
 }
 EXPORT_SYMBOL(kmem_cache_free);
 
index f7368bf..a862682 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3526,8 +3526,8 @@ void kmem_cache_free(struct kmem_cache *s, void *x)
        s = cache_from_obj(s, x);
        if (!s)
                return;
-       slab_free(s, virt_to_head_page(x), x, NULL, 1, _RET_IP_);
        trace_kmem_cache_free(_RET_IP_, x, s->name);
+       slab_free(s, virt_to_head_page(x), x, NULL, 1, _RET_IP_);
 }
 EXPORT_SYMBOL(kmem_cache_free);
 
index 1841c24..e8c9dc6 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -156,6 +156,7 @@ void put_pages_list(struct list_head *pages)
        }
 
        free_unref_page_list(pages);
+       INIT_LIST_HEAD(pages);
 }
 EXPORT_SYMBOL(put_pages_list);
 
index e58151a..741ba32 100644 (file)
--- a/mm/util.c
+++ b/mm/util.c
@@ -670,7 +670,7 @@ bool folio_mapped(struct folio *folio)
 {
        long i, nr;
 
-       if (folio_test_single(folio))
+       if (!folio_test_large(folio))
                return atomic_read(&folio->_mapcount) >= 0;
        if (atomic_read(folio_mapcount_ptr(folio)) >= 0)
                return true;
index a3a0a5e..abaa5d9 100644 (file)
@@ -184,9 +184,6 @@ int register_vlan_dev(struct net_device *dev, struct netlink_ext_ack *extack)
        if (err)
                goto out_unregister_netdev;
 
-       /* Account for reference in struct vlan_dev_priv */
-       dev_hold(real_dev);
-
        vlan_stacked_transfer_operstate(real_dev, dev, vlan);
        linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */
 
index ab6dee2..a54535c 100644 (file)
@@ -615,6 +615,9 @@ static int vlan_dev_init(struct net_device *dev)
        if (!vlan->vlan_pcpu_stats)
                return -ENOMEM;
 
+       /* Get vlan's reference to real_dev */
+       dev_hold(real_dev);
+
        return 0;
 }
 
index 5ba4f94..5ad72db 100644 (file)
@@ -4229,7 +4229,9 @@ static void __devlink_flash_update_notify(struct devlink *devlink,
        WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE &&
                cmd != DEVLINK_CMD_FLASH_UPDATE_END &&
                cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS);
-       WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
+
+       if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
+               return;
 
        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
index e471c9b..6102f09 100644 (file)
@@ -7162,6 +7162,8 @@ sock_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 #endif
        case BPF_FUNC_sk_storage_get:
                return &bpf_sk_storage_get_cg_sock_proto;
+       case BPF_FUNC_ktime_get_coarse_ns:
+               return &bpf_ktime_get_coarse_ns_proto;
        default:
                return bpf_base_func_proto(func_id);
        }
@@ -10327,6 +10329,8 @@ sk_reuseport_func_proto(enum bpf_func_id func_id,
                return &sk_reuseport_load_bytes_relative_proto;
        case BPF_FUNC_get_socket_cookie:
                return &bpf_get_socket_ptr_cookie_proto;
+       case BPF_FUNC_ktime_get_coarse_ns:
+               return &bpf_ktime_get_coarse_ns_proto;
        default:
                return bpf_base_func_proto(func_id);
        }
@@ -10833,6 +10837,8 @@ bpf_sk_base_func_proto(enum bpf_func_id func_id)
        case BPF_FUNC_skc_to_unix_sock:
                func = &bpf_skc_to_unix_sock_proto;
                break;
+       case BPF_FUNC_ktime_get_coarse_ns:
+               return &bpf_ktime_get_coarse_ns_proto;
        default:
                return bpf_base_func_proto(func_id);
        }
index 47931c8..72ba027 100644 (file)
@@ -1779,6 +1779,7 @@ int neigh_table_clear(int index, struct neigh_table *tbl)
 {
        neigh_tables[index] = NULL;
        /* It is not clean... Fix it to unload IPv6 module safely */
+       cancel_delayed_work_sync(&tbl->managed_work);
        cancel_delayed_work_sync(&tbl->gc_work);
        del_timer_sync(&tbl->proxy_timer);
        pneigh_queue_purge(&tbl->proxy_queue);
index 9b60e43..1a69784 100644 (file)
@@ -49,12 +49,6 @@ static int page_pool_init(struct page_pool *pool,
         * which is the XDP_TX use-case.
         */
        if (pool->p.flags & PP_FLAG_DMA_MAP) {
-               /* DMA-mapping is not supported on 32-bit systems with
-                * 64-bit DMA mapping.
-                */
-               if (sizeof(dma_addr_t) > sizeof(unsigned long))
-                       return -EOPNOTSUPP;
-
                if ((pool->p.dma_dir != DMA_FROM_DEVICE) &&
                    (pool->p.dma_dir != DMA_BIDIRECTIONAL))
                        return -EINVAL;
@@ -75,6 +69,10 @@ static int page_pool_init(struct page_pool *pool,
                 */
        }
 
+       if (PAGE_POOL_DMA_USE_PP_FRAG_COUNT &&
+           pool->p.flags & PP_FLAG_PAGE_FRAG)
+               return -EINVAL;
+
        if (ptr_ring_init(&pool->ring, ring_qsize, GFP_KERNEL) < 0)
                return -ENOMEM;
 
index 8f2b2f2..41e91d0 100644 (file)
@@ -2124,8 +2124,10 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
        newsk->sk_prot_creator = prot;
 
        /* SANITY */
-       if (likely(newsk->sk_net_refcnt))
+       if (likely(newsk->sk_net_refcnt)) {
                get_net(sock_net(newsk));
+               sock_inuse_add(sock_net(newsk), 1);
+       }
        sk_node_init(&newsk->sk_node);
        sock_lock_init(newsk);
        bh_lock_sock(newsk);
@@ -2197,8 +2199,6 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
        newsk->sk_err_soft = 0;
        newsk->sk_priority = 0;
        newsk->sk_incoming_cpu = raw_smp_processor_id();
-       if (likely(newsk->sk_net_refcnt))
-               sock_inuse_add(sock_net(newsk), 1);
 
        /* Before updating sk_refcnt, we must commit prior changes to memory
         * (Documentation/RCU/rculist_nulls.rst for details)
index 65e9bc1..20bcf86 100644 (file)
@@ -1719,7 +1719,7 @@ static noinline_for_stack int ethtool_set_coalesce(struct net_device *dev,
        struct ethtool_coalesce coalesce;
        int ret;
 
-       if (!dev->ethtool_ops->set_coalesce && !dev->ethtool_ops->get_coalesce)
+       if (!dev->ethtool_ops->set_coalesce || !dev->ethtool_ops->get_coalesce)
                return -EOPNOTSUPP;
 
        ret = dev->ethtool_ops->get_coalesce(dev, &coalesce, &kernel_coalesce,
index 2cf02b4..4bb9401 100644 (file)
@@ -205,6 +205,8 @@ bpf_tcp_ca_get_func_proto(enum bpf_func_id func_id,
                    offsetof(struct tcp_congestion_ops, release))
                        return &bpf_sk_getsockopt_proto;
                return NULL;
+       case BPF_FUNC_ktime_get_coarse_ns:
+               return &bpf_ktime_get_coarse_ns_proto;
        default:
                return bpf_base_func_proto(func_id);
        }
index ec73a0d..323e622 100644 (file)
@@ -2591,7 +2591,7 @@ static int __devinet_sysctl_register(struct net *net, char *dev_name,
 free:
        kfree(t);
 out:
-       return -ENOBUFS;
+       return -ENOMEM;
 }
 
 static void __devinet_sysctl_unregister(struct net *net,
index 9e81007..5dbd4b5 100644 (file)
@@ -1899,15 +1899,36 @@ static void remove_nexthop(struct net *net, struct nexthop *nh,
 /* if any FIB entries reference this nexthop, any dst entries
  * need to be regenerated
  */
-static void nh_rt_cache_flush(struct net *net, struct nexthop *nh)
+static void nh_rt_cache_flush(struct net *net, struct nexthop *nh,
+                             struct nexthop *replaced_nh)
 {
        struct fib6_info *f6i;
+       struct nh_group *nhg;
+       int i;
 
        if (!list_empty(&nh->fi_list))
                rt_cache_flush(net);
 
        list_for_each_entry(f6i, &nh->f6i_list, nh_list)
                ipv6_stub->fib6_update_sernum(net, f6i);
+
+       /* if an IPv6 group was replaced, we have to release all old
+        * dsts to make sure all refcounts are released
+        */
+       if (!replaced_nh->is_group)
+               return;
+
+       /* new dsts must use only the new nexthop group */
+       synchronize_net();
+
+       nhg = rtnl_dereference(replaced_nh->nh_grp);
+       for (i = 0; i < nhg->num_nh; i++) {
+               struct nh_grp_entry *nhge = &nhg->nh_entries[i];
+               struct nh_info *nhi = rtnl_dereference(nhge->nh->nh_info);
+
+               if (nhi->family == AF_INET6)
+                       ipv6_stub->fib6_nh_release_dsts(&nhi->fib6_nh);
+       }
 }
 
 static int replace_nexthop_grp(struct net *net, struct nexthop *old,
@@ -2247,7 +2268,7 @@ static int replace_nexthop(struct net *net, struct nexthop *old,
                err = replace_nexthop_single(net, old, new, extack);
 
        if (!err) {
-               nh_rt_cache_flush(net, old);
+               nh_rt_cache_flush(net, old, new);
 
                __remove_nexthop(net, new, NULL);
                nexthop_put(new);
@@ -2544,11 +2565,15 @@ static int nh_create_ipv6(struct net *net,  struct nexthop *nh,
        /* sets nh_dev if successful */
        err = ipv6_stub->fib6_nh_init(net, fib6_nh, &fib6_cfg, GFP_KERNEL,
                                      extack);
-       if (err)
+       if (err) {
+               /* IPv6 is not enabled, don't call fib6_nh_release */
+               if (err == -EAFNOSUPPORT)
+                       goto out;
                ipv6_stub->fib6_nh_release(fib6_nh);
-       else
+       } else {
                nh->nh_flags = fib6_nh->fib_nh_flags;
-
+       }
+out:
        return err;
 }
 
index b7796b4..bbb3d39 100644 (file)
@@ -1758,6 +1758,9 @@ static skb_frag_t *skb_advance_to_frag(struct sk_buff *skb, u32 offset_skb,
 {
        skb_frag_t *frag;
 
+       if (unlikely(offset_skb >= skb->len))
+               return NULL;
+
        offset_skb -= skb_headlen(skb);
        if ((int)offset_skb < 0 || skb_has_frag_list(skb))
                return NULL;
index 5e9d9c5..e07837e 100644 (file)
@@ -330,8 +330,6 @@ static void cubictcp_cong_avoid(struct sock *sk, u32 ack, u32 acked)
                return;
 
        if (tcp_in_slow_start(tp)) {
-               if (hystart && after(ack, ca->end_seq))
-                       bictcp_hystart_reset(sk);
                acked = tcp_slow_start(tp, acked);
                if (!acked)
                        return;
@@ -391,6 +389,9 @@ static void hystart_update(struct sock *sk, u32 delay)
        struct bictcp *ca = inet_csk_ca(sk);
        u32 threshold;
 
+       if (after(tp->snd_una, ca->end_seq))
+               bictcp_hystart_reset(sk);
+
        if (hystart_detect & HYSTART_ACK_TRAIN) {
                u32 now = bictcp_clock_us(sk);
 
index 319dd7b..8bcecdd 100644 (file)
@@ -1807,6 +1807,17 @@ int udp_read_sock(struct sock *sk, read_descriptor_t *desc,
                skb = skb_recv_udp(sk, 0, 1, &err);
                if (!skb)
                        return err;
+
+               if (udp_lib_checksum_complete(skb)) {
+                       __UDP_INC_STATS(sock_net(sk), UDP_MIB_CSUMERRORS,
+                                       IS_UDPLITE(sk));
+                       __UDP_INC_STATS(sock_net(sk), UDP_MIB_INERRORS,
+                                       IS_UDPLITE(sk));
+                       atomic_inc(&sk->sk_drops);
+                       kfree_skb(skb);
+                       continue;
+               }
+
                used = recv_actor(desc, skb, 0, skb->len);
                if (used <= 0) {
                        if (!copied)
index 0c4da16..dab4a04 100644 (file)
@@ -1026,6 +1026,7 @@ static const struct ipv6_stub ipv6_stub_impl = {
        .ip6_mtu_from_fib6 = ip6_mtu_from_fib6,
        .fib6_nh_init      = fib6_nh_init,
        .fib6_nh_release   = fib6_nh_release,
+       .fib6_nh_release_dsts = fib6_nh_release_dsts,
        .fib6_update_sernum = fib6_update_sernum_stub,
        .fib6_rt_update    = fib6_rt_update,
        .ip6_del_rt        = ip6_del_rt,
index ed2f061..f0bac6f 100644 (file)
@@ -808,6 +808,12 @@ int esp6_input_done2(struct sk_buff *skb, int err)
                struct tcphdr *th;
 
                offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
+
+               if (offset < 0) {
+                       err = -EINVAL;
+                       goto out;
+               }
+
                uh = (void *)(skb->data + offset);
                th = (void *)(skb->data + offset);
                hdr_len += offset;
index 2f044a4..ff4e83e 100644 (file)
@@ -174,7 +174,7 @@ static int __ip6_finish_output(struct net *net, struct sock *sk, struct sk_buff
 #if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM)
        /* Policy lookup after SNAT yielded a new policy */
        if (skb_dst(skb)->xfrm) {
-               IPCB(skb)->flags |= IPSKB_REROUTED;
+               IP6CB(skb)->flags |= IP6SKB_REROUTED;
                return dst_output(net, sk, skb);
        }
 #endif
index 3ae25b8..42d60c7 100644 (file)
@@ -3680,6 +3680,25 @@ void fib6_nh_release(struct fib6_nh *fib6_nh)
        fib_nh_common_release(&fib6_nh->nh_common);
 }
 
+void fib6_nh_release_dsts(struct fib6_nh *fib6_nh)
+{
+       int cpu;
+
+       if (!fib6_nh->rt6i_pcpu)
+               return;
+
+       for_each_possible_cpu(cpu) {
+               struct rt6_info *pcpu_rt, **ppcpu_rt;
+
+               ppcpu_rt = per_cpu_ptr(fib6_nh->rt6i_pcpu, cpu);
+               pcpu_rt = xchg(ppcpu_rt, NULL);
+               if (pcpu_rt) {
+                       dst_dev_put(&pcpu_rt->dst);
+                       dst_release(&pcpu_rt->dst);
+               }
+       }
+}
+
 static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
                                              gfp_t gfp_flags,
                                              struct netlink_ext_ack *extack)
index e2b791c..bd3d319 100644 (file)
@@ -80,7 +80,8 @@ static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata,
        }
 
        /* also validate MU-MIMO change */
-       monitor_sdata = rtnl_dereference(local->monitor_sdata);
+       monitor_sdata = wiphy_dereference(local->hw.wiphy,
+                                         local->monitor_sdata);
 
        if (!monitor_sdata &&
            (params->vht_mumimo_groups || params->vht_mumimo_follow_addr))
@@ -840,7 +841,8 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
 
        mutex_lock(&local->mtx);
        if (local->use_chanctx) {
-               sdata = rtnl_dereference(local->monitor_sdata);
+               sdata = wiphy_dereference(local->hw.wiphy,
+                                         local->monitor_sdata);
                if (sdata) {
                        ieee80211_vif_release_channel(sdata);
                        ret = ieee80211_vif_use_channel(sdata, chandef,
@@ -2707,7 +2709,8 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
                sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
 
                if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
-                       sdata = rtnl_dereference(local->monitor_sdata);
+                       sdata = wiphy_dereference(local->hw.wiphy,
+                                                 local->monitor_sdata);
                        if (!sdata)
                                return -EOPNOTSUPP;
                }
@@ -2767,7 +2770,8 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
        mutex_unlock(&local->iflist_mtx);
 
        if (has_monitor) {
-               sdata = rtnl_dereference(local->monitor_sdata);
+               sdata = wiphy_dereference(local->hw.wiphy,
+                                         local->monitor_sdata);
                if (sdata) {
                        sdata->user_power_level = local->user_power_level;
                        if (txp_type != sdata->vif.bss_conf.txpower_type)
index 9a2145c..20aa5cc 100644 (file)
@@ -588,7 +588,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
         */
        if (local->suspended) {
                WARN_ON(local->wowlan);
-               WARN_ON(rtnl_dereference(local->monitor_sdata));
+               WARN_ON(rcu_access_pointer(local->monitor_sdata));
                return;
        }
 
@@ -961,6 +961,7 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
                return 0;
 
        ASSERT_RTNL();
+       lockdep_assert_wiphy(local->hw.wiphy);
 
        if (local->monitor_sdata)
                return 0;
@@ -1028,6 +1029,7 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
                return;
 
        ASSERT_RTNL();
+       lockdep_assert_wiphy(local->hw.wiphy);
 
        mutex_lock(&local->iflist_mtx);
 
index fb3aaa3..b71a142 100644 (file)
@@ -72,19 +72,19 @@ static inline void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local,
 #endif
 
 static inline void
-ieee80211_tpt_led_trig_tx(struct ieee80211_local *local, __le16 fc, int bytes)
+ieee80211_tpt_led_trig_tx(struct ieee80211_local *local, int bytes)
 {
 #ifdef CONFIG_MAC80211_LEDS
-       if (ieee80211_is_data(fc) && atomic_read(&local->tpt_led_active))
+       if (atomic_read(&local->tpt_led_active))
                local->tpt_led_trigger->tx_bytes += bytes;
 #endif
 }
 
 static inline void
-ieee80211_tpt_led_trig_rx(struct ieee80211_local *local, __le16 fc, int bytes)
+ieee80211_tpt_led_trig_rx(struct ieee80211_local *local, int bytes)
 {
 #ifdef CONFIG_MAC80211_LEDS
-       if (ieee80211_is_data(fc) && atomic_read(&local->tpt_led_active))
+       if (atomic_read(&local->tpt_led_active))
                local->tpt_led_trigger->rx_bytes += bytes;
 #endif
 }
index fc5c608..9541a4c 100644 (file)
@@ -364,7 +364,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
         * the compiler to think we have walked past the end of the
         * struct member.
         */
-       pos = (void *)&rthdr->it_optional[it_present - rthdr->it_optional];
+       pos = (void *)&rthdr->it_optional[it_present + 1 - rthdr->it_optional];
 
        /* the order of the following fields is important */
 
@@ -1952,7 +1952,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
                int keyid = rx->sta->ptk_idx;
                sta_ptk = rcu_dereference(rx->sta->ptk[keyid]);
 
-               if (ieee80211_has_protected(fc)) {
+               if (ieee80211_has_protected(fc) &&
+                   !(status->flag & RX_FLAG_IV_STRIPPED)) {
                        cs = rx->sta->cipher_scheme;
                        keyid = ieee80211_get_keyid(rx->skb, cs);
 
@@ -4863,6 +4864,7 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
        struct ieee80211_rate *rate = NULL;
        struct ieee80211_supported_band *sband;
        struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 
        WARN_ON_ONCE(softirq_count() == 0);
 
@@ -4959,9 +4961,9 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
        if (!(status->flag & RX_FLAG_8023))
                skb = ieee80211_rx_monitor(local, skb, rate);
        if (skb) {
-               ieee80211_tpt_led_trig_rx(local,
-                                         ((struct ieee80211_hdr *)skb->data)->frame_control,
-                                         skb->len);
+               if ((status->flag & RX_FLAG_8023) ||
+                       ieee80211_is_data_present(hdr->frame_control))
+                       ieee80211_tpt_led_trig_rx(local, skb->len);
 
                if (status->flag & RX_FLAG_8023)
                        __ieee80211_rx_handle_8023(hw, pubsta, skb, list);
index a756a19..278945e 100644 (file)
@@ -1721,21 +1721,19 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local,
  * Returns false if the frame couldn't be transmitted but was queued instead.
  */
 static bool __ieee80211_tx(struct ieee80211_local *local,
-                          struct sk_buff_head *skbs, int led_len,
-                          struct sta_info *sta, bool txpending)
+                          struct sk_buff_head *skbs, struct sta_info *sta,
+                          bool txpending)
 {
        struct ieee80211_tx_info *info;
        struct ieee80211_sub_if_data *sdata;
        struct ieee80211_vif *vif;
        struct sk_buff *skb;
        bool result;
-       __le16 fc;
 
        if (WARN_ON(skb_queue_empty(skbs)))
                return true;
 
        skb = skb_peek(skbs);
-       fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
        info = IEEE80211_SKB_CB(skb);
        sdata = vif_to_sdata(info->control.vif);
        if (sta && !sta->uploaded)
@@ -1769,8 +1767,6 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
 
        result = ieee80211_tx_frags(local, vif, sta, skbs, txpending);
 
-       ieee80211_tpt_led_trig_tx(local, fc, led_len);
-
        WARN_ON_ONCE(!skb_queue_empty(skbs));
 
        return result;
@@ -1920,7 +1916,6 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata,
        ieee80211_tx_result res_prepare;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        bool result = true;
-       int led_len;
 
        if (unlikely(skb->len < 10)) {
                dev_kfree_skb(skb);
@@ -1928,7 +1923,6 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata,
        }
 
        /* initialises tx */
-       led_len = skb->len;
        res_prepare = ieee80211_tx_prepare(sdata, &tx, sta, skb);
 
        if (unlikely(res_prepare == TX_DROP)) {
@@ -1951,8 +1945,7 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata,
                return true;
 
        if (!invoke_tx_handlers_late(&tx))
-               result = __ieee80211_tx(local, &tx.skbs, led_len,
-                                       tx.sta, txpending);
+               result = __ieee80211_tx(local, &tx.skbs, tx.sta, txpending);
 
        return result;
 }
@@ -4175,6 +4168,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
        struct sk_buff *next;
+       int len = skb->len;
 
        if (unlikely(skb->len < ETH_HLEN)) {
                kfree_skb(skb);
@@ -4221,10 +4215,8 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
                }
        } else {
                /* we cannot process non-linear frames on this path */
-               if (skb_linearize(skb)) {
-                       kfree_skb(skb);
-                       goto out;
-               }
+               if (skb_linearize(skb))
+                       goto out_free;
 
                /* the frame could be fragmented, software-encrypted, and other
                 * things so we cannot really handle checksum offload with it -
@@ -4258,7 +4250,10 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
        goto out;
  out_free:
        kfree_skb(skb);
+       len = 0;
  out:
+       if (len)
+               ieee80211_tpt_led_trig_tx(local, len);
        rcu_read_unlock();
 }
 
@@ -4396,8 +4391,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 }
 
 static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata,
-                             struct sk_buff *skb, int led_len,
-                             struct sta_info *sta,
+                             struct sk_buff *skb, struct sta_info *sta,
                              bool txpending)
 {
        struct ieee80211_local *local = sdata->local;
@@ -4410,6 +4404,8 @@ static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata,
        if (sta)
                sk_pacing_shift_update(skb->sk, local->hw.tx_sk_pacing_shift);
 
+       ieee80211_tpt_led_trig_tx(local, skb->len);
+
        if (ieee80211_queue_skb(local, sdata, sta, skb))
                return true;
 
@@ -4498,7 +4494,7 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
        if (key)
                info->control.hw_key = &key->conf;
 
-       ieee80211_tx_8023(sdata, skb, skb->len, sta, false);
+       ieee80211_tx_8023(sdata, skb, sta, false);
 
        return;
 
@@ -4637,7 +4633,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
                if (IS_ERR(sta) || (sta && !sta->uploaded))
                        sta = NULL;
 
-               result = ieee80211_tx_8023(sdata, skb, skb->len, sta, true);
+               result = ieee80211_tx_8023(sdata, skb, sta, true);
        } else {
                struct sk_buff_head skbs;
 
@@ -4647,7 +4643,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
                hdr = (struct ieee80211_hdr *)skb->data;
                sta = sta_info_get(sdata, hdr->addr1);
 
-               result = __ieee80211_tx(local, &skbs, skb->len, sta, true);
+               result = __ieee80211_tx(local, &skbs, sta, true);
        }
 
        return result;
index 39fa2a5..43df2f0 100644 (file)
@@ -796,7 +796,7 @@ static void __iterate_interfaces(struct ieee80211_local *local,
 
        sdata = rcu_dereference_check(local->monitor_sdata,
                                      lockdep_is_held(&local->iflist_mtx) ||
-                                     lockdep_rtnl_is_held());
+                                     lockdep_is_held(&local->hw.wiphy->mtx));
        if (sdata &&
            (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || !active_only ||
             sdata->flags & IEEE80211_SDATA_IN_DRIVER))
@@ -2381,7 +2381,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                                   IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
 
        /* add interfaces */
-       sdata = rtnl_dereference(local->monitor_sdata);
+       sdata = wiphy_dereference(local->hw.wiphy, local->monitor_sdata);
        if (sdata) {
                /* in HW restart it exists already */
                WARN_ON(local->resuming);
@@ -2426,7 +2426,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                                WARN_ON(drv_add_chanctx(local, ctx));
                mutex_unlock(&local->chanctx_mtx);
 
-               sdata = rtnl_dereference(local->monitor_sdata);
+               sdata = wiphy_dereference(local->hw.wiphy,
+                                         local->monitor_sdata);
                if (sdata && ieee80211_sdata_running(sdata))
                        ieee80211_assign_chanctx(local, sdata);
        }
index 9ea6004..62c6733 100644 (file)
@@ -143,7 +143,6 @@ u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
 u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
                             struct sta_info *sta, struct sk_buff *skb)
 {
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct mac80211_qos_map *qos_map;
        bool qos;
 
@@ -156,7 +155,7 @@ u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
        else
                qos = false;
 
-       if (!qos || (info->control.flags & IEEE80211_TX_CTRL_DONT_REORDER)) {
+       if (!qos) {
                skb->priority = 0; /* required for correct WPA/11i MIC */
                return IEEE80211_AC_BE;
        }
index 7c3420a..fe98e4f 100644 (file)
@@ -422,28 +422,6 @@ bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
        return false;
 }
 
-/* MP_JOIN client subflow must wait for 4th ack before sending any data:
- * TCP can't schedule delack timer before the subflow is fully established.
- * MPTCP uses the delack timer to do 3rd ack retransmissions
- */
-static void schedule_3rdack_retransmission(struct sock *sk)
-{
-       struct inet_connection_sock *icsk = inet_csk(sk);
-       struct tcp_sock *tp = tcp_sk(sk);
-       unsigned long timeout;
-
-       /* reschedule with a timeout above RTT, as we must look only for drop */
-       if (tp->srtt_us)
-               timeout = tp->srtt_us << 1;
-       else
-               timeout = TCP_TIMEOUT_INIT;
-
-       WARN_ON_ONCE(icsk->icsk_ack.pending & ICSK_ACK_TIMER);
-       icsk->icsk_ack.pending |= ICSK_ACK_SCHED | ICSK_ACK_TIMER;
-       icsk->icsk_ack.timeout = timeout;
-       sk_reset_timer(sk, &icsk->icsk_delack_timer, timeout);
-}
-
 static void clear_3rdack_retransmission(struct sock *sk)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
@@ -526,7 +504,15 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb,
                *size = TCPOLEN_MPTCP_MPJ_ACK;
                pr_debug("subflow=%p", subflow);
 
-               schedule_3rdack_retransmission(sk);
+               /* we can use the full delegate action helper only from BH context
+                * If we are in process context - sk is flushing the backlog at
+                * socket lock release time - just set the appropriate flag, will
+                * be handled by the release callback
+                */
+               if (sock_owned_by_user(sk))
+                       set_bit(MPTCP_DELEGATE_ACK, &subflow->delegated_status);
+               else
+                       mptcp_subflow_delegate(subflow, MPTCP_DELEGATE_ACK);
                return true;
        }
        return false;
index b7e32e3..c82a76d 100644 (file)
@@ -1596,7 +1596,8 @@ static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk)
                        if (!xmit_ssk)
                                goto out;
                        if (xmit_ssk != ssk) {
-                               mptcp_subflow_delegate(mptcp_subflow_ctx(xmit_ssk));
+                               mptcp_subflow_delegate(mptcp_subflow_ctx(xmit_ssk),
+                                                      MPTCP_DELEGATE_SEND);
                                goto out;
                        }
 
@@ -2943,7 +2944,7 @@ void __mptcp_check_push(struct sock *sk, struct sock *ssk)
                if (xmit_ssk == ssk)
                        __mptcp_subflow_push_pending(sk, ssk);
                else if (xmit_ssk)
-                       mptcp_subflow_delegate(mptcp_subflow_ctx(xmit_ssk));
+                       mptcp_subflow_delegate(mptcp_subflow_ctx(xmit_ssk), MPTCP_DELEGATE_SEND);
        } else {
                set_bit(MPTCP_PUSH_PENDING, &mptcp_sk(sk)->flags);
        }
@@ -2993,18 +2994,50 @@ static void mptcp_release_cb(struct sock *sk)
        __mptcp_update_rmem(sk);
 }
 
+/* MP_JOIN client subflow must wait for 4th ack before sending any data:
+ * TCP can't schedule delack timer before the subflow is fully established.
+ * MPTCP uses the delack timer to do 3rd ack retransmissions
+ */
+static void schedule_3rdack_retransmission(struct sock *ssk)
+{
+       struct inet_connection_sock *icsk = inet_csk(ssk);
+       struct tcp_sock *tp = tcp_sk(ssk);
+       unsigned long timeout;
+
+       if (mptcp_subflow_ctx(ssk)->fully_established)
+               return;
+
+       /* reschedule with a timeout above RTT, as we must look only for drop */
+       if (tp->srtt_us)
+               timeout = usecs_to_jiffies(tp->srtt_us >> (3 - 1));
+       else
+               timeout = TCP_TIMEOUT_INIT;
+       timeout += jiffies;
+
+       WARN_ON_ONCE(icsk->icsk_ack.pending & ICSK_ACK_TIMER);
+       icsk->icsk_ack.pending |= ICSK_ACK_SCHED | ICSK_ACK_TIMER;
+       icsk->icsk_ack.timeout = timeout;
+       sk_reset_timer(ssk, &icsk->icsk_delack_timer, timeout);
+}
+
 void mptcp_subflow_process_delegated(struct sock *ssk)
 {
        struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
        struct sock *sk = subflow->conn;
 
-       mptcp_data_lock(sk);
-       if (!sock_owned_by_user(sk))
-               __mptcp_subflow_push_pending(sk, ssk);
-       else
-               set_bit(MPTCP_PUSH_PENDING, &mptcp_sk(sk)->flags);
-       mptcp_data_unlock(sk);
-       mptcp_subflow_delegated_done(subflow);
+       if (test_bit(MPTCP_DELEGATE_SEND, &subflow->delegated_status)) {
+               mptcp_data_lock(sk);
+               if (!sock_owned_by_user(sk))
+                       __mptcp_subflow_push_pending(sk, ssk);
+               else
+                       set_bit(MPTCP_PUSH_PENDING, &mptcp_sk(sk)->flags);
+               mptcp_data_unlock(sk);
+               mptcp_subflow_delegated_done(subflow, MPTCP_DELEGATE_SEND);
+       }
+       if (test_bit(MPTCP_DELEGATE_ACK, &subflow->delegated_status)) {
+               schedule_3rdack_retransmission(ssk);
+               mptcp_subflow_delegated_done(subflow, MPTCP_DELEGATE_ACK);
+       }
 }
 
 static int mptcp_hash(struct sock *sk)
index 67a61ac..d87cc04 100644 (file)
@@ -387,6 +387,7 @@ struct mptcp_delegated_action {
 DECLARE_PER_CPU(struct mptcp_delegated_action, mptcp_delegated_actions);
 
 #define MPTCP_DELEGATE_SEND            0
+#define MPTCP_DELEGATE_ACK             1
 
 /* MPTCP subflow context */
 struct mptcp_subflow_context {
@@ -492,23 +493,23 @@ static inline void mptcp_add_pending_subflow(struct mptcp_sock *msk,
 
 void mptcp_subflow_process_delegated(struct sock *ssk);
 
-static inline void mptcp_subflow_delegate(struct mptcp_subflow_context *subflow)
+static inline void mptcp_subflow_delegate(struct mptcp_subflow_context *subflow, int action)
 {
        struct mptcp_delegated_action *delegated;
        bool schedule;
 
+       /* the caller held the subflow bh socket lock */
+       lockdep_assert_in_softirq();
+
        /* The implied barrier pairs with mptcp_subflow_delegated_done(), and
         * ensures the below list check sees list updates done prior to status
         * bit changes
         */
-       if (!test_and_set_bit(MPTCP_DELEGATE_SEND, &subflow->delegated_status)) {
+       if (!test_and_set_bit(action, &subflow->delegated_status)) {
                /* still on delegated list from previous scheduling */
                if (!list_empty(&subflow->delegated_node))
                        return;
 
-               /* the caller held the subflow bh socket lock */
-               lockdep_assert_in_softirq();
-
                delegated = this_cpu_ptr(&mptcp_delegated_actions);
                schedule = list_empty(&delegated->head);
                list_add_tail(&subflow->delegated_node, &delegated->head);
@@ -533,16 +534,16 @@ mptcp_subflow_delegated_next(struct mptcp_delegated_action *delegated)
 
 static inline bool mptcp_subflow_has_delegated_action(const struct mptcp_subflow_context *subflow)
 {
-       return test_bit(MPTCP_DELEGATE_SEND, &subflow->delegated_status);
+       return !!READ_ONCE(subflow->delegated_status);
 }
 
-static inline void mptcp_subflow_delegated_done(struct mptcp_subflow_context *subflow)
+static inline void mptcp_subflow_delegated_done(struct mptcp_subflow_context *subflow, int action)
 {
        /* pairs with mptcp_subflow_delegate, ensures delegate_node is updated before
         * touching the status bit
         */
        smp_wmb();
-       clear_bit(MPTCP_DELEGATE_SEND, &subflow->delegated_status);
+       clear_bit(action, &subflow->delegated_status);
 }
 
 int mptcp_is_enabled(const struct net *net);
index ba9ae48..dda8b76 100644 (file)
@@ -18,6 +18,8 @@
 #include "internal.h"
 #include "ncsi-pkt.h"
 
+static const int padding_bytes = 26;
+
 u32 ncsi_calculate_checksum(unsigned char *data, int len)
 {
        u32 checksum = 0;
@@ -213,12 +215,17 @@ static int ncsi_cmd_handler_oem(struct sk_buff *skb,
 {
        struct ncsi_cmd_oem_pkt *cmd;
        unsigned int len;
+       int payload;
+       /* NC-SI spec DSP_0222_1.2.0, section 8.2.2.2
+        * requires payload to be padded with 0 to
+        * 32-bit boundary before the checksum field.
+        * Ensure the padding bytes are accounted for in
+        * skb allocation
+        */
 
+       payload = ALIGN(nca->payload, 4);
        len = sizeof(struct ncsi_cmd_pkt_hdr) + 4;
-       if (nca->payload < 26)
-               len += 26;
-       else
-               len += nca->payload;
+       len += max(payload, padding_bytes);
 
        cmd = skb_put_zero(skb, len);
        memcpy(&cmd->mfr_id, nca->data, nca->payload);
@@ -272,6 +279,7 @@ static struct ncsi_request *ncsi_alloc_command(struct ncsi_cmd_arg *nca)
        struct net_device *dev = nd->dev;
        int hlen = LL_RESERVED_SPACE(dev);
        int tlen = dev->needed_tailroom;
+       int payload;
        int len = hlen + tlen;
        struct sk_buff *skb;
        struct ncsi_request *nr;
@@ -281,14 +289,14 @@ static struct ncsi_request *ncsi_alloc_command(struct ncsi_cmd_arg *nca)
                return NULL;
 
        /* NCSI command packet has 16-bytes header, payload, 4 bytes checksum.
+        * Payload needs padding so that the checksum field following payload is
+        * aligned to 32-bit boundary.
         * The packet needs padding if its payload is less than 26 bytes to
         * meet 64 bytes minimal ethernet frame length.
         */
        len += sizeof(struct ncsi_cmd_pkt_hdr) + 4;
-       if (nca->payload < 26)
-               len += 26;
-       else
-               len += nca->payload;
+       payload = ALIGN(nca->payload, 4);
+       len += max(payload, padding_bytes);
 
        /* Allocate skb */
        skb = alloc_skb(len, GFP_ATOMIC);
index e93c937..51ad557 100644 (file)
@@ -1919,7 +1919,6 @@ ip_vs_in_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state
        struct ip_vs_proto_data *pd;
        struct ip_vs_conn *cp;
        int ret, pkts;
-       int conn_reuse_mode;
        struct sock *sk;
        int af = state->pf;
 
@@ -1997,15 +1996,16 @@ ip_vs_in_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state
        cp = INDIRECT_CALL_1(pp->conn_in_get, ip_vs_conn_in_get_proto,
                             ipvs, af, skb, &iph);
 
-       conn_reuse_mode = sysctl_conn_reuse_mode(ipvs);
-       if (conn_reuse_mode && !iph.fragoffs && is_new_conn(skb, &iph) && cp) {
+       if (!iph.fragoffs && is_new_conn(skb, &iph) && cp) {
+               int conn_reuse_mode = sysctl_conn_reuse_mode(ipvs);
                bool old_ct = false, resched = false;
 
                if (unlikely(sysctl_expire_nodest_conn(ipvs)) && cp->dest &&
                    unlikely(!atomic_read(&cp->dest->weight))) {
                        resched = true;
                        old_ct = ip_vs_conn_uses_old_conntrack(cp, skb);
-               } else if (is_new_conn_expected(cp, conn_reuse_mode)) {
+               } else if (conn_reuse_mode &&
+                          is_new_conn_expected(cp, conn_reuse_mode)) {
                        old_ct = ip_vs_conn_uses_old_conntrack(cp, skb);
                        if (!atomic_read(&cp->n_control)) {
                                resched = true;
index f1e5443..c7708bd 100644 (file)
@@ -1011,11 +1011,9 @@ ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family)
                                                   CTA_TUPLE_REPLY,
                                                   filter->family,
                                                   &filter->zone,
-                                                  filter->orig_flags);
-               if (err < 0) {
-                       err = -EINVAL;
+                                                  filter->reply_flags);
+               if (err < 0)
                        goto err_filter;
-               }
        }
 
        return filter;
index d6bf1b2..b561e0a 100644 (file)
@@ -65,11 +65,11 @@ static void nf_flow_rule_lwt_match(struct nf_flow_match *match,
                       sizeof(struct in6_addr));
                if (memcmp(&key->enc_ipv6.src, &in6addr_any,
                           sizeof(struct in6_addr)))
-                       memset(&key->enc_ipv6.src, 0xff,
+                       memset(&mask->enc_ipv6.src, 0xff,
                               sizeof(struct in6_addr));
                if (memcmp(&key->enc_ipv6.dst, &in6addr_any,
                           sizeof(struct in6_addr)))
-                       memset(&key->enc_ipv6.dst, 0xff,
+                       memset(&mask->enc_ipv6.dst, 0xff,
                               sizeof(struct in6_addr));
                enc_keys |= BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS);
                key->enc_control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
index cbfe4e4..bd68993 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/icmpv6.h>
 #include <linux/ip.h>
 #include <linux/ipv6.h>
-#include <linux/ip.h>
 #include <net/sctp/checksum.h>
 
 static bool nft_payload_rebuild_vlan_hdr(const struct sk_buff *skb, int mac_off,
index 2f7cf5e..0f8bb0b 100644 (file)
@@ -85,9 +85,9 @@ static ssize_t idletimer_tg_show(struct device *dev,
        mutex_unlock(&list_mutex);
 
        if (time_after(expires, jiffies) || ktimespec.tv_sec > 0)
-               return snprintf(buf, PAGE_SIZE, "%ld\n", time_diff);
+               return sysfs_emit(buf, "%ld\n", time_diff);
 
-       return snprintf(buf, PAGE_SIZE, "0\n");
+       return sysfs_emit(buf, "0\n");
 }
 
 static void idletimer_tg_work(struct work_struct *work)
index 3c645c1..dc7a240 100644 (file)
@@ -94,13 +94,13 @@ int nfc_dev_up(struct nfc_dev *dev)
 
        device_lock(&dev->dev);
 
-       if (dev->rfkill && rfkill_blocked(dev->rfkill)) {
-               rc = -ERFKILL;
+       if (!device_is_registered(&dev->dev)) {
+               rc = -ENODEV;
                goto error;
        }
 
-       if (!device_is_registered(&dev->dev)) {
-               rc = -ENODEV;
+       if (dev->rfkill && rfkill_blocked(dev->rfkill)) {
+               rc = -ERFKILL;
                goto error;
        }
 
@@ -1125,11 +1125,7 @@ int nfc_register_device(struct nfc_dev *dev)
        if (rc)
                pr_err("Could not register llcp device\n");
 
-       rc = nfc_genl_device_added(dev);
-       if (rc)
-               pr_debug("The userspace won't be notified that the device %s was added\n",
-                        dev_name(&dev->dev));
-
+       device_lock(&dev->dev);
        dev->rfkill = rfkill_alloc(dev_name(&dev->dev), &dev->dev,
                                   RFKILL_TYPE_NFC, &nfc_rfkill_ops, dev);
        if (dev->rfkill) {
@@ -1138,6 +1134,12 @@ int nfc_register_device(struct nfc_dev *dev)
                        dev->rfkill = NULL;
                }
        }
+       device_unlock(&dev->dev);
+
+       rc = nfc_genl_device_added(dev);
+       if (rc)
+               pr_debug("The userspace won't be notified that the device %s was added\n",
+                        dev_name(&dev->dev));
 
        return 0;
 }
@@ -1154,10 +1156,17 @@ void nfc_unregister_device(struct nfc_dev *dev)
 
        pr_debug("dev_name=%s\n", dev_name(&dev->dev));
 
+       rc = nfc_genl_device_removed(dev);
+       if (rc)
+               pr_debug("The userspace won't be notified that the device %s "
+                        "was removed\n", dev_name(&dev->dev));
+
+       device_lock(&dev->dev);
        if (dev->rfkill) {
                rfkill_unregister(dev->rfkill);
                rfkill_destroy(dev->rfkill);
        }
+       device_unlock(&dev->dev);
 
        if (dev->ops->check_presence) {
                device_lock(&dev->dev);
@@ -1167,11 +1176,6 @@ void nfc_unregister_device(struct nfc_dev *dev)
                cancel_work_sync(&dev->check_pres_work);
        }
 
-       rc = nfc_genl_device_removed(dev);
-       if (rc)
-               pr_debug("The userspace won't be notified that the device %s "
-                        "was removed\n", dev_name(&dev->dev));
-
        nfc_llcp_unregister_device(dev);
 
        mutex_lock(&nfc_devlist_mutex);
index 6fd873a..d253738 100644 (file)
@@ -144,12 +144,15 @@ inline int nci_request(struct nci_dev *ndev,
 {
        int rc;
 
-       if (!test_bit(NCI_UP, &ndev->flags))
-               return -ENETDOWN;
-
        /* Serialize all requests */
        mutex_lock(&ndev->req_lock);
-       rc = __nci_request(ndev, req, opt, timeout);
+       /* check the state after obtaing the lock against any races
+        * from nci_close_device when the device gets removed.
+        */
+       if (test_bit(NCI_UP, &ndev->flags))
+               rc = __nci_request(ndev, req, opt, timeout);
+       else
+               rc = -ENETDOWN;
        mutex_unlock(&ndev->req_lock);
 
        return rc;
@@ -473,6 +476,11 @@ static int nci_open_device(struct nci_dev *ndev)
 
        mutex_lock(&ndev->req_lock);
 
+       if (test_bit(NCI_UNREG, &ndev->flags)) {
+               rc = -ENODEV;
+               goto done;
+       }
+
        if (test_bit(NCI_UP, &ndev->flags)) {
                rc = -EALREADY;
                goto done;
@@ -545,6 +553,10 @@ done:
 static int nci_close_device(struct nci_dev *ndev)
 {
        nci_req_cancel(ndev, ENODEV);
+
+       /* This mutex needs to be held as a barrier for
+        * caller nci_unregister_device
+        */
        mutex_lock(&ndev->req_lock);
 
        if (!test_and_clear_bit(NCI_UP, &ndev->flags)) {
@@ -582,8 +594,8 @@ static int nci_close_device(struct nci_dev *ndev)
 
        del_timer_sync(&ndev->cmd_timer);
 
-       /* Clear flags */
-       ndev->flags = 0;
+       /* Clear flags except NCI_UNREG */
+       ndev->flags &= BIT(NCI_UNREG);
 
        mutex_unlock(&ndev->req_lock);
 
@@ -1266,6 +1278,12 @@ void nci_unregister_device(struct nci_dev *ndev)
 {
        struct nci_conn_info *conn_info, *n;
 
+       /* This set_bit is not protected with specialized barrier,
+        * However, it is fine because the mutex_lock(&ndev->req_lock);
+        * in nci_close_device() will help to emit one.
+        */
+       set_bit(NCI_UNREG, &ndev->flags);
+
        nci_close_device(ndev);
 
        destroy_workqueue(ndev->cmd_wq);
index d64b0ee..efc963a 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/if_arp.h>
 #include <net/net_namespace.h>
 #include <net/netlink.h>
+#include <net/dst.h>
 #include <net/pkt_sched.h>
 #include <net/pkt_cls.h>
 #include <linux/tc_act/tc_mirred.h>
@@ -228,6 +229,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a,
        bool want_ingress;
        bool is_redirect;
        bool expects_nh;
+       bool at_ingress;
        int m_eaction;
        int mac_len;
        bool at_nh;
@@ -263,7 +265,8 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a,
         * ingress - that covers the TC S/W datapath.
         */
        is_redirect = tcf_mirred_is_act_redirect(m_eaction);
-       use_reinsert = skb_at_tc_ingress(skb) && is_redirect &&
+       at_ingress = skb_at_tc_ingress(skb);
+       use_reinsert = at_ingress && is_redirect &&
                       tcf_mirred_can_reinsert(retval);
        if (!use_reinsert) {
                skb2 = skb_clone(skb, GFP_ATOMIC);
@@ -271,10 +274,12 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a,
                        goto out;
        }
 
+       want_ingress = tcf_mirred_act_wants_ingress(m_eaction);
+
        /* All mirred/redirected skbs should clear previous ct info */
        nf_reset_ct(skb2);
-
-       want_ingress = tcf_mirred_act_wants_ingress(m_eaction);
+       if (want_ingress && !at_ingress) /* drop dst for egress -> ingress */
+               skb_dst_drop(skb2);
 
        expects_nh = want_ingress || !m_mac_header_xmit;
        at_nh = skb->data == skb_network_header(skb);
index 0eae9ff..e007fc7 100644 (file)
@@ -665,12 +665,14 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
                        q->classes[i].deficit = quanta[i];
                }
        }
+       for (i = q->nbands; i < oldbands; i++) {
+               qdisc_tree_flush_backlog(q->classes[i].qdisc);
+               if (i >= q->nstrict)
+                       list_del(&q->classes[i].alist);
+       }
        q->nstrict = nstrict;
        memcpy(q->prio2band, priomap, sizeof(priomap));
 
-       for (i = q->nbands; i < oldbands; i++)
-               qdisc_tree_flush_backlog(q->classes[i].qdisc);
-
        for (i = 0; i < q->nbands; i++)
                q->classes[i].quantum = quanta[i];
 
index 59284da..230072f 100644 (file)
@@ -566,6 +566,10 @@ static void smc_stat_fallback(struct smc_sock *smc)
 
 static void smc_switch_to_fallback(struct smc_sock *smc, int reason_code)
 {
+       wait_queue_head_t *smc_wait = sk_sleep(&smc->sk);
+       wait_queue_head_t *clc_wait = sk_sleep(smc->clcsock->sk);
+       unsigned long flags;
+
        smc->use_fallback = true;
        smc->fallback_rsn = reason_code;
        smc_stat_fallback(smc);
@@ -575,6 +579,16 @@ static void smc_switch_to_fallback(struct smc_sock *smc, int reason_code)
                smc->clcsock->file->private_data = smc->clcsock;
                smc->clcsock->wq.fasync_list =
                        smc->sk.sk_socket->wq.fasync_list;
+
+               /* There may be some entries remaining in
+                * smc socket->wq, which should be removed
+                * to clcsocket->wq during the fallback.
+                */
+               spin_lock_irqsave(&smc_wait->lock, flags);
+               spin_lock_nested(&clc_wait->lock, SINGLE_DEPTH_NESTING);
+               list_splice_init(&smc_wait->head, &clc_wait->head);
+               spin_unlock(&clc_wait->lock);
+               spin_unlock_irqrestore(&smc_wait->lock, flags);
        }
 }
 
@@ -2120,8 +2134,10 @@ static int smc_listen(struct socket *sock, int backlog)
        smc->clcsock->sk->sk_user_data =
                (void *)((uintptr_t)smc | SK_USER_DATA_NOCOPY);
        rc = kernel_listen(smc->clcsock, backlog);
-       if (rc)
+       if (rc) {
+               smc->clcsock->sk->sk_data_ready = smc->clcsk_data_ready;
                goto out;
+       }
        sk->sk_max_ack_backlog = backlog;
        sk->sk_ack_backlog = 0;
        sk->sk_state = SMC_LISTEN;
@@ -2354,8 +2370,10 @@ static __poll_t smc_poll(struct file *file, struct socket *sock,
 static int smc_shutdown(struct socket *sock, int how)
 {
        struct sock *sk = sock->sk;
+       bool do_shutdown = true;
        struct smc_sock *smc;
        int rc = -EINVAL;
+       int old_state;
        int rc1 = 0;
 
        smc = smc_sk(sk);
@@ -2382,7 +2400,11 @@ static int smc_shutdown(struct socket *sock, int how)
        }
        switch (how) {
        case SHUT_RDWR:         /* shutdown in both directions */
+               old_state = sk->sk_state;
                rc = smc_close_active(smc);
+               if (old_state == SMC_ACTIVE &&
+                   sk->sk_state == SMC_PEERCLOSEWAIT1)
+                       do_shutdown = false;
                break;
        case SHUT_WR:
                rc = smc_close_shutdown_write(smc);
@@ -2392,7 +2414,7 @@ static int smc_shutdown(struct socket *sock, int how)
                /* nothing more to do because peer is not involved */
                break;
        }
-       if (smc->clcsock)
+       if (do_shutdown && smc->clcsock)
                rc1 = kernel_sock_shutdown(smc->clcsock, how);
        /* map sock_shutdown_cmd constants to sk_shutdown value range */
        sk->sk_shutdown |= how + 1;
index 0f9ffba..3715d2f 100644 (file)
@@ -228,6 +228,12 @@ again:
                        /* send close request */
                        rc = smc_close_final(conn);
                        sk->sk_state = SMC_PEERCLOSEWAIT1;
+
+                       /* actively shutdown clcsock before peer close it,
+                        * prevent peer from entering TIME_WAIT state.
+                        */
+                       if (smc->clcsock && smc->clcsock->sk)
+                               rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR);
                } else {
                        /* peer event has changed the state */
                        goto again;
@@ -354,9 +360,9 @@ static void smc_close_passive_work(struct work_struct *work)
        if (rxflags->peer_conn_abort) {
                /* peer has not received all data */
                smc_close_passive_abort_received(smc);
-               release_sock(&smc->sk);
+               release_sock(sk);
                cancel_delayed_work_sync(&conn->tx_work);
-               lock_sock(&smc->sk);
+               lock_sock(sk);
                goto wakeup;
        }
 
index 49b8ba3..bb52c8b 100644 (file)
@@ -708,13 +708,14 @@ static u8 smcr_next_link_id(struct smc_link_group *lgr)
        int i;
 
        while (1) {
+again:
                link_id = ++lgr->next_link_id;
                if (!link_id)   /* skip zero as link_id */
                        link_id = ++lgr->next_link_id;
                for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
                        if (smc_link_usable(&lgr->lnk[i]) &&
                            lgr->lnk[i].link_id == link_id)
-                               continue;
+                               goto again;
                }
                break;
        }
@@ -1671,14 +1672,26 @@ static void smc_link_down_work(struct work_struct *work)
        mutex_unlock(&lgr->llc_conf_mutex);
 }
 
-/* Determine vlan of internal TCP socket.
- * @vlan_id: address to store the determined vlan id into
- */
+static int smc_vlan_by_tcpsk_walk(struct net_device *lower_dev,
+                                 struct netdev_nested_priv *priv)
+{
+       unsigned short *vlan_id = (unsigned short *)priv->data;
+
+       if (is_vlan_dev(lower_dev)) {
+               *vlan_id = vlan_dev_vlan_id(lower_dev);
+               return 1;
+       }
+
+       return 0;
+}
+
+/* Determine vlan of internal TCP socket. */
 int smc_vlan_by_tcpsk(struct socket *clcsock, struct smc_init_info *ini)
 {
        struct dst_entry *dst = sk_dst_get(clcsock->sk);
+       struct netdev_nested_priv priv;
        struct net_device *ndev;
-       int i, nest_lvl, rc = 0;
+       int rc = 0;
 
        ini->vlan_id = 0;
        if (!dst) {
@@ -1696,20 +1709,9 @@ int smc_vlan_by_tcpsk(struct socket *clcsock, struct smc_init_info *ini)
                goto out_rel;
        }
 
+       priv.data = (void *)&ini->vlan_id;
        rtnl_lock();
-       nest_lvl = ndev->lower_level;
-       for (i = 0; i < nest_lvl; i++) {
-               struct list_head *lower = &ndev->adj_list.lower;
-
-               if (list_empty(lower))
-                       break;
-               lower = lower->next;
-               ndev = (struct net_device *)netdev_lower_get_next(ndev, &lower);
-               if (is_vlan_dev(ndev)) {
-                       ini->vlan_id = vlan_dev_vlan_id(ndev);
-                       break;
-               }
-       }
+       netdev_walk_all_lower_dev(ndev, smc_vlan_by_tcpsk_walk, &priv);
        rtnl_unlock();
 
 out_rel:
index ae48c9c..d8ee06a 100644 (file)
@@ -1720,15 +1720,15 @@ static void xs_local_set_port(struct rpc_xprt *xprt, unsigned short port)
 }
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
-static struct lock_class_key xs_key[2];
-static struct lock_class_key xs_slock_key[2];
+static struct lock_class_key xs_key[3];
+static struct lock_class_key xs_slock_key[3];
 
 static inline void xs_reclassify_socketu(struct socket *sock)
 {
        struct sock *sk = sock->sk;
 
        sock_lock_init_class_and_name(sk, "slock-AF_LOCAL-RPC",
-               &xs_slock_key[1], "sk_lock-AF_LOCAL-RPC", &xs_key[1]);
+               &xs_slock_key[0], "sk_lock-AF_LOCAL-RPC", &xs_key[0]);
 }
 
 static inline void xs_reclassify_socket4(struct socket *sock)
@@ -1736,7 +1736,7 @@ static inline void xs_reclassify_socket4(struct socket *sock)
        struct sock *sk = sock->sk;
 
        sock_lock_init_class_and_name(sk, "slock-AF_INET-RPC",
-               &xs_slock_key[0], "sk_lock-AF_INET-RPC", &xs_key[0]);
+               &xs_slock_key[1], "sk_lock-AF_INET-RPC", &xs_key[1]);
 }
 
 static inline void xs_reclassify_socket6(struct socket *sock)
@@ -1744,7 +1744,7 @@ static inline void xs_reclassify_socket6(struct socket *sock)
        struct sock *sk = sock->sk;
 
        sock_lock_init_class_and_name(sk, "slock-AF_INET6-RPC",
-               &xs_slock_key[1], "sk_lock-AF_INET6-RPC", &xs_key[1]);
+               &xs_slock_key[2], "sk_lock-AF_INET6-RPC", &xs_key[2]);
 }
 
 static inline void xs_reclassify_socket(int family, struct socket *sock)
index dc60c32..b4d9419 100644 (file)
@@ -524,7 +524,7 @@ static int tipc_aead_init(struct tipc_aead **aead, struct tipc_aead_key *ukey,
                return -EEXIST;
 
        /* Allocate a new AEAD */
-       tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC);
+       tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
        if (unlikely(!tmp))
                return -ENOMEM;
 
@@ -597,6 +597,10 @@ static int tipc_aead_init(struct tipc_aead **aead, struct tipc_aead_key *ukey,
        tmp->cloned = NULL;
        tmp->authsize = TIPC_AES_GCM_TAG_SIZE;
        tmp->key = kmemdup(ukey, tipc_aead_key_size(ukey), GFP_KERNEL);
+       if (!tmp->key) {
+               tipc_aead_free(&tmp->rcu);
+               return -ENOMEM;
+       }
        memcpy(&tmp->salt, ukey->key + keylen, TIPC_AES_GCM_SALT_SIZE);
        atomic_set(&tmp->users, 0);
        atomic64_set(&tmp->seqno, 0);
@@ -1470,7 +1474,7 @@ int tipc_crypto_start(struct tipc_crypto **crypto, struct net *net,
                return -EEXIST;
 
        /* Allocate crypto */
-       c = kzalloc(sizeof(*c), GFP_ATOMIC);
+       c = kzalloc(sizeof(*c), GFP_KERNEL);
        if (!c)
                return -ENOMEM;
 
@@ -1484,7 +1488,7 @@ int tipc_crypto_start(struct tipc_crypto **crypto, struct net *net,
        }
 
        /* Allocate statistic structure */
-       c->stats = alloc_percpu_gfp(struct tipc_crypto_stats, GFP_ATOMIC);
+       c->stats = alloc_percpu(struct tipc_crypto_stats);
        if (!c->stats) {
                if (c->wq)
                        destroy_workqueue(c->wq);
@@ -2457,7 +2461,7 @@ static void tipc_crypto_work_tx(struct work_struct *work)
        }
 
        /* Lets duplicate it first */
-       skey = kmemdup(aead->key, tipc_aead_key_size(aead->key), GFP_ATOMIC);
+       skey = kmemdup(aead->key, tipc_aead_key_size(aead->key), GFP_KERNEL);
        rcu_read_unlock();
 
        /* Now, generate new key, initiate & distribute it */
index 1b7a487..09ae844 100644 (file)
@@ -1298,8 +1298,11 @@ static bool tipc_data_input(struct tipc_link *l, struct sk_buff *skb,
                return false;
 #ifdef CONFIG_TIPC_CRYPTO
        case MSG_CRYPTO:
-               tipc_crypto_msg_rcv(l->net, skb);
-               return true;
+               if (TIPC_SKB_CB(skb)->decrypted) {
+                       tipc_crypto_msg_rcv(l->net, skb);
+                       return true;
+               }
+               fallthrough;
 #endif
        default:
                pr_warn("Dropping received illegal msg type\n");
index acfba9f..6bc2879 100644 (file)
@@ -61,7 +61,7 @@ static DEFINE_MUTEX(tcpv6_prot_mutex);
 static const struct proto *saved_tcpv4_prot;
 static DEFINE_MUTEX(tcpv4_prot_mutex);
 static struct proto tls_prots[TLS_NUM_PROTS][TLS_NUM_CONFIG][TLS_NUM_CONFIG];
-static struct proto_ops tls_sw_proto_ops;
+static struct proto_ops tls_proto_ops[TLS_NUM_PROTS][TLS_NUM_CONFIG][TLS_NUM_CONFIG];
 static void build_protos(struct proto prot[TLS_NUM_CONFIG][TLS_NUM_CONFIG],
                         const struct proto *base);
 
@@ -71,6 +71,8 @@ void update_sk_prot(struct sock *sk, struct tls_context *ctx)
 
        WRITE_ONCE(sk->sk_prot,
                   &tls_prots[ip_ver][ctx->tx_conf][ctx->rx_conf]);
+       WRITE_ONCE(sk->sk_socket->ops,
+                  &tls_proto_ops[ip_ver][ctx->tx_conf][ctx->rx_conf]);
 }
 
 int wait_on_pending_writer(struct sock *sk, long *timeo)
@@ -669,8 +671,6 @@ static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
        if (tx) {
                ctx->sk_write_space = sk->sk_write_space;
                sk->sk_write_space = tls_write_space;
-       } else {
-               sk->sk_socket->ops = &tls_sw_proto_ops;
        }
        goto out;
 
@@ -728,6 +728,39 @@ struct tls_context *tls_ctx_create(struct sock *sk)
        return ctx;
 }
 
+static void build_proto_ops(struct proto_ops ops[TLS_NUM_CONFIG][TLS_NUM_CONFIG],
+                           const struct proto_ops *base)
+{
+       ops[TLS_BASE][TLS_BASE] = *base;
+
+       ops[TLS_SW  ][TLS_BASE] = ops[TLS_BASE][TLS_BASE];
+       ops[TLS_SW  ][TLS_BASE].sendpage_locked = tls_sw_sendpage_locked;
+
+       ops[TLS_BASE][TLS_SW  ] = ops[TLS_BASE][TLS_BASE];
+       ops[TLS_BASE][TLS_SW  ].splice_read     = tls_sw_splice_read;
+
+       ops[TLS_SW  ][TLS_SW  ] = ops[TLS_SW  ][TLS_BASE];
+       ops[TLS_SW  ][TLS_SW  ].splice_read     = tls_sw_splice_read;
+
+#ifdef CONFIG_TLS_DEVICE
+       ops[TLS_HW  ][TLS_BASE] = ops[TLS_BASE][TLS_BASE];
+       ops[TLS_HW  ][TLS_BASE].sendpage_locked = NULL;
+
+       ops[TLS_HW  ][TLS_SW  ] = ops[TLS_BASE][TLS_SW  ];
+       ops[TLS_HW  ][TLS_SW  ].sendpage_locked = NULL;
+
+       ops[TLS_BASE][TLS_HW  ] = ops[TLS_BASE][TLS_SW  ];
+
+       ops[TLS_SW  ][TLS_HW  ] = ops[TLS_SW  ][TLS_SW  ];
+
+       ops[TLS_HW  ][TLS_HW  ] = ops[TLS_HW  ][TLS_SW  ];
+       ops[TLS_HW  ][TLS_HW  ].sendpage_locked = NULL;
+#endif
+#ifdef CONFIG_TLS_TOE
+       ops[TLS_HW_RECORD][TLS_HW_RECORD] = *base;
+#endif
+}
+
 static void tls_build_proto(struct sock *sk)
 {
        int ip_ver = sk->sk_family == AF_INET6 ? TLSV6 : TLSV4;
@@ -739,6 +772,8 @@ static void tls_build_proto(struct sock *sk)
                mutex_lock(&tcpv6_prot_mutex);
                if (likely(prot != saved_tcpv6_prot)) {
                        build_protos(tls_prots[TLSV6], prot);
+                       build_proto_ops(tls_proto_ops[TLSV6],
+                                       sk->sk_socket->ops);
                        smp_store_release(&saved_tcpv6_prot, prot);
                }
                mutex_unlock(&tcpv6_prot_mutex);
@@ -749,6 +784,8 @@ static void tls_build_proto(struct sock *sk)
                mutex_lock(&tcpv4_prot_mutex);
                if (likely(prot != saved_tcpv4_prot)) {
                        build_protos(tls_prots[TLSV4], prot);
+                       build_proto_ops(tls_proto_ops[TLSV4],
+                                       sk->sk_socket->ops);
                        smp_store_release(&saved_tcpv4_prot, prot);
                }
                mutex_unlock(&tcpv4_prot_mutex);
@@ -959,10 +996,6 @@ static int __init tls_register(void)
        if (err)
                return err;
 
-       tls_sw_proto_ops = inet_stream_ops;
-       tls_sw_proto_ops.splice_read = tls_sw_splice_read;
-       tls_sw_proto_ops.sendpage_locked   = tls_sw_sendpage_locked;
-
        tls_device_init();
        tcp_register_ulp(&tcp_tls_ulp_ops);
 
index d815640..d3e7ff9 100644 (file)
@@ -2005,6 +2005,7 @@ ssize_t tls_sw_splice_read(struct socket *sock,  loff_t *ppos,
        struct sock *sk = sock->sk;
        struct sk_buff *skb;
        ssize_t copied = 0;
+       bool from_queue;
        int err = 0;
        long timeo;
        int chunk;
@@ -2014,25 +2015,28 @@ ssize_t tls_sw_splice_read(struct socket *sock,  loff_t *ppos,
 
        timeo = sock_rcvtimeo(sk, flags & SPLICE_F_NONBLOCK);
 
-       skb = tls_wait_data(sk, NULL, flags & SPLICE_F_NONBLOCK, timeo, &err);
-       if (!skb)
-               goto splice_read_end;
-
-       if (!ctx->decrypted) {
-               err = decrypt_skb_update(sk, skb, NULL, &chunk, &zc, false);
-
-               /* splice does not support reading control messages */
-               if (ctx->control != TLS_RECORD_TYPE_DATA) {
-                       err = -EINVAL;
+       from_queue = !skb_queue_empty(&ctx->rx_list);
+       if (from_queue) {
+               skb = __skb_dequeue(&ctx->rx_list);
+       } else {
+               skb = tls_wait_data(sk, NULL, flags & SPLICE_F_NONBLOCK, timeo,
+                                   &err);
+               if (!skb)
                        goto splice_read_end;
-               }
 
+               err = decrypt_skb_update(sk, skb, NULL, &chunk, &zc, false);
                if (err < 0) {
                        tls_err_abort(sk, -EBADMSG);
                        goto splice_read_end;
                }
-               ctx->decrypted = 1;
        }
+
+       /* splice does not support reading control messages */
+       if (ctx->control != TLS_RECORD_TYPE_DATA) {
+               err = -EINVAL;
+               goto splice_read_end;
+       }
+
        rxm = strp_msg(skb);
 
        chunk = min_t(unsigned int, rxm->full_len, len);
@@ -2040,7 +2044,17 @@ ssize_t tls_sw_splice_read(struct socket *sock,  loff_t *ppos,
        if (copied < 0)
                goto splice_read_end;
 
-       tls_sw_advance_skb(sk, skb, copied);
+       if (!from_queue) {
+               ctx->recv_pkt = NULL;
+               __strp_unpause(&ctx->strp);
+       }
+       if (chunk < rxm->full_len) {
+               __skb_queue_head(&ctx->rx_list, skb);
+               rxm->offset += len;
+               rxm->full_len -= len;
+       } else {
+               consume_skb(skb);
+       }
 
 splice_read_end:
        release_sock(sk);
index 78e08e8..b0bfc78 100644 (file)
@@ -2882,9 +2882,6 @@ static int unix_shutdown(struct socket *sock, int mode)
 
        unix_state_lock(sk);
        sk->sk_shutdown |= mode;
-       if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) &&
-           mode == SHUTDOWN_MASK)
-               sk->sk_state = TCP_CLOSE;
        other = unix_peer(sk);
        if (other)
                sock_hold(other);
index 81232b7..a27b3b5 100644 (file)
@@ -936,33 +936,37 @@ nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = {
        [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 },
 };
 
-int nl80211_prepare_wdev_dump(struct netlink_callback *cb,
-                             struct cfg80211_registered_device **rdev,
-                             struct wireless_dev **wdev)
+static int nl80211_prepare_wdev_dump(struct netlink_callback *cb,
+                                    struct cfg80211_registered_device **rdev,
+                                    struct wireless_dev **wdev,
+                                    struct nlattr **attrbuf)
 {
        int err;
 
        if (!cb->args[0]) {
-               struct nlattr **attrbuf;
+               struct nlattr **attrbuf_free = NULL;
 
-               attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf),
-                                 GFP_KERNEL);
-               if (!attrbuf)
-                       return -ENOMEM;
+               if (!attrbuf) {
+                       attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf),
+                                         GFP_KERNEL);
+                       if (!attrbuf)
+                               return -ENOMEM;
+                       attrbuf_free = attrbuf;
+               }
 
                err = nlmsg_parse_deprecated(cb->nlh,
                                             GENL_HDRLEN + nl80211_fam.hdrsize,
                                             attrbuf, nl80211_fam.maxattr,
                                             nl80211_policy, NULL);
                if (err) {
-                       kfree(attrbuf);
+                       kfree(attrbuf_free);
                        return err;
                }
 
                rtnl_lock();
                *wdev = __cfg80211_wdev_from_attrs(NULL, sock_net(cb->skb->sk),
                                                   attrbuf);
-               kfree(attrbuf);
+               kfree(attrbuf_free);
                if (IS_ERR(*wdev)) {
                        rtnl_unlock();
                        return PTR_ERR(*wdev);
@@ -6197,7 +6201,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
        int sta_idx = cb->args[2];
        int err;
 
-       err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
+       err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL);
        if (err)
                return err;
        /* nl80211_prepare_wdev_dump acquired it in the successful case */
@@ -7092,7 +7096,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
        int path_idx = cb->args[2];
        int err;
 
-       err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
+       err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL);
        if (err)
                return err;
        /* nl80211_prepare_wdev_dump acquired it in the successful case */
@@ -7292,7 +7296,7 @@ static int nl80211_dump_mpp(struct sk_buff *skb,
        int path_idx = cb->args[2];
        int err;
 
-       err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
+       err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL);
        if (err)
                return err;
        /* nl80211_prepare_wdev_dump acquired it in the successful case */
@@ -9718,7 +9722,7 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
        int start = cb->args[2], idx = 0;
        int err;
 
-       err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
+       err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL);
        if (err)
                return err;
        /* nl80211_prepare_wdev_dump acquired it in the successful case */
@@ -9851,7 +9855,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
        if (!attrbuf)
                return -ENOMEM;
 
-       res = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
+       res = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, attrbuf);
        if (res) {
                kfree(attrbuf);
                return res;
index a3f3877..d642e3b 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Portions of this file
- * Copyright (C) 2018, 2020 Intel Corporation
+ * Copyright (C) 2018, 2020-2021 Intel Corporation
  */
 #ifndef __NET_WIRELESS_NL80211_H
 #define __NET_WIRELESS_NL80211_H
@@ -22,10 +22,6 @@ static inline u64 wdev_id(struct wireless_dev *wdev)
               ((u64)wiphy_to_rdev(wdev->wiphy)->wiphy_idx << 32);
 }
 
-int nl80211_prepare_wdev_dump(struct netlink_callback *cb,
-                             struct cfg80211_registered_device **rdev,
-                             struct wireless_dev **wdev);
-
 int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
                          struct genl_info *info,
                          struct cfg80211_chan_def *chandef);
index 5ff1f87..41ea65d 100644 (file)
@@ -1046,6 +1046,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
 
                switch (otype) {
                case NL80211_IFTYPE_AP:
+               case NL80211_IFTYPE_P2P_GO:
                        cfg80211_stop_ap(rdev, dev, true);
                        break;
                case NL80211_IFTYPE_ADHOC:
index 90c4e1e..bc4ad48 100644 (file)
@@ -500,7 +500,7 @@ struct xdp_buff *xp_alloc(struct xsk_buff_pool *pool)
                pool->free_list_cnt--;
                xskb = list_first_entry(&pool->free_list, struct xdp_buff_xsk,
                                        free_list_node);
-               list_del(&xskb->free_list_node);
+               list_del_init(&xskb->free_list_node);
        }
 
        xskb->xdp.data = xskb->xdp.data_hard_start + XDP_PACKET_HEADROOM;
@@ -568,7 +568,7 @@ static u32 xp_alloc_reused(struct xsk_buff_pool *pool, struct xdp_buff **xdp, u3
        i = nb_entries;
        while (i--) {
                xskb = list_first_entry(&pool->free_list, struct xdp_buff_xsk, free_list_node);
-               list_del(&xskb->free_list_node);
+               list_del_init(&xskb->free_list_node);
 
                *xdp = &xskb->xdp;
                xdp++;
@@ -615,6 +615,9 @@ EXPORT_SYMBOL(xp_can_alloc);
 
 void xp_free(struct xdp_buff_xsk *xskb)
 {
+       if (!list_empty(&xskb->free_list_node))
+               return;
+
        xskb->pool->free_list_cnt++;
        list_add(&xskb->free_list_node, &xskb->pool->free_list);
 }
index bec3528..43d2e9a 100644 (file)
@@ -31,6 +31,15 @@ config SAMPLE_FTRACE_DIRECT
          This builds an ftrace direct function example
          that hooks to wake_up_process and prints the parameters.
 
+config SAMPLE_FTRACE_DIRECT_MULTI
+       tristate "Build register_ftrace_direct_multi() example"
+       depends on DYNAMIC_FTRACE_WITH_DIRECT_CALLS && m
+       depends on HAVE_SAMPLE_FTRACE_DIRECT_MULTI
+       help
+         This builds an ftrace direct function example
+         that hooks to wake_up_process and schedule, and prints
+         the function addresses.
+
 config SAMPLE_TRACE_ARRAY
         tristate "Build sample module for kernel access to Ftrace instancess"
        depends on EVENT_TRACING && m
@@ -237,5 +246,5 @@ endif # SAMPLES
 config HAVE_SAMPLE_FTRACE_DIRECT
        bool
 
-config HAVE_SAMPLE_FTRACE_MULTI_DIRECT
+config HAVE_SAMPLE_FTRACE_DIRECT_MULTI
        bool
index b7b9830..4bcd6b9 100644 (file)
@@ -22,7 +22,7 @@ subdir-$(CONFIG_SAMPLE_TIMER)         += timers
 obj-$(CONFIG_SAMPLE_TRACE_EVENTS)      += trace_events/
 obj-$(CONFIG_SAMPLE_TRACE_PRINTK)      += trace_printk/
 obj-$(CONFIG_SAMPLE_FTRACE_DIRECT)     += ftrace/
-obj-$(CONFIG_SAMPLE_FTRACE_MULTI_DIRECT) += ftrace/
+obj-$(CONFIG_SAMPLE_FTRACE_DIRECT_MULTI) += ftrace/
 obj-$(CONFIG_SAMPLE_TRACE_ARRAY)       += ftrace/
 subdir-$(CONFIG_SAMPLE_UHID)           += uhid
 obj-$(CONFIG_VIDEO_PCI_SKELETON)       += v4l/
index 722b3fa..1752a46 100644 (file)
@@ -9,8 +9,6 @@
  * Include file for sample Host Bandwidth Manager (HBM) BPF programs
  */
 #define KBUILD_MODNAME "foo"
-#include <stddef.h>
-#include <stdbool.h>
 #include <uapi/linux/bpf.h>
 #include <uapi/linux/if_ether.h>
 #include <uapi/linux/if_packet.h>
index d84e694..a81704d 100644 (file)
@@ -309,7 +309,6 @@ int main(int argc, char **argv)
        const char *mprog_filename = NULL, *mprog_name = NULL;
        struct xdp_redirect_cpu *skel;
        struct bpf_map_info info = {};
-       char ifname_buf[IF_NAMESIZE];
        struct bpf_cpumap_val value;
        __u32 infosz = sizeof(info);
        int ret = EXIT_FAIL_OPTION;
@@ -390,10 +389,10 @@ int main(int argc, char **argv)
                case 'd':
                        if (strlen(optarg) >= IF_NAMESIZE) {
                                fprintf(stderr, "-d/--dev name too long\n");
+                               usage(argv, long_options, __doc__, mask, true, skel->obj);
                                goto end_cpu;
                        }
-                       safe_strncpy(ifname_buf, optarg, strlen(ifname_buf));
-                       ifindex = if_nametoindex(ifname_buf);
+                       ifindex = if_nametoindex(optarg);
                        if (!ifindex)
                                ifindex = strtoul(optarg, NULL, 0);
                        if (!ifindex) {
index b32d821..8740838 100644 (file)
@@ -120,7 +120,10 @@ struct sample_output {
                __u64 xmit;
        } totals;
        struct {
-               __u64 pps;
+               union {
+                       __u64 pps;
+                       __u64 num;
+               };
                __u64 drop;
                __u64 err;
        } rx_cnt;
@@ -1322,7 +1325,7 @@ int sample_install_xdp(struct bpf_program *xdp_prog, int ifindex, bool generic,
 
 static void sample_summary_print(void)
 {
-       double period = sample_out.rx_cnt.pps;
+       double num = sample_out.rx_cnt.num;
 
        if (sample_out.totals.rx) {
                double pkts = sample_out.totals.rx;
@@ -1330,7 +1333,7 @@ static void sample_summary_print(void)
                print_always("  Packets received    : %'-10llu\n",
                             sample_out.totals.rx);
                print_always("  Average packets/s   : %'-10.0f\n",
-                            sample_round(pkts / period));
+                            sample_round(pkts / num));
        }
        if (sample_out.totals.redir) {
                double pkts = sample_out.totals.redir;
@@ -1338,7 +1341,7 @@ static void sample_summary_print(void)
                print_always("  Packets redirected  : %'-10llu\n",
                             sample_out.totals.redir);
                print_always("  Average redir/s     : %'-10.0f\n",
-                            sample_round(pkts / period));
+                            sample_round(pkts / num));
        }
        if (sample_out.totals.drop)
                print_always("  Rx dropped          : %'-10llu\n",
@@ -1355,7 +1358,7 @@ static void sample_summary_print(void)
                print_always("  Packets transmitted : %'-10llu\n",
                             sample_out.totals.xmit);
                print_always("  Average transmit/s  : %'-10.0f\n",
-                            sample_round(pkts / period));
+                            sample_round(pkts / num));
        }
 }
 
@@ -1422,7 +1425,7 @@ static int sample_stats_collect(struct stats_record *rec)
        return 0;
 }
 
-static void sample_summary_update(struct sample_output *out, int interval)
+static void sample_summary_update(struct sample_output *out)
 {
        sample_out.totals.rx += out->totals.rx;
        sample_out.totals.redir += out->totals.redir;
@@ -1430,12 +1433,11 @@ static void sample_summary_update(struct sample_output *out, int interval)
        sample_out.totals.drop_xmit += out->totals.drop_xmit;
        sample_out.totals.err += out->totals.err;
        sample_out.totals.xmit += out->totals.xmit;
-       sample_out.rx_cnt.pps += interval;
+       sample_out.rx_cnt.num++;
 }
 
 static void sample_stats_print(int mask, struct stats_record *cur,
-                              struct stats_record *prev, char *prog_name,
-                              int interval)
+                              struct stats_record *prev, char *prog_name)
 {
        struct sample_output out = {};
 
@@ -1452,7 +1454,7 @@ static void sample_stats_print(int mask, struct stats_record *cur,
        else if (mask & SAMPLE_DEVMAP_XMIT_CNT_MULTI)
                stats_get_devmap_xmit_multi(cur, prev, 0, &out,
                                            mask & SAMPLE_DEVMAP_XMIT_CNT);
-       sample_summary_update(&out, interval);
+       sample_summary_update(&out);
 
        stats_print(prog_name, mask, cur, prev, &out);
 }
@@ -1495,7 +1497,7 @@ static void swap(struct stats_record **a, struct stats_record **b)
 }
 
 static int sample_timer_cb(int timerfd, struct stats_record **rec,
-                          struct stats_record **prev, int interval)
+                          struct stats_record **prev)
 {
        char line[64] = "Summary";
        int ret;
@@ -1524,7 +1526,7 @@ static int sample_timer_cb(int timerfd, struct stats_record **rec,
                snprintf(line, sizeof(line), "%s->%s", f ?: "?", t ?: "?");
        }
 
-       sample_stats_print(sample_mask, *rec, *prev, line, interval);
+       sample_stats_print(sample_mask, *rec, *prev, line);
        return 0;
 }
 
@@ -1579,7 +1581,7 @@ int sample_run(int interval, void (*post_cb)(void *), void *ctx)
                if (pfd[0].revents & POLLIN)
                        ret = sample_signal_cb();
                else if (pfd[1].revents & POLLIN)
-                       ret = sample_timer_cb(timerfd, &rec, &prev, interval);
+                       ret = sample_timer_cb(timerfd, &rec, &prev);
 
                if (ret)
                        break;
index e8a3f85..b9198e2 100644 (file)
@@ -3,7 +3,7 @@
 obj-$(CONFIG_SAMPLE_FTRACE_DIRECT) += ftrace-direct.o
 obj-$(CONFIG_SAMPLE_FTRACE_DIRECT) += ftrace-direct-too.o
 obj-$(CONFIG_SAMPLE_FTRACE_DIRECT) += ftrace-direct-modify.o
-obj-$(CONFIG_SAMPLE_FTRACE_MULTI_DIRECT) += ftrace-direct-multi.o
+obj-$(CONFIG_SAMPLE_FTRACE_DIRECT_MULTI) += ftrace-direct-multi.o
 
 CFLAGS_sample-trace-array.o := -I$(src)
 obj-$(CONFIG_SAMPLE_TRACE_ARRAY) += sample-trace-array.o
index b6d7806..2fafc9a 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/mm.h> /* for handle_mm_fault() */
 #include <linux/ftrace.h>
 #include <linux/sched/stat.h>
+#include <asm/asm-offsets.h>
 
 extern void my_direct_func(unsigned long ip);
 
@@ -14,6 +15,8 @@ void my_direct_func(unsigned long ip)
 
 extern void my_tramp(void *);
 
+#ifdef CONFIG_X86_64
+
 asm (
 "      .pushsection    .text, \"ax\", @progbits\n"
 "      .type           my_tramp, @function\n"
@@ -31,6 +34,33 @@ asm (
 "      .popsection\n"
 );
 
+#endif /* CONFIG_X86_64 */
+
+#ifdef CONFIG_S390
+
+asm (
+"      .pushsection    .text, \"ax\", @progbits\n"
+"      .type           my_tramp, @function\n"
+"      .globl          my_tramp\n"
+"   my_tramp:"
+"      lgr             %r1,%r15\n"
+"      stmg            %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n"
+"      stg             %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n"
+"      aghi            %r15,"__stringify(-STACK_FRAME_OVERHEAD)"\n"
+"      stg             %r1,"__stringify(__SF_BACKCHAIN)"(%r15)\n"
+"      lgr             %r2,%r0\n"
+"      brasl           %r14,my_direct_func\n"
+"      aghi            %r15,"__stringify(STACK_FRAME_OVERHEAD)"\n"
+"      lmg             %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n"
+"      lg              %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n"
+"      lgr             %r1,%r0\n"
+"      br              %r1\n"
+"      .size           my_tramp, .-my_tramp\n"
+"      .popsection\n"
+);
+
+#endif /* CONFIG_S390 */
+
 static struct ftrace_ops direct;
 
 static int __init ftrace_direct_multi_init(void)
index cc36256..c0d3bcb 100644 (file)
@@ -259,5 +259,8 @@ int main(void)
        DEVID_FIELD(dfl_device_id, type);
        DEVID_FIELD(dfl_device_id, feature_id);
 
+       DEVID(ishtp_device_id);
+       DEVID_FIELD(ishtp_device_id, guid);
+
        return 0;
 }
index 49aba86..5258247 100644 (file)
@@ -115,6 +115,17 @@ static inline void add_uuid(char *str, uuid_le uuid)
                uuid.b[12], uuid.b[13], uuid.b[14], uuid.b[15]);
 }
 
+static inline void add_guid(char *str, guid_t guid)
+{
+       int len = strlen(str);
+
+       sprintf(str + len, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+               guid.b[3], guid.b[2], guid.b[1], guid.b[0],
+               guid.b[5], guid.b[4], guid.b[7], guid.b[6],
+               guid.b[8], guid.b[9], guid.b[10], guid.b[11],
+               guid.b[12], guid.b[13], guid.b[14], guid.b[15]);
+}
+
 /**
  * Check that sizeof(device_id type) are consistent with size of section
  * in .o file. If in-consistent then userspace and kernel does not agree
@@ -1380,6 +1391,18 @@ static int do_mhi_entry(const char *filename, void *symval, char *alias)
        return 1;
 }
 
+/* Looks like: ishtp:{guid} */
+static int do_ishtp_entry(const char *filename, void *symval, char *alias)
+{
+       DEF_FIELD(symval, ishtp_device_id, guid);
+
+       strcpy(alias, ISHTP_MODULE_PREFIX "{");
+       add_guid(alias, guid);
+       strcat(alias, "}");
+
+       return 1;
+}
+
 static int do_auxiliary_entry(const char *filename, void *symval, char *alias)
 {
        DEF_FIELD_ADDR(symval, auxiliary_device_id, name);
@@ -1499,6 +1522,7 @@ static const struct devtable devtable[] = {
        {"auxiliary", SIZE_auxiliary_device_id, do_auxiliary_entry},
        {"ssam", SIZE_ssam_device_id, do_ssam_entry},
        {"dfl", SIZE_dfl_device_id, do_dfl_entry},
+       {"ishtp", SIZE_ishtp_device_id, do_ishtp_entry},
 };
 
 /* Create MODULE_ALIAS() statements.
index 727c3b4..0ae4e4e 100644 (file)
@@ -31,13 +31,20 @@ static u32 hashtab_compute_size(u32 nel)
 
 int hashtab_init(struct hashtab *h, u32 nel_hint)
 {
-       h->size = hashtab_compute_size(nel_hint);
+       u32 size = hashtab_compute_size(nel_hint);
+
+       /* should already be zeroed, but better be safe */
        h->nel = 0;
-       if (!h->size)
-               return 0;
+       h->size = 0;
+       h->htable = NULL;
 
-       h->htable = kcalloc(h->size, sizeof(*h->htable), GFP_KERNEL);
-       return h->htable ? 0 : -ENOMEM;
+       if (size) {
+               h->htable = kcalloc(size, sizeof(*h->htable), GFP_KERNEL);
+               if (!h->htable)
+                       return -ENOMEM;
+               h->size = size;
+       }
+       return 0;
 }
 
 int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst,
index b9ac9e9..10a0bff 100644 (file)
@@ -299,6 +299,15 @@ static const struct config_entry config_table[] = {
        },
 #endif
 
+/* JasperLake */
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE)
+       {
+               .flags = FLAG_SOF,
+               .device = 0x4dc8,
+               .codec_hid = "ESSX8336",
+       },
+#endif
+
 /* Tigerlake */
 #if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE)
        {
index ea20236..9a678b5 100644 (file)
@@ -3218,7 +3218,6 @@ static int snd_cmipci_probe(struct pci_dev *pci,
 {
        static int dev;
        struct snd_card *card;
-       struct cmipci *cm;
        int err;
 
        if (dev >= SNDRV_CARDS)
@@ -3229,10 +3228,9 @@ static int snd_cmipci_probe(struct pci_dev *pci,
        }
 
        err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
-                               sizeof(*cm), &card);
+                               sizeof(struct cmipci), &card);
        if (err < 0)
                return err;
-       cm = card->private_data;
        
        switch (pci->device) {
        case PCI_DEVICE_ID_CMEDIA_CM8738:
index da6e635..d074727 100644 (file)
 
 #define BLANK_SLOT             4094
 
-static int amixer_master(struct rsc *rsc)
+static void amixer_master(struct rsc *rsc)
 {
        rsc->conj = 0;
-       return rsc->idx = container_of(rsc, struct amixer, rsc)->idx[0];
+       rsc->idx = container_of(rsc, struct amixer, rsc)->idx[0];
 }
 
-static int amixer_next_conj(struct rsc *rsc)
+static void amixer_next_conj(struct rsc *rsc)
 {
        rsc->conj++;
-       return container_of(rsc, struct amixer, rsc)->idx[rsc->conj];
 }
 
 static int amixer_index(const struct rsc *rsc)
@@ -331,16 +330,15 @@ int amixer_mgr_destroy(struct amixer_mgr *amixer_mgr)
 
 /* SUM resource management */
 
-static int sum_master(struct rsc *rsc)
+static void sum_master(struct rsc *rsc)
 {
        rsc->conj = 0;
-       return rsc->idx = container_of(rsc, struct sum, rsc)->idx[0];
+       rsc->idx = container_of(rsc, struct sum, rsc)->idx[0];
 }
 
-static int sum_next_conj(struct rsc *rsc)
+static void sum_next_conj(struct rsc *rsc)
 {
        rsc->conj++;
-       return container_of(rsc, struct sum, rsc)->idx[rsc->conj];
 }
 
 static int sum_index(const struct rsc *rsc)
index f589da0..7fc7200 100644 (file)
@@ -51,12 +51,12 @@ static const struct daio_rsc_idx idx_20k2[NUM_DAIOTYP] = {
        [SPDIFIO] = {.left = 0x05, .right = 0x85},
 };
 
-static int daio_master(struct rsc *rsc)
+static void daio_master(struct rsc *rsc)
 {
        /* Actually, this is not the resource index of DAIO.
         * For DAO, it is the input mapper index. And, for DAI,
         * it is the output time-slot index. */
-       return rsc->conj = rsc->idx;
+       rsc->conj = rsc->idx;
 }
 
 static int daio_index(const struct rsc *rsc)
@@ -64,19 +64,19 @@ static int daio_index(const struct rsc *rsc)
        return rsc->conj;
 }
 
-static int daio_out_next_conj(struct rsc *rsc)
+static void daio_out_next_conj(struct rsc *rsc)
 {
-       return rsc->conj += 2;
+       rsc->conj += 2;
 }
 
-static int daio_in_next_conj_20k1(struct rsc *rsc)
+static void daio_in_next_conj_20k1(struct rsc *rsc)
 {
-       return rsc->conj += 0x200;
+       rsc->conj += 0x200;
 }
 
-static int daio_in_next_conj_20k2(struct rsc *rsc)
+static void daio_in_next_conj_20k2(struct rsc *rsc)
 {
-       return rsc->conj += 0x100;
+       rsc->conj += 0x100;
 }
 
 static const struct rsc_ops daio_out_rsc_ops = {
index 81ad269..be1d3e6 100644 (file)
@@ -109,18 +109,17 @@ static int audio_ring_slot(const struct rsc *rsc)
     return (rsc->conj << 4) + offset_in_audio_slot_block[rsc->type];
 }
 
-static int rsc_next_conj(struct rsc *rsc)
+static void rsc_next_conj(struct rsc *rsc)
 {
        unsigned int i;
        for (i = 0; (i < 8) && (!(rsc->msr & (0x1 << i))); )
                i++;
        rsc->conj += (AUDIO_SLOT_BLOCK_NUM >> i);
-       return rsc->conj;
 }
 
-static int rsc_master(struct rsc *rsc)
+static void rsc_master(struct rsc *rsc)
 {
-       return rsc->conj = rsc->idx;
+       rsc->conj = rsc->idx;
 }
 
 static const struct rsc_ops rsc_generic_ops = {
index fdbfd80..58553bd 100644 (file)
@@ -39,8 +39,8 @@ struct rsc {
 };
 
 struct rsc_ops {
-       int (*master)(struct rsc *rsc); /* Move to master resource */
-       int (*next_conj)(struct rsc *rsc); /* Move to next conjugate resource */
+       void (*master)(struct rsc *rsc); /* Move to master resource */
+       void (*next_conj)(struct rsc *rsc); /* Move to next conjugate resource */
        int (*index)(const struct rsc *rsc); /* Return the index of resource */
        /* Return the output slot number */
        int (*output_slot)(const struct rsc *rsc);
index bd4697b..4a94b47 100644 (file)
@@ -590,16 +590,15 @@ int src_mgr_destroy(struct src_mgr *src_mgr)
 
 /* SRCIMP resource manager operations */
 
-static int srcimp_master(struct rsc *rsc)
+static void srcimp_master(struct rsc *rsc)
 {
        rsc->conj = 0;
-       return rsc->idx = container_of(rsc, struct srcimp, rsc)->idx[0];
+       rsc->idx = container_of(rsc, struct srcimp, rsc)->idx[0];
 }
 
-static int srcimp_next_conj(struct rsc *rsc)
+static void srcimp_next_conj(struct rsc *rsc)
 {
        rsc->conj++;
-       return container_of(rsc, struct srcimp, rsc)->idx[rsc->conj];
 }
 
 static int srcimp_index(const struct rsc *rsc)
index 2f1727f..9ce7457 100644 (file)
@@ -6521,6 +6521,27 @@ static void alc256_fixup_tongfang_reset_persistent_settings(struct hda_codec *co
        alc_write_coef_idx(codec, 0x45, 0x5089);
 }
 
+static const struct coef_fw alc233_fixup_no_audio_jack_coefs[] = {
+       WRITE_COEF(0x1a, 0x9003), WRITE_COEF(0x1b, 0x0e2b), WRITE_COEF(0x37, 0xfe06),
+       WRITE_COEF(0x38, 0x4981), WRITE_COEF(0x45, 0xd489), WRITE_COEF(0x46, 0x0074),
+       WRITE_COEF(0x49, 0x0149),
+       {}
+};
+
+static void alc233_fixup_no_audio_jack(struct hda_codec *codec,
+                                      const struct hda_fixup *fix,
+                                      int action)
+{
+       /*
+        * The audio jack input and output is not detected on the ASRock NUC Box
+        * 1100 series when cold booting without this fix. Warm rebooting from a
+        * certain other OS makes the audio functional, as COEF settings are
+        * preserved in this case. This fix sets these altered COEF values as
+        * the default.
+        */
+       alc_process_coef_fw(codec, alc233_fixup_no_audio_jack_coefs);
+}
+
 enum {
        ALC269_FIXUP_GPIO2,
        ALC269_FIXUP_SONY_VAIO,
@@ -6740,6 +6761,7 @@ enum {
        ALC287_FIXUP_13S_GEN2_SPEAKERS,
        ALC256_FIXUP_TONGFANG_RESET_PERSISTENT_SETTINGS,
        ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
+       ALC233_FIXUP_NO_AUDIO_JACK,
 };
 
 static const struct hda_fixup alc269_fixups[] = {
@@ -8460,6 +8482,10 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
        },
+       [ALC233_FIXUP_NO_AUDIO_JACK] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc233_fixup_no_audio_jack,
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -8639,6 +8665,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x8728, "HP EliteBook 840 G7", ALC285_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8729, "HP", ALC285_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8730, "HP ProBook 445 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+       SND_PCI_QUIRK(0x103c, 0x8735, "HP ProBook 435 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
        SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_AMP_INIT),
        SND_PCI_QUIRK(0x103c, 0x8760, "HP", ALC285_FIXUP_HP_MUTE_LED),
        SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED),
@@ -8894,6 +8921,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
+       SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK),
        SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
        SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20),
        SND_PCI_QUIRK(0x1b35, 0x1236, "CZC TMI", ALC269_FIXUP_CZC_TMI),
index 94ed21d..9d0530d 100644 (file)
@@ -612,6 +612,12 @@ static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = {
        SND_SOC_DAPM_AIF_OUT("ASPTX3", NULL, 0, CS35L41_SP_ENABLES, 2, 0),
        SND_SOC_DAPM_AIF_OUT("ASPTX4", NULL, 0, CS35L41_SP_ENABLES, 3, 0),
 
+       SND_SOC_DAPM_SIGGEN("VSENSE"),
+       SND_SOC_DAPM_SIGGEN("ISENSE"),
+       SND_SOC_DAPM_SIGGEN("VP"),
+       SND_SOC_DAPM_SIGGEN("VBST"),
+       SND_SOC_DAPM_SIGGEN("TEMP"),
+
        SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L41_PWR_CTRL2, 12, 0),
        SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L41_PWR_CTRL2, 13, 0),
        SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L41_PWR_CTRL2, 8, 0),
@@ -623,12 +629,6 @@ static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = {
                               cs35l41_main_amp_event,
                               SND_SOC_DAPM_POST_PMD |  SND_SOC_DAPM_POST_PMU),
 
-       SND_SOC_DAPM_INPUT("VP"),
-       SND_SOC_DAPM_INPUT("VBST"),
-       SND_SOC_DAPM_INPUT("ISENSE"),
-       SND_SOC_DAPM_INPUT("VSENSE"),
-       SND_SOC_DAPM_INPUT("TEMP"),
-
        SND_SOC_DAPM_MUX("ASP TX1 Source", SND_SOC_NOPM, 0, 0, &asp_tx1_mux),
        SND_SOC_DAPM_MUX("ASP TX2 Source", SND_SOC_NOPM, 0, 0, &asp_tx2_mux),
        SND_SOC_DAPM_MUX("ASP TX3 Source", SND_SOC_NOPM, 0, 0, &asp_tx3_mux),
@@ -674,8 +674,8 @@ static const struct snd_soc_dapm_route cs35l41_audio_map[] = {
        {"VMON ADC", NULL, "VSENSE"},
        {"IMON ADC", NULL, "ISENSE"},
        {"VPMON ADC", NULL, "VP"},
-       {"TEMPMON ADC", NULL, "TEMP"},
        {"VBSTMON ADC", NULL, "VBST"},
+       {"TEMPMON ADC", NULL, "TEMP"},
 
        {"ASPRX1", NULL, "AMP Playback"},
        {"ASPRX2", NULL, "AMP Playback"},
index 2bed5cf..aec5127 100644 (file)
@@ -2188,7 +2188,7 @@ static int rx_macro_config_classh(struct snd_soc_component *component,
                snd_soc_component_update_bits(component,
                                CDC_RX_CLSH_DECAY_CTRL,
                                CDC_RX_CLSH_DECAY_RATE_MASK, 0x0);
-               snd_soc_component_update_bits(component,
+               snd_soc_component_write_field(component,
                                CDC_RX_RX1_RX_PATH_CFG0,
                                CDC_RX_RXn_CLSH_EN_MASK, 0x1);
                break;
index 297af7f..b62301a 100644 (file)
@@ -1311,13 +1311,54 @@ static int rt1011_r0_load_info(struct snd_kcontrol *kcontrol,
        .put = rt1011_r0_load_mode_put \
 }
 
-static const char * const rt1011_i2s_ref_texts[] = {
-       "Left Channel", "Right Channel"
+static const char * const rt1011_i2s_ref[] = {
+       "None", "Left Channel", "Right Channel"
 };
 
-static SOC_ENUM_SINGLE_DECL(rt1011_i2s_ref_enum,
-                           RT1011_TDM1_SET_1, 7,
-                           rt1011_i2s_ref_texts);
+static SOC_ENUM_SINGLE_DECL(rt1011_i2s_ref_enum, 0, 0,
+       rt1011_i2s_ref);
+
+static int rt1011_i2s_ref_put(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component =
+               snd_soc_kcontrol_component(kcontrol);
+       struct rt1011_priv *rt1011 =
+               snd_soc_component_get_drvdata(component);
+
+       rt1011->i2s_ref = ucontrol->value.enumerated.item[0];
+       switch (rt1011->i2s_ref) {
+       case RT1011_I2S_REF_LEFT_CH:
+               regmap_write(rt1011->regmap, RT1011_TDM_TOTAL_SET, 0x0240);
+               regmap_write(rt1011->regmap, RT1011_TDM1_SET_2, 0x8);
+               regmap_write(rt1011->regmap, RT1011_TDM1_SET_1, 0x1022);
+               regmap_write(rt1011->regmap, RT1011_ADCDAT_OUT_SOURCE, 0x4);
+               break;
+       case RT1011_I2S_REF_RIGHT_CH:
+               regmap_write(rt1011->regmap, RT1011_TDM_TOTAL_SET, 0x0240);
+               regmap_write(rt1011->regmap, RT1011_TDM1_SET_2, 0x8);
+               regmap_write(rt1011->regmap, RT1011_TDM1_SET_1, 0x10a2);
+               regmap_write(rt1011->regmap, RT1011_ADCDAT_OUT_SOURCE, 0x4);
+               break;
+       default:
+               dev_info(component->dev, "I2S Reference: Do nothing\n");
+       }
+
+       return 0;
+}
+
+static int rt1011_i2s_ref_get(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component =
+               snd_soc_kcontrol_component(kcontrol);
+       struct rt1011_priv *rt1011 =
+               snd_soc_component_get_drvdata(component);
+
+       ucontrol->value.enumerated.item[0] = rt1011->i2s_ref;
+
+       return 0;
+}
 
 static const struct snd_kcontrol_new rt1011_snd_controls[] = {
        /* I2S Data In Selection */
@@ -1358,7 +1399,8 @@ static const struct snd_kcontrol_new rt1011_snd_controls[] = {
        SOC_SINGLE("R0 Temperature", RT1011_STP_INITIAL_RESISTANCE_TEMP,
                2, 255, 0),
        /* I2S Reference */
-       SOC_ENUM("I2S Reference", rt1011_i2s_ref_enum),
+       SOC_ENUM_EXT("I2S Reference", rt1011_i2s_ref_enum,
+               rt1011_i2s_ref_get, rt1011_i2s_ref_put),
 };
 
 static int rt1011_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
@@ -2017,6 +2059,7 @@ static int rt1011_probe(struct snd_soc_component *component)
 
        schedule_work(&rt1011->cali_work);
 
+       rt1011->i2s_ref = 0;
        rt1011->bq_drc_params = devm_kcalloc(component->dev,
                RT1011_ADVMODE_NUM, sizeof(struct rt1011_bq_drc_params *),
                GFP_KERNEL);
index 68fadc1..4d6e749 100644 (file)
@@ -654,6 +654,12 @@ enum {
        RT1011_AIFS
 };
 
+enum {
+       RT1011_I2S_REF_NONE,
+       RT1011_I2S_REF_LEFT_CH,
+       RT1011_I2S_REF_RIGHT_CH,
+};
+
 /* BiQual & DRC related settings */
 #define RT1011_BQ_DRC_NUM 128
 struct rt1011_bq_drc_params {
@@ -692,6 +698,7 @@ struct rt1011_priv {
        unsigned int r0_reg, cali_done;
        unsigned int r0_calib, temperature_calib;
        int recv_spk_mode;
+       int i2s_ref;
 };
 
 #endif         /* end of _RT1011_H_ */
index 983347b..20e0f90 100644 (file)
@@ -198,6 +198,7 @@ static int rt5682_i2c_probe(struct i2c_client *i2c,
        }
 
        mutex_init(&rt5682->calibrate_mutex);
+       mutex_init(&rt5682->jdet_mutex);
        rt5682_calibrate(rt5682);
 
        rt5682_apply_patch_list(rt5682, &i2c->dev);
index 78b4cb5..04cb747 100644 (file)
@@ -48,6 +48,8 @@ static const struct reg_sequence patch_list[] = {
        {RT5682_SAR_IL_CMD_6, 0x0110},
        {RT5682_CHARGE_PUMP_1, 0x0210},
        {RT5682_HP_LOGIC_CTRL_2, 0x0007},
+       {RT5682_SAR_IL_CMD_2, 0xac00},
+       {RT5682_CBJ_CTRL_7, 0x0104},
 };
 
 void rt5682_apply_patch_list(struct rt5682_priv *rt5682, struct device *dev)
@@ -940,6 +942,10 @@ int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert)
                snd_soc_component_update_bits(component,
                        RT5682_HP_CHARGE_PUMP_1,
                        RT5682_OSW_L_MASK | RT5682_OSW_R_MASK, 0);
+               rt5682_enable_push_button_irq(component, false);
+               snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1,
+                       RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_LOW);
+               usleep_range(55000, 60000);
                snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1,
                        RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_HIGH);
 
@@ -1092,6 +1098,7 @@ void rt5682_jack_detect_handler(struct work_struct *work)
        while (!rt5682->component->card->instantiated)
                usleep_range(10000, 15000);
 
+       mutex_lock(&rt5682->jdet_mutex);
        mutex_lock(&rt5682->calibrate_mutex);
 
        val = snd_soc_component_read(rt5682->component, RT5682_AJD1_CTRL)
@@ -1165,6 +1172,7 @@ void rt5682_jack_detect_handler(struct work_struct *work)
        }
 
        mutex_unlock(&rt5682->calibrate_mutex);
+       mutex_unlock(&rt5682->jdet_mutex);
 }
 EXPORT_SYMBOL_GPL(rt5682_jack_detect_handler);
 
@@ -1514,6 +1522,7 @@ static int rt5682_hp_event(struct snd_soc_dapm_widget *w,
 {
        struct snd_soc_component *component =
                snd_soc_dapm_to_component(w->dapm);
+       struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
@@ -1525,12 +1534,17 @@ static int rt5682_hp_event(struct snd_soc_dapm_widget *w,
                        RT5682_DEPOP_1, 0x60, 0x60);
                snd_soc_component_update_bits(component,
                        RT5682_DAC_ADC_DIG_VOL1, 0x00c0, 0x0080);
+
+               mutex_lock(&rt5682->jdet_mutex);
+
                snd_soc_component_update_bits(component, RT5682_HP_CTRL_2,
                        RT5682_HP_C2_DAC_L_EN | RT5682_HP_C2_DAC_R_EN,
                        RT5682_HP_C2_DAC_L_EN | RT5682_HP_C2_DAC_R_EN);
                usleep_range(5000, 10000);
                snd_soc_component_update_bits(component, RT5682_CHARGE_PUMP_1,
                        RT5682_CP_SW_SIZE_MASK, RT5682_CP_SW_SIZE_L);
+
+               mutex_unlock(&rt5682->jdet_mutex);
                break;
 
        case SND_SOC_DAPM_POST_PMD:
@@ -2942,10 +2956,7 @@ static int rt5682_suspend(struct snd_soc_component *component)
 
        cancel_delayed_work_sync(&rt5682->jack_detect_work);
        cancel_delayed_work_sync(&rt5682->jd_check_work);
-       if (rt5682->hs_jack && rt5682->jack_type == SND_JACK_HEADSET) {
-               snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1,
-                       RT5682_MB1_PATH_MASK | RT5682_MB2_PATH_MASK,
-                       RT5682_CTRL_MB1_REG | RT5682_CTRL_MB2_REG);
+       if (rt5682->hs_jack && (rt5682->jack_type & SND_JACK_HEADSET) == SND_JACK_HEADSET) {
                val = snd_soc_component_read(component,
                                RT5682_CBJ_CTRL_2) & RT5682_JACK_TYPE_MASK;
 
@@ -2967,10 +2978,17 @@ static int rt5682_suspend(struct snd_soc_component *component)
                /* enter SAR ADC power saving mode */
                snd_soc_component_update_bits(component, RT5682_SAR_IL_CMD_1,
                        RT5682_SAR_BUTT_DET_MASK | RT5682_SAR_BUTDET_MODE_MASK |
-                       RT5682_SAR_BUTDET_RST_MASK | RT5682_SAR_SEL_MB1_MB2_MASK, 0);
+                       RT5682_SAR_SEL_MB1_MB2_MASK, 0);
+               usleep_range(5000, 6000);
+               snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1,
+                       RT5682_MB1_PATH_MASK | RT5682_MB2_PATH_MASK,
+                       RT5682_CTRL_MB1_REG | RT5682_CTRL_MB2_REG);
+               usleep_range(10000, 12000);
                snd_soc_component_update_bits(component, RT5682_SAR_IL_CMD_1,
-                       RT5682_SAR_BUTT_DET_MASK | RT5682_SAR_BUTDET_MODE_MASK | RT5682_SAR_BUTDET_RST_MASK,
-                       RT5682_SAR_BUTT_DET_EN | RT5682_SAR_BUTDET_POW_SAV | RT5682_SAR_BUTDET_RST_NORMAL);
+                       RT5682_SAR_BUTT_DET_MASK | RT5682_SAR_BUTDET_MODE_MASK,
+                       RT5682_SAR_BUTT_DET_EN | RT5682_SAR_BUTDET_POW_SAV);
+               snd_soc_component_update_bits(component, RT5682_HP_CHARGE_PUMP_1,
+                       RT5682_OSW_L_MASK | RT5682_OSW_R_MASK, 0);
        }
 
        regcache_cache_only(rt5682->regmap, true);
@@ -2988,10 +3006,11 @@ static int rt5682_resume(struct snd_soc_component *component)
        regcache_cache_only(rt5682->regmap, false);
        regcache_sync(rt5682->regmap);
 
-       if (rt5682->hs_jack && rt5682->jack_type == SND_JACK_HEADSET) {
+       if (rt5682->hs_jack && (rt5682->jack_type & SND_JACK_HEADSET) == SND_JACK_HEADSET) {
                snd_soc_component_update_bits(component, RT5682_SAR_IL_CMD_1,
                        RT5682_SAR_BUTDET_MODE_MASK | RT5682_SAR_SEL_MB1_MB2_MASK,
                        RT5682_SAR_BUTDET_POW_NORM | RT5682_SAR_SEL_MB1_MB2_AUTO);
+               usleep_range(5000, 6000);
                snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1,
                        RT5682_MB1_PATH_MASK | RT5682_MB2_PATH_MASK,
                        RT5682_CTRL_MB1_FSM | RT5682_CTRL_MB2_FSM);
@@ -2999,8 +3018,9 @@ static int rt5682_resume(struct snd_soc_component *component)
                        RT5682_PWR_CBJ, RT5682_PWR_CBJ);
        }
 
+       rt5682->jack_type = 0;
        mod_delayed_work(system_power_efficient_wq,
-               &rt5682->jack_detect_work, msecs_to_jiffies(250));
+               &rt5682->jack_detect_work, msecs_to_jiffies(0));
 
        return 0;
 }
index d93829c..c917c76 100644 (file)
@@ -1463,6 +1463,7 @@ struct rt5682_priv {
 
        int jack_type;
        int irq_work_delay_time;
+       struct mutex jdet_mutex;
 };
 
 extern const char *rt5682_supply_names[RT5682_NUM_SUPPLIES];
index f957498..7aa1772 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include <linux/bits.h>
+#include <linux/bitfield.h>
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #define RT9120_REG_ERRRPT      0x10
 #define RT9120_REG_MSVOL       0x20
 #define RT9120_REG_SWRESET     0x40
+#define RT9120_REG_INTERCFG    0x63
 #define RT9120_REG_INTERNAL0   0x65
 #define RT9120_REG_INTERNAL1   0x69
 #define RT9120_REG_UVPOPT      0x6C
+#define RT9120_REG_DIGCFG      0xF8
 
 #define RT9120_VID_MASK                GENMASK(15, 8)
 #define RT9120_SWRST_MASK      BIT(7)
 #define RT9120_CFG_WORDLEN_24  24
 #define RT9120_CFG_WORDLEN_32  32
 #define RT9120_DVDD_UVSEL_MASK GENMASK(5, 4)
+#define RT9120_AUTOSYNC_MASK   BIT(6)
 
-#define RT9120_VENDOR_ID       0x4200
+#define RT9120_VENDOR_ID       0x42
+#define RT9120S_VENDOR_ID      0x43
 #define RT9120_RESET_WAITMS    20
 #define RT9120_CHIPON_WAITMS   20
 #define RT9120_AMPON_WAITMS    50
                                 SNDRV_PCM_FMTBIT_S24_LE |\
                                 SNDRV_PCM_FMTBIT_S32_LE)
 
+enum {
+       CHIP_IDX_RT9120 = 0,
+       CHIP_IDX_RT9120S,
+       CHIP_IDX_MAX
+};
+
 struct rt9120_data {
        struct device *dev;
        struct regmap *regmap;
+       int chip_idx;
 };
 
 /* 11bit [min,max,step] = [-103.9375dB, 24dB, 0.0625dB] */
@@ -149,8 +161,12 @@ static int rt9120_codec_probe(struct snd_soc_component *comp)
        snd_soc_component_init_regmap(comp, data->regmap);
 
        /* Internal setting */
-       snd_soc_component_write(comp, RT9120_REG_INTERNAL1, 0x03);
-       snd_soc_component_write(comp, RT9120_REG_INTERNAL0, 0x69);
+       if (data->chip_idx == CHIP_IDX_RT9120S) {
+               snd_soc_component_write(comp, RT9120_REG_INTERCFG, 0xde);
+               snd_soc_component_write(comp, RT9120_REG_INTERNAL0, 0x66);
+       } else
+               snd_soc_component_write(comp, RT9120_REG_INTERNAL0, 0x04);
+
        return 0;
 }
 
@@ -201,8 +217,8 @@ static int rt9120_hw_params(struct snd_pcm_substream *substream,
                            struct snd_soc_dai *dai)
 {
        struct snd_soc_component *comp = dai->component;
-       unsigned int param_width, param_slot_width;
-       int width;
+       unsigned int param_width, param_slot_width, auto_sync;
+       int width, fs;
 
        switch (width = params_width(param)) {
        case 16:
@@ -240,6 +256,16 @@ static int rt9120_hw_params(struct snd_pcm_substream *substream,
 
        snd_soc_component_update_bits(comp, RT9120_REG_I2SWL,
                                      RT9120_AUDWL_MASK, param_slot_width);
+
+       fs = width * params_channels(param);
+       /* If fs is divided by 48, disable auto sync */
+       if (fs % 48 == 0)
+               auto_sync = 0;
+       else
+               auto_sync = RT9120_AUTOSYNC_MASK;
+
+       snd_soc_component_update_bits(comp, RT9120_REG_DIGCFG,
+                                     RT9120_AUTOSYNC_MASK, auto_sync);
        return 0;
 }
 
@@ -279,9 +305,11 @@ static const struct regmap_range rt9120_rd_yes_ranges[] = {
        regmap_reg_range(0x20, 0x27),
        regmap_reg_range(0x30, 0x38),
        regmap_reg_range(0x3A, 0x40),
+       regmap_reg_range(0x63, 0x63),
        regmap_reg_range(0x65, 0x65),
        regmap_reg_range(0x69, 0x69),
-       regmap_reg_range(0x6C, 0x6C)
+       regmap_reg_range(0x6C, 0x6C),
+       regmap_reg_range(0xF8, 0xF8)
 };
 
 static const struct regmap_access_table rt9120_rd_table = {
@@ -297,9 +325,11 @@ static const struct regmap_range rt9120_wr_yes_ranges[] = {
        regmap_reg_range(0x30, 0x38),
        regmap_reg_range(0x3A, 0x3D),
        regmap_reg_range(0x40, 0x40),
+       regmap_reg_range(0x63, 0x63),
        regmap_reg_range(0x65, 0x65),
        regmap_reg_range(0x69, 0x69),
-       regmap_reg_range(0x6C, 0x6C)
+       regmap_reg_range(0x6C, 0x6C),
+       regmap_reg_range(0xF8, 0xF8)
 };
 
 static const struct regmap_access_table rt9120_wr_table = {
@@ -370,7 +400,7 @@ static int rt9120_reg_write(void *context, unsigned int reg, unsigned int val)
 static const struct regmap_config rt9120_regmap_config = {
        .reg_bits = 8,
        .val_bits = 32,
-       .max_register = RT9120_REG_UVPOPT,
+       .max_register = RT9120_REG_DIGCFG,
 
        .reg_read = rt9120_reg_read,
        .reg_write = rt9120_reg_write,
@@ -388,8 +418,16 @@ static int rt9120_check_vendor_info(struct rt9120_data *data)
        if (ret)
                return ret;
 
-       if ((devid & RT9120_VID_MASK) != RT9120_VENDOR_ID) {
-               dev_err(data->dev, "DEVID not correct [0x%04x]\n", devid);
+       devid = FIELD_GET(RT9120_VID_MASK, devid);
+       switch (devid) {
+       case RT9120_VENDOR_ID:
+               data->chip_idx = CHIP_IDX_RT9120;
+               break;
+       case RT9120S_VENDOR_ID:
+               data->chip_idx = CHIP_IDX_RT9120S;
+               break;
+       default:
+               dev_err(data->dev, "DEVID not correct [0x%0x]\n", devid);
                return -ENODEV;
        }
 
index c496b35..4f568ab 100644 (file)
@@ -1896,9 +1896,8 @@ static int wcd934x_hw_params(struct snd_pcm_substream *substream,
        }
 
        wcd->dai[dai->id].sconfig.rate = params_rate(params);
-       wcd934x_slim_set_hw_params(wcd, &wcd->dai[dai->id], substream->stream);
 
-       return 0;
+       return wcd934x_slim_set_hw_params(wcd, &wcd->dai[dai->id], substream->stream);
 }
 
 static int wcd934x_hw_free(struct snd_pcm_substream *substream,
index 52de7d1..67151c7 100644 (file)
@@ -1174,6 +1174,9 @@ static bool wcd938x_readonly_register(struct device *dev, unsigned int reg)
        case WCD938X_DIGITAL_INTR_STATUS_0:
        case WCD938X_DIGITAL_INTR_STATUS_1:
        case WCD938X_DIGITAL_INTR_STATUS_2:
+       case WCD938X_DIGITAL_INTR_CLEAR_0:
+       case WCD938X_DIGITAL_INTR_CLEAR_1:
+       case WCD938X_DIGITAL_INTR_CLEAR_2:
        case WCD938X_DIGITAL_SWR_HM_TEST_0:
        case WCD938X_DIGITAL_SWR_HM_TEST_1:
        case WCD938X_DIGITAL_EFUSE_T_DATA_0:
index d4f0d72..6cb01a8 100644 (file)
@@ -617,8 +617,9 @@ static int wm_adsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl)
        switch (cs_dsp->fw_ver) {
        case 0:
        case 1:
-               snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s %x",
-                        cs_dsp->name, region_name, cs_ctl->alg_region.alg);
+               ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
+                               "%s %s %x", cs_dsp->name, region_name,
+                               cs_ctl->alg_region.alg);
                break;
        case 2:
                ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
index f104962..77219c3 100644 (file)
@@ -248,6 +248,75 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
                                        SOF_BT_OFFLOAD_SSP(2) |
                                        SOF_SSP_BT_OFFLOAD_PRESENT),
        },
+       {
+               .callback = sof_sdw_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AF3"),
+               },
+               /* No Jack */
+               .driver_data = (void *)(SOF_SDW_TGL_HDMI |
+                                       SOF_SDW_FOUR_SPK),
+       },
+       {
+               .callback = sof_sdw_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B00")
+               },
+               .driver_data = (void *)(SOF_SDW_TGL_HDMI |
+                                       RT711_JD2 |
+                                       SOF_SDW_FOUR_SPK),
+       },
+       {
+               .callback = sof_sdw_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B01")
+               },
+               .driver_data = (void *)(SOF_SDW_TGL_HDMI |
+                                       RT711_JD2 |
+                                       SOF_SDW_FOUR_SPK),
+       },
+       {
+               .callback = sof_sdw_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B11")
+               },
+               .driver_data = (void *)(SOF_SDW_TGL_HDMI |
+                                       RT711_JD2 |
+                                       SOF_SDW_FOUR_SPK),
+       },
+       {
+               .callback = sof_sdw_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B12")
+               },
+               .driver_data = (void *)(SOF_SDW_TGL_HDMI |
+                                       RT711_JD2 |
+                                       SOF_SDW_FOUR_SPK),
+       },
+       {
+               .callback = sof_sdw_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B13"),
+               },
+               /* No Jack */
+               .driver_data = (void *)SOF_SDW_TGL_HDMI,
+       },
+       {
+               .callback = sof_sdw_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B29"),
+               },
+               .driver_data = (void *)(SOF_SDW_TGL_HDMI |
+                                       RT711_JD2 |
+                                       SOF_SDW_FOUR_SPK),
+       },
        {}
 };
 
index 06f5034..b61a778 100644 (file)
@@ -74,6 +74,15 @@ static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = {
        }
 };
 
+static const struct snd_soc_acpi_adr_device rt711_sdca_2_adr[] = {
+       {
+               .adr = 0x000230025D071101ull,
+               .num_endpoints = 1,
+               .endpoints = &single_endpoint,
+               .name_prefix = "rt711"
+       }
+};
+
 static const struct snd_soc_acpi_adr_device rt1316_1_group1_adr[] = {
        {
                .adr = 0x000131025D131601ull, /* unique ID is set for some reason */
@@ -101,6 +110,24 @@ static const struct snd_soc_acpi_adr_device rt1316_3_group1_adr[] = {
        }
 };
 
+static const struct snd_soc_acpi_adr_device rt1316_0_group2_adr[] = {
+       {
+               .adr = 0x000031025D131601ull,
+               .num_endpoints = 1,
+               .endpoints = &spk_l_endpoint,
+               .name_prefix = "rt1316-1"
+       }
+};
+
+static const struct snd_soc_acpi_adr_device rt1316_1_group2_adr[] = {
+       {
+               .adr = 0x000130025D131601ull,
+               .num_endpoints = 1,
+               .endpoints = &spk_r_endpoint,
+               .name_prefix = "rt1316-2"
+       }
+};
+
 static const struct snd_soc_acpi_adr_device rt1316_2_single_adr[] = {
        {
                .adr = 0x000230025D131601ull,
@@ -209,6 +236,63 @@ static const struct snd_soc_acpi_link_adr adl_sdca_3_in_1[] = {
        {}
 };
 
+static const struct snd_soc_acpi_link_adr adl_sdw_rt711_link2_rt1316_link01_rt714_link3[] = {
+       {
+               .mask = BIT(2),
+               .num_adr = ARRAY_SIZE(rt711_sdca_2_adr),
+               .adr_d = rt711_sdca_2_adr,
+       },
+       {
+               .mask = BIT(0),
+               .num_adr = ARRAY_SIZE(rt1316_0_group2_adr),
+               .adr_d = rt1316_0_group2_adr,
+       },
+       {
+               .mask = BIT(1),
+               .num_adr = ARRAY_SIZE(rt1316_1_group2_adr),
+               .adr_d = rt1316_1_group2_adr,
+       },
+       {
+               .mask = BIT(3),
+               .num_adr = ARRAY_SIZE(rt714_3_adr),
+               .adr_d = rt714_3_adr,
+       },
+       {}
+};
+
+static const struct snd_soc_acpi_link_adr adl_sdw_rt1316_link12_rt714_link0[] = {
+       {
+               .mask = BIT(1),
+               .num_adr = ARRAY_SIZE(rt1316_1_group1_adr),
+               .adr_d = rt1316_1_group1_adr,
+       },
+       {
+               .mask = BIT(2),
+               .num_adr = ARRAY_SIZE(rt1316_2_group1_adr),
+               .adr_d = rt1316_2_group1_adr,
+       },
+       {
+               .mask = BIT(0),
+               .num_adr = ARRAY_SIZE(rt714_0_adr),
+               .adr_d = rt714_0_adr,
+       },
+       {}
+};
+
+static const struct snd_soc_acpi_link_adr adl_sdw_rt1316_link2_rt714_link3[] = {
+       {
+               .mask = BIT(2),
+               .num_adr = ARRAY_SIZE(rt1316_2_single_adr),
+               .adr_d = rt1316_2_single_adr,
+       },
+       {
+               .mask = BIT(3),
+               .num_adr = ARRAY_SIZE(rt714_3_adr),
+               .adr_d = rt714_3_adr,
+       },
+       {}
+};
+
 static const struct snd_soc_acpi_link_adr adl_sdw_rt1316_link2_rt714_link0[] = {
        {
                .mask = BIT(2),
@@ -339,6 +423,27 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = {
                .drv_name = "sof_sdw",
                .sof_tplg_filename = "sof-adl-rt711-l0-rt1316-l13-rt714-l2.tplg",
        },
+       {
+               .link_mask = 0xF, /* 4 active links required */
+               .links = adl_sdw_rt711_link2_rt1316_link01_rt714_link3,
+               .drv_name = "sof_sdw",
+               .sof_fw_filename = "sof-adl.ri",
+               .sof_tplg_filename = "sof-adl-rt711-l2-rt1316-l01-rt714-l3.tplg",
+       },
+       {
+               .link_mask = 0xC, /* rt1316 on link2 & rt714 on link3 */
+               .links = adl_sdw_rt1316_link2_rt714_link3,
+               .drv_name = "sof_sdw",
+               .sof_fw_filename = "sof-adl.ri",
+               .sof_tplg_filename = "sof-adl-rt1316-l2-mono-rt714-l3.tplg",
+       },
+       {
+               .link_mask = 0x7, /* rt714 on link0 & two rt1316s on link1 and link2 */
+               .links = adl_sdw_rt1316_link12_rt714_link0,
+               .drv_name = "sof_sdw",
+               .sof_fw_filename = "sof-adl.ri",
+               .sof_tplg_filename = "sof-adl-rt1316-l12-rt714-l0.tplg",
+       },
        {
                .link_mask = 0x5, /* 2 active links required */
                .links = adl_sdw_rt1316_link2_rt714_link0,
index 6350390..3149493 100644 (file)
@@ -1054,6 +1054,7 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
        int irq_id;
        struct mtk_base_afe *afe;
        struct mt8173_afe_private *afe_priv;
+       struct snd_soc_component *comp_pcm, *comp_hdmi;
 
        ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33));
        if (ret)
@@ -1142,23 +1143,55 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
        if (ret)
                goto err_pm_disable;
 
-       ret = devm_snd_soc_register_component(&pdev->dev,
-                                        &mt8173_afe_pcm_dai_component,
-                                        mt8173_afe_pcm_dais,
-                                        ARRAY_SIZE(mt8173_afe_pcm_dais));
+       comp_pcm = devm_kzalloc(&pdev->dev, sizeof(*comp_pcm), GFP_KERNEL);
+       if (!comp_pcm) {
+               ret = -ENOMEM;
+               goto err_pm_disable;
+       }
+
+       ret = snd_soc_component_initialize(comp_pcm,
+                                          &mt8173_afe_pcm_dai_component,
+                                          &pdev->dev);
        if (ret)
                goto err_pm_disable;
 
-       ret = devm_snd_soc_register_component(&pdev->dev,
-                                        &mt8173_afe_hdmi_dai_component,
-                                        mt8173_afe_hdmi_dais,
-                                        ARRAY_SIZE(mt8173_afe_hdmi_dais));
+#ifdef CONFIG_DEBUG_FS
+       comp_pcm->debugfs_prefix = "pcm";
+#endif
+
+       ret = snd_soc_add_component(comp_pcm,
+                                   mt8173_afe_pcm_dais,
+                                   ARRAY_SIZE(mt8173_afe_pcm_dais));
+       if (ret)
+               goto err_pm_disable;
+
+       comp_hdmi = devm_kzalloc(&pdev->dev, sizeof(*comp_hdmi), GFP_KERNEL);
+       if (!comp_hdmi) {
+               ret = -ENOMEM;
+               goto err_pm_disable;
+       }
+
+       ret = snd_soc_component_initialize(comp_hdmi,
+                                          &mt8173_afe_hdmi_dai_component,
+                                          &pdev->dev);
        if (ret)
                goto err_pm_disable;
 
+#ifdef CONFIG_DEBUG_FS
+       comp_hdmi->debugfs_prefix = "hdmi";
+#endif
+
+       ret = snd_soc_add_component(comp_hdmi,
+                                   mt8173_afe_hdmi_dais,
+                                   ARRAY_SIZE(mt8173_afe_hdmi_dais));
+       if (ret)
+               goto err_cleanup_components;
+
        dev_info(&pdev->dev, "MT8173 AFE driver initialized.\n");
        return 0;
 
+err_cleanup_components:
+       snd_soc_unregister_component(&pdev->dev);
 err_pm_disable:
        pm_runtime_disable(&pdev->dev);
        return ret;
@@ -1166,6 +1199,8 @@ err_pm_disable:
 
 static int mt8173_afe_pcm_dev_remove(struct platform_device *pdev)
 {
+       snd_soc_unregister_component(&pdev->dev);
+
        pm_runtime_disable(&pdev->dev);
        if (!pm_runtime_status_suspended(&pdev->dev))
                mt8173_afe_runtime_suspend(&pdev->dev);
index c28ebf8..2cbf679 100644 (file)
@@ -30,15 +30,15 @@ static struct mt8173_rt5650_platform_data mt8173_rt5650_priv = {
 };
 
 static const struct snd_soc_dapm_widget mt8173_rt5650_widgets[] = {
-       SND_SOC_DAPM_SPK("Speaker", NULL),
+       SND_SOC_DAPM_SPK("Ext Spk", NULL),
        SND_SOC_DAPM_MIC("Int Mic", NULL),
        SND_SOC_DAPM_HP("Headphone", NULL),
        SND_SOC_DAPM_MIC("Headset Mic", NULL),
 };
 
 static const struct snd_soc_dapm_route mt8173_rt5650_routes[] = {
-       {"Speaker", NULL, "SPOL"},
-       {"Speaker", NULL, "SPOR"},
+       {"Ext Spk", NULL, "SPOL"},
+       {"Ext Spk", NULL, "SPOR"},
        {"DMIC L1", NULL, "Int Mic"},
        {"DMIC R1", NULL, "Int Mic"},
        {"Headphone", NULL, "HPOL"},
@@ -48,7 +48,7 @@ static const struct snd_soc_dapm_route mt8173_rt5650_routes[] = {
 };
 
 static const struct snd_kcontrol_new mt8173_rt5650_controls[] = {
-       SOC_DAPM_PIN_SWITCH("Speaker"),
+       SOC_DAPM_PIN_SWITCH("Ext Spk"),
        SOC_DAPM_PIN_SWITCH("Int Mic"),
        SOC_DAPM_PIN_SWITCH("Headphone"),
        SOC_DAPM_PIN_SWITCH("Headset Mic"),
index 4f693a2..3ee8bfc 100644 (file)
@@ -550,6 +550,10 @@ struct audio_hw_clk_cfg {
        uint32_t clock_root;
 } __packed;
 
+struct audio_hw_clk_rel_cfg {
+       uint32_t clock_id;
+} __packed;
+
 #define PARAM_ID_HW_EP_POWER_MODE_CFG  0x8001176
 #define AR_HW_EP_POWER_MODE_0  0 /* default */
 #define AR_HW_EP_POWER_MODE_1  1 /* XO Shutdown allowed */
index 3d831b6..72c5719 100644 (file)
@@ -390,7 +390,7 @@ struct q6copp *q6adm_open(struct device *dev, int port_id, int path, int rate,
        int ret = 0;
 
        if (port_id < 0) {
-               dev_err(dev, "Invalid port_id 0x%x\n", port_id);
+               dev_err(dev, "Invalid port_id %d\n", port_id);
                return ERR_PTR(-EINVAL);
        }
 
@@ -508,7 +508,7 @@ int q6adm_matrix_map(struct device *dev, int path,
                int port_idx = payload_map.port_id[i];
 
                if (port_idx < 0) {
-                       dev_err(dev, "Invalid port_id 0x%x\n",
+                       dev_err(dev, "Invalid port_id %d\n",
                                payload_map.port_id[i]);
                        kfree(pkt);
                        return -EINVAL;
index 46f3655..b74b677 100644 (file)
@@ -269,9 +269,7 @@ static int q6asm_dai_prepare(struct snd_soc_component *component,
 
        if (ret < 0) {
                dev_err(dev, "%s: q6asm_open_write failed\n", __func__);
-               q6asm_audio_client_free(prtd->audio_client);
-               prtd->audio_client = NULL;
-               return -ENOMEM;
+               goto open_err;
        }
 
        prtd->session_id = q6asm_get_session_id(prtd->audio_client);
@@ -279,7 +277,7 @@ static int q6asm_dai_prepare(struct snd_soc_component *component,
                              prtd->session_id, substream->stream);
        if (ret) {
                dev_err(dev, "%s: stream reg failed ret:%d\n", __func__, ret);
-               return ret;
+               goto routing_err;
        }
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -301,10 +299,19 @@ static int q6asm_dai_prepare(struct snd_soc_component *component,
        }
        if (ret < 0)
                dev_info(dev, "%s: CMD Format block failed\n", __func__);
+       else
+               prtd->state = Q6ASM_STREAM_RUNNING;
 
-       prtd->state = Q6ASM_STREAM_RUNNING;
+       return ret;
 
-       return 0;
+routing_err:
+       q6asm_cmd(prtd->audio_client, prtd->stream_id,  CMD_CLOSE);
+open_err:
+       q6asm_unmap_memory_regions(substream->stream, prtd->audio_client);
+       q6asm_audio_client_free(prtd->audio_client);
+       prtd->audio_client = NULL;
+
+       return ret;
 }
 
 static int q6asm_dai_trigger(struct snd_soc_component *component,
index 82c40f2..cda33de 100644 (file)
@@ -42,6 +42,12 @@ struct prm_cmd_request_rsc {
        struct audio_hw_clk_cfg clock_id;
 } __packed;
 
+struct prm_cmd_release_rsc {
+       struct apm_module_param_data param_data;
+       uint32_t num_clk_id;
+       struct audio_hw_clk_rel_cfg clock_id;
+} __packed;
+
 static int q6prm_send_cmd_sync(struct q6prm *prm, struct gpr_pkt *pkt, uint32_t rsp_opcode)
 {
        return audioreach_send_cmd_sync(prm->dev, prm->gdev, &prm->result, &prm->lock,
@@ -102,8 +108,8 @@ int q6prm_unvote_lpass_core_hw(struct device *dev, uint32_t hw_block_id, uint32_
 }
 EXPORT_SYMBOL_GPL(q6prm_unvote_lpass_core_hw);
 
-int q6prm_set_lpass_clock(struct device *dev, int clk_id, int clk_attr, int clk_root,
-                         unsigned int freq)
+static int q6prm_request_lpass_clock(struct device *dev, int clk_id, int clk_attr, int clk_root,
+                                    unsigned int freq)
 {
        struct q6prm *prm = dev_get_drvdata(dev->parent);
        struct apm_module_param_data *param_data;
@@ -138,6 +144,49 @@ int q6prm_set_lpass_clock(struct device *dev, int clk_id, int clk_attr, int clk_
 
        return rc;
 }
+
+static int q6prm_release_lpass_clock(struct device *dev, int clk_id, int clk_attr, int clk_root,
+                         unsigned int freq)
+{
+       struct q6prm *prm = dev_get_drvdata(dev->parent);
+       struct apm_module_param_data *param_data;
+       struct prm_cmd_release_rsc *rel;
+       gpr_device_t *gdev = prm->gdev;
+       struct gpr_pkt *pkt;
+       int rc;
+
+       pkt = audioreach_alloc_cmd_pkt(sizeof(*rel), PRM_CMD_RELEASE_HW_RSC, 0, gdev->svc.id,
+                                      GPR_PRM_MODULE_IID);
+       if (IS_ERR(pkt))
+               return PTR_ERR(pkt);
+
+       rel = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
+
+       param_data = &rel->param_data;
+
+       param_data->module_instance_id = GPR_PRM_MODULE_IID;
+       param_data->error_code = 0;
+       param_data->param_id = PARAM_ID_RSC_AUDIO_HW_CLK;
+       param_data->param_size = sizeof(*rel) - APM_MODULE_PARAM_DATA_SIZE;
+
+       rel->num_clk_id = 1;
+       rel->clock_id.clock_id = clk_id;
+
+       rc = q6prm_send_cmd_sync(prm, pkt, PRM_CMD_RSP_RELEASE_HW_RSC);
+
+       kfree(pkt);
+
+       return rc;
+}
+
+int q6prm_set_lpass_clock(struct device *dev, int clk_id, int clk_attr, int clk_root,
+                         unsigned int freq)
+{
+       if (freq)
+               return q6prm_request_lpass_clock(dev, clk_id, clk_attr, clk_attr, freq);
+
+       return q6prm_release_lpass_clock(dev, clk_id, clk_attr, clk_attr, freq);
+}
 EXPORT_SYMBOL_GPL(q6prm_set_lpass_clock);
 
 static int prm_callback(struct gpr_resp_pkt *data, void *priv, int op)
index 3390ebe..cd74681 100644 (file)
@@ -372,6 +372,12 @@ int q6routing_stream_open(int fedai_id, int perf_mode,
        }
 
        session = &routing_data->sessions[stream_id - 1];
+       if (session->port_id < 0) {
+               dev_err(routing_data->dev, "Routing not setup for MultiMedia%d Session\n",
+                       session->fedai_id);
+               return -EINVAL;
+       }
+
        pdata = &routing_data->port_data[session->port_id];
 
        mutex_lock(&routing_data->lock);
@@ -495,7 +501,11 @@ static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol,
                session->port_id = be_id;
                snd_soc_dapm_mixer_update_power(dapm, kcontrol, 1, update);
        } else {
-               session->port_id = -1;
+               if (session->port_id == be_id) {
+                       session->port_id = -1;
+                       return 0;
+               }
+
                snd_soc_dapm_mixer_update_power(dapm, kcontrol, 0, update);
        }
 
index 16c6e02..03e0d4e 100644 (file)
@@ -102,7 +102,7 @@ static int rsnd_dmaen_stop(struct rsnd_mod *mod,
        struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
 
        if (dmaen->chan)
-               dmaengine_terminate_sync(dmaen->chan);
+               dmaengine_terminate_async(dmaen->chan);
 
        return 0;
 }
index 2892b0a..b06c568 100644 (file)
@@ -2559,8 +2559,13 @@ static struct snd_soc_dapm_widget *dapm_find_widget(
        return NULL;
 }
 
-static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
-                               const char *pin, int status)
+/*
+ * set the DAPM pin status:
+ * returns 1 when the value has been updated, 0 when unchanged, or a negative
+ * error code; called from kcontrol put callback
+ */
+static int __snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
+                                 const char *pin, int status)
 {
        struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
        int ret = 0;
@@ -2586,6 +2591,18 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
        return ret;
 }
 
+/*
+ * similar as __snd_soc_dapm_set_pin(), but returns 0 when successful;
+ * called from several API functions below
+ */
+static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
+                               const char *pin, int status)
+{
+       int ret = __snd_soc_dapm_set_pin(dapm, pin, status);
+
+       return ret < 0 ? ret : 0;
+}
+
 /**
  * snd_soc_dapm_sync_unlocked - scan and power dapm paths
  * @dapm: DAPM context
@@ -3589,10 +3606,10 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
        const char *pin = (const char *)kcontrol->private_value;
        int ret;
 
-       if (ucontrol->value.integer.value[0])
-               ret = snd_soc_dapm_enable_pin(&card->dapm, pin);
-       else
-               ret = snd_soc_dapm_disable_pin(&card->dapm, pin);
+       mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
+       ret = __snd_soc_dapm_set_pin(&card->dapm, pin,
+                                    !!ucontrol->value.integer.value[0]);
+       mutex_unlock(&card->dapm_mutex);
 
        snd_soc_dapm_sync(&card->dapm);
        return ret;
index 557e22c..f5b9e66 100644 (file)
@@ -2700,6 +2700,7 @@ EXPORT_SYMBOL_GPL(snd_soc_tplg_component_load);
 /* remove dynamic controls from the component driver */
 int snd_soc_tplg_component_remove(struct snd_soc_component *comp)
 {
+       struct snd_card *card = comp->card->snd_card;
        struct snd_soc_dobj *dobj, *next_dobj;
        int pass = SOC_TPLG_PASS_END;
 
@@ -2707,6 +2708,7 @@ int snd_soc_tplg_component_remove(struct snd_soc_component *comp)
        while (pass >= SOC_TPLG_PASS_START) {
 
                /* remove mixer controls */
+               down_write(&card->controls_rwsem);
                list_for_each_entry_safe(dobj, next_dobj, &comp->dobj_list,
                        list) {
 
@@ -2745,6 +2747,7 @@ int snd_soc_tplg_component_remove(struct snd_soc_component *comp)
                                break;
                        }
                }
+               up_write(&card->controls_rwsem);
                pass--;
        }
 
index 6bb4db8..041c546 100644 (file)
@@ -47,7 +47,7 @@ config SND_SOC_SOF_OF
          Say Y if you need this option. If unsure select "N".
 
 config SND_SOC_SOF_COMPRESS
-       tristate
+       bool
        select SND_SOC_COMPRESS
 
 config SND_SOC_SOF_DEBUG_PROBES
index 58bb89a..bb1dfe4 100644 (file)
@@ -69,7 +69,7 @@ static void snd_sof_refresh_control(struct snd_sof_control *scontrol)
 {
        struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
        struct snd_soc_component *scomp = scontrol->scomp;
-       enum sof_ipc_ctrl_type ctrl_type;
+       u32 ipc_cmd;
        int ret;
 
        if (!scontrol->comp_data_dirty)
@@ -79,9 +79,9 @@ static void snd_sof_refresh_control(struct snd_sof_control *scontrol)
                return;
 
        if (scontrol->cmd == SOF_CTRL_CMD_BINARY)
-               ctrl_type = SOF_IPC_COMP_GET_DATA;
+               ipc_cmd = SOF_IPC_COMP_GET_DATA;
        else
-               ctrl_type = SOF_IPC_COMP_GET_VALUE;
+               ipc_cmd = SOF_IPC_COMP_GET_VALUE;
 
        /* set the ABI header values */
        cdata->data->magic = SOF_ABI_MAGIC;
@@ -89,7 +89,7 @@ static void snd_sof_refresh_control(struct snd_sof_control *scontrol)
 
        /* refresh the component data from DSP */
        scontrol->comp_data_dirty = false;
-       ret = snd_sof_ipc_set_get_comp_data(scontrol, ctrl_type,
+       ret = snd_sof_ipc_set_get_comp_data(scontrol, ipc_cmd,
                                            SOF_CTRL_TYPE_VALUE_CHAN_GET,
                                            scontrol->cmd, false);
        if (ret < 0) {
index 30025d3..0862ff8 100644 (file)
@@ -10,6 +10,8 @@
 #include <linux/io.h>
 #include <sound/hdaudio.h>
 #include <sound/hda_i915.h>
+#include <sound/hda_codec.h>
+#include <sound/hda_register.h>
 #include "../sof-priv.h"
 #include "hda.h"
 
 #endif
 
 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
+static void update_codec_wake_enable(struct hdac_bus *bus, unsigned int addr, bool link_power)
+{
+       unsigned int mask = snd_hdac_chip_readw(bus, WAKEEN);
+
+       if (link_power)
+               mask &= ~BIT(addr);
+       else
+               mask |= BIT(addr);
+
+       snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, mask);
+}
+
 static void sof_hda_bus_link_power(struct hdac_device *codec, bool enable)
 {
        struct hdac_bus *bus = codec->bus;
@@ -41,6 +55,9 @@ static void sof_hda_bus_link_power(struct hdac_device *codec, bool enable)
         */
        if (codec->addr == HDA_IDISP_ADDR && !enable)
                snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false);
+
+       /* WAKEEN needs to be set for disabled links */
+       update_codec_wake_enable(bus, codec->addr, enable);
 }
 
 static const struct hdac_bus_ops bus_core_ops = {
index 058baca..287dc0e 100644 (file)
@@ -622,8 +622,7 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
        hda_dsp_ipc_int_disable(sdev);
 
 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
-       if (runtime_suspend)
-               hda_codec_jack_wake_enable(sdev, true);
+       hda_codec_jack_wake_enable(sdev, runtime_suspend);
 
        /* power down all hda link */
        snd_hdac_ext_bus_link_power_down_all(bus);
index 883d78d..568d351 100644 (file)
@@ -810,6 +810,20 @@ skip_soundwire:
        return 0;
 }
 
+static void hda_check_for_state_change(struct snd_sof_dev *sdev)
+{
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
+       struct hdac_bus *bus = sof_to_bus(sdev);
+       unsigned int codec_mask;
+
+       codec_mask = snd_hdac_chip_readw(bus, STATESTS);
+       if (codec_mask) {
+               hda_codec_jack_check(sdev);
+               snd_hdac_chip_writew(bus, STATESTS, codec_mask);
+       }
+#endif
+}
+
 static irqreturn_t hda_dsp_interrupt_handler(int irq, void *context)
 {
        struct snd_sof_dev *sdev = context;
@@ -851,6 +865,8 @@ static irqreturn_t hda_dsp_interrupt_thread(int irq, void *context)
        if (hda_sdw_check_wakeen_irq(sdev))
                hda_sdw_process_wakeen(sdev);
 
+       hda_check_for_state_change(sdev);
+
        /* enable GIE interrupt */
        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
                                SOF_HDA_INTCTL,
index 6254bac..717f45a 100644 (file)
@@ -700,7 +700,7 @@ static int stm32_i2s_configure_clock(struct snd_soc_dai *cpu_dai,
                if (ret < 0)
                        return ret;
 
-               nb_bits = frame_len * ((cgfr & I2S_CGFR_CHLEN) + 1);
+               nb_bits = frame_len * (FIELD_GET(I2S_CGFR_CHLEN, cgfr) + 1);
                ret = stm32_i2s_calc_clk_div(i2s, i2s_clock_rate,
                                             (nb_bits * rate));
                if (ret)
index 95ec8ee..cec6e91 100644 (file)
@@ -581,6 +581,12 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
        return 0;
 }
 
+/* free-wheeling mode? (e.g. dmix) */
+static int in_free_wheeling_mode(struct snd_pcm_runtime *runtime)
+{
+       return runtime->stop_threshold > runtime->buffer_size;
+}
+
 /* check whether early start is needed for playback stream */
 static int lowlatency_playback_available(struct snd_pcm_runtime *runtime,
                                         struct snd_usb_substream *subs)
@@ -592,8 +598,7 @@ static int lowlatency_playback_available(struct snd_pcm_runtime *runtime,
        /* disabled via module option? */
        if (!chip->lowlatency)
                return false;
-       /* free-wheeling mode? (e.g. dmix) */
-       if (runtime->stop_threshold > runtime->buffer_size)
+       if (in_free_wheeling_mode(runtime))
                return false;
        /* implicit feedback mode has own operation mode */
        if (snd_usb_endpoint_implicit_feedback_sink(subs->data_endpoint))
@@ -635,7 +640,8 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
        runtime->delay = 0;
 
        subs->lowlatency_playback = lowlatency_playback_available(runtime, subs);
-       if (!subs->lowlatency_playback)
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
+           !subs->lowlatency_playback)
                ret = start_endpoints(subs);
 
  unlock:
@@ -1552,6 +1558,8 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea
                                              subs);
                if (subs->lowlatency_playback &&
                    cmd == SNDRV_PCM_TRIGGER_START) {
+                       if (in_free_wheeling_mode(substream->runtime))
+                               subs->lowlatency_playback = false;
                        err = start_endpoints(subs);
                        if (err < 0) {
                                snd_usb_endpoint_set_callback(subs->data_endpoint,
index 2cb0a19..4041748 100644 (file)
@@ -358,6 +358,7 @@ static struct xenbus_driver xen_driver = {
        .probe = xen_drv_probe,
        .remove = xen_drv_remove,
        .otherend_changed = sndback_changed,
+       .not_essential = true,
 };
 
 static int __init xen_drv_init(void)
index d0ce5cf..d5b5f2a 100644 (file)
 #define X86_FEATURE_XSAVEC             (10*32+ 1) /* XSAVEC instruction */
 #define X86_FEATURE_XGETBV1            (10*32+ 2) /* XGETBV with ECX = 1 instruction */
 #define X86_FEATURE_XSAVES             (10*32+ 3) /* XSAVES/XRSTORS instructions */
+#define X86_FEATURE_XFD                        (10*32+ 4) /* "" eXtended Feature Disabling */
 
 /*
  * Extended auxiliary flags: Linux defined - for features scattered in various
 /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
 #define X86_FEATURE_AVX_VNNI           (12*32+ 4) /* AVX VNNI instructions */
 #define X86_FEATURE_AVX512_BF16                (12*32+ 5) /* AVX512 BFLOAT16 instructions */
+#define X86_FEATURE_AMX_TILE           (18*32+24) /* AMX tile Support */
 
 /* AMD-defined CPU features, CPUID level 0x80000008 (EBX), word 13 */
 #define X86_FEATURE_CLZERO             (13*32+ 0) /* CLZERO instruction */
index 2ef1f65..5a776a0 100644 (file)
@@ -504,4 +504,8 @@ struct kvm_pmu_event_filter {
 #define KVM_PMU_EVENT_ALLOW 0
 #define KVM_PMU_EVENT_DENY 1
 
+/* for KVM_{GET,SET,HAS}_DEVICE_ATTR */
+#define KVM_VCPU_TSC_CTRL 0 /* control group for the timestamp counter (TSC) */
+#define   KVM_VCPU_TSC_OFFSET 0 /* attribute for the TSC offset */
+
 #endif /* _ASM_X86_KVM_H */
index bbd1150..8791d0e 100644 (file)
@@ -88,5 +88,4 @@ $(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(BPFOBJ_OU
 
 $(DEFAULT_BPFTOOL): $(BPFOBJ) | $(BPFTOOL_OUTPUT)
        $(Q)$(MAKE) $(submake_extras) -C ../bpftool OUTPUT=$(BPFTOOL_OUTPUT)   \
-                   LIBBPF_OUTPUT=$(BPFOBJ_OUTPUT)                             \
-                   LIBBPF_DESTDIR=$(BPF_DESTDIR) CC=$(HOSTCC) LD=$(HOSTLD)
+                   CC=$(HOSTCC) LD=$(HOSTLD)
index 9204395..0b243ce 100644 (file)
@@ -200,7 +200,6 @@ int main(int argc, char *argv[])
        main_test_timerfd();
        main_test_stackprotector_all();
        main_test_libdw_dwarf_unwind();
-       main_test_sync_compare_and_swap(argc, argv);
        main_test_zlib();
        main_test_pthread_attr_setaffinity_np();
        main_test_pthread_barrier();
index b3610fd..eebd389 100644 (file)
@@ -7,24 +7,23 @@
 
 /* This struct should be in sync with struct rtnl_link_stats64 */
 struct rtnl_link_stats {
-       __u32   rx_packets;             /* total packets received       */
-       __u32   tx_packets;             /* total packets transmitted    */
-       __u32   rx_bytes;               /* total bytes received         */
-       __u32   tx_bytes;               /* total bytes transmitted      */
-       __u32   rx_errors;              /* bad packets received         */
-       __u32   tx_errors;              /* packet transmit problems     */
-       __u32   rx_dropped;             /* no space in linux buffers    */
-       __u32   tx_dropped;             /* no space available in linux  */
-       __u32   multicast;              /* multicast packets received   */
+       __u32   rx_packets;
+       __u32   tx_packets;
+       __u32   rx_bytes;
+       __u32   tx_bytes;
+       __u32   rx_errors;
+       __u32   tx_errors;
+       __u32   rx_dropped;
+       __u32   tx_dropped;
+       __u32   multicast;
        __u32   collisions;
-
        /* detailed rx_errors: */
        __u32   rx_length_errors;
-       __u32   rx_over_errors;         /* receiver ring buff overflow  */
-       __u32   rx_crc_errors;          /* recved pkt with crc error    */
-       __u32   rx_frame_errors;        /* recv'd frame alignment error */
-       __u32   rx_fifo_errors;         /* recv'r fifo overrun          */
-       __u32   rx_missed_errors;       /* receiver missed packet       */
+       __u32   rx_over_errors;
+       __u32   rx_crc_errors;
+       __u32   rx_frame_errors;
+       __u32   rx_fifo_errors;
+       __u32   rx_missed_errors;
 
        /* detailed tx_errors */
        __u32   tx_aborted_errors;
@@ -37,29 +36,201 @@ struct rtnl_link_stats {
        __u32   rx_compressed;
        __u32   tx_compressed;
 
-       __u32   rx_nohandler;           /* dropped, no handler found    */
+       __u32   rx_nohandler;
 };
 
-/* The main device statistics structure */
+/**
+ * struct rtnl_link_stats64 - The main device statistics structure.
+ *
+ * @rx_packets: Number of good packets received by the interface.
+ *   For hardware interfaces counts all good packets received from the device
+ *   by the host, including packets which host had to drop at various stages
+ *   of processing (even in the driver).
+ *
+ * @tx_packets: Number of packets successfully transmitted.
+ *   For hardware interfaces counts packets which host was able to successfully
+ *   hand over to the device, which does not necessarily mean that packets
+ *   had been successfully transmitted out of the device, only that device
+ *   acknowledged it copied them out of host memory.
+ *
+ * @rx_bytes: Number of good received bytes, corresponding to @rx_packets.
+ *
+ *   For IEEE 802.3 devices should count the length of Ethernet Frames
+ *   excluding the FCS.
+ *
+ * @tx_bytes: Number of good transmitted bytes, corresponding to @tx_packets.
+ *
+ *   For IEEE 802.3 devices should count the length of Ethernet Frames
+ *   excluding the FCS.
+ *
+ * @rx_errors: Total number of bad packets received on this network device.
+ *   This counter must include events counted by @rx_length_errors,
+ *   @rx_crc_errors, @rx_frame_errors and other errors not otherwise
+ *   counted.
+ *
+ * @tx_errors: Total number of transmit problems.
+ *   This counter must include events counter by @tx_aborted_errors,
+ *   @tx_carrier_errors, @tx_fifo_errors, @tx_heartbeat_errors,
+ *   @tx_window_errors and other errors not otherwise counted.
+ *
+ * @rx_dropped: Number of packets received but not processed,
+ *   e.g. due to lack of resources or unsupported protocol.
+ *   For hardware interfaces this counter may include packets discarded
+ *   due to L2 address filtering but should not include packets dropped
+ *   by the device due to buffer exhaustion which are counted separately in
+ *   @rx_missed_errors (since procfs folds those two counters together).
+ *
+ * @tx_dropped: Number of packets dropped on their way to transmission,
+ *   e.g. due to lack of resources.
+ *
+ * @multicast: Multicast packets received.
+ *   For hardware interfaces this statistic is commonly calculated
+ *   at the device level (unlike @rx_packets) and therefore may include
+ *   packets which did not reach the host.
+ *
+ *   For IEEE 802.3 devices this counter may be equivalent to:
+ *
+ *    - 30.3.1.1.21 aMulticastFramesReceivedOK
+ *
+ * @collisions: Number of collisions during packet transmissions.
+ *
+ * @rx_length_errors: Number of packets dropped due to invalid length.
+ *   Part of aggregate "frame" errors in `/proc/net/dev`.
+ *
+ *   For IEEE 802.3 devices this counter should be equivalent to a sum
+ *   of the following attributes:
+ *
+ *    - 30.3.1.1.23 aInRangeLengthErrors
+ *    - 30.3.1.1.24 aOutOfRangeLengthField
+ *    - 30.3.1.1.25 aFrameTooLongErrors
+ *
+ * @rx_over_errors: Receiver FIFO overflow event counter.
+ *
+ *   Historically the count of overflow events. Such events may be
+ *   reported in the receive descriptors or via interrupts, and may
+ *   not correspond one-to-one with dropped packets.
+ *
+ *   The recommended interpretation for high speed interfaces is -
+ *   number of packets dropped because they did not fit into buffers
+ *   provided by the host, e.g. packets larger than MTU or next buffer
+ *   in the ring was not available for a scatter transfer.
+ *
+ *   Part of aggregate "frame" errors in `/proc/net/dev`.
+ *
+ *   This statistics was historically used interchangeably with
+ *   @rx_fifo_errors.
+ *
+ *   This statistic corresponds to hardware events and is not commonly used
+ *   on software devices.
+ *
+ * @rx_crc_errors: Number of packets received with a CRC error.
+ *   Part of aggregate "frame" errors in `/proc/net/dev`.
+ *
+ *   For IEEE 802.3 devices this counter must be equivalent to:
+ *
+ *    - 30.3.1.1.6 aFrameCheckSequenceErrors
+ *
+ * @rx_frame_errors: Receiver frame alignment errors.
+ *   Part of aggregate "frame" errors in `/proc/net/dev`.
+ *
+ *   For IEEE 802.3 devices this counter should be equivalent to:
+ *
+ *    - 30.3.1.1.7 aAlignmentErrors
+ *
+ * @rx_fifo_errors: Receiver FIFO error counter.
+ *
+ *   Historically the count of overflow events. Those events may be
+ *   reported in the receive descriptors or via interrupts, and may
+ *   not correspond one-to-one with dropped packets.
+ *
+ *   This statistics was used interchangeably with @rx_over_errors.
+ *   Not recommended for use in drivers for high speed interfaces.
+ *
+ *   This statistic is used on software devices, e.g. to count software
+ *   packet queue overflow (can) or sequencing errors (GRE).
+ *
+ * @rx_missed_errors: Count of packets missed by the host.
+ *   Folded into the "drop" counter in `/proc/net/dev`.
+ *
+ *   Counts number of packets dropped by the device due to lack
+ *   of buffer space. This usually indicates that the host interface
+ *   is slower than the network interface, or host is not keeping up
+ *   with the receive packet rate.
+ *
+ *   This statistic corresponds to hardware events and is not used
+ *   on software devices.
+ *
+ * @tx_aborted_errors:
+ *   Part of aggregate "carrier" errors in `/proc/net/dev`.
+ *   For IEEE 802.3 devices capable of half-duplex operation this counter
+ *   must be equivalent to:
+ *
+ *    - 30.3.1.1.11 aFramesAbortedDueToXSColls
+ *
+ *   High speed interfaces may use this counter as a general device
+ *   discard counter.
+ *
+ * @tx_carrier_errors: Number of frame transmission errors due to loss
+ *   of carrier during transmission.
+ *   Part of aggregate "carrier" errors in `/proc/net/dev`.
+ *
+ *   For IEEE 802.3 devices this counter must be equivalent to:
+ *
+ *    - 30.3.1.1.13 aCarrierSenseErrors
+ *
+ * @tx_fifo_errors: Number of frame transmission errors due to device
+ *   FIFO underrun / underflow. This condition occurs when the device
+ *   begins transmission of a frame but is unable to deliver the
+ *   entire frame to the transmitter in time for transmission.
+ *   Part of aggregate "carrier" errors in `/proc/net/dev`.
+ *
+ * @tx_heartbeat_errors: Number of Heartbeat / SQE Test errors for
+ *   old half-duplex Ethernet.
+ *   Part of aggregate "carrier" errors in `/proc/net/dev`.
+ *
+ *   For IEEE 802.3 devices possibly equivalent to:
+ *
+ *    - 30.3.2.1.4 aSQETestErrors
+ *
+ * @tx_window_errors: Number of frame transmission errors due
+ *   to late collisions (for Ethernet - after the first 64B of transmission).
+ *   Part of aggregate "carrier" errors in `/proc/net/dev`.
+ *
+ *   For IEEE 802.3 devices this counter must be equivalent to:
+ *
+ *    - 30.3.1.1.10 aLateCollisions
+ *
+ * @rx_compressed: Number of correctly received compressed packets.
+ *   This counters is only meaningful for interfaces which support
+ *   packet compression (e.g. CSLIP, PPP).
+ *
+ * @tx_compressed: Number of transmitted compressed packets.
+ *   This counters is only meaningful for interfaces which support
+ *   packet compression (e.g. CSLIP, PPP).
+ *
+ * @rx_nohandler: Number of packets received on the interface
+ *   but dropped by the networking stack because the device is
+ *   not designated to receive packets (e.g. backup link in a bond).
+ */
 struct rtnl_link_stats64 {
-       __u64   rx_packets;             /* total packets received       */
-       __u64   tx_packets;             /* total packets transmitted    */
-       __u64   rx_bytes;               /* total bytes received         */
-       __u64   tx_bytes;               /* total bytes transmitted      */
-       __u64   rx_errors;              /* bad packets received         */
-       __u64   tx_errors;              /* packet transmit problems     */
-       __u64   rx_dropped;             /* no space in linux buffers    */
-       __u64   tx_dropped;             /* no space available in linux  */
-       __u64   multicast;              /* multicast packets received   */
+       __u64   rx_packets;
+       __u64   tx_packets;
+       __u64   rx_bytes;
+       __u64   tx_bytes;
+       __u64   rx_errors;
+       __u64   tx_errors;
+       __u64   rx_dropped;
+       __u64   tx_dropped;
+       __u64   multicast;
        __u64   collisions;
 
        /* detailed rx_errors: */
        __u64   rx_length_errors;
-       __u64   rx_over_errors;         /* receiver ring buff overflow  */
-       __u64   rx_crc_errors;          /* recved pkt with crc error    */
-       __u64   rx_frame_errors;        /* recv'd frame alignment error */
-       __u64   rx_fifo_errors;         /* recv'r fifo overrun          */
-       __u64   rx_missed_errors;       /* receiver missed packet       */
+       __u64   rx_over_errors;
+       __u64   rx_crc_errors;
+       __u64   rx_frame_errors;
+       __u64   rx_fifo_errors;
+       __u64   rx_missed_errors;
 
        /* detailed tx_errors */
        __u64   tx_aborted_errors;
@@ -71,8 +242,7 @@ struct rtnl_link_stats64 {
        /* for cslip etc */
        __u64   rx_compressed;
        __u64   tx_compressed;
-
-       __u64   rx_nohandler;           /* dropped, no handler found    */
+       __u64   rx_nohandler;
 };
 
 /* The struct should be in sync with struct ifmap */
@@ -170,12 +340,29 @@ enum {
        IFLA_PROP_LIST,
        IFLA_ALT_IFNAME, /* Alternative ifname */
        IFLA_PERM_ADDRESS,
+       IFLA_PROTO_DOWN_REASON,
+
+       /* device (sysfs) name as parent, used instead
+        * of IFLA_LINK where there's no parent netdev
+        */
+       IFLA_PARENT_DEV_NAME,
+       IFLA_PARENT_DEV_BUS_NAME,
+
        __IFLA_MAX
 };
 
 
 #define IFLA_MAX (__IFLA_MAX - 1)
 
+enum {
+       IFLA_PROTO_DOWN_REASON_UNSPEC,
+       IFLA_PROTO_DOWN_REASON_MASK,    /* u32, mask for reason bits */
+       IFLA_PROTO_DOWN_REASON_VALUE,   /* u32, reason bit value */
+
+       __IFLA_PROTO_DOWN_REASON_CNT,
+       IFLA_PROTO_DOWN_REASON_MAX = __IFLA_PROTO_DOWN_REASON_CNT - 1
+};
+
 /* backwards compatibility for userspace */
 #ifndef __KERNEL__
 #define IFLA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
@@ -293,6 +480,7 @@ enum {
        IFLA_BR_MCAST_MLD_VERSION,
        IFLA_BR_VLAN_STATS_PER_PORT,
        IFLA_BR_MULTI_BOOLOPT,
+       IFLA_BR_MCAST_QUERIER_STATE,
        __IFLA_BR_MAX,
 };
 
@@ -346,6 +534,8 @@ enum {
        IFLA_BRPORT_BACKUP_PORT,
        IFLA_BRPORT_MRP_RING_OPEN,
        IFLA_BRPORT_MRP_IN_OPEN,
+       IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT,
+       IFLA_BRPORT_MCAST_EHT_HOSTS_CNT,
        __IFLA_BRPORT_MAX
 };
 #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
@@ -433,6 +623,7 @@ enum macvlan_macaddr_mode {
 };
 
 #define MACVLAN_FLAG_NOPROMISC 1
+#define MACVLAN_FLAG_NODST     2 /* skip dst macvlan if matching src macvlan */
 
 /* VRF section */
 enum {
@@ -597,6 +788,18 @@ enum ifla_geneve_df {
        GENEVE_DF_MAX = __GENEVE_DF_END - 1,
 };
 
+/* Bareudp section  */
+enum {
+       IFLA_BAREUDP_UNSPEC,
+       IFLA_BAREUDP_PORT,
+       IFLA_BAREUDP_ETHERTYPE,
+       IFLA_BAREUDP_SRCPORT_MIN,
+       IFLA_BAREUDP_MULTIPROTO_MODE,
+       __IFLA_BAREUDP_MAX
+};
+
+#define IFLA_BAREUDP_MAX (__IFLA_BAREUDP_MAX - 1)
+
 /* PPP section */
 enum {
        IFLA_PPP_UNSPEC,
@@ -899,7 +1102,14 @@ enum {
 #define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1)
 
 
-/* HSR section */
+/* HSR/PRP section, both uses same interface */
+
+/* Different redundancy protocols for hsr device */
+enum {
+       HSR_PROTOCOL_HSR,
+       HSR_PROTOCOL_PRP,
+       HSR_PROTOCOL_MAX,
+};
 
 enum {
        IFLA_HSR_UNSPEC,
@@ -909,6 +1119,9 @@ enum {
        IFLA_HSR_SUPERVISION_ADDR,      /* Supervision frame multicast addr */
        IFLA_HSR_SEQ_NR,
        IFLA_HSR_VERSION,               /* HSR version */
+       IFLA_HSR_PROTOCOL,              /* Indicate different protocol than
+                                        * HSR. For example PRP.
+                                        */
        __IFLA_HSR_MAX,
 };
 
@@ -1033,6 +1246,8 @@ enum {
 #define RMNET_FLAGS_INGRESS_MAP_COMMANDS          (1U << 1)
 #define RMNET_FLAGS_INGRESS_MAP_CKSUMV4           (1U << 2)
 #define RMNET_FLAGS_EGRESS_MAP_CKSUMV4            (1U << 3)
+#define RMNET_FLAGS_INGRESS_MAP_CKSUMV5           (1U << 4)
+#define RMNET_FLAGS_EGRESS_MAP_CKSUMV5            (1U << 5)
 
 enum {
        IFLA_RMNET_UNSPEC,
@@ -1048,4 +1263,14 @@ struct ifla_rmnet_flags {
        __u32   mask;
 };
 
+/* MCTP section */
+
+enum {
+       IFLA_MCTP_UNSPEC,
+       IFLA_MCTP_NET,
+       __IFLA_MCTP_MAX,
+};
+
+#define IFLA_MCTP_MAX (__IFLA_MCTP_MAX - 1)
+
 #endif /* _UAPI_LINUX_IF_LINK_H */
index a067410..1daa452 100644 (file)
@@ -269,6 +269,7 @@ struct kvm_xen_exit {
 #define KVM_EXIT_AP_RESET_HOLD    32
 #define KVM_EXIT_X86_BUS_LOCK     33
 #define KVM_EXIT_XEN              34
+#define KVM_EXIT_RISCV_SBI        35
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 /* Emulate instruction failed. */
@@ -397,13 +398,23 @@ struct kvm_run {
                 * "ndata" is correct, that new fields are enumerated in "flags",
                 * and that each flag enumerates fields that are 64-bit aligned
                 * and sized (so that ndata+internal.data[] is valid/accurate).
+                *
+                * Space beyond the defined fields may be used to store arbitrary
+                * debug information relating to the emulation failure. It is
+                * accounted for in "ndata" but the format is unspecified and is
+                * not represented in "flags". Any such information is *not* ABI!
                 */
                struct {
                        __u32 suberror;
                        __u32 ndata;
                        __u64 flags;
-                       __u8  insn_size;
-                       __u8  insn_bytes[15];
+                       union {
+                               struct {
+                                       __u8  insn_size;
+                                       __u8  insn_bytes[15];
+                               };
+                       };
+                       /* Arbitrary debug data may follow. */
                } emulation_failure;
                /* KVM_EXIT_OSI */
                struct {
@@ -469,6 +480,13 @@ struct kvm_run {
                } msr;
                /* KVM_EXIT_XEN */
                struct kvm_xen_exit xen;
+               /* KVM_EXIT_RISCV_SBI */
+               struct {
+                       unsigned long extension_id;
+                       unsigned long function_id;
+                       unsigned long args[6];
+                       unsigned long ret[2];
+               } riscv_sbi;
                /* Fix the size of the union. */
                char padding[256];
        };
@@ -1112,6 +1130,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_BINARY_STATS_FD 203
 #define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204
 #define KVM_CAP_ARM_MTE 205
+#define KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM 206
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1223,11 +1242,16 @@ struct kvm_irqfd {
 
 /* Do not use 1, KVM_CHECK_EXTENSION returned it before we had flags.  */
 #define KVM_CLOCK_TSC_STABLE           2
+#define KVM_CLOCK_REALTIME             (1 << 2)
+#define KVM_CLOCK_HOST_TSC             (1 << 3)
 
 struct kvm_clock_data {
        __u64 clock;
        __u32 flags;
-       __u32 pad[9];
+       __u32 pad0;
+       __u64 realtime;
+       __u64 host_tsc;
+       __u32 pad[4];
 };
 
 /* For KVM_CAP_SW_TLB */
index d26e547..6f3df00 100644 (file)
@@ -45,8 +45,8 @@ struct bpf_gen {
        int nr_fd_array;
 };
 
-void bpf_gen__init(struct bpf_gen *gen, int log_level);
-int bpf_gen__finish(struct bpf_gen *gen);
+void bpf_gen__init(struct bpf_gen *gen, int log_level, int nr_progs, int nr_maps);
+int bpf_gen__finish(struct bpf_gen *gen, int nr_progs, int nr_maps);
 void bpf_gen__free(struct bpf_gen *gen);
 void bpf_gen__load_btf(struct bpf_gen *gen, const void *raw_data, __u32 raw_size);
 void bpf_gen__map_create(struct bpf_gen *gen, struct bpf_create_map_params *map_attr, int map_idx);
index 502dea5..9934851 100644 (file)
@@ -18,7 +18,7 @@
 #define MAX_USED_MAPS  64
 #define MAX_USED_PROGS 32
 #define MAX_KFUNC_DESCS 256
-#define MAX_FD_ARRAY_SZ (MAX_USED_PROGS + MAX_KFUNC_DESCS)
+#define MAX_FD_ARRAY_SZ (MAX_USED_MAPS + MAX_KFUNC_DESCS)
 
 /* The following structure describes the stack layout of the loader program.
  * In addition R6 contains the pointer to context.
@@ -33,8 +33,8 @@
  */
 struct loader_stack {
        __u32 btf_fd;
-       __u32 prog_fd[MAX_USED_PROGS];
        __u32 inner_map_fd;
+       __u32 prog_fd[MAX_USED_PROGS];
 };
 
 #define stack_off(field) \
@@ -42,6 +42,11 @@ struct loader_stack {
 
 #define attr_field(attr, field) (attr + offsetof(union bpf_attr, field))
 
+static int blob_fd_array_off(struct bpf_gen *gen, int index)
+{
+       return gen->fd_array + index * sizeof(int);
+}
+
 static int realloc_insn_buf(struct bpf_gen *gen, __u32 size)
 {
        size_t off = gen->insn_cur - gen->insn_start;
@@ -102,11 +107,15 @@ static void emit2(struct bpf_gen *gen, struct bpf_insn insn1, struct bpf_insn in
        emit(gen, insn2);
 }
 
-void bpf_gen__init(struct bpf_gen *gen, int log_level)
+static int add_data(struct bpf_gen *gen, const void *data, __u32 size);
+static void emit_sys_close_blob(struct bpf_gen *gen, int blob_off);
+
+void bpf_gen__init(struct bpf_gen *gen, int log_level, int nr_progs, int nr_maps)
 {
-       size_t stack_sz = sizeof(struct loader_stack);
+       size_t stack_sz = sizeof(struct loader_stack), nr_progs_sz;
        int i;
 
+       gen->fd_array = add_data(gen, NULL, MAX_FD_ARRAY_SZ * sizeof(int));
        gen->log_level = log_level;
        /* save ctx pointer into R6 */
        emit(gen, BPF_MOV64_REG(BPF_REG_6, BPF_REG_1));
@@ -118,19 +127,27 @@ void bpf_gen__init(struct bpf_gen *gen, int log_level)
        emit(gen, BPF_MOV64_IMM(BPF_REG_3, 0));
        emit(gen, BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel));
 
+       /* amount of stack actually used, only used to calculate iterations, not stack offset */
+       nr_progs_sz = offsetof(struct loader_stack, prog_fd[nr_progs]);
        /* jump over cleanup code */
        emit(gen, BPF_JMP_IMM(BPF_JA, 0, 0,
-                             /* size of cleanup code below */
-                             (stack_sz / 4) * 3 + 2));
+                             /* size of cleanup code below (including map fd cleanup) */
+                             (nr_progs_sz / 4) * 3 + 2 +
+                             /* 6 insns for emit_sys_close_blob,
+                              * 6 insns for debug_regs in emit_sys_close_blob
+                              */
+                             nr_maps * (6 + (gen->log_level ? 6 : 0))));
 
        /* remember the label where all error branches will jump to */
        gen->cleanup_label = gen->insn_cur - gen->insn_start;
        /* emit cleanup code: close all temp FDs */
-       for (i = 0; i < stack_sz; i += 4) {
+       for (i = 0; i < nr_progs_sz; i += 4) {
                emit(gen, BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_10, -stack_sz + i));
                emit(gen, BPF_JMP_IMM(BPF_JSLE, BPF_REG_1, 0, 1));
                emit(gen, BPF_EMIT_CALL(BPF_FUNC_sys_close));
        }
+       for (i = 0; i < nr_maps; i++)
+               emit_sys_close_blob(gen, blob_fd_array_off(gen, i));
        /* R7 contains the error code from sys_bpf. Copy it into R0 and exit. */
        emit(gen, BPF_MOV64_REG(BPF_REG_0, BPF_REG_7));
        emit(gen, BPF_EXIT_INSN());
@@ -160,8 +177,6 @@ static int add_data(struct bpf_gen *gen, const void *data, __u32 size)
  */
 static int add_map_fd(struct bpf_gen *gen)
 {
-       if (!gen->fd_array)
-               gen->fd_array = add_data(gen, NULL, MAX_FD_ARRAY_SZ * sizeof(int));
        if (gen->nr_maps == MAX_USED_MAPS) {
                pr_warn("Total maps exceeds %d\n", MAX_USED_MAPS);
                gen->error = -E2BIG;
@@ -174,8 +189,6 @@ static int add_kfunc_btf_fd(struct bpf_gen *gen)
 {
        int cur;
 
-       if (!gen->fd_array)
-               gen->fd_array = add_data(gen, NULL, MAX_FD_ARRAY_SZ * sizeof(int));
        if (gen->nr_fd_array == MAX_KFUNC_DESCS) {
                cur = add_data(gen, NULL, sizeof(int));
                return (cur - gen->fd_array) / sizeof(int);
@@ -183,11 +196,6 @@ static int add_kfunc_btf_fd(struct bpf_gen *gen)
        return MAX_USED_MAPS + gen->nr_fd_array++;
 }
 
-static int blob_fd_array_off(struct bpf_gen *gen, int index)
-{
-       return gen->fd_array + index * sizeof(int);
-}
-
 static int insn_bytes_to_bpf_size(__u32 sz)
 {
        switch (sz) {
@@ -359,10 +367,15 @@ static void emit_sys_close_blob(struct bpf_gen *gen, int blob_off)
        __emit_sys_close(gen);
 }
 
-int bpf_gen__finish(struct bpf_gen *gen)
+int bpf_gen__finish(struct bpf_gen *gen, int nr_progs, int nr_maps)
 {
        int i;
 
+       if (nr_progs != gen->nr_progs || nr_maps != gen->nr_maps) {
+               pr_warn("progs/maps mismatch\n");
+               gen->error = -EFAULT;
+               return gen->error;
+       }
        emit_sys_close_stack(gen, stack_off(btf_fd));
        for (i = 0; i < gen->nr_progs; i++)
                move_stack2ctx(gen,
index a1bea19..7c74342 100644 (file)
@@ -7258,7 +7258,7 @@ int bpf_object__load_xattr(struct bpf_object_load_attr *attr)
        }
 
        if (obj->gen_loader)
-               bpf_gen__init(obj->gen_loader, attr->log_level);
+               bpf_gen__init(obj->gen_loader, attr->log_level, obj->nr_programs, obj->nr_maps);
 
        err = bpf_object__probe_loading(obj);
        err = err ? : bpf_object__load_vmlinux_btf(obj, false);
@@ -7277,7 +7277,7 @@ int bpf_object__load_xattr(struct bpf_object_load_attr *attr)
                for (i = 0; i < obj->nr_maps; i++)
                        obj->maps[i].fd = -1;
                if (!err)
-                       err = bpf_gen__finish(obj->gen_loader);
+                       err = bpf_gen__finish(obj->gen_loader, obj->nr_programs, obj->nr_maps);
        }
 
        /* clean up fd_array */
index 07e65a0..afd1447 100644 (file)
@@ -1010,6 +1010,9 @@ ifndef NO_AUXTRACE
   ifndef NO_AUXTRACE
     $(call detected,CONFIG_AUXTRACE)
     CFLAGS += -DHAVE_AUXTRACE_SUPPORT
+    ifeq ($(feature-reallocarray), 0)
+      CFLAGS += -DCOMPAT_NEED_REALLOCARRAY
+    endif
   endif
 endif
 
index 1ca7bc3..e2c481f 100644 (file)
 446    n64     landlock_restrict_self          sys_landlock_restrict_self
 # 447 reserved for memfd_secret
 448    n64     process_mrelease                sys_process_mrelease
+449    n64     futex_waitv                     sys_futex_waitv
index 488f6e6..fa0ff4c 100644 (file)
@@ -223,6 +223,8 @@ static unsigned int group(pthread_t *pth,
                snd_ctx->out_fds[i] = fds[1];
                if (!thread_mode)
                        close(fds[0]);
+
+               free(ctx);
        }
 
        /* Now we have all the fds, fork the senders */
@@ -239,6 +241,8 @@ static unsigned int group(pthread_t *pth,
                for (i = 0; i < num_fds; i++)
                        close(snd_ctx->out_fds[i]);
 
+       free(snd_ctx);
+
        /* Return number of children to reap */
        return num_fds * 2;
 }
index 8167ebf..8ae4004 100644 (file)
@@ -619,14 +619,17 @@ static int report__browse_hists(struct report *rep)
        int ret;
        struct perf_session *session = rep->session;
        struct evlist *evlist = session->evlist;
-       const char *help = perf_tip(system_path(TIPDIR));
+       char *help = NULL, *path = NULL;
 
-       if (help == NULL) {
+       path = system_path(TIPDIR);
+       if (perf_tip(&help, path) || help == NULL) {
                /* fallback for people who don't install perf ;-) */
-               help = perf_tip(DOCDIR);
-               if (help == NULL)
-                       help = "Cannot load tips.txt file, please install perf!";
+               free(path);
+               path = system_path(DOCDIR);
+               if (perf_tip(&help, path) || help == NULL)
+                       help = strdup("Cannot load tips.txt file, please install perf!");
        }
+       free(path);
 
        switch (use_browser) {
        case 1:
@@ -651,7 +654,7 @@ static int report__browse_hists(struct report *rep)
                ret = evlist__tty_browse_hists(evlist, rep, help);
                break;
        }
-
+       free(help);
        return ret;
 }
 
index fbb68de..d01532d 100644 (file)
@@ -88,7 +88,6 @@ static int test__event_update(struct test_suite *test __maybe_unused, int subtes
        struct evsel *evsel;
        struct event_name tmp;
        struct evlist *evlist = evlist__new_default();
-       char *unit = strdup("KRAVA");
 
        TEST_ASSERT_VAL("failed to get evlist", evlist);
 
@@ -99,7 +98,8 @@ static int test__event_update(struct test_suite *test __maybe_unused, int subtes
 
        perf_evlist__id_add(&evlist->core, &evsel->core, 0, 0, 123);
 
-       evsel->unit = unit;
+       free((char *)evsel->unit);
+       evsel->unit = strdup("KRAVA");
 
        TEST_ASSERT_VAL("failed to synthesize attr update unit",
                        !perf_event__synthesize_event_update_unit(NULL, evsel, process_event_unit));
@@ -119,7 +119,6 @@ static int test__event_update(struct test_suite *test __maybe_unused, int subtes
        TEST_ASSERT_VAL("failed to synthesize attr update cpus",
                        !perf_event__synthesize_event_update_cpus(&tmp.tool, evsel, process_event_cpus));
 
-       free(unit);
        evlist__delete(evlist);
        return 0;
 }
index b669d22..07f2411 100644 (file)
@@ -36,7 +36,7 @@
  * These are based on the input value (213) specified
  * in branch_stack variable.
  */
-#define BS_EXPECTED_BE 0xa00d000000000000
+#define BS_EXPECTED_BE 0xa000d00000000000
 #define BS_EXPECTED_LE 0xd5000000
 #define FLAG(s)        s->branch_stack->entries[i].flags
 
index 820d942..9d4c451 100644 (file)
@@ -21,6 +21,7 @@ do {                                            \
 volatile u64 data1;
 volatile u8 data2[3];
 
+#ifndef __s390x__
 static int wp_read(int fd, long long *count, int size)
 {
        int ret = read(fd, count, size);
@@ -48,7 +49,6 @@ static void get__perf_event_attr(struct perf_event_attr *attr, int wp_type,
        attr->exclude_hv     = 1;
 }
 
-#ifndef __s390x__
 static int __event(int wp_type, void *wp_addr, unsigned long wp_len)
 {
        int fd;
index c1f24d0..5075ece 100644 (file)
@@ -535,6 +535,18 @@ struct perf_hpp_list perf_hpp_list = {
 #undef __HPP_SORT_ACC_FN
 #undef __HPP_SORT_RAW_FN
 
+static void fmt_free(struct perf_hpp_fmt *fmt)
+{
+       /*
+        * At this point fmt should be completely
+        * unhooked, if not it's a bug.
+        */
+       BUG_ON(!list_empty(&fmt->list));
+       BUG_ON(!list_empty(&fmt->sort_list));
+
+       if (fmt->free)
+               fmt->free(fmt);
+}
 
 void perf_hpp__init(void)
 {
@@ -598,9 +610,10 @@ void perf_hpp_list__prepend_sort_field(struct perf_hpp_list *list,
        list_add(&format->sort_list, &list->sorts);
 }
 
-void perf_hpp__column_unregister(struct perf_hpp_fmt *format)
+static void perf_hpp__column_unregister(struct perf_hpp_fmt *format)
 {
        list_del_init(&format->list);
+       fmt_free(format);
 }
 
 void perf_hpp__cancel_cumulate(void)
@@ -672,19 +685,6 @@ next:
 }
 
 
-static void fmt_free(struct perf_hpp_fmt *fmt)
-{
-       /*
-        * At this point fmt should be completely
-        * unhooked, if not it's a bug.
-        */
-       BUG_ON(!list_empty(&fmt->list));
-       BUG_ON(!list_empty(&fmt->sort_list));
-
-       if (fmt->free)
-               fmt->free(fmt);
-}
-
 void perf_hpp__reset_output_field(struct perf_hpp_list *list)
 {
        struct perf_hpp_fmt *fmt, *tmp;
index 4748bcf..fccac06 100644 (file)
@@ -51,6 +51,7 @@ struct arm_spe {
        u8                              timeless_decoding;
        u8                              data_queued;
 
+       u64                             sample_type;
        u8                              sample_flc;
        u8                              sample_llc;
        u8                              sample_tlb;
@@ -287,6 +288,12 @@ static void arm_spe_prep_sample(struct arm_spe *spe,
        event->sample.header.size = sizeof(struct perf_event_header);
 }
 
+static int arm_spe__inject_event(union perf_event *event, struct perf_sample *sample, u64 type)
+{
+       event->header.size = perf_event__sample_event_size(sample, type, 0);
+       return perf_event__synthesize_sample(event, type, 0, sample);
+}
+
 static inline int
 arm_spe_deliver_synth_event(struct arm_spe *spe,
                            struct arm_spe_queue *speq __maybe_unused,
@@ -295,6 +302,12 @@ arm_spe_deliver_synth_event(struct arm_spe *spe,
 {
        int ret;
 
+       if (spe->synth_opts.inject) {
+               ret = arm_spe__inject_event(event, sample, spe->sample_type);
+               if (ret)
+                       return ret;
+       }
+
        ret = perf_session__deliver_synth_event(spe->session, event, sample);
        if (ret)
                pr_err("ARM SPE: failed to deliver event, error %d\n", ret);
@@ -986,6 +999,8 @@ arm_spe_synth_events(struct arm_spe *spe, struct perf_session *session)
        else
                attr.sample_type |= PERF_SAMPLE_TIME;
 
+       spe->sample_type = attr.sample_type;
+
        attr.exclude_user = evsel->core.attr.exclude_user;
        attr.exclude_kernel = evsel->core.attr.exclude_kernel;
        attr.exclude_hv = evsel->core.attr.exclude_hv;
index a59fb2e..ac0127b 100644 (file)
@@ -241,7 +241,7 @@ void evsel__init(struct evsel *evsel,
 {
        perf_evsel__init(&evsel->core, attr, idx);
        evsel->tracking    = !idx;
-       evsel->unit        = "";
+       evsel->unit        = strdup("");
        evsel->scale       = 1.0;
        evsel->max_events  = ULONG_MAX;
        evsel->evlist      = NULL;
@@ -276,13 +276,8 @@ struct evsel *evsel__new_idx(struct perf_event_attr *attr, int idx)
        }
 
        if (evsel__is_clock(evsel)) {
-               /*
-                * The evsel->unit points to static alias->unit
-                * so it's ok to use static string in here.
-                */
-               static const char *unit = "msec";
-
-               evsel->unit = unit;
+               free((char *)evsel->unit);
+               evsel->unit = strdup("msec");
                evsel->scale = 1e-6;
        }
 
@@ -420,7 +415,11 @@ struct evsel *evsel__clone(struct evsel *orig)
 
        evsel->max_events = orig->max_events;
        evsel->tool_event = orig->tool_event;
-       evsel->unit = orig->unit;
+       free((char *)evsel->unit);
+       evsel->unit = strdup(orig->unit);
+       if (evsel->unit == NULL)
+               goto out_err;
+
        evsel->scale = orig->scale;
        evsel->snapshot = orig->snapshot;
        evsel->per_pkg = orig->per_pkg;
@@ -1441,6 +1440,7 @@ void evsel__exit(struct evsel *evsel)
        zfree(&evsel->group_name);
        zfree(&evsel->name);
        zfree(&evsel->pmu_name);
+       zfree(&evsel->unit);
        zfree(&evsel->metric_id);
        evsel__zero_per_pkg(evsel);
        hashmap__free(evsel->per_pkg_mask);
index fda8d14..79cce21 100644 (file)
@@ -4257,9 +4257,11 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
 
        switch (ev->type) {
        case PERF_EVENT_UPDATE__UNIT:
+               free((char *)evsel->unit);
                evsel->unit = strdup(ev->data);
                break;
        case PERF_EVENT_UPDATE__NAME:
+               free(evsel->name);
                evsel->name = strdup(ev->data);
                break;
        case PERF_EVENT_UPDATE__SCALE:
@@ -4268,11 +4270,11 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
                break;
        case PERF_EVENT_UPDATE__CPUS:
                ev_cpus = (struct perf_record_event_update_cpus *)ev->data;
-
                map = cpu_map__new_data(&ev_cpus->cpus);
-               if (map)
+               if (map) {
+                       perf_cpu_map__put(evsel->core.own_cpus);
                        evsel->core.own_cpus = map;
-               else
+               else
                        pr_err("failed to get event_update cpus\n");
        default:
                break;
index 65fe65b..b776465 100644 (file)
@@ -289,15 +289,10 @@ static long hist_time(unsigned long htime)
        return htime;
 }
 
-static void he_stat__add_period(struct he_stat *he_stat, u64 period,
-                               u64 weight, u64 ins_lat, u64 p_stage_cyc)
+static void he_stat__add_period(struct he_stat *he_stat, u64 period)
 {
-
        he_stat->period         += period;
-       he_stat->weight         += weight;
        he_stat->nr_events      += 1;
-       he_stat->ins_lat        += ins_lat;
-       he_stat->p_stage_cyc    += p_stage_cyc;
 }
 
 static void he_stat__add_stat(struct he_stat *dest, struct he_stat *src)
@@ -308,9 +303,6 @@ static void he_stat__add_stat(struct he_stat *dest, struct he_stat *src)
        dest->period_guest_sys  += src->period_guest_sys;
        dest->period_guest_us   += src->period_guest_us;
        dest->nr_events         += src->nr_events;
-       dest->weight            += src->weight;
-       dest->ins_lat           += src->ins_lat;
-       dest->p_stage_cyc               += src->p_stage_cyc;
 }
 
 static void he_stat__decay(struct he_stat *he_stat)
@@ -598,9 +590,6 @@ static struct hist_entry *hists__findnew_entry(struct hists *hists,
        struct hist_entry *he;
        int64_t cmp;
        u64 period = entry->stat.period;
-       u64 weight = entry->stat.weight;
-       u64 ins_lat = entry->stat.ins_lat;
-       u64 p_stage_cyc = entry->stat.p_stage_cyc;
        bool leftmost = true;
 
        p = &hists->entries_in->rb_root.rb_node;
@@ -619,11 +608,11 @@ static struct hist_entry *hists__findnew_entry(struct hists *hists,
 
                if (!cmp) {
                        if (sample_self) {
-                               he_stat__add_period(&he->stat, period, weight, ins_lat, p_stage_cyc);
+                               he_stat__add_period(&he->stat, period);
                                hist_entry__add_callchain_period(he, period);
                        }
                        if (symbol_conf.cumulate_callchain)
-                               he_stat__add_period(he->stat_acc, period, weight, ins_lat, p_stage_cyc);
+                               he_stat__add_period(he->stat_acc, period);
 
                        /*
                         * This mem info was allocated from sample__resolve_mem
@@ -733,9 +722,6 @@ __hists__add_entry(struct hists *hists,
                .stat = {
                        .nr_events = 1,
                        .period = sample->period,
-                       .weight = sample->weight,
-                       .ins_lat = sample->ins_lat,
-                       .p_stage_cyc = sample->p_stage_cyc,
                },
                .parent = sym_parent,
                .filtered = symbol__parent_filter(sym_parent) | al->filtered,
@@ -748,6 +734,9 @@ __hists__add_entry(struct hists *hists,
                .raw_size = sample->raw_size,
                .ops = ops,
                .time = hist_time(sample->time),
+               .weight = sample->weight,
+               .ins_lat = sample->ins_lat,
+               .p_stage_cyc = sample->p_stage_cyc,
        }, *he = hists__findnew_entry(hists, &entry, al, sample_self);
 
        if (!hists->has_callchains && he && he->callchain_size != 0)
index 5343b62..621f35a 100644 (file)
@@ -369,7 +369,6 @@ enum {
 };
 
 void perf_hpp__init(void);
-void perf_hpp__column_unregister(struct perf_hpp_fmt *format);
 void perf_hpp__cancel_cumulate(void);
 void perf_hpp__setup_output_field(struct perf_hpp_list *list);
 void perf_hpp__reset_output_field(struct perf_hpp_list *list);
index 5bfb6f8..ba74fdf 100644 (file)
@@ -402,8 +402,10 @@ static int add_event_tool(struct list_head *list, int *idx,
        if (!evsel)
                return -ENOMEM;
        evsel->tool_event = tool_event;
-       if (tool_event == PERF_TOOL_DURATION_TIME)
-               evsel->unit = "ns";
+       if (tool_event == PERF_TOOL_DURATION_TIME) {
+               free((char *)evsel->unit);
+               evsel->unit = strdup("ns");
+       }
        return 0;
 }
 
@@ -1630,7 +1632,8 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
        if (parse_state->fake_pmu)
                return 0;
 
-       evsel->unit = info.unit;
+       free((char *)evsel->unit);
+       evsel->unit = strdup(info.unit);
        evsel->scale = info.scale;
        evsel->per_pkg = info.per_pkg;
        evsel->snapshot = info.snapshot;
index 568a88c..a111065 100644 (file)
@@ -1325,88 +1325,68 @@ struct sort_entry sort_mispredict = {
        .se_width_idx   = HISTC_MISPREDICT,
 };
 
-static u64 he_weight(struct hist_entry *he)
-{
-       return he->stat.nr_events ? he->stat.weight / he->stat.nr_events : 0;
-}
-
 static int64_t
-sort__local_weight_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__weight_cmp(struct hist_entry *left, struct hist_entry *right)
 {
-       return he_weight(left) - he_weight(right);
+       return left->weight - right->weight;
 }
 
 static int hist_entry__local_weight_snprintf(struct hist_entry *he, char *bf,
                                    size_t size, unsigned int width)
 {
-       return repsep_snprintf(bf, size, "%-*llu", width, he_weight(he));
+       return repsep_snprintf(bf, size, "%-*llu", width, he->weight);
 }
 
 struct sort_entry sort_local_weight = {
        .se_header      = "Local Weight",
-       .se_cmp         = sort__local_weight_cmp,
+       .se_cmp         = sort__weight_cmp,
        .se_snprintf    = hist_entry__local_weight_snprintf,
        .se_width_idx   = HISTC_LOCAL_WEIGHT,
 };
 
-static int64_t
-sort__global_weight_cmp(struct hist_entry *left, struct hist_entry *right)
-{
-       return left->stat.weight - right->stat.weight;
-}
-
 static int hist_entry__global_weight_snprintf(struct hist_entry *he, char *bf,
                                              size_t size, unsigned int width)
 {
-       return repsep_snprintf(bf, size, "%-*llu", width, he->stat.weight);
+       return repsep_snprintf(bf, size, "%-*llu", width,
+                              he->weight * he->stat.nr_events);
 }
 
 struct sort_entry sort_global_weight = {
        .se_header      = "Weight",
-       .se_cmp         = sort__global_weight_cmp,
+       .se_cmp         = sort__weight_cmp,
        .se_snprintf    = hist_entry__global_weight_snprintf,
        .se_width_idx   = HISTC_GLOBAL_WEIGHT,
 };
 
-static u64 he_ins_lat(struct hist_entry *he)
-{
-               return he->stat.nr_events ? he->stat.ins_lat / he->stat.nr_events : 0;
-}
-
 static int64_t
-sort__local_ins_lat_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__ins_lat_cmp(struct hist_entry *left, struct hist_entry *right)
 {
-               return he_ins_lat(left) - he_ins_lat(right);
+       return left->ins_lat - right->ins_lat;
 }
 
 static int hist_entry__local_ins_lat_snprintf(struct hist_entry *he, char *bf,
                                              size_t size, unsigned int width)
 {
-               return repsep_snprintf(bf, size, "%-*u", width, he_ins_lat(he));
+       return repsep_snprintf(bf, size, "%-*u", width, he->ins_lat);
 }
 
 struct sort_entry sort_local_ins_lat = {
        .se_header      = "Local INSTR Latency",
-       .se_cmp         = sort__local_ins_lat_cmp,
+       .se_cmp         = sort__ins_lat_cmp,
        .se_snprintf    = hist_entry__local_ins_lat_snprintf,
        .se_width_idx   = HISTC_LOCAL_INS_LAT,
 };
 
-static int64_t
-sort__global_ins_lat_cmp(struct hist_entry *left, struct hist_entry *right)
-{
-               return left->stat.ins_lat - right->stat.ins_lat;
-}
-
 static int hist_entry__global_ins_lat_snprintf(struct hist_entry *he, char *bf,
                                               size_t size, unsigned int width)
 {
-               return repsep_snprintf(bf, size, "%-*u", width, he->stat.ins_lat);
+       return repsep_snprintf(bf, size, "%-*u", width,
+                              he->ins_lat * he->stat.nr_events);
 }
 
 struct sort_entry sort_global_ins_lat = {
        .se_header      = "INSTR Latency",
-       .se_cmp         = sort__global_ins_lat_cmp,
+       .se_cmp         = sort__ins_lat_cmp,
        .se_snprintf    = hist_entry__global_ins_lat_snprintf,
        .se_width_idx   = HISTC_GLOBAL_INS_LAT,
 };
@@ -1414,13 +1394,13 @@ struct sort_entry sort_global_ins_lat = {
 static int64_t
 sort__global_p_stage_cyc_cmp(struct hist_entry *left, struct hist_entry *right)
 {
-       return left->stat.p_stage_cyc - right->stat.p_stage_cyc;
+       return left->p_stage_cyc - right->p_stage_cyc;
 }
 
 static int hist_entry__p_stage_cyc_snprintf(struct hist_entry *he, char *bf,
                                        size_t size, unsigned int width)
 {
-       return repsep_snprintf(bf, size, "%-*u", width, he->stat.p_stage_cyc);
+       return repsep_snprintf(bf, size, "%-*u", width, he->p_stage_cyc);
 }
 
 struct sort_entry sort_p_stage_cyc = {
index b67c469..7b71455 100644 (file)
@@ -49,9 +49,6 @@ struct he_stat {
        u64                     period_us;
        u64                     period_guest_sys;
        u64                     period_guest_us;
-       u64                     weight;
-       u64                     ins_lat;
-       u64                     p_stage_cyc;
        u32                     nr_events;
 };
 
@@ -109,6 +106,9 @@ struct hist_entry {
        s32                     socket;
        s32                     cpu;
        u64                     code_page_size;
+       u64                     weight;
+       u64                     ins_lat;
+       u64                     p_stage_cyc;
        u8                      cpumode;
        u8                      depth;
 
index 37a9492..df3c467 100644 (file)
@@ -379,32 +379,32 @@ fetch_kernel_version(unsigned int *puint, char *str,
        return 0;
 }
 
-const char *perf_tip(const char *dirpath)
+int perf_tip(char **strp, const char *dirpath)
 {
        struct strlist *tips;
        struct str_node *node;
-       char *tip = NULL;
        struct strlist_config conf = {
                .dirname = dirpath,
                .file_only = true,
        };
+       int ret = 0;
 
+       *strp = NULL;
        tips = strlist__new("tips.txt", &conf);
        if (tips == NULL)
-               return errno == ENOENT ? NULL :
-                       "Tip: check path of tips.txt or get more memory! ;-p";
+               return -errno;
 
        if (strlist__nr_entries(tips) == 0)
                goto out;
 
        node = strlist__entry(tips, random() % strlist__nr_entries(tips));
-       if (asprintf(&tip, "Tip: %s", node->s) < 0)
-               tip = (char *)"Tip: get more memory! ;-)";
+       if (asprintf(strp, "Tip: %s", node->s) < 0)
+               ret = -ENOMEM;
 
 out:
        strlist__delete(tips);
 
-       return tip;
+       return ret;
 }
 
 char *perf_exe(char *buf, int len)
index ad73705..9f0d36b 100644 (file)
@@ -39,7 +39,7 @@ int fetch_kernel_version(unsigned int *puint,
 #define KVER_FMT       "%d.%d.%d"
 #define KVER_PARAM(x)  KVER_VERSION(x), KVER_PATCHLEVEL(x), KVER_SUBLEVEL(x)
 
-const char *perf_tip(const char *dirpath);
+int perf_tip(char **strp, const char *dirpath);
 
 #ifndef HAVE_SCHED_GETCPU_SUPPORT
 int sched_getcpu(void);
index 54b0a41..62fafbe 100644 (file)
@@ -187,7 +187,7 @@ DEFAULT_BPFTOOL := $(HOST_SCRATCH_DIR)/sbin/bpftool
 $(OUTPUT)/runqslower: $(BPFOBJ) | $(DEFAULT_BPFTOOL) $(RUNQSLOWER_OUTPUT)
        $(Q)$(MAKE) $(submake_extras) -C $(TOOLSDIR)/bpf/runqslower            \
                    OUTPUT=$(RUNQSLOWER_OUTPUT) VMLINUX_BTF=$(VMLINUX_BTF)     \
-                   BPFTOOL_OUTPUT=$(BUILD_DIR)/bpftool/                       \
+                   BPFTOOL_OUTPUT=$(HOST_BUILD_DIR)/bpftool/                  \
                    BPFOBJ_OUTPUT=$(BUILD_DIR)/libbpf                          \
                    BPFOBJ=$(BPFOBJ) BPF_INCLUDE=$(INCLUDE_DIR) &&             \
                    cp $(RUNQSLOWER_OUTPUT)runqslower $@
diff --git a/tools/testing/selftests/bpf/prog_tests/helper_restricted.c b/tools/testing/selftests/bpf/prog_tests/helper_restricted.c
new file mode 100644 (file)
index 0000000..e1de5f8
--- /dev/null
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <test_progs.h>
+#include "test_helper_restricted.skel.h"
+
+void test_helper_restricted(void)
+{
+       int prog_i = 0, prog_cnt;
+       int duration = 0;
+
+       do {
+               struct test_helper_restricted *test;
+               int maybeOK;
+
+               test = test_helper_restricted__open();
+               if (!ASSERT_OK_PTR(test, "open"))
+                       return;
+
+               prog_cnt = test->skeleton->prog_cnt;
+
+               for (int j = 0; j < prog_cnt; ++j) {
+                       struct bpf_program *prog = *test->skeleton->progs[j].prog;
+
+                       maybeOK = bpf_program__set_autoload(prog, prog_i == j);
+                       ASSERT_OK(maybeOK, "set autoload");
+               }
+
+               maybeOK = test_helper_restricted__load(test);
+               CHECK(!maybeOK, test->skeleton->progs[prog_i].name, "helper isn't restricted");
+
+               test_helper_restricted__destroy(test);
+       } while (++prog_i < prog_cnt);
+}
diff --git a/tools/testing/selftests/bpf/progs/test_helper_restricted.c b/tools/testing/selftests/bpf/progs/test_helper_restricted.c
new file mode 100644 (file)
index 0000000..68d64c3
--- /dev/null
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <time.h>
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+
+struct timer {
+       struct bpf_timer t;
+};
+
+struct lock {
+       struct bpf_spin_lock l;
+};
+
+struct {
+       __uint(type, BPF_MAP_TYPE_ARRAY);
+       __uint(max_entries, 1);
+       __type(key, __u32);
+       __type(value, struct timer);
+} timers SEC(".maps");
+
+struct {
+       __uint(type, BPF_MAP_TYPE_ARRAY);
+       __uint(max_entries, 1);
+       __type(key, __u32);
+       __type(value, struct lock);
+} locks SEC(".maps");
+
+static int timer_cb(void *map, int *key, struct timer *timer)
+{
+       return 0;
+}
+
+static void timer_work(void)
+{
+       struct timer *timer;
+       const int key = 0;
+
+       timer  = bpf_map_lookup_elem(&timers, &key);
+       if (timer) {
+               bpf_timer_init(&timer->t, &timers, CLOCK_MONOTONIC);
+               bpf_timer_set_callback(&timer->t, timer_cb);
+               bpf_timer_start(&timer->t, 10E9, 0);
+               bpf_timer_cancel(&timer->t);
+       }
+}
+
+static void spin_lock_work(void)
+{
+       const int key = 0;
+       struct lock *lock;
+
+       lock = bpf_map_lookup_elem(&locks, &key);
+       if (lock) {
+               bpf_spin_lock(&lock->l);
+               bpf_spin_unlock(&lock->l);
+       }
+}
+
+SEC("raw_tp/sys_enter")
+int raw_tp_timer(void *ctx)
+{
+       timer_work();
+
+       return 0;
+}
+
+SEC("tp/syscalls/sys_enter_nanosleep")
+int tp_timer(void *ctx)
+{
+       timer_work();
+
+       return 0;
+}
+
+SEC("kprobe/sys_nanosleep")
+int kprobe_timer(void *ctx)
+{
+       timer_work();
+
+       return 0;
+}
+
+SEC("perf_event")
+int perf_event_timer(void *ctx)
+{
+       timer_work();
+
+       return 0;
+}
+
+SEC("raw_tp/sys_enter")
+int raw_tp_spin_lock(void *ctx)
+{
+       spin_lock_work();
+
+       return 0;
+}
+
+SEC("tp/syscalls/sys_enter_nanosleep")
+int tp_spin_lock(void *ctx)
+{
+       spin_lock_work();
+
+       return 0;
+}
+
+SEC("kprobe/sys_nanosleep")
+int kprobe_spin_lock(void *ctx)
+{
+       spin_lock_work();
+
+       return 0;
+}
+
+SEC("perf_event")
+int perf_event_spin_lock(void *ctx)
+{
+       spin_lock_work();
+
+       return 0;
+}
+
+const char LICENSE[] SEC("license") = "GPL";
index 25afe42..465ef3f 100644 (file)
@@ -92,6 +92,7 @@ struct bpf_test {
        int fixup_map_event_output[MAX_FIXUPS];
        int fixup_map_reuseport_array[MAX_FIXUPS];
        int fixup_map_ringbuf[MAX_FIXUPS];
+       int fixup_map_timer[MAX_FIXUPS];
        /* Expected verifier log output for result REJECT or VERBOSE_ACCEPT.
         * Can be a tab-separated sequence of expected strings. An empty string
         * means no log verification.
@@ -604,8 +605,15 @@ static int create_cgroup_storage(bool percpu)
  *   int cnt;
  *   struct bpf_spin_lock l;
  * };
+ * struct bpf_timer {
+ *   __u64 :64;
+ *   __u64 :64;
+ * } __attribute__((aligned(8)));
+ * struct timer {
+ *   struct bpf_timer t;
+ * };
  */
-static const char btf_str_sec[] = "\0bpf_spin_lock\0val\0cnt\0l";
+static const char btf_str_sec[] = "\0bpf_spin_lock\0val\0cnt\0l\0bpf_timer\0timer\0t";
 static __u32 btf_raw_types[] = {
        /* int */
        BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
@@ -616,6 +624,11 @@ static __u32 btf_raw_types[] = {
        BTF_TYPE_ENC(15, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
        BTF_MEMBER_ENC(19, 1, 0), /* int cnt; */
        BTF_MEMBER_ENC(23, 2, 32),/* struct bpf_spin_lock l; */
+       /* struct bpf_timer */                          /* [4] */
+       BTF_TYPE_ENC(25, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 0), 16),
+       /* struct timer */                              /* [5] */
+       BTF_TYPE_ENC(35, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 16),
+       BTF_MEMBER_ENC(41, 4, 0), /* struct bpf_timer t; */
 };
 
 static int load_btf(void)
@@ -696,6 +709,29 @@ static int create_sk_storage_map(void)
        return fd;
 }
 
+static int create_map_timer(void)
+{
+       struct bpf_create_map_attr attr = {
+               .name = "test_map",
+               .map_type = BPF_MAP_TYPE_ARRAY,
+               .key_size = 4,
+               .value_size = 16,
+               .max_entries = 1,
+               .btf_key_type_id = 1,
+               .btf_value_type_id = 5,
+       };
+       int fd, btf_fd;
+
+       btf_fd = load_btf();
+       if (btf_fd < 0)
+               return -1;
+       attr.btf_fd = btf_fd;
+       fd = bpf_create_map_xattr(&attr);
+       if (fd < 0)
+               printf("Failed to create map with timer\n");
+       return fd;
+}
+
 static char bpf_vlog[UINT_MAX >> 8];
 
 static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type,
@@ -722,6 +758,7 @@ static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type,
        int *fixup_map_event_output = test->fixup_map_event_output;
        int *fixup_map_reuseport_array = test->fixup_map_reuseport_array;
        int *fixup_map_ringbuf = test->fixup_map_ringbuf;
+       int *fixup_map_timer = test->fixup_map_timer;
 
        if (test->fill_helper) {
                test->fill_insns = calloc(MAX_TEST_INSNS, sizeof(struct bpf_insn));
@@ -907,6 +944,13 @@ static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type,
                        fixup_map_ringbuf++;
                } while (*fixup_map_ringbuf);
        }
+       if (*fixup_map_timer) {
+               map_fds[21] = create_map_timer();
+               do {
+                       prog[*fixup_map_timer].imm = map_fds[21];
+                       fixup_map_timer++;
+               } while (*fixup_map_timer);
+       }
 }
 
 struct libcap {
diff --git a/tools/testing/selftests/bpf/verifier/helper_restricted.c b/tools/testing/selftests/bpf/verifier/helper_restricted.c
new file mode 100644 (file)
index 0000000..a067b70
--- /dev/null
@@ -0,0 +1,196 @@
+{
+       "bpf_ktime_get_coarse_ns is forbidden in BPF_PROG_TYPE_KPROBE",
+       .insns = {
+               BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ktime_get_coarse_ns),
+               BPF_MOV64_IMM(BPF_REG_0, 0),
+               BPF_EXIT_INSN(),
+       },
+       .errstr = "unknown func bpf_ktime_get_coarse_ns",
+       .result = REJECT,
+       .prog_type = BPF_PROG_TYPE_KPROBE,
+},
+{
+       "bpf_ktime_get_coarse_ns is forbidden in BPF_PROG_TYPE_TRACEPOINT",
+       .insns = {
+               BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ktime_get_coarse_ns),
+               BPF_MOV64_IMM(BPF_REG_0, 0),
+               BPF_EXIT_INSN(),
+       },
+       .errstr = "unknown func bpf_ktime_get_coarse_ns",
+       .result = REJECT,
+       .prog_type = BPF_PROG_TYPE_TRACEPOINT,
+},
+{
+       "bpf_ktime_get_coarse_ns is forbidden in BPF_PROG_TYPE_PERF_EVENT",
+       .insns = {
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ktime_get_coarse_ns),
+       BPF_MOV64_IMM(BPF_REG_0, 0),
+       BPF_EXIT_INSN(),
+       },
+       .errstr = "unknown func bpf_ktime_get_coarse_ns",
+       .result = REJECT,
+       .prog_type = BPF_PROG_TYPE_PERF_EVENT,
+},
+{
+       "bpf_ktime_get_coarse_ns is forbidden in BPF_PROG_TYPE_RAW_TRACEPOINT",
+       .insns = {
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ktime_get_coarse_ns),
+       BPF_MOV64_IMM(BPF_REG_0, 0),
+       BPF_EXIT_INSN(),
+       },
+       .errstr = "unknown func bpf_ktime_get_coarse_ns",
+       .result = REJECT,
+       .prog_type = BPF_PROG_TYPE_RAW_TRACEPOINT,
+},
+{
+       "bpf_timer_init isn restricted in BPF_PROG_TYPE_KPROBE",
+       .insns = {
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+       BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+       BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
+       BPF_LD_MAP_FD(BPF_REG_1, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
+       BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
+       BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
+       BPF_LD_MAP_FD(BPF_REG_2, 0),
+       BPF_MOV64_IMM(BPF_REG_3, 1),
+       BPF_EMIT_CALL(BPF_FUNC_timer_init),
+       BPF_EXIT_INSN(),
+       },
+       .fixup_map_timer = { 3, 8 },
+       .errstr = "tracing progs cannot use bpf_timer yet",
+       .result = REJECT,
+       .prog_type = BPF_PROG_TYPE_KPROBE,
+},
+{
+       "bpf_timer_init is forbidden in BPF_PROG_TYPE_PERF_EVENT",
+       .insns = {
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+       BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+       BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
+       BPF_LD_MAP_FD(BPF_REG_1, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
+       BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
+       BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
+       BPF_LD_MAP_FD(BPF_REG_2, 0),
+       BPF_MOV64_IMM(BPF_REG_3, 1),
+       BPF_EMIT_CALL(BPF_FUNC_timer_init),
+       BPF_EXIT_INSN(),
+       },
+       .fixup_map_timer = { 3, 8 },
+       .errstr = "tracing progs cannot use bpf_timer yet",
+       .result = REJECT,
+       .prog_type = BPF_PROG_TYPE_PERF_EVENT,
+},
+{
+       "bpf_timer_init is forbidden in BPF_PROG_TYPE_TRACEPOINT",
+       .insns = {
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+       BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+       BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
+       BPF_LD_MAP_FD(BPF_REG_1, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
+       BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
+       BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
+       BPF_LD_MAP_FD(BPF_REG_2, 0),
+       BPF_MOV64_IMM(BPF_REG_3, 1),
+       BPF_EMIT_CALL(BPF_FUNC_timer_init),
+       BPF_EXIT_INSN(),
+       },
+       .fixup_map_timer = { 3, 8 },
+       .errstr = "tracing progs cannot use bpf_timer yet",
+       .result = REJECT,
+       .prog_type = BPF_PROG_TYPE_TRACEPOINT,
+},
+{
+       "bpf_timer_init is forbidden in BPF_PROG_TYPE_RAW_TRACEPOINT",
+       .insns = {
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+       BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+       BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
+       BPF_LD_MAP_FD(BPF_REG_1, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
+       BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
+       BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
+       BPF_LD_MAP_FD(BPF_REG_2, 0),
+       BPF_MOV64_IMM(BPF_REG_3, 1),
+       BPF_EMIT_CALL(BPF_FUNC_timer_init),
+       BPF_EXIT_INSN(),
+       },
+       .fixup_map_timer = { 3, 8 },
+       .errstr = "tracing progs cannot use bpf_timer yet",
+       .result = REJECT,
+       .prog_type = BPF_PROG_TYPE_RAW_TRACEPOINT,
+},
+{
+       "bpf_spin_lock is forbidden in BPF_PROG_TYPE_KPROBE",
+       .insns = {
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+       BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+       BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
+       BPF_LD_MAP_FD(BPF_REG_1, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
+       BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
+       BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
+       BPF_EMIT_CALL(BPF_FUNC_spin_lock),
+       BPF_EXIT_INSN(),
+       },
+       .fixup_map_spin_lock = { 3 },
+       .errstr = "tracing progs cannot use bpf_spin_lock yet",
+       .result = REJECT,
+       .prog_type = BPF_PROG_TYPE_KPROBE,
+},
+{
+       "bpf_spin_lock is forbidden in BPF_PROG_TYPE_TRACEPOINT",
+       .insns = {
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+       BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+       BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
+       BPF_LD_MAP_FD(BPF_REG_1, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
+       BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
+       BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
+       BPF_EMIT_CALL(BPF_FUNC_spin_lock),
+       BPF_EXIT_INSN(),
+       },
+       .fixup_map_spin_lock = { 3 },
+       .errstr = "tracing progs cannot use bpf_spin_lock yet",
+       .result = REJECT,
+       .prog_type = BPF_PROG_TYPE_TRACEPOINT,
+},
+{
+       "bpf_spin_lock is forbidden in BPF_PROG_TYPE_PERF_EVENT",
+       .insns = {
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+       BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+       BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
+       BPF_LD_MAP_FD(BPF_REG_1, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
+       BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
+       BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
+       BPF_EMIT_CALL(BPF_FUNC_spin_lock),
+       BPF_EXIT_INSN(),
+       },
+       .fixup_map_spin_lock = { 3 },
+       .errstr = "tracing progs cannot use bpf_spin_lock yet",
+       .result = REJECT,
+       .prog_type = BPF_PROG_TYPE_PERF_EVENT,
+},
+{
+       "bpf_spin_lock is forbidden in BPF_PROG_TYPE_RAW_TRACEPOINT",
+       .insns = {
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+       BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+       BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
+       BPF_LD_MAP_FD(BPF_REG_1, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
+       BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
+       BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
+       BPF_EMIT_CALL(BPF_FUNC_spin_lock),
+       BPF_EXIT_INSN(),
+       },
+       .fixup_map_spin_lock = { 3 },
+       .errstr = "tracing progs cannot use bpf_spin_lock yet",
+       .result = REJECT,
+       .prog_type = BPF_PROG_TYPE_RAW_TRACEPOINT,
+},
index 2798927..128a348 100644 (file)
        .fixup_map_in_map = { 3 },
        .result = ACCEPT,
 },
+{
+       "map in map state pruning",
+       .insns = {
+       BPF_ST_MEM(0, BPF_REG_10, -4, 0),
+       BPF_MOV64_REG(BPF_REG_6, BPF_REG_10),
+       BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -4),
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_6),
+       BPF_LD_MAP_FD(BPF_REG_1, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
+       BPF_EXIT_INSN(),
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_6),
+       BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 11),
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_6),
+       BPF_LD_MAP_FD(BPF_REG_1, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
+       BPF_EXIT_INSN(),
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_6),
+       BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
+       BPF_EXIT_INSN(),
+       BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0),
+       BPF_EXIT_INSN(),
+       },
+       .fixup_map_in_map = { 4, 14 },
+       .flags = BPF_F_TEST_STATE_FREQ,
+       .result = VERBOSE_ACCEPT,
+       .errstr = "processed 25 insns",
+       .prog_type = BPF_PROG_TYPE_XDP,
+},
 {
        "invalid inner map pointer",
        .insns = {
index 39f2bbe..d7b312b 100644 (file)
@@ -3,5 +3,6 @@
 TEST_PROGS := gpio-mockup.sh
 TEST_FILES := gpio-mockup-sysfs.sh
 TEST_GEN_PROGS_EXTENDED := gpio-mockup-cdev
+CFLAGS += -O2 -g -Wall -I../../../../usr/include/
 
 include ../lib.mk
index e83eac7..d1640f4 100644 (file)
@@ -117,7 +117,7 @@ int main(int argc, char *argv[])
 {
        char *chip;
        int opt, ret, cfd, lfd;
-       unsigned int offset, val, abiv;
+       unsigned int offset, val = 0, abiv;
        uint32_t flags_v1;
        uint64_t flags_v2;
 
index d4a8301..3763105 100644 (file)
@@ -23,6 +23,7 @@
 /x86_64/platform_info_test
 /x86_64/set_boot_cpu_id
 /x86_64/set_sregs_test
+/x86_64/sev_migrate_tests
 /x86_64/smm_test
 /x86_64/state_test
 /x86_64/svm_vmcall_test
index 5d95113..d890903 100644 (file)
@@ -47,7 +47,7 @@
 #include "guest_modes.h"
 
 /* Global variable used to synchronize all of the vCPU threads. */
-static int iteration = -1;
+static int iteration;
 
 /* Defines what vCPU threads should do during a given iteration. */
 static enum {
@@ -215,12 +215,11 @@ static bool spin_wait_for_next_iteration(int *current_iteration)
        return true;
 }
 
-static void *vcpu_thread_main(void *arg)
+static void vcpu_thread_main(struct perf_test_vcpu_args *vcpu_args)
 {
-       struct perf_test_vcpu_args *vcpu_args = arg;
        struct kvm_vm *vm = perf_test_args.vm;
        int vcpu_id = vcpu_args->vcpu_id;
-       int current_iteration = -1;
+       int current_iteration = 0;
 
        while (spin_wait_for_next_iteration(&current_iteration)) {
                switch (READ_ONCE(iteration_work)) {
@@ -235,8 +234,6 @@ static void *vcpu_thread_main(void *arg)
 
                vcpu_last_completed_iteration[vcpu_id] = current_iteration;
        }
-
-       return NULL;
 }
 
 static void spin_wait_for_vcpu(int vcpu_id, int target_iteration)
@@ -277,8 +274,7 @@ static void run_iteration(struct kvm_vm *vm, int vcpus, const char *description)
 static void access_memory(struct kvm_vm *vm, int vcpus, enum access_type access,
                          const char *description)
 {
-       perf_test_args.wr_fract = (access == ACCESS_READ) ? INT_MAX : 1;
-       sync_global_to_guest(vm, perf_test_args);
+       perf_test_set_wr_fract(vm, (access == ACCESS_READ) ? INT_MAX : 1);
        iteration_work = ITERATION_ACCESS_MEMORY;
        run_iteration(vm, vcpus, description);
 }
@@ -296,48 +292,16 @@ static void mark_memory_idle(struct kvm_vm *vm, int vcpus)
        run_iteration(vm, vcpus, "Mark memory idle");
 }
 
-static pthread_t *create_vcpu_threads(int vcpus)
-{
-       pthread_t *vcpu_threads;
-       int i;
-
-       vcpu_threads = malloc(vcpus * sizeof(vcpu_threads[0]));
-       TEST_ASSERT(vcpu_threads, "Failed to allocate vcpu_threads.");
-
-       for (i = 0; i < vcpus; i++) {
-               vcpu_last_completed_iteration[i] = iteration;
-               pthread_create(&vcpu_threads[i], NULL, vcpu_thread_main,
-                              &perf_test_args.vcpu_args[i]);
-       }
-
-       return vcpu_threads;
-}
-
-static void terminate_vcpu_threads(pthread_t *vcpu_threads, int vcpus)
-{
-       int i;
-
-       /* Set done to signal the vCPU threads to exit */
-       done = true;
-
-       for (i = 0; i < vcpus; i++)
-               pthread_join(vcpu_threads[i], NULL);
-}
-
 static void run_test(enum vm_guest_mode mode, void *arg)
 {
        struct test_params *params = arg;
        struct kvm_vm *vm;
-       pthread_t *vcpu_threads;
        int vcpus = params->vcpus;
 
        vm = perf_test_create_vm(mode, vcpus, params->vcpu_memory_bytes, 1,
-                                params->backing_src);
+                                params->backing_src, !overlap_memory_access);
 
-       perf_test_setup_vcpus(vm, vcpus, params->vcpu_memory_bytes,
-                             !overlap_memory_access);
-
-       vcpu_threads = create_vcpu_threads(vcpus);
+       perf_test_start_vcpu_threads(vcpus, vcpu_thread_main);
 
        pr_info("\n");
        access_memory(vm, vcpus, ACCESS_WRITE, "Populating memory");
@@ -352,8 +316,10 @@ static void run_test(enum vm_guest_mode mode, void *arg)
        mark_memory_idle(vm, vcpus);
        access_memory(vm, vcpus, ACCESS_READ, "Reading from idle memory");
 
-       terminate_vcpu_threads(vcpu_threads, vcpus);
-       free(vcpu_threads);
+       /* Set done to signal the vCPU threads to exit */
+       done = true;
+
+       perf_test_join_vcpu_threads(vcpus);
        perf_test_destroy_vm(vm);
 }
 
index 1510b21..6a719d0 100644 (file)
@@ -42,10 +42,9 @@ static uint64_t guest_percpu_mem_size = DEFAULT_PER_VCPU_MEM_SIZE;
 static size_t demand_paging_size;
 static char *guest_data_prototype;
 
-static void *vcpu_worker(void *data)
+static void vcpu_worker(struct perf_test_vcpu_args *vcpu_args)
 {
        int ret;
-       struct perf_test_vcpu_args *vcpu_args = (struct perf_test_vcpu_args *)data;
        int vcpu_id = vcpu_args->vcpu_id;
        struct kvm_vm *vm = perf_test_args.vm;
        struct kvm_run *run;
@@ -68,8 +67,6 @@ static void *vcpu_worker(void *data)
        ts_diff = timespec_elapsed(start);
        PER_VCPU_DEBUG("vCPU %d execution time: %ld.%.9lds\n", vcpu_id,
                       ts_diff.tv_sec, ts_diff.tv_nsec);
-
-       return NULL;
 }
 
 static int handle_uffd_page_request(int uffd_mode, int uffd, uint64_t addr)
@@ -282,7 +279,6 @@ struct test_params {
 static void run_test(enum vm_guest_mode mode, void *arg)
 {
        struct test_params *p = arg;
-       pthread_t *vcpu_threads;
        pthread_t *uffd_handler_threads = NULL;
        struct uffd_handler_args *uffd_args = NULL;
        struct timespec start;
@@ -293,9 +289,7 @@ static void run_test(enum vm_guest_mode mode, void *arg)
        int r;
 
        vm = perf_test_create_vm(mode, nr_vcpus, guest_percpu_mem_size, 1,
-                                p->src_type);
-
-       perf_test_args.wr_fract = 1;
+                                p->src_type, p->partition_vcpu_memory_access);
 
        demand_paging_size = get_backing_src_pagesz(p->src_type);
 
@@ -304,12 +298,6 @@ static void run_test(enum vm_guest_mode mode, void *arg)
                    "Failed to allocate buffer for guest data pattern");
        memset(guest_data_prototype, 0xAB, demand_paging_size);
 
-       vcpu_threads = malloc(nr_vcpus * sizeof(*vcpu_threads));
-       TEST_ASSERT(vcpu_threads, "Memory allocation failed");
-
-       perf_test_setup_vcpus(vm, nr_vcpus, guest_percpu_mem_size,
-                             p->partition_vcpu_memory_access);
-
        if (p->uffd_mode) {
                uffd_handler_threads =
                        malloc(nr_vcpus * sizeof(*uffd_handler_threads));
@@ -322,26 +310,15 @@ static void run_test(enum vm_guest_mode mode, void *arg)
                TEST_ASSERT(pipefds, "Unable to allocate memory for pipefd");
 
                for (vcpu_id = 0; vcpu_id < nr_vcpus; vcpu_id++) {
-                       vm_paddr_t vcpu_gpa;
+                       struct perf_test_vcpu_args *vcpu_args;
                        void *vcpu_hva;
                        void *vcpu_alias;
-                       uint64_t vcpu_mem_size;
-
 
-                       if (p->partition_vcpu_memory_access) {
-                               vcpu_gpa = guest_test_phys_mem +
-                                          (vcpu_id * guest_percpu_mem_size);
-                               vcpu_mem_size = guest_percpu_mem_size;
-                       } else {
-                               vcpu_gpa = guest_test_phys_mem;
-                               vcpu_mem_size = guest_percpu_mem_size * nr_vcpus;
-                       }
-                       PER_VCPU_DEBUG("Added VCPU %d with test mem gpa [%lx, %lx)\n",
-                                      vcpu_id, vcpu_gpa, vcpu_gpa + vcpu_mem_size);
+                       vcpu_args = &perf_test_args.vcpu_args[vcpu_id];
 
                        /* Cache the host addresses of the region */
-                       vcpu_hva = addr_gpa2hva(vm, vcpu_gpa);
-                       vcpu_alias = addr_gpa2alias(vm, vcpu_gpa);
+                       vcpu_hva = addr_gpa2hva(vm, vcpu_args->gpa);
+                       vcpu_alias = addr_gpa2alias(vm, vcpu_args->gpa);
 
                        /*
                         * Set up user fault fd to handle demand paging
@@ -355,32 +332,18 @@ static void run_test(enum vm_guest_mode mode, void *arg)
                                            pipefds[vcpu_id * 2], p->uffd_mode,
                                            p->uffd_delay, &uffd_args[vcpu_id],
                                            vcpu_hva, vcpu_alias,
-                                           vcpu_mem_size);
+                                           vcpu_args->pages * perf_test_args.guest_page_size);
                }
        }
 
-       /* Export the shared variables to the guest */
-       sync_global_to_guest(vm, perf_test_args);
-
        pr_info("Finished creating vCPUs and starting uffd threads\n");
 
        clock_gettime(CLOCK_MONOTONIC, &start);
-
-       for (vcpu_id = 0; vcpu_id < nr_vcpus; vcpu_id++) {
-               pthread_create(&vcpu_threads[vcpu_id], NULL, vcpu_worker,
-                              &perf_test_args.vcpu_args[vcpu_id]);
-       }
-
+       perf_test_start_vcpu_threads(nr_vcpus, vcpu_worker);
        pr_info("Started all vCPUs\n");
 
-       /* Wait for the vcpu threads to quit */
-       for (vcpu_id = 0; vcpu_id < nr_vcpus; vcpu_id++) {
-               pthread_join(vcpu_threads[vcpu_id], NULL);
-               PER_VCPU_DEBUG("Joined thread for vCPU %d\n", vcpu_id);
-       }
-
+       perf_test_join_vcpu_threads(nr_vcpus);
        ts_diff = timespec_elapsed(start);
-
        pr_info("All vCPU threads joined\n");
 
        if (p->uffd_mode) {
@@ -404,7 +367,6 @@ static void run_test(enum vm_guest_mode mode, void *arg)
        perf_test_destroy_vm(vm);
 
        free(guest_data_prototype);
-       free(vcpu_threads);
        if (p->uffd_mode) {
                free(uffd_handler_threads);
                free(uffd_args);
index 7ffab5b..1954b96 100644 (file)
@@ -31,7 +31,7 @@ static bool host_quit;
 static int iteration;
 static int vcpu_last_completed_iteration[KVM_MAX_VCPUS];
 
-static void *vcpu_worker(void *data)
+static void vcpu_worker(struct perf_test_vcpu_args *vcpu_args)
 {
        int ret;
        struct kvm_vm *vm = perf_test_args.vm;
@@ -41,7 +41,6 @@ static void *vcpu_worker(void *data)
        struct timespec ts_diff;
        struct timespec total = (struct timespec){0};
        struct timespec avg;
-       struct perf_test_vcpu_args *vcpu_args = (struct perf_test_vcpu_args *)data;
        int vcpu_id = vcpu_args->vcpu_id;
 
        run = vcpu_state(vm, vcpu_id);
@@ -83,8 +82,6 @@ static void *vcpu_worker(void *data)
        pr_debug("\nvCPU %d dirtied 0x%lx pages over %d iterations in %ld.%.9lds. (Avg %ld.%.9lds/iteration)\n",
                vcpu_id, pages_count, vcpu_last_completed_iteration[vcpu_id],
                total.tv_sec, total.tv_nsec, avg.tv_sec, avg.tv_nsec);
-
-       return NULL;
 }
 
 struct test_params {
@@ -170,7 +167,6 @@ static void free_bitmaps(unsigned long *bitmaps[], int slots)
 static void run_test(enum vm_guest_mode mode, void *arg)
 {
        struct test_params *p = arg;
-       pthread_t *vcpu_threads;
        struct kvm_vm *vm;
        unsigned long **bitmaps;
        uint64_t guest_num_pages;
@@ -186,9 +182,10 @@ static void run_test(enum vm_guest_mode mode, void *arg)
        struct timespec clear_dirty_log_total = (struct timespec){0};
 
        vm = perf_test_create_vm(mode, nr_vcpus, guest_percpu_mem_size,
-                                p->slots, p->backing_src);
+                                p->slots, p->backing_src,
+                                p->partition_vcpu_memory_access);
 
-       perf_test_args.wr_fract = p->wr_fract;
+       perf_test_set_wr_fract(vm, p->wr_fract);
 
        guest_num_pages = (nr_vcpus * guest_percpu_mem_size) >> vm_get_page_shift(vm);
        guest_num_pages = vm_adjust_num_guest_pages(mode, guest_num_pages);
@@ -203,25 +200,15 @@ static void run_test(enum vm_guest_mode mode, void *arg)
                vm_enable_cap(vm, &cap);
        }
 
-       vcpu_threads = malloc(nr_vcpus * sizeof(*vcpu_threads));
-       TEST_ASSERT(vcpu_threads, "Memory allocation failed");
-
-       perf_test_setup_vcpus(vm, nr_vcpus, guest_percpu_mem_size,
-                             p->partition_vcpu_memory_access);
-
-       sync_global_to_guest(vm, perf_test_args);
-
        /* Start the iterations */
        iteration = 0;
        host_quit = false;
 
        clock_gettime(CLOCK_MONOTONIC, &start);
-       for (vcpu_id = 0; vcpu_id < nr_vcpus; vcpu_id++) {
+       for (vcpu_id = 0; vcpu_id < nr_vcpus; vcpu_id++)
                vcpu_last_completed_iteration[vcpu_id] = -1;
 
-               pthread_create(&vcpu_threads[vcpu_id], NULL, vcpu_worker,
-                              &perf_test_args.vcpu_args[vcpu_id]);
-       }
+       perf_test_start_vcpu_threads(nr_vcpus, vcpu_worker);
 
        /* Allow the vCPUs to populate memory */
        pr_debug("Starting iteration %d - Populating\n", iteration);
@@ -290,8 +277,7 @@ static void run_test(enum vm_guest_mode mode, void *arg)
 
        /* Tell the vcpu thread to quit */
        host_quit = true;
-       for (vcpu_id = 0; vcpu_id < nr_vcpus; vcpu_id++)
-               pthread_join(vcpu_threads[vcpu_id], NULL);
+       perf_test_join_vcpu_threads(nr_vcpus);
 
        avg = timespec_div(get_dirty_log_total, p->iterations);
        pr_info("Get dirty log over %lu iterations took %ld.%.9lds. (Avg %ld.%.9lds/iteration)\n",
@@ -306,7 +292,6 @@ static void run_test(enum vm_guest_mode mode, void *arg)
        }
 
        free_bitmaps(bitmaps, p->slots);
-       free(vcpu_threads);
        perf_test_destroy_vm(vm);
 }
 
index 792c60e..3fcd89e 100644 (file)
@@ -115,7 +115,7 @@ static void guest_code(void)
                        addr = guest_test_virt_mem;
                        addr += (READ_ONCE(random_array[i]) % guest_num_pages)
                                * guest_page_size;
-                       addr &= ~(host_page_size - 1);
+                       addr = align_down(addr, host_page_size);
                        *(uint64_t *)addr = READ_ONCE(iteration);
                }
 
@@ -737,14 +737,14 @@ static void run_test(enum vm_guest_mode mode, void *arg)
        if (!p->phys_offset) {
                guest_test_phys_mem = (vm_get_max_gfn(vm) -
                                       guest_num_pages) * guest_page_size;
-               guest_test_phys_mem &= ~(host_page_size - 1);
+               guest_test_phys_mem = align_down(guest_test_phys_mem, host_page_size);
        } else {
                guest_test_phys_mem = p->phys_offset;
        }
 
 #ifdef __s390x__
        /* Align to 1M (segment size) */
-       guest_test_phys_mem &= ~((1 << 20) - 1);
+       guest_test_phys_mem = align_down(guest_test_phys_mem, 1 << 20);
 #endif
 
        pr_info("guest physical test memory offset: 0x%lx\n", guest_test_phys_mem);
index df9f1a3..a86f953 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef SELFTEST_KVM_PERF_TEST_UTIL_H
 #define SELFTEST_KVM_PERF_TEST_UTIL_H
 
+#include <pthread.h>
+
 #include "kvm_util.h"
 
 /* Default guest test virtual memory offset */
@@ -18,6 +20,7 @@
 #define PERF_TEST_MEM_SLOT_INDEX       1
 
 struct perf_test_vcpu_args {
+       uint64_t gpa;
        uint64_t gva;
        uint64_t pages;
 
@@ -27,7 +30,7 @@ struct perf_test_vcpu_args {
 
 struct perf_test_args {
        struct kvm_vm *vm;
-       uint64_t host_page_size;
+       uint64_t gpa;
        uint64_t guest_page_size;
        int wr_fract;
 
@@ -36,19 +39,15 @@ struct perf_test_args {
 
 extern struct perf_test_args perf_test_args;
 
-/*
- * Guest physical memory offset of the testing memory slot.
- * This will be set to the topmost valid physical address minus
- * the test memory size.
- */
-extern uint64_t guest_test_phys_mem;
-
 struct kvm_vm *perf_test_create_vm(enum vm_guest_mode mode, int vcpus,
                                   uint64_t vcpu_memory_bytes, int slots,
-                                  enum vm_mem_backing_src_type backing_src);
+                                  enum vm_mem_backing_src_type backing_src,
+                                  bool partition_vcpu_memory_access);
 void perf_test_destroy_vm(struct kvm_vm *vm);
-void perf_test_setup_vcpus(struct kvm_vm *vm, int vcpus,
-                          uint64_t vcpu_memory_bytes,
-                          bool partition_vcpu_memory_access);
+
+void perf_test_set_wr_fract(struct kvm_vm *vm, int wr_fract);
+
+void perf_test_start_vcpu_threads(int vcpus, void (*vcpu_fn)(struct perf_test_vcpu_args *));
+void perf_test_join_vcpu_threads(int vcpus);
 
 #endif /* SELFTEST_KVM_PERF_TEST_UTIL_H */
index f8fddc8..99e0dcd 100644 (file)
@@ -104,6 +104,7 @@ size_t get_trans_hugepagesz(void);
 size_t get_def_hugetlb_pagesz(void);
 const struct vm_mem_backing_src_alias *vm_mem_backing_src_alias(uint32_t i);
 size_t get_backing_src_pagesz(uint32_t i);
+bool is_backing_src_hugetlb(uint32_t i);
 void backing_src_help(const char *flag);
 enum vm_mem_backing_src_type parse_backing_src_type(const char *type_name);
 long get_run_delay(void);
@@ -117,4 +118,29 @@ static inline bool backing_src_is_shared(enum vm_mem_backing_src_type t)
        return vm_mem_backing_src_alias(t)->flag & MAP_SHARED;
 }
 
+/* Aligns x up to the next multiple of size. Size must be a power of 2. */
+static inline uint64_t align_up(uint64_t x, uint64_t size)
+{
+       uint64_t mask = size - 1;
+
+       TEST_ASSERT(size != 0 && !(size & (size - 1)),
+                   "size not a power of 2: %lu", size);
+       return ((x + mask) & ~mask);
+}
+
+static inline uint64_t align_down(uint64_t x, uint64_t size)
+{
+       uint64_t x_aligned_up = align_up(x, size);
+
+       if (x == x_aligned_up)
+               return x;
+       else
+               return x_aligned_up - size;
+}
+
+static inline void *align_ptr_up(void *x, size_t size)
+{
+       return (void *)align_up((unsigned long)x, size);
+}
+
 #endif /* SELFTEST_KVM_TEST_UTIL_H */
index 36407cb..3836322 100644 (file)
@@ -280,7 +280,7 @@ static struct kvm_vm *pre_init_before_test(enum vm_guest_mode mode, void *arg)
 #ifdef __s390x__
        alignment = max(0x100000, alignment);
 #endif
-       guest_test_phys_mem &= ~(alignment - 1);
+       guest_test_phys_mem = align_down(guest_test_virt_mem, alignment);
 
        /* Set up the shared data structure test_args */
        test_args.vm = vm;
index eac44f5..13e8e3d 100644 (file)
@@ -157,8 +157,7 @@ void kvm_vm_elf_load(struct kvm_vm *vm, const char *filename)
                        "memsize of 0,\n"
                        "  phdr index: %u p_memsz: 0x%" PRIx64,
                        n1, (uint64_t) phdr.p_memsz);
-               vm_vaddr_t seg_vstart = phdr.p_vaddr;
-               seg_vstart &= ~(vm_vaddr_t)(vm->page_size - 1);
+               vm_vaddr_t seg_vstart = align_down(phdr.p_vaddr, vm->page_size);
                vm_vaddr_t seg_vend = phdr.p_vaddr + phdr.p_memsz - 1;
                seg_vend |= vm->page_size - 1;
                size_t seg_size = seg_vend - seg_vstart + 1;
index 14bb4d5..8f2e0bb 100644 (file)
 
 static int vcpu_mmap_sz(void);
 
-/* Aligns x up to the next multiple of size. Size must be a power of 2. */
-static void *align(void *x, size_t size)
-{
-       size_t mask = size - 1;
-       TEST_ASSERT(size != 0 && !(size & (size - 1)),
-                   "size not a power of 2: %lu", size);
-       return (void *) (((size_t) x + mask) & ~mask);
-}
-
 int open_path_or_exit(const char *path, int flags)
 {
        int fd;
@@ -191,15 +182,15 @@ const char *vm_guest_mode_string(uint32_t i)
 }
 
 const struct vm_guest_mode_params vm_guest_mode_params[] = {
-       { 52, 48,  0x1000, 12 },
-       { 52, 48, 0x10000, 16 },
-       { 48, 48,  0x1000, 12 },
-       { 48, 48, 0x10000, 16 },
-       { 40, 48,  0x1000, 12 },
-       { 40, 48, 0x10000, 16 },
-       {  0,  0,  0x1000, 12 },
-       { 47, 64,  0x1000, 12 },
-       { 44, 64,  0x1000, 12 },
+       [VM_MODE_P52V48_4K]     = { 52, 48,  0x1000, 12 },
+       [VM_MODE_P52V48_64K]    = { 52, 48, 0x10000, 16 },
+       [VM_MODE_P48V48_4K]     = { 48, 48,  0x1000, 12 },
+       [VM_MODE_P48V48_64K]    = { 48, 48, 0x10000, 16 },
+       [VM_MODE_P40V48_4K]     = { 40, 48,  0x1000, 12 },
+       [VM_MODE_P40V48_64K]    = { 40, 48, 0x10000, 16 },
+       [VM_MODE_PXXV48_4K]     = {  0,  0,  0x1000, 12 },
+       [VM_MODE_P47V64_4K]     = { 47, 64,  0x1000, 12 },
+       [VM_MODE_P44V64_4K]     = { 44, 64,  0x1000, 12 },
 };
 _Static_assert(sizeof(vm_guest_mode_params)/sizeof(struct vm_guest_mode_params) == NUM_VM_MODES,
               "Missing new mode params?");
@@ -879,9 +870,17 @@ void vm_userspace_mem_region_add(struct kvm_vm *vm,
        alignment = 1;
 #endif
 
+       /*
+        * When using THP mmap is not guaranteed to returned a hugepage aligned
+        * address so we have to pad the mmap. Padding is not needed for HugeTLB
+        * because mmap will always return an address aligned to the HugeTLB
+        * page size.
+        */
        if (src_type == VM_MEM_SRC_ANONYMOUS_THP)
                alignment = max(backing_src_pagesz, alignment);
 
+       ASSERT_EQ(guest_paddr, align_up(guest_paddr, backing_src_pagesz));
+
        /* Add enough memory to align up if necessary */
        if (alignment > 1)
                region->mmap_size += alignment;
@@ -914,8 +913,13 @@ void vm_userspace_mem_region_add(struct kvm_vm *vm,
                    "test_malloc failed, mmap_start: %p errno: %i",
                    region->mmap_start, errno);
 
+       TEST_ASSERT(!is_backing_src_hugetlb(src_type) ||
+                   region->mmap_start == align_ptr_up(region->mmap_start, backing_src_pagesz),
+                   "mmap_start %p is not aligned to HugeTLB page size 0x%lx",
+                   region->mmap_start, backing_src_pagesz);
+
        /* Align host address */
-       region->host_mem = align(region->mmap_start, alignment);
+       region->host_mem = align_ptr_up(region->mmap_start, alignment);
 
        /* As needed perform madvise */
        if ((src_type == VM_MEM_SRC_ANONYMOUS ||
@@ -958,7 +962,7 @@ void vm_userspace_mem_region_add(struct kvm_vm *vm,
                            "mmap of alias failed, errno: %i", errno);
 
                /* Align host alias address */
-               region->host_alias = align(region->mmap_alias, alignment);
+               region->host_alias = align_ptr_up(region->mmap_alias, alignment);
        }
 }
 
index 0ef80db..722df3a 100644 (file)
 
 struct perf_test_args perf_test_args;
 
-uint64_t guest_test_phys_mem;
-
 /*
  * Guest virtual memory offset of the testing memory slot.
  * Must not conflict with identity mapped test code.
  */
 static uint64_t guest_test_virt_mem = DEFAULT_GUEST_TEST_MEM;
 
+struct vcpu_thread {
+       /* The id of the vCPU. */
+       int vcpu_id;
+
+       /* The pthread backing the vCPU. */
+       pthread_t thread;
+
+       /* Set to true once the vCPU thread is up and running. */
+       bool running;
+};
+
+/* The vCPU threads involved in this test. */
+static struct vcpu_thread vcpu_threads[KVM_MAX_VCPUS];
+
+/* The function run by each vCPU thread, as provided by the test. */
+static void (*vcpu_thread_fn)(struct perf_test_vcpu_args *);
+
+/* Set to true once all vCPU threads are up and running. */
+static bool all_vcpu_threads_running;
+
 /*
  * Continuously write to the first 8 bytes of each page in the
  * specified region.
  */
 static void guest_code(uint32_t vcpu_id)
 {
-       struct perf_test_vcpu_args *vcpu_args = &perf_test_args.vcpu_args[vcpu_id];
+       struct perf_test_args *pta = &perf_test_args;
+       struct perf_test_vcpu_args *vcpu_args = &pta->vcpu_args[vcpu_id];
        uint64_t gva;
        uint64_t pages;
        int i;
@@ -37,9 +56,9 @@ static void guest_code(uint32_t vcpu_id)
 
        while (true) {
                for (i = 0; i < pages; i++) {
-                       uint64_t addr = gva + (i * perf_test_args.guest_page_size);
+                       uint64_t addr = gva + (i * pta->guest_page_size);
 
-                       if (i % perf_test_args.wr_fract == 0)
+                       if (i % pta->wr_fract == 0)
                                *(uint64_t *)addr = 0x0123456789ABCDEF;
                        else
                                READ_ONCE(*(uint64_t *)addr);
@@ -49,35 +68,81 @@ static void guest_code(uint32_t vcpu_id)
        }
 }
 
+void perf_test_setup_vcpus(struct kvm_vm *vm, int vcpus,
+                          uint64_t vcpu_memory_bytes,
+                          bool partition_vcpu_memory_access)
+{
+       struct perf_test_args *pta = &perf_test_args;
+       struct perf_test_vcpu_args *vcpu_args;
+       int vcpu_id;
+
+       for (vcpu_id = 0; vcpu_id < vcpus; vcpu_id++) {
+               vcpu_args = &pta->vcpu_args[vcpu_id];
+
+               vcpu_args->vcpu_id = vcpu_id;
+               if (partition_vcpu_memory_access) {
+                       vcpu_args->gva = guest_test_virt_mem +
+                                        (vcpu_id * vcpu_memory_bytes);
+                       vcpu_args->pages = vcpu_memory_bytes /
+                                          pta->guest_page_size;
+                       vcpu_args->gpa = pta->gpa + (vcpu_id * vcpu_memory_bytes);
+               } else {
+                       vcpu_args->gva = guest_test_virt_mem;
+                       vcpu_args->pages = (vcpus * vcpu_memory_bytes) /
+                                          pta->guest_page_size;
+                       vcpu_args->gpa = pta->gpa;
+               }
+
+               vcpu_args_set(vm, vcpu_id, 1, vcpu_id);
+
+               pr_debug("Added VCPU %d with test mem gpa [%lx, %lx)\n",
+                        vcpu_id, vcpu_args->gpa, vcpu_args->gpa +
+                        (vcpu_args->pages * pta->guest_page_size));
+       }
+}
+
 struct kvm_vm *perf_test_create_vm(enum vm_guest_mode mode, int vcpus,
                                   uint64_t vcpu_memory_bytes, int slots,
-                                  enum vm_mem_backing_src_type backing_src)
+                                  enum vm_mem_backing_src_type backing_src,
+                                  bool partition_vcpu_memory_access)
 {
+       struct perf_test_args *pta = &perf_test_args;
        struct kvm_vm *vm;
        uint64_t guest_num_pages;
+       uint64_t backing_src_pagesz = get_backing_src_pagesz(backing_src);
        int i;
 
        pr_info("Testing guest mode: %s\n", vm_guest_mode_string(mode));
 
-       perf_test_args.host_page_size = getpagesize();
-       perf_test_args.guest_page_size = vm_guest_mode_params[mode].page_size;
+       /* By default vCPUs will write to memory. */
+       pta->wr_fract = 1;
+
+       /*
+        * Snapshot the non-huge page size.  This is used by the guest code to
+        * access/dirty pages at the logging granularity.
+        */
+       pta->guest_page_size = vm_guest_mode_params[mode].page_size;
 
        guest_num_pages = vm_adjust_num_guest_pages(mode,
-                               (vcpus * vcpu_memory_bytes) / perf_test_args.guest_page_size);
+                               (vcpus * vcpu_memory_bytes) / pta->guest_page_size);
 
-       TEST_ASSERT(vcpu_memory_bytes % perf_test_args.host_page_size == 0,
+       TEST_ASSERT(vcpu_memory_bytes % getpagesize() == 0,
                    "Guest memory size is not host page size aligned.");
-       TEST_ASSERT(vcpu_memory_bytes % perf_test_args.guest_page_size == 0,
+       TEST_ASSERT(vcpu_memory_bytes % pta->guest_page_size == 0,
                    "Guest memory size is not guest page size aligned.");
        TEST_ASSERT(guest_num_pages % slots == 0,
                    "Guest memory cannot be evenly divided into %d slots.",
                    slots);
 
+       /*
+        * Pass guest_num_pages to populate the page tables for test memory.
+        * The memory is also added to memslot 0, but that's a benign side
+        * effect as KVM allows aliasing HVAs in meslots.
+        */
        vm = vm_create_with_vcpus(mode, vcpus, DEFAULT_GUEST_PHY_PAGES,
-                                 (vcpus * vcpu_memory_bytes) / perf_test_args.guest_page_size,
-                                 0, guest_code, NULL);
+                                 guest_num_pages, 0, guest_code, NULL);
 
-       perf_test_args.vm = vm;
+       pta->vm = vm;
 
        /*
         * If there should be more memory in the guest test region than there
@@ -90,20 +155,18 @@ struct kvm_vm *perf_test_create_vm(enum vm_guest_mode mode, int vcpus,
                    guest_num_pages, vm_get_max_gfn(vm), vcpus,
                    vcpu_memory_bytes);
 
-       guest_test_phys_mem = (vm_get_max_gfn(vm) - guest_num_pages) *
-                             perf_test_args.guest_page_size;
-       guest_test_phys_mem &= ~(perf_test_args.host_page_size - 1);
+       pta->gpa = (vm_get_max_gfn(vm) - guest_num_pages) * pta->guest_page_size;
+       pta->gpa = align_down(pta->gpa, backing_src_pagesz);
 #ifdef __s390x__
        /* Align to 1M (segment size) */
-       guest_test_phys_mem &= ~((1 << 20) - 1);
+       pta->gpa = align_down(pta->gpa, 1 << 20);
 #endif
-       pr_info("guest physical test memory offset: 0x%lx\n", guest_test_phys_mem);
+       pr_info("guest physical test memory offset: 0x%lx\n", pta->gpa);
 
        /* Add extra memory slots for testing */
        for (i = 0; i < slots; i++) {
                uint64_t region_pages = guest_num_pages / slots;
-               vm_paddr_t region_start = guest_test_phys_mem +
-                       region_pages * perf_test_args.guest_page_size * i;
+               vm_paddr_t region_start = pta->gpa + region_pages * pta->guest_page_size * i;
 
                vm_userspace_mem_region_add(vm, backing_src, region_start,
                                            PERF_TEST_MEM_SLOT_INDEX + i,
@@ -111,10 +174,15 @@ struct kvm_vm *perf_test_create_vm(enum vm_guest_mode mode, int vcpus,
        }
 
        /* Do mapping for the demand paging memory slot */
-       virt_map(vm, guest_test_virt_mem, guest_test_phys_mem, guest_num_pages);
+       virt_map(vm, guest_test_virt_mem, pta->gpa, guest_num_pages);
+
+       perf_test_setup_vcpus(vm, vcpus, vcpu_memory_bytes, partition_vcpu_memory_access);
 
        ucall_init(vm, NULL);
 
+       /* Export the shared variables to the guest. */
+       sync_global_to_guest(vm, perf_test_args);
+
        return vm;
 }
 
@@ -124,36 +192,60 @@ void perf_test_destroy_vm(struct kvm_vm *vm)
        kvm_vm_free(vm);
 }
 
-void perf_test_setup_vcpus(struct kvm_vm *vm, int vcpus,
-                          uint64_t vcpu_memory_bytes,
-                          bool partition_vcpu_memory_access)
+void perf_test_set_wr_fract(struct kvm_vm *vm, int wr_fract)
+{
+       perf_test_args.wr_fract = wr_fract;
+       sync_global_to_guest(vm, perf_test_args);
+}
+
+static void *vcpu_thread_main(void *data)
+{
+       struct vcpu_thread *vcpu = data;
+
+       WRITE_ONCE(vcpu->running, true);
+
+       /*
+        * Wait for all vCPU threads to be up and running before calling the test-
+        * provided vCPU thread function. This prevents thread creation (which
+        * requires taking the mmap_sem in write mode) from interfering with the
+        * guest faulting in its memory.
+        */
+       while (!READ_ONCE(all_vcpu_threads_running))
+               ;
+
+       vcpu_thread_fn(&perf_test_args.vcpu_args[vcpu->vcpu_id]);
+
+       return NULL;
+}
+
+void perf_test_start_vcpu_threads(int vcpus, void (*vcpu_fn)(struct perf_test_vcpu_args *))
 {
-       vm_paddr_t vcpu_gpa;
-       struct perf_test_vcpu_args *vcpu_args;
        int vcpu_id;
 
+       vcpu_thread_fn = vcpu_fn;
+       WRITE_ONCE(all_vcpu_threads_running, false);
+
        for (vcpu_id = 0; vcpu_id < vcpus; vcpu_id++) {
-               vcpu_args = &perf_test_args.vcpu_args[vcpu_id];
+               struct vcpu_thread *vcpu = &vcpu_threads[vcpu_id];
 
-               vcpu_args->vcpu_id = vcpu_id;
-               if (partition_vcpu_memory_access) {
-                       vcpu_args->gva = guest_test_virt_mem +
-                                        (vcpu_id * vcpu_memory_bytes);
-                       vcpu_args->pages = vcpu_memory_bytes /
-                                          perf_test_args.guest_page_size;
-                       vcpu_gpa = guest_test_phys_mem +
-                                  (vcpu_id * vcpu_memory_bytes);
-               } else {
-                       vcpu_args->gva = guest_test_virt_mem;
-                       vcpu_args->pages = (vcpus * vcpu_memory_bytes) /
-                                          perf_test_args.guest_page_size;
-                       vcpu_gpa = guest_test_phys_mem;
-               }
+               vcpu->vcpu_id = vcpu_id;
+               WRITE_ONCE(vcpu->running, false);
 
-               vcpu_args_set(vm, vcpu_id, 1, vcpu_id);
+               pthread_create(&vcpu->thread, NULL, vcpu_thread_main, vcpu);
+       }
 
-               pr_debug("Added VCPU %d with test mem gpa [%lx, %lx)\n",
-                        vcpu_id, vcpu_gpa, vcpu_gpa +
-                        (vcpu_args->pages * perf_test_args.guest_page_size));
+       for (vcpu_id = 0; vcpu_id < vcpus; vcpu_id++) {
+               while (!READ_ONCE(vcpu_threads[vcpu_id].running))
+                       ;
        }
+
+       WRITE_ONCE(all_vcpu_threads_running, true);
+}
+
+void perf_test_join_vcpu_threads(int vcpus)
+{
+       int vcpu_id;
+
+       for (vcpu_id = 0; vcpu_id < vcpus; vcpu_id++)
+               pthread_join(vcpu_threads[vcpu_id].thread, NULL);
 }
index b724291..6d23878 100644 (file)
@@ -283,6 +283,11 @@ size_t get_backing_src_pagesz(uint32_t i)
        }
 }
 
+bool is_backing_src_hugetlb(uint32_t i)
+{
+       return !!(vm_mem_backing_src_alias(i)->flag & MAP_HUGETLB);
+}
+
 static void print_available_backing_src_types(const char *prefix)
 {
        int i;
index 4cfcafe..1410d0a 100644 (file)
@@ -36,11 +36,9 @@ static uint64_t guest_percpu_mem_size = DEFAULT_PER_VCPU_MEM_SIZE;
 
 static bool run_vcpus = true;
 
-static void *vcpu_worker(void *data)
+static void vcpu_worker(struct perf_test_vcpu_args *vcpu_args)
 {
        int ret;
-       struct perf_test_vcpu_args *vcpu_args =
-               (struct perf_test_vcpu_args *)data;
        int vcpu_id = vcpu_args->vcpu_id;
        struct kvm_vm *vm = perf_test_args.vm;
        struct kvm_run *run;
@@ -59,8 +57,6 @@ static void *vcpu_worker(void *data)
                            "Invalid guest sync status: exit_reason=%s\n",
                            exit_reason_str(run->exit_reason));
        }
-
-       return NULL;
 }
 
 struct memslot_antagonist_args {
@@ -80,7 +76,7 @@ static void add_remove_memslot(struct kvm_vm *vm, useconds_t delay,
         * Add the dummy memslot just below the perf_test_util memslot, which is
         * at the top of the guest physical address space.
         */
-       gpa = guest_test_phys_mem - pages * vm_get_page_size(vm);
+       gpa = perf_test_args.gpa - pages * vm_get_page_size(vm);
 
        for (i = 0; i < nr_modifications; i++) {
                usleep(delay);
@@ -100,29 +96,15 @@ struct test_params {
 static void run_test(enum vm_guest_mode mode, void *arg)
 {
        struct test_params *p = arg;
-       pthread_t *vcpu_threads;
        struct kvm_vm *vm;
-       int vcpu_id;
 
        vm = perf_test_create_vm(mode, nr_vcpus, guest_percpu_mem_size, 1,
-                                VM_MEM_SRC_ANONYMOUS);
-
-       perf_test_args.wr_fract = 1;
-
-       vcpu_threads = malloc(nr_vcpus * sizeof(*vcpu_threads));
-       TEST_ASSERT(vcpu_threads, "Memory allocation failed");
-
-       perf_test_setup_vcpus(vm, nr_vcpus, guest_percpu_mem_size,
-                             p->partition_vcpu_memory_access);
-
-       /* Export the shared variables to the guest */
-       sync_global_to_guest(vm, perf_test_args);
+                                VM_MEM_SRC_ANONYMOUS,
+                                p->partition_vcpu_memory_access);
 
        pr_info("Finished creating vCPUs\n");
 
-       for (vcpu_id = 0; vcpu_id < nr_vcpus; vcpu_id++)
-               pthread_create(&vcpu_threads[vcpu_id], NULL, vcpu_worker,
-                              &perf_test_args.vcpu_args[vcpu_id]);
+       perf_test_start_vcpu_threads(nr_vcpus, vcpu_worker);
 
        pr_info("Started all vCPUs\n");
 
@@ -131,16 +113,10 @@ static void run_test(enum vm_guest_mode mode, void *arg)
 
        run_vcpus = false;
 
-       /* Wait for the vcpu threads to quit */
-       for (vcpu_id = 0; vcpu_id < nr_vcpus; vcpu_id++)
-               pthread_join(vcpu_threads[vcpu_id], NULL);
-
+       perf_test_join_vcpu_threads(nr_vcpus);
        pr_info("All vCPU threads joined\n");
 
-       ucall_uninit(vm);
-       kvm_vm_free(vm);
-
-       free(vcpu_threads);
+       perf_test_destroy_vm(vm);
 }
 
 static void help(char *name)
index eda0d2a..a0699f0 100644 (file)
 
 #define PVTIME_ADDR    (SHINFO_REGION_GPA + PAGE_SIZE)
 #define RUNSTATE_ADDR  (SHINFO_REGION_GPA + PAGE_SIZE + 0x20)
+#define VCPU_INFO_ADDR (SHINFO_REGION_GPA + 0x40)
 
 #define RUNSTATE_VADDR (SHINFO_REGION_GVA + PAGE_SIZE + 0x20)
+#define VCPU_INFO_VADDR        (SHINFO_REGION_GVA + 0x40)
+
+#define EVTCHN_VECTOR  0x10
 
 static struct kvm_vm *vm;
 
@@ -56,15 +60,44 @@ struct vcpu_runstate_info {
     uint64_t time[4];
 };
 
+struct arch_vcpu_info {
+    unsigned long cr2;
+    unsigned long pad; /* sizeof(vcpu_info_t) == 64 */
+};
+
+struct vcpu_info {
+        uint8_t evtchn_upcall_pending;
+        uint8_t evtchn_upcall_mask;
+        unsigned long evtchn_pending_sel;
+        struct arch_vcpu_info arch;
+        struct pvclock_vcpu_time_info time;
+}; /* 64 bytes (x86) */
+
 #define RUNSTATE_running  0
 #define RUNSTATE_runnable 1
 #define RUNSTATE_blocked  2
 #define RUNSTATE_offline  3
 
+static void evtchn_handler(struct ex_regs *regs)
+{
+       struct vcpu_info *vi = (void *)VCPU_INFO_VADDR;
+       vi->evtchn_upcall_pending = 0;
+
+       GUEST_SYNC(0x20);
+}
+
 static void guest_code(void)
 {
        struct vcpu_runstate_info *rs = (void *)RUNSTATE_VADDR;
 
+       __asm__ __volatile__(
+               "sti\n"
+               "nop\n"
+       );
+
+       /* Trigger an interrupt injection */
+       GUEST_SYNC(0);
+
        /* Test having the host set runstates manually */
        GUEST_SYNC(RUNSTATE_runnable);
        GUEST_ASSERT(rs->time[RUNSTATE_runnable] != 0);
@@ -153,7 +186,7 @@ int main(int argc, char *argv[])
 
        struct kvm_xen_vcpu_attr vi = {
                .type = KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO,
-               .u.gpa = SHINFO_REGION_GPA + 0x40,
+               .u.gpa = VCPU_INFO_ADDR,
        };
        vcpu_ioctl(vm, VCPU_ID, KVM_XEN_VCPU_SET_ATTR, &vi);
 
@@ -163,6 +196,16 @@ int main(int argc, char *argv[])
        };
        vcpu_ioctl(vm, VCPU_ID, KVM_XEN_VCPU_SET_ATTR, &pvclock);
 
+       struct kvm_xen_hvm_attr vec = {
+               .type = KVM_XEN_ATTR_TYPE_UPCALL_VECTOR,
+               .u.vector = EVTCHN_VECTOR,
+       };
+       vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &vec);
+
+       vm_init_descriptor_tables(vm);
+       vcpu_init_descriptor_tables(vm, VCPU_ID);
+       vm_install_exception_handler(vm, EVTCHN_VECTOR, evtchn_handler);
+
        if (do_runstate_tests) {
                struct kvm_xen_vcpu_attr st = {
                        .type = KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR,
@@ -171,9 +214,14 @@ int main(int argc, char *argv[])
                vcpu_ioctl(vm, VCPU_ID, KVM_XEN_VCPU_SET_ATTR, &st);
        }
 
+       struct vcpu_info *vinfo = addr_gpa2hva(vm, VCPU_INFO_VADDR);
+       vinfo->evtchn_upcall_pending = 0;
+
        struct vcpu_runstate_info *rs = addr_gpa2hva(vm, RUNSTATE_ADDR);
        rs->state = 0x5a;
 
+       bool evtchn_irq_expected = false;
+
        for (;;) {
                volatile struct kvm_run *run = vcpu_state(vm, VCPU_ID);
                struct ucall uc;
@@ -193,16 +241,21 @@ int main(int argc, char *argv[])
                        struct kvm_xen_vcpu_attr rst;
                        long rundelay;
 
-                       /* If no runstate support, bail out early */
-                       if (!do_runstate_tests)
-                               goto done;
-
-                       TEST_ASSERT(rs->state_entry_time == rs->time[0] +
-                                   rs->time[1] + rs->time[2] + rs->time[3],
-                                   "runstate times don't add up");
+                       if (do_runstate_tests)
+                               TEST_ASSERT(rs->state_entry_time == rs->time[0] +
+                                           rs->time[1] + rs->time[2] + rs->time[3],
+                                           "runstate times don't add up");
 
                        switch (uc.args[1]) {
-                       case RUNSTATE_running...RUNSTATE_offline:
+                       case 0:
+                               evtchn_irq_expected = true;
+                               vinfo->evtchn_upcall_pending = 1;
+                               break;
+
+                       case RUNSTATE_runnable...RUNSTATE_offline:
+                               TEST_ASSERT(!evtchn_irq_expected, "Event channel IRQ not seen");
+                               if (!do_runstate_tests)
+                                       goto done;
                                rst.type = KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT;
                                rst.u.runstate.state = uc.args[1];
                                vcpu_ioctl(vm, VCPU_ID, KVM_XEN_VCPU_SET_ATTR, &rst);
@@ -236,6 +289,10 @@ int main(int argc, char *argv[])
                                        sched_yield();
                                } while (get_run_delay() < rundelay);
                                break;
+                       case 0x20:
+                               TEST_ASSERT(evtchn_irq_expected, "Unexpected event channel IRQ");
+                               evtchn_irq_expected = false;
+                               break;
                        }
                        break;
                }
index 7615f29..9897fa9 100644 (file)
@@ -34,6 +34,7 @@ TEST_PROGS += srv6_end_dt46_l3vpn_test.sh
 TEST_PROGS += srv6_end_dt4_l3vpn_test.sh
 TEST_PROGS += srv6_end_dt6_l3vpn_test.sh
 TEST_PROGS += vrf_strict_mode_test.sh
+TEST_PROGS += arp_ndisc_evict_nocarrier.sh
 TEST_PROGS_EXTENDED := in_netns.sh setup_loopback.sh setup_veth.sh
 TEST_PROGS_EXTENDED += toeplitz_client.sh toeplitz.sh
 TEST_GEN_FILES =  socket nettest
index b5a69ad..d444ee6 100755 (executable)
@@ -629,6 +629,66 @@ ipv6_fcnal()
        log_test $? 0 "Nexthops removed on admin down"
 }
 
+ipv6_grp_refs()
+{
+       if [ ! -x "$(command -v mausezahn)" ]; then
+               echo "SKIP: Could not run test; need mausezahn tool"
+               return
+       fi
+
+       run_cmd "$IP link set dev veth1 up"
+       run_cmd "$IP link add veth1.10 link veth1 up type vlan id 10"
+       run_cmd "$IP link add veth1.20 link veth1 up type vlan id 20"
+       run_cmd "$IP -6 addr add 2001:db8:91::1/64 dev veth1.10"
+       run_cmd "$IP -6 addr add 2001:db8:92::1/64 dev veth1.20"
+       run_cmd "$IP -6 neigh add 2001:db8:91::2 lladdr 00:11:22:33:44:55 dev veth1.10"
+       run_cmd "$IP -6 neigh add 2001:db8:92::2 lladdr 00:11:22:33:44:55 dev veth1.20"
+       run_cmd "$IP nexthop add id 100 via 2001:db8:91::2 dev veth1.10"
+       run_cmd "$IP nexthop add id 101 via 2001:db8:92::2 dev veth1.20"
+       run_cmd "$IP nexthop add id 102 group 100"
+       run_cmd "$IP route add 2001:db8:101::1/128 nhid 102"
+
+       # create per-cpu dsts through nh 100
+       run_cmd "ip netns exec me mausezahn -6 veth1.10 -B 2001:db8:101::1 -A 2001:db8:91::1 -c 5 -t tcp "dp=1-1023, flags=syn" >/dev/null 2>&1"
+
+       # remove nh 100 from the group to delete the route potentially leaving
+       # a stale per-cpu dst which holds a reference to the nexthop's net
+       # device and to the IPv6 route
+       run_cmd "$IP nexthop replace id 102 group 101"
+       run_cmd "$IP route del 2001:db8:101::1/128"
+
+       # add both nexthops to the group so a reference is taken on them
+       run_cmd "$IP nexthop replace id 102 group 100/101"
+
+       # if the bug described in commit "net: nexthop: release IPv6 per-cpu
+       # dsts when replacing a nexthop group" exists at this point we have
+       # an unlinked IPv6 route (but not freed due to stale dst) with a
+       # reference over the group so we delete the group which will again
+       # only unlink it due to the route reference
+       run_cmd "$IP nexthop del id 102"
+
+       # delete the nexthop with stale dst, since we have an unlinked
+       # group with a ref to it and an unlinked IPv6 route with ref to the
+       # group, the nh will only be unlinked and not freed so the stale dst
+       # remains forever and we get a net device refcount imbalance
+       run_cmd "$IP nexthop del id 100"
+
+       # if a reference was lost this command will hang because the net device
+       # cannot be removed
+       timeout -s KILL 5 ip netns exec me ip link del veth1.10 >/dev/null 2>&1
+
+       # we can't cleanup if the command is hung trying to delete the netdev
+       if [ $? -eq 137 ]; then
+               return 1
+       fi
+
+       # cleanup
+       run_cmd "$IP link del veth1.20"
+       run_cmd "$IP nexthop flush"
+
+       return 0
+}
+
 ipv6_grp_fcnal()
 {
        local rc
@@ -734,6 +794,9 @@ ipv6_grp_fcnal()
 
        run_cmd "$IP nexthop add id 108 group 31/24"
        log_test $? 2 "Nexthop group can not have a blackhole and another nexthop"
+
+       ipv6_grp_refs
+       log_test $? 0 "Nexthop group replace refcounts"
 }
 
 ipv6_res_grp_fcnal()
index a4bd1b0..697994a 100644 (file)
@@ -6,6 +6,7 @@ CONFIG_IPV6_MULTIPLE_TABLES=y
 CONFIG_NET_VRF=m
 CONFIG_BPF_SYSCALL=y
 CONFIG_CGROUP_BPF=y
+CONFIG_NET_ACT_CT=m
 CONFIG_NET_ACT_MIRRED=m
 CONFIG_NET_ACT_MPLS=m
 CONFIG_NET_ACT_VLAN=m
index d9eca22..de19eb6 100755 (executable)
@@ -3,7 +3,7 @@
 
 ALL_TESTS="gact_drop_and_ok_test mirred_egress_redirect_test \
        mirred_egress_mirror_test matchall_mirred_egress_mirror_test \
-       gact_trap_test"
+       gact_trap_test mirred_egress_to_ingress_test"
 NUM_NETIFS=4
 source tc_common.sh
 source lib.sh
@@ -13,10 +13,12 @@ tcflags="skip_hw"
 h1_create()
 {
        simple_if_init $h1 192.0.2.1/24
+       tc qdisc add dev $h1 clsact
 }
 
 h1_destroy()
 {
+       tc qdisc del dev $h1 clsact
        simple_if_fini $h1 192.0.2.1/24
 }
 
@@ -153,6 +155,49 @@ gact_trap_test()
        log_test "trap ($tcflags)"
 }
 
+mirred_egress_to_ingress_test()
+{
+       RET=0
+
+       tc filter add dev $h1 protocol ip pref 100 handle 100 egress flower \
+               ip_proto icmp src_ip 192.0.2.1 dst_ip 192.0.2.2 type 8 action \
+                       ct commit nat src addr 192.0.2.2 pipe \
+                       ct clear pipe \
+                       ct commit nat dst addr 192.0.2.1 pipe \
+                       mirred ingress redirect dev $h1
+
+       tc filter add dev $swp1 protocol ip pref 11 handle 111 ingress flower \
+               ip_proto icmp src_ip 192.0.2.1 dst_ip 192.0.2.2 type 8 action drop
+       tc filter add dev $swp1 protocol ip pref 12 handle 112 ingress flower \
+               ip_proto icmp src_ip 192.0.2.1 dst_ip 192.0.2.2 type 0 action pass
+
+       $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
+               -t icmp "ping,id=42,seq=10" -q
+
+       tc_check_packets "dev $h1 egress" 100 1
+       check_err $? "didn't mirror first packet"
+
+       tc_check_packets "dev $swp1 ingress" 111 1
+       check_fail $? "didn't redirect first packet"
+       tc_check_packets "dev $swp1 ingress" 112 1
+       check_err $? "didn't receive reply to first packet"
+
+       ping 192.0.2.2 -I$h1 -c1 -w1 -q 1>/dev/null 2>&1
+
+       tc_check_packets "dev $h1 egress" 100 2
+       check_err $? "didn't mirror second packet"
+       tc_check_packets "dev $swp1 ingress" 111 1
+       check_fail $? "didn't redirect second packet"
+       tc_check_packets "dev $swp1 ingress" 112 2
+       check_err $? "didn't receive reply to second packet"
+
+       tc filter del dev $h1 egress protocol ip pref 100 handle 100 flower
+       tc filter del dev $swp1 ingress protocol ip pref 11 handle 111 flower
+       tc filter del dev $swp1 ingress protocol ip pref 12 handle 112 flower
+
+       log_test "mirred_egress_to_ingress ($tcflags)"
+}
+
 setup_prepare()
 {
        h1=${NETIFS[p1]}
index fdeb44d..3224651 100755 (executable)
@@ -118,16 +118,18 @@ gre_gst_test_checks()
        local addr=$2
        local proto=$3
 
-       $NS_EXEC nc $proto -kl $port >/dev/null &
+       [ "$proto" == 6 ] && addr="[$addr]"
+
+       $NS_EXEC socat - tcp${proto}-listen:$port,reuseaddr,fork >/dev/null &
        PID=$!
        while ! $NS_EXEC ss -ltn | grep -q $port; do ((i++)); sleep 0.01; done
 
-       cat $TMPFILE | timeout 1 nc $proto -N $addr $port
+       cat $TMPFILE | timeout 1 socat -u STDIN TCP:$addr:$port
        log_test $? 0 "$name - copy file w/ TSO"
 
        ethtool -K veth0 tso off
 
-       cat $TMPFILE | timeout 1 nc $proto -N $addr $port
+       cat $TMPFILE | timeout 1 socat -u STDIN TCP:$addr:$port
        log_test $? 0 "$name - copy file w/ GSO"
 
        ethtool -K veth0 tso on
@@ -155,8 +157,8 @@ gre6_gso_test()
 
        sleep 2
 
-       gre_gst_test_checks GREv6/v4 172.16.2.2
-       gre_gst_test_checks GREv6/v6 2001:db8:1::2 -6
+       gre_gst_test_checks GREv6/v4 172.16.2.2 4
+       gre_gst_test_checks GREv6/v6 2001:db8:1::2 6
 
        cleanup
 }
@@ -212,8 +214,8 @@ if [ ! -x "$(command -v ip)" ]; then
        exit $ksft_skip
 fi
 
-if [ ! -x "$(command -v nc)" ]; then
-       echo "SKIP: Could not run test without nc tool"
+if [ ! -x "$(command -v socat)" ]; then
+       echo "SKIP: Could not run test without socat tool"
        exit $ksft_skip
 fi
 
index e61fc4c..8a22db0 100644 (file)
@@ -78,26 +78,21 @@ static void memrnd(void *s, size_t n)
                *byte++ = rand();
 }
 
-FIXTURE(tls_basic)
-{
-       int fd, cfd;
-       bool notls;
-};
-
-FIXTURE_SETUP(tls_basic)
+static void ulp_sock_pair(struct __test_metadata *_metadata,
+                         int *fd, int *cfd, bool *notls)
 {
        struct sockaddr_in addr;
        socklen_t len;
        int sfd, ret;
 
-       self->notls = false;
+       *notls = false;
        len = sizeof(addr);
 
        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = htonl(INADDR_ANY);
        addr.sin_port = 0;
 
-       self->fd = socket(AF_INET, SOCK_STREAM, 0);
+       *fd = socket(AF_INET, SOCK_STREAM, 0);
        sfd = socket(AF_INET, SOCK_STREAM, 0);
 
        ret = bind(sfd, &addr, sizeof(addr));
@@ -108,26 +103,96 @@ FIXTURE_SETUP(tls_basic)
        ret = getsockname(sfd, &addr, &len);
        ASSERT_EQ(ret, 0);
 
-       ret = connect(self->fd, &addr, sizeof(addr));
+       ret = connect(*fd, &addr, sizeof(addr));
        ASSERT_EQ(ret, 0);
 
-       self->cfd = accept(sfd, &addr, &len);
-       ASSERT_GE(self->cfd, 0);
+       *cfd = accept(sfd, &addr, &len);
+       ASSERT_GE(*cfd, 0);
 
        close(sfd);
 
-       ret = setsockopt(self->fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
+       ret = setsockopt(*fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
        if (ret != 0) {
                ASSERT_EQ(errno, ENOENT);
-               self->notls = true;
+               *notls = true;
                printf("Failure setting TCP_ULP, testing without tls\n");
                return;
        }
 
-       ret = setsockopt(self->cfd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
+       ret = setsockopt(*cfd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
        ASSERT_EQ(ret, 0);
 }
 
+/* Produce a basic cmsg */
+static int tls_send_cmsg(int fd, unsigned char record_type,
+                        void *data, size_t len, int flags)
+{
+       char cbuf[CMSG_SPACE(sizeof(char))];
+       int cmsg_len = sizeof(char);
+       struct cmsghdr *cmsg;
+       struct msghdr msg;
+       struct iovec vec;
+
+       vec.iov_base = data;
+       vec.iov_len = len;
+       memset(&msg, 0, sizeof(struct msghdr));
+       msg.msg_iov = &vec;
+       msg.msg_iovlen = 1;
+       msg.msg_control = cbuf;
+       msg.msg_controllen = sizeof(cbuf);
+       cmsg = CMSG_FIRSTHDR(&msg);
+       cmsg->cmsg_level = SOL_TLS;
+       /* test sending non-record types. */
+       cmsg->cmsg_type = TLS_SET_RECORD_TYPE;
+       cmsg->cmsg_len = CMSG_LEN(cmsg_len);
+       *CMSG_DATA(cmsg) = record_type;
+       msg.msg_controllen = cmsg->cmsg_len;
+
+       return sendmsg(fd, &msg, flags);
+}
+
+static int tls_recv_cmsg(struct __test_metadata *_metadata,
+                        int fd, unsigned char record_type,
+                        void *data, size_t len, int flags)
+{
+       char cbuf[CMSG_SPACE(sizeof(char))];
+       struct cmsghdr *cmsg;
+       unsigned char ctype;
+       struct msghdr msg;
+       struct iovec vec;
+       int n;
+
+       vec.iov_base = data;
+       vec.iov_len = len;
+       memset(&msg, 0, sizeof(struct msghdr));
+       msg.msg_iov = &vec;
+       msg.msg_iovlen = 1;
+       msg.msg_control = cbuf;
+       msg.msg_controllen = sizeof(cbuf);
+
+       n = recvmsg(fd, &msg, flags);
+
+       cmsg = CMSG_FIRSTHDR(&msg);
+       EXPECT_NE(cmsg, NULL);
+       EXPECT_EQ(cmsg->cmsg_level, SOL_TLS);
+       EXPECT_EQ(cmsg->cmsg_type, TLS_GET_RECORD_TYPE);
+       ctype = *((unsigned char *)CMSG_DATA(cmsg));
+       EXPECT_EQ(ctype, record_type);
+
+       return n;
+}
+
+FIXTURE(tls_basic)
+{
+       int fd, cfd;
+       bool notls;
+};
+
+FIXTURE_SETUP(tls_basic)
+{
+       ulp_sock_pair(_metadata, &self->fd, &self->cfd, &self->notls);
+}
+
 FIXTURE_TEARDOWN(tls_basic)
 {
        close(self->fd);
@@ -199,60 +264,21 @@ FIXTURE_VARIANT_ADD(tls, 13_sm4_ccm)
 FIXTURE_SETUP(tls)
 {
        struct tls_crypto_info_keys tls12;
-       struct sockaddr_in addr;
-       socklen_t len;
-       int sfd, ret;
-
-       self->notls = false;
-       len = sizeof(addr);
+       int ret;
 
        tls_crypto_info_init(variant->tls_version, variant->cipher_type,
                             &tls12);
 
-       addr.sin_family = AF_INET;
-       addr.sin_addr.s_addr = htonl(INADDR_ANY);
-       addr.sin_port = 0;
+       ulp_sock_pair(_metadata, &self->fd, &self->cfd, &self->notls);
 
-       self->fd = socket(AF_INET, SOCK_STREAM, 0);
-       sfd = socket(AF_INET, SOCK_STREAM, 0);
-
-       ret = bind(sfd, &addr, sizeof(addr));
-       ASSERT_EQ(ret, 0);
-       ret = listen(sfd, 10);
-       ASSERT_EQ(ret, 0);
+       if (self->notls)
+               return;
 
-       ret = getsockname(sfd, &addr, &len);
+       ret = setsockopt(self->fd, SOL_TLS, TLS_TX, &tls12, tls12.len);
        ASSERT_EQ(ret, 0);
 
-       ret = connect(self->fd, &addr, sizeof(addr));
+       ret = setsockopt(self->cfd, SOL_TLS, TLS_RX, &tls12, tls12.len);
        ASSERT_EQ(ret, 0);
-
-       ret = setsockopt(self->fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
-       if (ret != 0) {
-               self->notls = true;
-               printf("Failure setting TCP_ULP, testing without tls\n");
-       }
-
-       if (!self->notls) {
-               ret = setsockopt(self->fd, SOL_TLS, TLS_TX, &tls12,
-                                tls12.len);
-               ASSERT_EQ(ret, 0);
-       }
-
-       self->cfd = accept(sfd, &addr, &len);
-       ASSERT_GE(self->cfd, 0);
-
-       if (!self->notls) {
-               ret = setsockopt(self->cfd, IPPROTO_TCP, TCP_ULP, "tls",
-                                sizeof("tls"));
-               ASSERT_EQ(ret, 0);
-
-               ret = setsockopt(self->cfd, SOL_TLS, TLS_RX, &tls12,
-                                tls12.len);
-               ASSERT_EQ(ret, 0);
-       }
-
-       close(sfd);
 }
 
 FIXTURE_TEARDOWN(tls)
@@ -613,6 +639,95 @@ TEST_F(tls, splice_to_pipe)
        EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
 }
 
+TEST_F(tls, splice_cmsg_to_pipe)
+{
+       char *test_str = "test_read";
+       char record_type = 100;
+       int send_len = 10;
+       char buf[10];
+       int p[2];
+
+       ASSERT_GE(pipe(p), 0);
+       EXPECT_EQ(tls_send_cmsg(self->fd, 100, test_str, send_len, 0), 10);
+       EXPECT_EQ(splice(self->cfd, NULL, p[1], NULL, send_len, 0), -1);
+       EXPECT_EQ(errno, EINVAL);
+       EXPECT_EQ(recv(self->cfd, buf, send_len, 0), -1);
+       EXPECT_EQ(errno, EIO);
+       EXPECT_EQ(tls_recv_cmsg(_metadata, self->cfd, record_type,
+                               buf, sizeof(buf), MSG_WAITALL),
+                 send_len);
+       EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
+}
+
+TEST_F(tls, splice_dec_cmsg_to_pipe)
+{
+       char *test_str = "test_read";
+       char record_type = 100;
+       int send_len = 10;
+       char buf[10];
+       int p[2];
+
+       ASSERT_GE(pipe(p), 0);
+       EXPECT_EQ(tls_send_cmsg(self->fd, 100, test_str, send_len, 0), 10);
+       EXPECT_EQ(recv(self->cfd, buf, send_len, 0), -1);
+       EXPECT_EQ(errno, EIO);
+       EXPECT_EQ(splice(self->cfd, NULL, p[1], NULL, send_len, 0), -1);
+       EXPECT_EQ(errno, EINVAL);
+       EXPECT_EQ(tls_recv_cmsg(_metadata, self->cfd, record_type,
+                               buf, sizeof(buf), MSG_WAITALL),
+                 send_len);
+       EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
+}
+
+TEST_F(tls, recv_and_splice)
+{
+       int send_len = TLS_PAYLOAD_MAX_LEN;
+       char mem_send[TLS_PAYLOAD_MAX_LEN];
+       char mem_recv[TLS_PAYLOAD_MAX_LEN];
+       int half = send_len / 2;
+       int p[2];
+
+       ASSERT_GE(pipe(p), 0);
+       EXPECT_EQ(send(self->fd, mem_send, send_len, 0), send_len);
+       /* Recv hald of the record, splice the other half */
+       EXPECT_EQ(recv(self->cfd, mem_recv, half, MSG_WAITALL), half);
+       EXPECT_EQ(splice(self->cfd, NULL, p[1], NULL, half, SPLICE_F_NONBLOCK),
+                 half);
+       EXPECT_EQ(read(p[0], &mem_recv[half], half), half);
+       EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
+}
+
+TEST_F(tls, peek_and_splice)
+{
+       int send_len = TLS_PAYLOAD_MAX_LEN;
+       char mem_send[TLS_PAYLOAD_MAX_LEN];
+       char mem_recv[TLS_PAYLOAD_MAX_LEN];
+       int chunk = TLS_PAYLOAD_MAX_LEN / 4;
+       int n, i, p[2];
+
+       memrnd(mem_send, sizeof(mem_send));
+
+       ASSERT_GE(pipe(p), 0);
+       for (i = 0; i < 4; i++)
+               EXPECT_EQ(send(self->fd, &mem_send[chunk * i], chunk, 0),
+                         chunk);
+
+       EXPECT_EQ(recv(self->cfd, mem_recv, chunk * 5 / 2,
+                      MSG_WAITALL | MSG_PEEK),
+                 chunk * 5 / 2);
+       EXPECT_EQ(memcmp(mem_send, mem_recv, chunk * 5 / 2), 0);
+
+       n = 0;
+       while (n < send_len) {
+               i = splice(self->cfd, NULL, p[1], NULL, send_len - n, 0);
+               EXPECT_GT(i, 0);
+               n += i;
+       }
+       EXPECT_EQ(n, send_len);
+       EXPECT_EQ(read(p[0], mem_recv, send_len), send_len);
+       EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
+}
+
 TEST_F(tls, recvmsg_single)
 {
        char const *test_str = "test_recvmsg_single";
@@ -1193,60 +1308,30 @@ TEST_F(tls, mutliproc_sendpage_writers)
 
 TEST_F(tls, control_msg)
 {
-       if (self->notls)
-               return;
-
-       char cbuf[CMSG_SPACE(sizeof(char))];
-       char const *test_str = "test_read";
-       int cmsg_len = sizeof(char);
+       char *test_str = "test_read";
        char record_type = 100;
-       struct cmsghdr *cmsg;
-       struct msghdr msg;
        int send_len = 10;
-       struct iovec vec;
        char buf[10];
 
-       vec.iov_base = (char *)test_str;
-       vec.iov_len = 10;
-       memset(&msg, 0, sizeof(struct msghdr));
-       msg.msg_iov = &vec;
-       msg.msg_iovlen = 1;
-       msg.msg_control = cbuf;
-       msg.msg_controllen = sizeof(cbuf);
-       cmsg = CMSG_FIRSTHDR(&msg);
-       cmsg->cmsg_level = SOL_TLS;
-       /* test sending non-record types. */
-       cmsg->cmsg_type = TLS_SET_RECORD_TYPE;
-       cmsg->cmsg_len = CMSG_LEN(cmsg_len);
-       *CMSG_DATA(cmsg) = record_type;
-       msg.msg_controllen = cmsg->cmsg_len;
+       if (self->notls)
+               SKIP(return, "no TLS support");
 
-       EXPECT_EQ(sendmsg(self->fd, &msg, 0), send_len);
+       EXPECT_EQ(tls_send_cmsg(self->fd, record_type, test_str, send_len, 0),
+                 send_len);
        /* Should fail because we didn't provide a control message */
        EXPECT_EQ(recv(self->cfd, buf, send_len, 0), -1);
 
-       vec.iov_base = buf;
-       EXPECT_EQ(recvmsg(self->cfd, &msg, MSG_WAITALL | MSG_PEEK), send_len);
-
-       cmsg = CMSG_FIRSTHDR(&msg);
-       EXPECT_NE(cmsg, NULL);
-       EXPECT_EQ(cmsg->cmsg_level, SOL_TLS);
-       EXPECT_EQ(cmsg->cmsg_type, TLS_GET_RECORD_TYPE);
-       record_type = *((unsigned char *)CMSG_DATA(cmsg));
-       EXPECT_EQ(record_type, 100);
+       EXPECT_EQ(tls_recv_cmsg(_metadata, self->cfd, record_type,
+                               buf, sizeof(buf), MSG_WAITALL | MSG_PEEK),
+                 send_len);
        EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
 
        /* Recv the message again without MSG_PEEK */
-       record_type = 0;
        memset(buf, 0, sizeof(buf));
 
-       EXPECT_EQ(recvmsg(self->cfd, &msg, MSG_WAITALL), send_len);
-       cmsg = CMSG_FIRSTHDR(&msg);
-       EXPECT_NE(cmsg, NULL);
-       EXPECT_EQ(cmsg->cmsg_level, SOL_TLS);
-       EXPECT_EQ(cmsg->cmsg_type, TLS_GET_RECORD_TYPE);
-       record_type = *((unsigned char *)CMSG_DATA(cmsg));
-       EXPECT_EQ(record_type, 100);
+       EXPECT_EQ(tls_recv_cmsg(_metadata, self->cfd, record_type,
+                               buf, sizeof(buf), MSG_WAITALL),
+                 send_len);
        EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
 }
 
@@ -1301,6 +1386,160 @@ TEST_F(tls, shutdown_reuse)
        EXPECT_EQ(errno, EISCONN);
 }
 
+FIXTURE(tls_err)
+{
+       int fd, cfd;
+       int fd2, cfd2;
+       bool notls;
+};
+
+FIXTURE_VARIANT(tls_err)
+{
+       uint16_t tls_version;
+};
+
+FIXTURE_VARIANT_ADD(tls_err, 12_aes_gcm)
+{
+       .tls_version = TLS_1_2_VERSION,
+};
+
+FIXTURE_VARIANT_ADD(tls_err, 13_aes_gcm)
+{
+       .tls_version = TLS_1_3_VERSION,
+};
+
+FIXTURE_SETUP(tls_err)
+{
+       struct tls_crypto_info_keys tls12;
+       int ret;
+
+       tls_crypto_info_init(variant->tls_version, TLS_CIPHER_AES_GCM_128,
+                            &tls12);
+
+       ulp_sock_pair(_metadata, &self->fd, &self->cfd, &self->notls);
+       ulp_sock_pair(_metadata, &self->fd2, &self->cfd2, &self->notls);
+       if (self->notls)
+               return;
+
+       ret = setsockopt(self->fd, SOL_TLS, TLS_TX, &tls12, tls12.len);
+       ASSERT_EQ(ret, 0);
+
+       ret = setsockopt(self->cfd2, SOL_TLS, TLS_RX, &tls12, tls12.len);
+       ASSERT_EQ(ret, 0);
+}
+
+FIXTURE_TEARDOWN(tls_err)
+{
+       close(self->fd);
+       close(self->cfd);
+       close(self->fd2);
+       close(self->cfd2);
+}
+
+TEST_F(tls_err, bad_rec)
+{
+       char buf[64];
+
+       if (self->notls)
+               SKIP(return, "no TLS support");
+
+       memset(buf, 0x55, sizeof(buf));
+       EXPECT_EQ(send(self->fd2, buf, sizeof(buf), 0), sizeof(buf));
+       EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), 0), -1);
+       EXPECT_EQ(errno, EMSGSIZE);
+       EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), MSG_DONTWAIT), -1);
+       EXPECT_EQ(errno, EAGAIN);
+}
+
+TEST_F(tls_err, bad_auth)
+{
+       char buf[128];
+       int n;
+
+       if (self->notls)
+               SKIP(return, "no TLS support");
+
+       memrnd(buf, sizeof(buf) / 2);
+       EXPECT_EQ(send(self->fd, buf, sizeof(buf) / 2, 0), sizeof(buf) / 2);
+       n = recv(self->cfd, buf, sizeof(buf), 0);
+       EXPECT_GT(n, sizeof(buf) / 2);
+
+       buf[n - 1]++;
+
+       EXPECT_EQ(send(self->fd2, buf, n, 0), n);
+       EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), 0), -1);
+       EXPECT_EQ(errno, EBADMSG);
+       EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), 0), -1);
+       EXPECT_EQ(errno, EBADMSG);
+}
+
+TEST_F(tls_err, bad_in_large_read)
+{
+       char txt[3][64];
+       char cip[3][128];
+       char buf[3 * 128];
+       int i, n;
+
+       if (self->notls)
+               SKIP(return, "no TLS support");
+
+       /* Put 3 records in the sockets */
+       for (i = 0; i < 3; i++) {
+               memrnd(txt[i], sizeof(txt[i]));
+               EXPECT_EQ(send(self->fd, txt[i], sizeof(txt[i]), 0),
+                         sizeof(txt[i]));
+               n = recv(self->cfd, cip[i], sizeof(cip[i]), 0);
+               EXPECT_GT(n, sizeof(txt[i]));
+               /* Break the third message */
+               if (i == 2)
+                       cip[2][n - 1]++;
+               EXPECT_EQ(send(self->fd2, cip[i], n, 0), n);
+       }
+
+       /* We should be able to receive the first two messages */
+       EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), 0), sizeof(txt[0]) * 2);
+       EXPECT_EQ(memcmp(buf, txt[0], sizeof(txt[0])), 0);
+       EXPECT_EQ(memcmp(buf + sizeof(txt[0]), txt[1], sizeof(txt[1])), 0);
+       /* Third mesasge is bad */
+       EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), 0), -1);
+       EXPECT_EQ(errno, EBADMSG);
+       EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), 0), -1);
+       EXPECT_EQ(errno, EBADMSG);
+}
+
+TEST_F(tls_err, bad_cmsg)
+{
+       char *test_str = "test_read";
+       int send_len = 10;
+       char cip[128];
+       char buf[128];
+       char txt[64];
+       int n;
+
+       if (self->notls)
+               SKIP(return, "no TLS support");
+
+       /* Queue up one data record */
+       memrnd(txt, sizeof(txt));
+       EXPECT_EQ(send(self->fd, txt, sizeof(txt), 0), sizeof(txt));
+       n = recv(self->cfd, cip, sizeof(cip), 0);
+       EXPECT_GT(n, sizeof(txt));
+       EXPECT_EQ(send(self->fd2, cip, n, 0), n);
+
+       EXPECT_EQ(tls_send_cmsg(self->fd, 100, test_str, send_len, 0), 10);
+       n = recv(self->cfd, cip, sizeof(cip), 0);
+       cip[n - 1]++; /* Break it */
+       EXPECT_GT(n, send_len);
+       EXPECT_EQ(send(self->fd2, cip, n, 0), n);
+
+       EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), 0), sizeof(txt));
+       EXPECT_EQ(memcmp(buf, txt, sizeof(txt)), 0);
+       EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), 0), -1);
+       EXPECT_EQ(errno, EBADMSG);
+       EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), 0), -1);
+       EXPECT_EQ(errno, EBADMSG);
+}
+
 TEST(non_established) {
        struct tls12_crypto_info_aes_gcm_256 tls12;
        struct sockaddr_in addr;
@@ -1355,64 +1594,82 @@ TEST(non_established) {
 
 TEST(keysizes) {
        struct tls12_crypto_info_aes_gcm_256 tls12;
-       struct sockaddr_in addr;
-       int sfd, ret, fd, cfd;
-       socklen_t len;
+       int ret, fd, cfd;
        bool notls;
 
-       notls = false;
-       len = sizeof(addr);
-
        memset(&tls12, 0, sizeof(tls12));
        tls12.info.version = TLS_1_2_VERSION;
        tls12.info.cipher_type = TLS_CIPHER_AES_GCM_256;
 
-       addr.sin_family = AF_INET;
-       addr.sin_addr.s_addr = htonl(INADDR_ANY);
-       addr.sin_port = 0;
+       ulp_sock_pair(_metadata, &fd, &cfd, &notls);
 
-       fd = socket(AF_INET, SOCK_STREAM, 0);
-       sfd = socket(AF_INET, SOCK_STREAM, 0);
+       if (!notls) {
+               ret = setsockopt(fd, SOL_TLS, TLS_TX, &tls12,
+                                sizeof(tls12));
+               EXPECT_EQ(ret, 0);
+
+               ret = setsockopt(cfd, SOL_TLS, TLS_RX, &tls12,
+                                sizeof(tls12));
+               EXPECT_EQ(ret, 0);
+       }
+
+       close(fd);
+       close(cfd);
+}
+
+TEST(tls_v6ops) {
+       struct tls_crypto_info_keys tls12;
+       struct sockaddr_in6 addr, addr2;
+       int sfd, ret, fd;
+       socklen_t len, len2;
+
+       tls_crypto_info_init(TLS_1_2_VERSION, TLS_CIPHER_AES_GCM_128, &tls12);
+
+       addr.sin6_family = AF_INET6;
+       addr.sin6_addr = in6addr_any;
+       addr.sin6_port = 0;
+
+       fd = socket(AF_INET6, SOCK_STREAM, 0);
+       sfd = socket(AF_INET6, SOCK_STREAM, 0);
 
        ret = bind(sfd, &addr, sizeof(addr));
        ASSERT_EQ(ret, 0);
        ret = listen(sfd, 10);
        ASSERT_EQ(ret, 0);
 
+       len = sizeof(addr);
        ret = getsockname(sfd, &addr, &len);
        ASSERT_EQ(ret, 0);
 
        ret = connect(fd, &addr, sizeof(addr));
        ASSERT_EQ(ret, 0);
 
+       len = sizeof(addr);
+       ret = getsockname(fd, &addr, &len);
+       ASSERT_EQ(ret, 0);
+
        ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
-       if (ret != 0) {
-               notls = true;
-               printf("Failure setting TCP_ULP, testing without tls\n");
+       if (ret) {
+               ASSERT_EQ(errno, ENOENT);
+               SKIP(return, "no TLS support");
        }
+       ASSERT_EQ(ret, 0);
 
-       if (!notls) {
-               ret = setsockopt(fd, SOL_TLS, TLS_TX, &tls12,
-                                sizeof(tls12));
-               EXPECT_EQ(ret, 0);
-       }
+       ret = setsockopt(fd, SOL_TLS, TLS_TX, &tls12, tls12.len);
+       ASSERT_EQ(ret, 0);
 
-       cfd = accept(sfd, &addr, &len);
-       ASSERT_GE(cfd, 0);
+       ret = setsockopt(fd, SOL_TLS, TLS_RX, &tls12, tls12.len);
+       ASSERT_EQ(ret, 0);
 
-       if (!notls) {
-               ret = setsockopt(cfd, IPPROTO_TCP, TCP_ULP, "tls",
-                                sizeof("tls"));
-               EXPECT_EQ(ret, 0);
+       len2 = sizeof(addr2);
+       ret = getsockname(fd, &addr2, &len2);
+       ASSERT_EQ(ret, 0);
 
-               ret = setsockopt(cfd, SOL_TLS, TLS_RX, &tls12,
-                                sizeof(tls12));
-               EXPECT_EQ(ret, 0);
-       }
+       EXPECT_EQ(len2, len);
+       EXPECT_EQ(memcmp(&addr, &addr2, len), 0);
 
-       close(sfd);
        close(fd);
-       close(cfd);
+       close(sfd);
 }
 
 TEST_HARNESS_MAIN
index 8748199..ffca314 100644 (file)
@@ -5,7 +5,8 @@ TEST_PROGS := nft_trans_stress.sh nft_fib.sh nft_nat.sh bridge_brouter.sh \
        conntrack_icmp_related.sh nft_flowtable.sh ipvs.sh \
        nft_concat_range.sh nft_conntrack_helper.sh \
        nft_queue.sh nft_meta.sh nf_nat_edemux.sh \
-       ipip-conntrack-mtu.sh conntrack_tcp_unreplied.sh
+       ipip-conntrack-mtu.sh conntrack_tcp_unreplied.sh \
+       conntrack_vrf.sh
 
 LDLIBS = -lmnl
 TEST_GEN_FILES =  nf-queue
diff --git a/tools/testing/selftests/netfilter/conntrack_vrf.sh b/tools/testing/selftests/netfilter/conntrack_vrf.sh
new file mode 100755 (executable)
index 0000000..91f3ef0
--- /dev/null
@@ -0,0 +1,219 @@
+#!/bin/sh
+
+# This script demonstrates interaction of conntrack and vrf.
+# The vrf driver calls the netfilter hooks again, with oif/iif
+# pointing at the VRF device.
+#
+# For ingress, this means first iteration has iifname of lower/real
+# device.  In this script, thats veth0.
+# Second iteration is iifname set to vrf device, tvrf in this script.
+#
+# For egress, this is reversed: first iteration has the vrf device,
+# second iteration is done with the lower/real/veth0 device.
+#
+# test_ct_zone_in demonstrates unexpected change of nftables
+# behavior # caused by commit 09e856d54bda5f28 "vrf: Reset skb conntrack
+# connection on VRF rcv"
+#
+# It was possible to assign conntrack zone to a packet (or mark it for
+# `notracking`) in the prerouting chain before conntrack, based on real iif.
+#
+# After the change, the zone assignment is lost and the zone is assigned based
+# on the VRF master interface (in case such a rule exists).
+# assignment is lost. Instead, assignment based on the `iif` matching
+# Thus it is impossible to distinguish packets based on the original
+# interface.
+#
+# test_masquerade_vrf and test_masquerade_veth0 demonstrate the problem
+# that was supposed to be fixed by the commit mentioned above to make sure
+# that any fix to test case 1 won't break masquerade again.
+
+ksft_skip=4
+
+IP0=172.30.30.1
+IP1=172.30.30.2
+PFXL=30
+ret=0
+
+sfx=$(mktemp -u "XXXXXXXX")
+ns0="ns0-$sfx"
+ns1="ns1-$sfx"
+
+cleanup()
+{
+       ip netns pids $ns0 | xargs kill 2>/dev/null
+       ip netns pids $ns1 | xargs kill 2>/dev/null
+
+       ip netns del $ns0 $ns1
+}
+
+nft --version > /dev/null 2>&1
+if [ $? -ne 0 ];then
+       echo "SKIP: Could not run test without nft tool"
+       exit $ksft_skip
+fi
+
+ip -Version > /dev/null 2>&1
+if [ $? -ne 0 ];then
+       echo "SKIP: Could not run test without ip tool"
+       exit $ksft_skip
+fi
+
+ip netns add "$ns0"
+if [ $? -ne 0 ];then
+       echo "SKIP: Could not create net namespace $ns0"
+       exit $ksft_skip
+fi
+ip netns add "$ns1"
+
+trap cleanup EXIT
+
+ip netns exec $ns0 sysctl -q -w net.ipv4.conf.default.rp_filter=0
+ip netns exec $ns0 sysctl -q -w net.ipv4.conf.all.rp_filter=0
+ip netns exec $ns0 sysctl -q -w net.ipv4.conf.all.rp_filter=0
+
+ip link add veth0 netns "$ns0" type veth peer name veth0 netns "$ns1" > /dev/null 2>&1
+if [ $? -ne 0 ];then
+       echo "SKIP: Could not add veth device"
+       exit $ksft_skip
+fi
+
+ip -net $ns0 li add tvrf type vrf table 9876
+if [ $? -ne 0 ];then
+       echo "SKIP: Could not add vrf device"
+       exit $ksft_skip
+fi
+
+ip -net $ns0 li set lo up
+
+ip -net $ns0 li set veth0 master tvrf
+ip -net $ns0 li set tvrf up
+ip -net $ns0 li set veth0 up
+ip -net $ns1 li set veth0 up
+
+ip -net $ns0 addr add $IP0/$PFXL dev veth0
+ip -net $ns1 addr add $IP1/$PFXL dev veth0
+
+ip netns exec $ns1 iperf3 -s > /dev/null 2>&1&
+if [ $? -ne 0 ];then
+       echo "SKIP: Could not start iperf3"
+       exit $ksft_skip
+fi
+
+# test vrf ingress handling.
+# The incoming connection should be placed in conntrack zone 1,
+# as decided by the first iteration of the ruleset.
+test_ct_zone_in()
+{
+ip netns exec $ns0 nft -f - <<EOF
+table testct {
+       chain rawpre {
+               type filter hook prerouting priority raw;
+
+               iif { veth0, tvrf } counter meta nftrace set 1
+               iif veth0 counter ct zone set 1 counter return
+               iif tvrf counter ct zone set 2 counter return
+               ip protocol icmp counter
+               notrack counter
+       }
+
+       chain rawout {
+               type filter hook output priority raw;
+
+               oif veth0 counter ct zone set 1 counter return
+               oif tvrf counter ct zone set 2 counter return
+               notrack counter
+       }
+}
+EOF
+       ip netns exec $ns1 ping -W 1 -c 1 -I veth0 $IP0 > /dev/null
+
+       # should be in zone 1, not zone 2
+       count=$(ip netns exec $ns0 conntrack -L -s $IP1 -d $IP0 -p icmp --zone 1 2>/dev/null | wc -l)
+       if [ $count -eq 1 ]; then
+               echo "PASS: entry found in conntrack zone 1"
+       else
+               echo "FAIL: entry not found in conntrack zone 1"
+               count=$(ip netns exec $ns0 conntrack -L -s $IP1 -d $IP0 -p icmp --zone 2 2> /dev/null | wc -l)
+               if [ $count -eq 1 ]; then
+                       echo "FAIL: entry found in zone 2 instead"
+               else
+                       echo "FAIL: entry not in zone 1 or 2, dumping table"
+                       ip netns exec $ns0 conntrack -L
+                       ip netns exec $ns0 nft list ruleset
+               fi
+       fi
+}
+
+# add masq rule that gets evaluated w. outif set to vrf device.
+# This tests the first iteration of the packet through conntrack,
+# oifname is the vrf device.
+test_masquerade_vrf()
+{
+       ip netns exec $ns0 conntrack -F 2>/dev/null
+
+ip netns exec $ns0 nft -f - <<EOF
+flush ruleset
+table ip nat {
+       chain postrouting {
+               type nat hook postrouting priority 0;
+               # NB: masquerade should always be combined with 'oif(name) bla',
+               # lack of this is intentional here, we want to exercise double-snat.
+               ip saddr 172.30.30.0/30 counter masquerade random
+       }
+}
+EOF
+       ip netns exec $ns0 ip vrf exec tvrf iperf3 -t 1 -c $IP1 >/dev/null
+       if [ $? -ne 0 ]; then
+               echo "FAIL: iperf3 connect failure with masquerade + sport rewrite on vrf device"
+               ret=1
+               return
+       fi
+
+       # must also check that nat table was evaluated on second (lower device) iteration.
+       ip netns exec $ns0 nft list table ip nat |grep -q 'counter packets 2'
+       if [ $? -eq 0 ]; then
+               echo "PASS: iperf3 connect with masquerade + sport rewrite on vrf device"
+       else
+               echo "FAIL: vrf masq rule has unexpected counter value"
+               ret=1
+       fi
+}
+
+# add masq rule that gets evaluated w. outif set to veth device.
+# This tests the 2nd iteration of the packet through conntrack,
+# oifname is the lower device (veth0 in this case).
+test_masquerade_veth()
+{
+       ip netns exec $ns0 conntrack -F 2>/dev/null
+ip netns exec $ns0 nft -f - <<EOF
+flush ruleset
+table ip nat {
+       chain postrouting {
+               type nat hook postrouting priority 0;
+               meta oif veth0 ip saddr 172.30.30.0/30 counter masquerade random
+       }
+}
+EOF
+       ip netns exec $ns0 ip vrf exec tvrf iperf3 -t 1 -c $IP1 > /dev/null
+       if [ $? -ne 0 ]; then
+               echo "FAIL: iperf3 connect failure with masquerade + sport rewrite on veth device"
+               ret=1
+               return
+       fi
+
+       # must also check that nat table was evaluated on second (lower device) iteration.
+       ip netns exec $ns0 nft list table ip nat |grep -q 'counter packets 2'
+       if [ $? -eq 0 ]; then
+               echo "PASS: iperf3 connect with masquerade + sport rewrite on veth device"
+       else
+               echo "FAIL: vrf masq rule has unexpected counter value"
+               ret=1
+       fi
+}
+
+test_ct_zone_in
+test_masquerade_vrf
+test_masquerade_veth
+
+exit $ret
index da1c1e4..d88867d 100755 (executable)
@@ -759,19 +759,21 @@ test_port_shadow()
        local result=""
        local logmsg=""
 
-       echo ROUTER | ip netns exec "$ns0" nc -w 5 -u -l -p 1405 >/dev/null 2>&1 &
-       nc_r=$!
+       # make shadow entry, from client (ns2), going to (ns1), port 41404, sport 1405.
+       echo "fake-entry" | ip netns exec "$ns2" timeout 1 socat -u STDIN UDP:"$daddrc":41404,sourceport=1405
 
-       echo CLIENT | ip netns exec "$ns2" nc -w 5 -u -l -p 1405 >/dev/null 2>&1 &
-       nc_c=$!
+       echo ROUTER | ip netns exec "$ns0" timeout 5 socat -u STDIN UDP4-LISTEN:1405 &
+       sc_r=$!
 
-       # make shadow entry, from client (ns2), going to (ns1), port 41404, sport 1405.
-       echo "fake-entry" | ip netns exec "$ns2" nc -w 1 -p 1405 -u "$daddrc" 41404 > /dev/null
+       echo CLIENT | ip netns exec "$ns2" timeout 5 socat -u STDIN UDP4-LISTEN:1405,reuseport &
+       sc_c=$!
+
+       sleep 0.3
 
        # ns1 tries to connect to ns0:1405.  With default settings this should connect
        # to client, it matches the conntrack entry created above.
 
-       result=$(echo "" | ip netns exec "$ns1" nc -w 1 -p 41404 -u "$daddrs" 1405)
+       result=$(echo "data" | ip netns exec "$ns1" timeout 1 socat - UDP:"$daddrs":1405,sourceport=41404)
 
        if [ "$result" = "$expect" ] ;then
                echo "PASS: portshadow test $test: got reply from ${expect}${logmsg}"
@@ -780,7 +782,7 @@ test_port_shadow()
                ret=1
        fi
 
-       kill $nc_r $nc_c 2>/dev/null
+       kill $sc_r $sc_c 2>/dev/null
 
        # flush udp entries for next test round, if any
        ip netns exec "$ns0" conntrack -F >/dev/null 2>&1
@@ -816,11 +818,10 @@ table $family raw {
        chain prerouting {
                type filter hook prerouting priority -300; policy accept;
                meta iif veth0 udp dport 1405 notrack
-               udp dport 1405 notrack
        }
        chain output {
                type filter hook output priority -300; policy accept;
-               udp sport 1405 notrack
+               meta oif veth0 udp sport 1405 notrack
        }
 }
 EOF
@@ -851,6 +852,18 @@ test_port_shadowing()
 {
        local family="ip"
 
+       conntrack -h >/dev/null 2>&1
+       if [ $? -ne 0 ];then
+               echo "SKIP: Could not run nat port shadowing test without conntrack tool"
+               return
+       fi
+
+       socat -h > /dev/null 2>&1
+       if [ $? -ne 0 ];then
+               echo "SKIP: Could not run nat port shadowing test without socat tool"
+               return
+       fi
+
        ip netns exec "$ns0" sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null
        ip netns exec "$ns0" sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null
 
index 3d202b9..7d27f1f 100755 (executable)
@@ -16,6 +16,10 @@ timeout=4
 
 cleanup()
 {
+       ip netns pids ${ns1} | xargs kill 2>/dev/null
+       ip netns pids ${ns2} | xargs kill 2>/dev/null
+       ip netns pids ${nsrouter} | xargs kill 2>/dev/null
+
        ip netns del ${ns1}
        ip netns del ${ns2}
        ip netns del ${nsrouter}
@@ -332,6 +336,55 @@ EOF
        echo "PASS: tcp via loopback and re-queueing"
 }
 
+test_icmp_vrf() {
+       ip -net $ns1 link add tvrf type vrf table 9876
+       if [ $? -ne 0 ];then
+               echo "SKIP: Could not add vrf device"
+               return
+       fi
+
+       ip -net $ns1 li set eth0 master tvrf
+       ip -net $ns1 li set tvrf up
+
+       ip -net $ns1 route add 10.0.2.0/24 via 10.0.1.1 dev eth0 table 9876
+ip netns exec ${ns1} nft -f /dev/stdin <<EOF
+flush ruleset
+table inet filter {
+       chain output {
+               type filter hook output priority 0; policy accept;
+               meta oifname "tvrf" icmp type echo-request counter queue num 1
+               meta oifname "eth0" icmp type echo-request counter queue num 1
+       }
+       chain post {
+               type filter hook postrouting priority 0; policy accept;
+               meta oifname "tvrf" icmp type echo-request counter queue num 1
+               meta oifname "eth0" icmp type echo-request counter queue num 1
+       }
+}
+EOF
+       ip netns exec ${ns1} ./nf-queue -q 1 -t $timeout &
+       local nfqpid=$!
+
+       sleep 1
+       ip netns exec ${ns1} ip vrf exec tvrf ping -c 1 10.0.2.99 > /dev/null
+
+       for n in output post; do
+               for d in tvrf eth0; do
+                       ip netns exec ${ns1} nft list chain inet filter $n | grep -q "oifname \"$d\" icmp type echo-request counter packets 1"
+                       if [ $? -ne 0 ] ; then
+                               echo "FAIL: chain $n: icmp packet counter mismatch for device $d" 1>&2
+                               ip netns exec ${ns1} nft list ruleset
+                               ret=1
+                               return
+                       fi
+               done
+       done
+
+       wait $nfqpid
+       [ $? -eq 0 ] && echo "PASS: icmp+nfqueue via vrf"
+       wait 2>/dev/null
+}
+
 ip netns exec ${nsrouter} sysctl net.ipv6.conf.all.forwarding=1 > /dev/null
 ip netns exec ${nsrouter} sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null
 ip netns exec ${nsrouter} sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null
@@ -372,5 +425,6 @@ test_queue 20
 test_tcp_forward
 test_tcp_localhost
 test_tcp_localhost_requeue
+test_icmp_vrf
 
 exit $ret
index 503982b..9183240 100644 (file)
@@ -68,7 +68,7 @@
         "cmdUnderTest": "$TC action add action bpf object-file $EBPFDIR/action.o section action-ok index 667",
         "expExitCode": "0",
         "verifyCmd": "$TC action get action bpf index 667",
-        "matchPattern": "action order [0-9]*: bpf action.o:\\[action-ok\\] id [0-9]* tag [0-9a-f]{16}( jited)? default-action pipe.*index 667 ref",
+        "matchPattern": "action order [0-9]*: bpf action.o:\\[action-ok\\] id [0-9].* tag [0-9a-f]{16}( jited)? default-action pipe.*index 667 ref",
         "matchCount": "1",
         "teardown": [
             "$TC action flush action bpf"
index 88a20c7..c604609 100644 (file)
@@ -15,7 +15,7 @@
            "cmdUnderTest": "$TC qdisc add dev $ETH root handle 1: mq",
            "expExitCode": "0",
            "verifyCmd": "$TC qdisc show dev $ETH",
-           "matchPattern": "qdisc pfifo_fast 0: parent 1:[1-4] bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1",
+           "matchPattern": "qdisc [a-zA-Z0-9_]+ 0: parent 1:[1-4]",
            "matchCount": "4",
            "teardown": [
                    "echo \"1\" > /sys/bus/netdevsim/del_device"
@@ -37,7 +37,7 @@
            "cmdUnderTest": "$TC qdisc add dev $ETH root handle 1: mq",
            "expExitCode": "0",
            "verifyCmd": "$TC qdisc show dev $ETH",
-           "matchPattern": "qdisc pfifo_fast 0: parent 1:[1-9,a-f][0-9,a-f]{0,2} bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1",
+           "matchPattern": "qdisc [a-zA-Z0-9_]+ 0: parent 1:[1-9,a-f][0-9,a-f]{0,2}",
            "matchCount": "256",
            "teardown": [
                    "echo \"1\" > /sys/bus/netdevsim/del_device"
@@ -60,7 +60,7 @@
            "cmdUnderTest": "$TC qdisc add dev $ETH root handle 1: mq",
            "expExitCode": "2",
            "verifyCmd": "$TC qdisc show dev $ETH",
-           "matchPattern": "qdisc pfifo_fast 0: parent 1:[1-4] bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1",
+           "matchPattern": "qdisc [a-zA-Z0-9_]+ 0: parent 1:[1-4]",
            "matchCount": "4",
            "teardown": [
                    "echo \"1\" > /sys/bus/netdevsim/del_device"
@@ -82,7 +82,7 @@
            "cmdUnderTest": "$TC qdisc del dev $ETH root handle 1: mq",
            "expExitCode": "2",
            "verifyCmd": "$TC qdisc show dev $ETH",
-           "matchPattern": "qdisc pfifo_fast 0: parent 1:[1-4] bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1",
+           "matchPattern": "qdisc [a-zA-Z0-9_]+ 0: parent 1:[1-4]",
            "matchCount": "0",
            "teardown": [
                    "echo \"1\" > /sys/bus/netdevsim/del_device"
            "cmdUnderTest": "$TC qdisc del dev $ETH root handle 1: mq",
            "expExitCode": "2",
            "verifyCmd": "$TC qdisc show dev $ETH",
-           "matchPattern": "qdisc pfifo_fast 0: parent 1:[1-4] bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1",
+           "matchPattern": "qdisc [a-zA-Z0-9_]+ 0: parent 1:[1-4]",
            "matchCount": "0",
            "teardown": [
                    "echo \"1\" > /sys/bus/netdevsim/del_device"
            "cmdUnderTest": "$TC qdisc add dev $ETH root handle 1: mq",
            "expExitCode": "2",
            "verifyCmd": "$TC qdisc show dev $ETH",
-           "matchPattern": "qdisc pfifo_fast 0: parent 1:[1-4] bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1",
+           "matchPattern": "qdisc [a-zA-Z0-9_]+ 0: parent 1:[1-4]",
            "matchCount": "0",
            "teardown": [
                    "echo \"1\" > /sys/bus/netdevsim/del_device"
index d317245..9646bb9 100644 (file)
@@ -2548,72 +2548,36 @@ struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn)
 }
 EXPORT_SYMBOL_GPL(gfn_to_page);
 
-void kvm_release_pfn(kvm_pfn_t pfn, bool dirty, struct gfn_to_pfn_cache *cache)
+void kvm_release_pfn(kvm_pfn_t pfn, bool dirty)
 {
        if (pfn == 0)
                return;
 
-       if (cache)
-               cache->pfn = cache->gfn = 0;
-
        if (dirty)
                kvm_release_pfn_dirty(pfn);
        else
                kvm_release_pfn_clean(pfn);
 }
 
-static void kvm_cache_gfn_to_pfn(struct kvm_memory_slot *slot, gfn_t gfn,
-                                struct gfn_to_pfn_cache *cache, u64 gen)
-{
-       kvm_release_pfn(cache->pfn, cache->dirty, cache);
-
-       cache->pfn = gfn_to_pfn_memslot(slot, gfn);
-       cache->gfn = gfn;
-       cache->dirty = false;
-       cache->generation = gen;
-}
-
-static int __kvm_map_gfn(struct kvm_memslots *slots, gfn_t gfn,
-                        struct kvm_host_map *map,
-                        struct gfn_to_pfn_cache *cache,
-                        bool atomic)
+int kvm_vcpu_map(struct kvm_vcpu *vcpu, gfn_t gfn, struct kvm_host_map *map)
 {
        kvm_pfn_t pfn;
        void *hva = NULL;
        struct page *page = KVM_UNMAPPED_PAGE;
-       struct kvm_memory_slot *slot = __gfn_to_memslot(slots, gfn);
-       u64 gen = slots->generation;
 
        if (!map)
                return -EINVAL;
 
-       if (cache) {
-               if (!cache->pfn || cache->gfn != gfn ||
-                       cache->generation != gen) {
-                       if (atomic)
-                               return -EAGAIN;
-                       kvm_cache_gfn_to_pfn(slot, gfn, cache, gen);
-               }
-               pfn = cache->pfn;
-       } else {
-               if (atomic)
-                       return -EAGAIN;
-               pfn = gfn_to_pfn_memslot(slot, gfn);
-       }
+       pfn = gfn_to_pfn(vcpu->kvm, gfn);
        if (is_error_noslot_pfn(pfn))
                return -EINVAL;
 
        if (pfn_valid(pfn)) {
                page = pfn_to_page(pfn);
-               if (atomic)
-                       hva = kmap_atomic(page);
-               else
-                       hva = kmap(page);
+               hva = kmap(page);
 #ifdef CONFIG_HAS_IOMEM
-       } else if (!atomic) {
-               hva = memremap(pfn_to_hpa(pfn), PAGE_SIZE, MEMREMAP_WB);
        } else {
-               return -EINVAL;
+               hva = memremap(pfn_to_hpa(pfn), PAGE_SIZE, MEMREMAP_WB);
 #endif
        }
 
@@ -2627,27 +2591,9 @@ static int __kvm_map_gfn(struct kvm_memslots *slots, gfn_t gfn,
 
        return 0;
 }
-
-int kvm_map_gfn(struct kvm_vcpu *vcpu, gfn_t gfn, struct kvm_host_map *map,
-               struct gfn_to_pfn_cache *cache, bool atomic)
-{
-       return __kvm_map_gfn(kvm_memslots(vcpu->kvm), gfn, map,
-                       cache, atomic);
-}
-EXPORT_SYMBOL_GPL(kvm_map_gfn);
-
-int kvm_vcpu_map(struct kvm_vcpu *vcpu, gfn_t gfn, struct kvm_host_map *map)
-{
-       return __kvm_map_gfn(kvm_vcpu_memslots(vcpu), gfn, map,
-               NULL, false);
-}
 EXPORT_SYMBOL_GPL(kvm_vcpu_map);
 
-static void __kvm_unmap_gfn(struct kvm *kvm,
-                       struct kvm_memory_slot *memslot,
-                       struct kvm_host_map *map,
-                       struct gfn_to_pfn_cache *cache,
-                       bool dirty, bool atomic)
+void kvm_vcpu_unmap(struct kvm_vcpu *vcpu, struct kvm_host_map *map, bool dirty)
 {
        if (!map)
                return;
@@ -2655,45 +2601,21 @@ static void __kvm_unmap_gfn(struct kvm *kvm,
        if (!map->hva)
                return;
 
-       if (map->page != KVM_UNMAPPED_PAGE) {
-               if (atomic)
-                       kunmap_atomic(map->hva);
-               else
-                       kunmap(map->page);
-       }
+       if (map->page != KVM_UNMAPPED_PAGE)
+               kunmap(map->page);
 #ifdef CONFIG_HAS_IOMEM
-       else if (!atomic)
-               memunmap(map->hva);
        else
-               WARN_ONCE(1, "Unexpected unmapping in atomic context");
+               memunmap(map->hva);
 #endif
 
        if (dirty)
-               mark_page_dirty_in_slot(kvm, memslot, map->gfn);
+               kvm_vcpu_mark_page_dirty(vcpu, map->gfn);
 
-       if (cache)
-               cache->dirty |= dirty;
-       else
-               kvm_release_pfn(map->pfn, dirty, NULL);
+       kvm_release_pfn(map->pfn, dirty);
 
        map->hva = NULL;
        map->page = NULL;
 }
-
-int kvm_unmap_gfn(struct kvm_vcpu *vcpu, struct kvm_host_map *map, 
-                 struct gfn_to_pfn_cache *cache, bool dirty, bool atomic)
-{
-       __kvm_unmap_gfn(vcpu->kvm, gfn_to_memslot(vcpu->kvm, map->gfn), map,
-                       cache, dirty, atomic);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(kvm_unmap_gfn);
-
-void kvm_vcpu_unmap(struct kvm_vcpu *vcpu, struct kvm_host_map *map, bool dirty)
-{
-       __kvm_unmap_gfn(vcpu->kvm, kvm_vcpu_gfn_to_memslot(vcpu, map->gfn),
-                       map, NULL, dirty, false);
-}
 EXPORT_SYMBOL_GPL(kvm_vcpu_unmap);
 
 struct page *kvm_vcpu_gfn_to_page(struct kvm_vcpu *vcpu, gfn_t gfn)